TensorFlow2 Python深度学习 - TensorFlow2框架入门 - 张量(Tensor)的定义与操作
锋哥原创的Scikit-learn Python机器学习视频教程:
https://www.bilibili.com/video/BV1X5xVz6E4w/
课程介绍
本课程主要讲解基于TensorFlow2的Python深度学习知识,包括深度学习概述,TensorFlow2框架入门知识,以及卷积神经网络(CNN),循环神经网络(RNN),生成对抗网络(GAN),模型保存与加载等。
TensorFlow2 Python深度学习 - TensorFlow2框架入门 - 张量(Tensor)的定义与操作
在 TensorFlow 2.x 中,张量(Tensor)是数据的核心表示方式,几乎所有的操作都会通过张量来进行。张量可以看作是一个多维数组或矩阵,它是一个包含数据的容器,可以存储不同类型的数据,如整数、浮点数、字符串等。
1. 张量的基本概念
张量是一个带有数据的 n 维数组。你可以把它理解为以下几种不同的情况:
-
0维张量:标量(数值),如
5
。 -
1维张量:向量,形如
[1, 2, 3]
。 -
2维张量:矩阵,形如
[[1, 2], [3, 4]]
。 -
3维张量:可以是一个立体数组,形如
[[[1, 2], [3, 4]], [[5, 6], [7, 8]]]
。 -
n维张量:任何维度的张量,形状根据数据决定。
2. 创建张量
从Python列表和NumPy数组创建
import tensorflow as tf
import numpy as np
# 创建0维张量(标量)
scalar = tf.constant(5)
print("标量:", scalar)
print("标量形状:", scalar.shape)
print("标量值:", scalar.numpy()) # 获取Python数值
# 创建1维张量(向量)
vector = tf.constant([1, 2, 3, 4, 5])
print("\n向量:", vector)
print("向量形状:", vector.shape)
# 创建2维张量(矩阵)
matrix = tf.constant([[1, 2, 3],[4, 5, 6]])
print("\n矩阵:", matrix)
print("矩阵形状:", matrix.shape)
# 创建3维张量
tensor_3d = tf.constant([[[1, 2], [3, 4]],[[5, 6], [7, 8]]])
print("\n3维张量:", tensor_3d)
print("3维张量形状:", tensor_3d.shape)
# 从NumPy数组创建
numpy_array = np.array([[1, 2], [3, 4]])
tensor_from_numpy = tf.constant(numpy_array)
print("\n从NumPy创建:", tensor_from_numpy)
运行结果:
标量: tf.Tensor(5, shape=(), dtype=int32)
标量形状: ()
标量值: 5
向量: tf.Tensor([1 2 3 4 5], shape=(5,), dtype=int32)
向量形状: (5,)
矩阵: tf.Tensor(
[[1 2 3][4 5 6]], shape=(2, 3), dtype=int32)
矩阵形状: (2, 3)
3维张量: tf.Tensor(
[[[1 2][3 4]]
[[5 6][7 8]]], shape=(2, 2, 2), dtype=int32)
3维张量形状: (2, 2, 2)
从NumPy创建: tf.Tensor(
[[1 2][3 4]], shape=(2, 2), dtype=int64)
创建特殊张量
import tensorflow as tf
# 创建全零张量
zeros = tf.zeros([2, 3])
print("全零矩阵:\n", zeros.numpy())
# 创建全一张量
ones = tf.ones([3, 2])
print("\n全一矩阵:\n", ones.numpy())
# 创建单位矩阵
eye = tf.eye(3) # 3x3单位矩阵
print("\n单位矩阵:\n", eye.numpy())
# 创建填充张量
filled = tf.fill([2, 2], 7) # 2x2矩阵,全部填充为7
print("\n填充矩阵:\n", filled.numpy())
# 创建随机张量
random_uniform = tf.random.uniform([2, 3], minval=0, maxval=1) # 均匀分布
print("\n均匀随机矩阵:\n", random_uniform.numpy())
random_normal = tf.random.normal([2, 2], mean=0, stddev=1) # 正态分布
print("\n正态随机矩阵:\n", random_normal.numpy())
运行结果:
全零矩阵:[[0. 0. 0.][0. 0. 0.]]
全一矩阵:[[1. 1.][1. 1.][1. 1.]]
单位矩阵:[[1. 0. 0.][0. 1. 0.][0. 0. 1.]]
填充矩阵:[[7 7][7 7]]
均匀随机矩阵:[[0.09006691 0.11618412 0.7688674 ][0.7187872 0.85705507 0.41901422]]
正态随机矩阵:[[-0.45069897 0.07884365][-0.29055706 0.04050421]]
3. 张量的关键属性
import tensorflow as tf
# 创建一个示例张量
tensor = tf.constant([[1, 2, 3],[4, 5, 6]], dtype=tf.float32)
print("张量:", tensor)
print("形状(shape):", tensor.shape) # 维度信息
print("秩(rank):", tensor.ndim) # 维度数量
print("数据类型(dtype):", tensor.dtype) # 数据类型
print("元素数量:", tf.size(tensor).numpy()) # 总元素个数
print("设备:", tensor.device) # 所在设备(CPU/GPU)
运行结果:
张量: tf.Tensor(
[[1. 2. 3.][4. 5. 6.]], shape=(2, 3), dtype=float32)
形状(shape): (2, 3)
秩(rank): 2
数据类型(dtype): <dtype: 'float32'>
元素数量: 6
设备: /job:localhost/replica:0/task:0/device:CPU:0
4. 张量的数据类型
import tensorflow as tf
# 指定数据类型创建张量
tensor_float32 = tf.constant([1, 2, 3], dtype=tf.float32)
tensor_int64 = tf.constant([1, 2, 3], dtype=tf.int64)
tensor_bool = tf.constant([True, False, True])
print("float32张量:", tensor_float32, tensor_float32.dtype)
print("int64张量:", tensor_int64, tensor_int64.dtype)
print("bool张量:", tensor_bool, tensor_bool.dtype)
# 数据类型转换
tensor_float = tf.constant([1.5, 2.7, 3.1])
tensor_int = tf.cast(tensor_float, dtype=tf.int32) # 浮点数转整数
print("\n原始浮点张量:", tensor_float.numpy())
print("转换为整数:", tensor_int.numpy())
5. 张量操作
数学运算
import tensorflow as tf
a = tf.constant([[1, 2],[3, 4]], dtype=tf.float32)
b = tf.constant([[5, 6],[7, 8]], dtype=tf.float32)
# 基本算术运算
print("加法:\n", (a + b).numpy()) # 或 tf.add(a, b)
print("\n减法:\n", (a - b).numpy()) # 或 tf.subtract(a, b)
print("\n逐元素乘法:\n", (a * b).numpy()) # 或 tf.multiply(a, b)
print("\n逐元素除法:\n", (a / b).numpy()) # 或 tf.divide(a, b)
# 矩阵乘法
matrix_mult = tf.matmul(a, b)
print("\n矩阵乘法:\n", matrix_mult.numpy())
# 其他数学运算
print("\n平方:\n", tf.square(a).numpy())
print("\n平方根:\n", tf.sqrt(a).numpy())
print("\n指数:\n", tf.exp(a).numpy())
print("\n对数:\n", tf.math.log(a).numpy())
运行结果:
加法:[[ 6. 8.][10. 12.]]
减法:[[-4. -4.][-4. -4.]]
逐元素乘法:[[ 5. 12.][21. 32.]]
逐元素除法:[[0.2 0.33333334][0.42857143 0.5 ]]
矩阵乘法:[[19. 22.][43. 50.]]
平方:[[ 1. 4.][ 9. 16.]]
平方根:[[1. 1.4142135][1.7320508 2. ]]
指数:[[ 2.7182817 7.389056 ][20.085537 54.59815 ]]
对数:[[0. 0.6931472][1.0986123 1.3862944]]
形状操作
import tensorflow as tf
tensor = tf.constant([[1, 2, 3],[4, 5, 6]])
print("原始张量:\n", tensor.numpy())
print("原始形状:", tensor.shape)
# 改变形状
reshaped = tf.reshape(tensor, [3, 2]) # 重塑为3x2
print("重塑为3x2:\n", reshaped.numpy())
# 展平
flattened = tf.reshape(tensor, [-1]) # -1 表示自动计算该维度大小
print("展平:", flattened.numpy())
# 转置
transposed = tf.transpose(tensor)
print("转置:\n", transposed.numpy())
# 增加/减少维度
expanded = tf.expand_dims(tensor, axis=0) # 在第0维增加维度
print("增加维度:\n", expanded.numpy())
print("增加维度后形状:", expanded.shape)
squeezed = tf.squeeze(expanded, axis=0) # 压缩维度
print("压缩维度:\n", squeezed.numpy())
print("压缩维度后形状:", squeezed.shape)
运行结果:
原始张量:[[1 2 3][4 5 6]]
原始形状: (2, 3)
重塑为3x2:[[1 2][3 4][5 6]]
展平: [1 2 3 4 5 6]
转置:[[1 4][2 5][3 6]]
增加维度:[[[1 2 3][4 5 6]]]
增加维度后形状: (1, 2, 3)
压缩维度:[[1 2 3][4 5 6]]
压缩维度后形状: (2, 3)
索引和切片
import tensorflow as tf
tensor = tf.constant([[1, 2, 3, 4],[5, 6, 7, 8],[9, 10, 11, 12]])
print("原始张量:\n", tensor.numpy())
# 索引
print("第一行:", tensor[0].numpy()) # 第一行
print("最后一个元素:", tensor[-1, -1].numpy()) # 最后一行最后一列
print("元素(1,2):", tensor[1, 2].numpy()) # 第2行第3列
# 切片
print("前两行:\n", tensor[0:2].numpy()) # 行切片
print("所有行的第2-4列:\n", tensor[:, 1:3].numpy()) # 列切片
print("间隔取样:\n", tensor[::2, ::2].numpy()) # 每隔一个取一个
# 布尔索引
mask = tensor > 5
print("大于5的掩码:\n", mask.numpy())
print("大于5的值:", tensor[mask].numpy())
运行结果:
原始张量:[[ 1 2 3 4][ 5 6 7 8][ 9 10 11 12]]
第一行: [1 2 3 4]
最后一个元素: 12
元素(1,2): 7
前两行:[[1 2 3 4][5 6 7 8]]
所有行的第2-4列:[[ 2 3][ 6 7][10 11]]
间隔取样:[[ 1 3][ 9 11]]
大于5的掩码:[[False False False False][False True True True][ True True True True]]
大于5的值: [ 6 7 8 9 10 11 12]
6. 张量广播
张量广播(Broadcasting)是一种使不同形状的张量能够进行元素级运算的技术,通过逻辑扩展小张量的维度使其与大张量形状兼容。
import tensorflow as tf
# 广播示例
a = tf.constant([[1, 2, 3]]) # 形状: (1, 3)
b = tf.constant([[4], [5], [6]]) # 形状: (3, 1)
print("a张量:\n", a.numpy())
print("b张量:\n", b.numpy())
# 广播机制会自动扩展维度以进行运算
result = a + b # 相当于 [[1,2,3]] + [[4],[5],[6]]
print("a的形状:", a.shape)
print("b的形状:", b.shape)
print("广播相加结果:\n", result.numpy())
print("结果形状:", result.shape)
运行结果:
a张量:[[1 2 3]]
b张量:[[4][5][6]]
a的形状: (1, 3)
b的形状: (3, 1)
广播相加结果:[[5 6 7][6 7 8][7 8 9]]
结果形状: (3, 3)