import tensorflow as tf
tf.__version__
'2.3.0'
1. 创建 tensor
- tensor 是存储和变换数据的主要工具, tensor 和 Numpy 的多维数组比较类似, 但是 tensor 可以提供 GPU 计算和自动求梯度等功能
# 创建行向量
x = tf.constant(range(12))
x
<tf.Tensor: shape=(12,), dtype=int32, numpy=array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])>
print(x.shape)
print(len(x)) # 获取向量中元素的个数
(12,)
12
# 使用reshape函数把行向量x的形状改为(3, 4)
x = tf.reshape(x,(3,4))
x
<tf.Tensor: shape=(3, 4), dtype=int32, numpy=
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])>
- 注意X属性中的形状发生了变化。上面x.reshape((3, 4))也可写成x.reshape((-1, 4))或x.reshape((3, -1))。由于x的元素个数是已知的,这里的-1是能够通过元素个数和其他维度的大小推断出来的。
2. 创建指定形状的张量
tf.zeros((2,3,4))
<tf.Tensor: shape=(2, 3, 4), dtype=float32, numpy=
array([[[0., 0., 0., 0.],
[0., 0., 0., 0.],
[0., 0., 0., 0.]],
[[0., 0., 0., 0.],
[0., 0., 0., 0.],
[0., 0., 0., 0.]]], dtype=float32)>
tf.ones((3,4))
<tf.Tensor: shape=(3, 4), dtype=float32, numpy=
array([[1., 1., 1., 1.],
[1., 1., 1., 1.],
[1., 1., 1., 1.]], dtype=float32)>
- 通过 Python 列表指定 tensor 中每个元素的值
y = tf.constant([[1,2,3,4],[4,5,6,7],[7,8,9,10]])
y
<tf.Tensor: shape=(3, 4), dtype=int32, numpy=
array([[ 1, 2, 3, 4],
[ 4, 5, 6, 7],
[ 7, 8, 9, 10]])>
-
随机生成tensor中每个元素的值。下面我们创建一个形状为(3, 4)的tensor。它的每个元素都随机采样于均值为0、标准差为1的正态分布。
-
tf.random.normal(shape=(3,4), mean=0, stddev=1)
- mean 均值
- 正态分布的标准差
tf.random.normal(shape=(3,4), mean=0, stddev=1)
<tf.Tensor: shape=(3, 4), dtype=float32, numpy=
array([[ 0.2814369 , 1.1456217 , 1.1553345 , 0.91973084],
[-0.24770287, -0.8750045 , -0.04902882, -0.02854874],
[ 1.4356786 , 2.6822388 , -0.58117944, 1.7481779 ]],
dtype=float32)>
3. Tensor 运算
print("x => ", x.shape)
print("y => ", x.shape)
print(x)
print(y)
x => (3, 4)
y => (3, 4)
tf.Tensor(
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]], shape=(3, 4), dtype=int32)
tf.Tensor(
[[ 1 2 3 4]
[ 4 5 6 7]
[ 7 8 9 10]], shape=(3, 4), dtype=int32)
3.1 按元素加法:
- 按对应元素相加
- x,y 都是 (3,4),做按元素加法, 结果形状不变
res01 = x + y
res01
<tf.Tensor: shape=(3, 4), dtype=int32, numpy=
array([[ 1, 3, 5, 7],
[ 8, 10, 12, 14],
[15, 17, 19, 21]])>
3.2 按元素乘法:
- 对应元素相乘, 注意不是矩阵的点乘
res02 = x * y
res02
<tf.Tensor: shape=(3, 4), dtype=int32, numpy=
array([[ 0, 2, 6, 12],
[ 16, 25, 36, 49],
[ 56, 72, 90, 110]])>
3.3 按元素除法:
res03 = x / y
res03
<tf.Tensor: shape=(3, 4), dtype=float64, numpy=
array([[0. , 0.5 , 0.66666667, 0.75 ],
[1. , 1. , 1. , 1. ],
[1.14285714, 1.125 , 1.11111111, 1.1 ]])>
3.4 按元素做指数运算:
- 类型转换 tf.cast(y, tf.float32)
- 指数运算 tf.exp(Y)
- 类型为bfloat16,half,float32,float64,complex64或complex128的张量。
- exp(y) = e^y
y = tf.cast(y, tf.float32) # 将y的类型转换为 float32
tf.exp(y) # 指数运算
<tf.Tensor: shape=(3, 4), dtype=float32, numpy=
array([[2.7182817e+00, 7.3890562e+00, 2.0085537e+01, 5.4598148e+01],
[5.4598148e+01, 1.4841316e+02, 4.0342880e+02, 1.0966332e+03],
[1.0966332e+03, 2.9809580e+03, 8.1030840e+03, 2.2026467e+04]],
dtype=float32)>
3.5 矩阵乘法
- 矩阵乘法要求两边行列对应: (3,4) <==> (4,3)
- 两边数据类型对应 int32 <==> int32
- tf.matmul(x,y)
- 矩阵乘法
- tf.transpose(y)
- 作用 : 转置
- (3,4) => (4,3)
y = tf.cast(y,tf.int32)
tf.matmul(x, tf.transpose(y))
<tf.Tensor: shape=(3, 3), dtype=int32, numpy=
array([[ 20, 38, 56],
[ 60, 126, 192],
[100, 214, 328]])>
3.6 矩阵拼接
- tf.concat([x,y],axis = 0)
- axis 表示维度 : 0 表示行, 1 表示列
- 分别在行上(维度0,即形状中的最左边元素)和列上(维度1,即形状中左起第二个元素)连结两个矩阵
- 在行上拼接两个矩阵,相当于将矩阵上下叠加 => shape = (6,4)
- 在列上拼接两个矩阵,相当于将矩阵左右叠加 => shape = (3,8)
print(x)
print(y)
tf.Tensor(
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]], shape=(3, 4), dtype=int32)
tf.Tensor(
[[ 1 2 3 4]
[ 4 5 6 7]
[ 7 8 9 10]], shape=(3, 4), dtype=int32)
tf.concat([x,y],axis = 0)
<tf.Tensor: shape=(6, 4), dtype=int32, numpy=
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11],
[ 1, 2, 3, 4],
[ 4, 5, 6, 7],
[ 7, 8, 9, 10]])>
tf.concat([x,y],axis = 1)
<tf.Tensor: shape=(3, 8), dtype=int32, numpy=
array([[ 0, 1, 2, 3, 1, 2, 3, 4],
[ 4, 5, 6, 7, 4, 5, 6, 7],
[ 8, 9, 10, 11, 7, 8, 9, 10]])>
3.7 矩阵比较
- 对应位置的元素进行比较
tf.equal(x,y)
<tf.Tensor: shape=(3, 4), dtype=bool, numpy=
array([[False, False, False, False],
[ True, True, True, True],
[False, False, False, False]])>
3.8 元素求和
- tf.reduce_sum(x) 对x中所有元素求和
- tf.norm(x) 计算x向量的范数
tf.reduce_sum(x) # numpy=66 结果
<tf.Tensor: shape=(), dtype=int32, numpy=66>
x = tf.cast(x, tf.float32)
tf.norm(x)
<tf.Tensor: shape=(), dtype=float32, numpy=22.494444>
4. 广播机制
- 当对两个形状不同的tensor按元素运算时,可能会触发广播(broadcasting)机制:先适当复制元素使这两个tensor形状相同后再按元素运算
- A: (3,1) B: (1,2)
- 由于A和B分别是3行1列和1行2列的矩阵,如果要计算A + B,那么A中第一列的3个元素被广播(复制)到了第二列,而B中第一行的2个元素被广播(复制)到了第二行和第三行。如此,就可以对2个3行2列的矩阵按元素相加。
A = tf.reshape(tf.constant(range(3)), (3,1))
B = tf.reshape(tf.constant(range(2)), (1,2))
A,B
(<tf.Tensor: shape=(3, 1), dtype=int32, numpy=
array([[0],
[1],
[2]])>,
<tf.Tensor: shape=(1, 2), dtype=int32, numpy=array([[0, 1]])>)
# 触发广播机制, A 中元素把第一列复制到第二列 => (3,2)
# B 中元素把第一行复制到第二行和第三行 => (3,2)
A + B
<tf.Tensor: shape=(3, 2), dtype=int32, numpy=
array([[0, 1],
[1, 2],
[2, 3]])>
5. 索引
- 在tensor中,索引(index)代表了元素的位置。tensor的索引从0开始逐一递增。例如,一个3行2列的矩阵的行索引分别为0、1和2,列索引分别为0和1。
5.1 获取指定范围的索引
- x[0:3] # 取索引为 0, 1, 2的三行
x[0:3] # 取索引为 0, 1, 2的三行
<tf.Tensor: shape=(3, 4), dtype=float32, numpy=
array([[ 0., 1., 2., 3.],
[ 4., 5., 6., 7.],
[ 8., 9., 10., 11.]], dtype=float32)>
5.2 为指定元素赋值
- tf.Variable 在修改Tensor值时, 必须转换成 Variable
- 变量通过 tf.Variable 类进行创建和跟踪。tf.Variable 表示张量,对它执行运算可以改变其值
- X[1,2].assign(9) : 为索引为 1,2 的元素赋值
x = tf.Variable(x)
x
<tf.Variable 'Variable:0' shape=(3, 4) dtype=float32, numpy=
array([[ 0., 1., 2., 3.],
[ 4., 5., 6., 7.],
[ 8., 9., 10., 11.]], dtype=float32)>
x[1,2].assign(9)
<tf.Variable 'UnreadVariable' shape=(3, 4) dtype=float32, numpy=
array([[ 0., 1., 2., 3.],
[ 4., 5., 9., 7.],
[ 8., 9., 10., 11.]], dtype=float32)>
5.3 为指定列赋值
x = tf.Variable(x)
x[1:2,:].assign(tf.ones(x[1:2,:].shape, dtype=tf.float32) * 3)
<tf.Variable 'UnreadVariable' shape=(3, 4) dtype=float32, numpy=
array([[ 0., 1., 2., 3.],
[ 3., 3., 3., 3.],
[ 8., 9., 10., 11.]], dtype=float32)>
6. tensor 和 numpy 的相互转换
- 通过array函数和asnumpy函数令数据在NDArray和NumPy格式之间相互变换。下面将NumPy实例变换成tensor实例
- numpy => tensor : tf.constant(P)
- tensor => numpy : np.array(T)
import numpy as np
P = np.ones((3,4))
T = tf.constant(P)
T
<tf.Tensor: shape=(3, 4), dtype=float64, numpy=
array([[1., 1., 1., 1.],
[1., 1., 1., 1.],
[1., 1., 1., 1.]])>
np.array(T)
array([[1., 1., 1., 1.],
[1., 1., 1., 1.],
[1., 1., 1., 1.]])