TensorFlow 2.0
github:https://github.com/dragen1860/Deep-Learning-with-TensorFlow-book
1、数据类型
x = tf.constant([[3,2],[3,4],[3,4]]) # constant:不可变常量 3行2列
print(type(x.shape)) #<class 'tensorflow.python.framework.tensor_shape.TensorShape'>
print(x.shape) # (3, 2) 3行2列
print(x.shape[0],x.shape[1], x.shape[-1], x.shape[-2] ) # 3 2 2 3 x.shape[0]:行数;x.shape[1]:列数;x.shape[-1]:列数
2、待优化张量 - Variable
用来定义:要计算梯度并优化的张量(属于一种特殊的张量),如神经网络层的W和𝒃。默认属性trainable=true(启动张量优化)
v=tf.Variable([[1,2,3],[3,4,5]]) # shape=(2, 3) 2行3列
3、创建张量
Numpy类型转tensor类型
a=tf.convert_to_tensor(np.array([[1,2.],[3,4]]))
创建全 0,全 1 张量
a =tf.fill([2,3],1) # tf.Tensor( [[1 1 1] [1 1 1]], shape=(2, 3), dtype=int32),value值决定类型。包含tf.zeros、tf.ones的赋值
b =tf.zeros([2,3],dtype=tf.dtypes.float32) # 全 0 张量, 值默认float32类型
b =tf.ones([2,3],dtype=tf.dtypes.float32) # 全 1 张量, 值默认float32类型
创建正态分布和均匀分布 张量
正态分布张量
通过 tf.random.normal(shape, mean=0.0, stddev=1.0)可以创建形状为 shape,均值为mean,标准差为 stddev 的正态分布𝒩(𝑚𝑒𝑎𝑛, 𝑠𝑡𝑑𝑑𝑒𝑣2)。例如:
创建均值为 0,标准差为 1的正太分布:a=tf.random.normal([2,3])
创建均值为 1,标准差为 2 的正太分布:a=tf.random.normal([2,2], mean=1,stddev=2)
tf.random.truncated_normal([784, 256]) 正态分布取值会在区间(μ-2σ,μ+2σ)内,否则重新取值
均匀分布 张量
创建采样自[𝑚𝑖𝑛𝑣𝑎𝑙, 𝑚𝑎𝑥𝑣𝑎𝑙]区间的均匀分布的张量。例如
创建采样自区间[0,1],shape 为[2,2]的矩阵:tf.random.uniform([2,2])
创建采样自区间[0,10],shape 为[2,2]的矩阵: tf.random.uniform([2,2],maxval=10)
创建序列张量
tf.range(limit, delta=1)可以创建[0,𝑙𝑖𝑚𝑖𝑡)之间,步长为 delta 的整形序列,不包含 limit 本身
例如,创建 0~9,步长为 1 的整形序列:
a=tf.range(10) # tf.Tensor([0 1 2 3 4 5 6 7 8 9], shape=(10,), dtype=int32)
向量
Dense全连接层创建
fc = layers.Dense(3) # 创建一层 Wx+b,输出节点为 3
# 通过 build 函数创建 W,b 张量,输入节点为 4
fc.build(input_shape=(2,4))
print(fc.kernel) # W shape=(4, 3) 4行3列向量
print(fc.bias) # 查看偏置b shape=(3,)
索引与切片
x = tf.random.normal([4,32,32,3])
print(x[0]) # shape=(32, 32, 3)
start: end: step切片的简写方式,其中从第一个元素读取时 start 可以省略,即 start=0 是可以省略,取到最后一个元素时 end 可以省略,步长为 1 时 step 可以省略
以 shape 为[4,32,32,3]的图片张量为例, 读取第 2,3 张图片: x[1:3] # shape=(2, 32, 32, 3)
2、维度变换Reshape
x=tf.range(96) # shape=(96,)
y= tf.reshape(x,[2,4,4,3]),过张量的 ndim 和 shape 成员属性获得张量的维度数和形状: x.ndim, x.shape # (4, TensorShape([2, 4, 4, 3]))
tf.reshape(x, new_shape),将张量的视图任意的合法改变。其中的参数-1 表示当前轴上长度需要根据视图总元素不变的法则自动计算
tf.reshape(x,[2,-1,3]) # x总共有96个元素, 96/(2*3)=16,即-1位置应该对应16个元素,所以 shape=(2, 16, 3)
# x [b, 28, 28] => [b, 28*28]
x = tf.reshape(x, [-1, 28*28])
维度增(expand_dims)删 (squeeze)
x = tf.random.uniform([28,28],maxval=10,dtype=tf.int32) # x.ndim=2 , x.shape=(28, 28)
通过 tf.expand_dims(x, axis)可在指定的 axis 轴插入一个新的维度(插入新维度原始数据不会变):
y = tf.expand_dims(x,axis=0) # y.ndim=3 , y.shape=(1, 28, 28) 在第0维度上插入一维
y = tf.expand_dims(x,axis=2) # y.ndim=3 , y.shape=(28, 28, 1) 在第2维度上插入一维
y = tf.squeeze(y, axis=0) # y.ndim=2 , y.shape=(28, 28) 只能删除长度为 1 的维度(数据缩小一维), 不会改变张量的存储。如果不指定axis参数,删除所有长度为 1 的维度。
数据复制和Broadcasting广播机制(自动扩展)
b = tf.constant([1,2]) # x.ndim=1 , tf.Tensor([1 2], shape=(2,), dtype=int32)
b = tf.expand_dims(b, axis=0) #x.ndim=2 , tf.Tensor([[1 2]], shape=(1, 2), dtype=int32)
c = tf.tile(b,multiples=[2,1]) #x.ndim=2 ,tf.Tensor([[1 2][1 2]], shape=(2, 2), dtype=int32)
操作符+在遇到 shape 不一致的 2 个张量时,会自动考虑将 2 个张量Broadcasting 到一致的 shape, 它调用 Broadcasting函数 tf.broadcast_to(x, new_shape)实现。
x = tf.random.normal([2,4])
w = tf.random.normal([4,3])
b = tf.random.normal([3])
y = x@w+b ----> y = x@w + tf.broadcast_to(b,[2,3]) # 列数不变,行数复制扩充。
数学运算
加(tf.add +)减(tf.subtract -)乘(tf.multiply *)除(tf.divide /)整除(//)余除(%)
乘方( tf.pow(x, a) 或𝑥 ∗∗ 𝑎 )
x = tf.range(4) # tf.Tensor([0 1 2 3], shape=(4,), dtype=int32)
tf.pow(x,3) # tf.Tensor([ 0 1 8 27], shape=(4,), dtype=int32)
y = tf.square(x) # 平方
z=tf.sqrt(x) # 平方根
指数(tf.pow(x, a) 或𝑥 ∗∗ 𝑎 )对数
自然指数 可以通过 tf.exp(x)实现,自然对数l g𝑒 𝑥可以通过 tf.math.log(x)实现
x=tf.exp(3.) # tf.Tensor(20.085537, shape=(), dtype=float32)
y=tf.math.log(x) # tf.Tensor(3.0, shape=(), dtype=float32)
矩阵相乘(tf.multiply *)
a 和 b 能够矩阵相乘的条件是,a 的倒数第一个维度长度(列)和b 的倒数第二个维度长度(行)必须相等(b最后一维是输出维数)
TensorFlow 进阶
合并(tf.concat) 堆叠(tf.stack) 分割( tf.split )
a = tf.random.normal([4,35,8]) # 模拟成绩册 A
b = tf.random.normal([6,35,8]) # 模拟成绩册 B
tf.concat([a,b],axis=0) # 合并成绩册 axis=0 表示在第一维上进行合并,剩下其它维shape要相同
a = tf.random.normal([35,8])
b = tf.random.normal([35,8])
tf.stack([a,b],axis=0) # 堆叠合并为 2 个班级 axis=0 表示在第一维前面增加一维,要堆叠的a、b的shape要相同
分割( tf.split )
x = tf.random.normal([10,35,8])
result = tf.split(x,axis=0,num_or_size_splits=10) # print(type(result)) --> <class 'list'> ; print(result[0].shape)--> (1, 35, 8)
result = tf.split(x,axis=0,num_or_size_splits=[4,2,2,2]) # print(result[0].shape)--> (4, 35, 8)
result = tf.unstack(x,axis=0)# Unstack 为长度为 1 result[0].shape--> (35, 8) unstack与split区别是分割后,维度没有了
向量范数
x = tf.ones([2,2])
tf.norm(x,ord=1) # 计算 L1 范数 , L1 范数,定义为向量𝒙的所有元素绝对值之和
tf.norm(x,ord=2) # 计算 L2 范数 , L2 范数,定义为向量𝒙的所有元素的平方和,再开根号
tf.norm(x,ord=np.inf) # 计算∞范数 ∞ −范数,定义为向量𝒙的所有元素绝对值的最大值
最大值(reduce_max)、最小值(reduce_min)、均值(reduce_mean)、和(reduce_sum )
通过 tf.reduce_max, tf.reduce_min, tf.reduce_mean, tf.reduce_sum 可以求解张量在某个维度上的最大、最小、均值、和,也可以求全局最大、最小、均值、和信息。
x = tf.random.normal([4,10])
tf.reduce_max(x,axis=1) # 统计第2维上的最大值
tf.reduce_min(x,axis=1) # 统计第2维上的最小值
tf.reduce_mean(x,axis=1) # 统计第2维上的均值
当不指定 axis 参数时,tf.reduce_*函数会求解出全局元素的最大、最小、均值、和
out = tf.random.normal([2,10])
max=tf.reduce_max(out,axis=1)# 返回第一维概率最大的值 tf.Tensor([1.1277846 0.40908417], shape=(2,), dtype=float32) , 1.1277846 --> 7位置值,0.40908417 --> 4位置值
pred = tf.argmax(out,axis=1)# 返回第一维概率最大值的位置 tf.Tensor([7 4], shape=(2,), dtype=int64)
argmin = tf.argmin(out,axis=1)# 返回第一维概率最小值的位置 tf.Tensor([3 8], shape=(2,), dtype=int64)
out = tf.random.normal([4,10])# 网络预测输出
y = tf.constant([1,2,2,0])# 真实标签
y = tf.one_hot(y,depth=10)# one-hot 编码
loss = tf.keras.losses.mse(y,out) # 计算每个样本的误差 tf.Tensor([0.7126961 0.79759413 0.5432343 0.9807483 ], shape=(4,), dtype=float32)
loss1 = tf.reduce_mean(loss) # 平均误差 tf.Tensor(0.75856817, shape=(), dtype=float32)
out = tf.nn.softmax(out, axis=1) # 输出转换为概率 ?
loss =tf.keras.losses.mse(y,out) # 计算每个样本的误差 ?
---------------------------------------------------
a=tf.random.uniform([2,5],maxval=5,dtype=tf.int32) # tf.Tensor([[0 4 1 4 0][2 4 2 1 3]], shape=(2, 5), dtype=int32)
b=tf.random.uniform([2,5],maxval=5,dtype=tf.int32) #tf.Tensor([[0 0 1 4 0][2 4 4 4 2]], shape=(2, 5), dtype=int32)
c=tf.equal(a,b) # 特征值是否相等 tf.Tensor([[ True False True True True][ True True False False False]], shape=(2, 5), dtype=bool)
d = tf.cast(c,dtype=tf.float32) # 布尔型转 int 型! tf.Tensor([[1. 0. 1. 1. 1.][1. 1. 0. 0. 0.]], shape=(2, 5), dtype=float32)
e=tf.reduce_sum(d,axis=1) # 第二维求和 tf.Tensor([4. 2.], shape=(2,), dtype=float32)
f=tf.reduce_sum(d) # 求总和 tf.Tensor(6.0, shape=(), dtype=float32)
常见大小比较函数:
g=tf.math.greater(a,b) # a>b 为true tf.Tensor([[False False True False False][False True True True False]], shape=(2, 5), dtype=bool)
m=tf.math.greater_equal(a,b) # a>=b 为true
h=tf.math.less(a,b) # a<b 为true
n=tf.math.less_equal(a,b) # a<=b 为true
l=tf.math.not_equal(a,b) # a不等于b 为true
t=tf.math.is_nan(a) # a=nan 为true
---------------------------------------------------
填充 tf.pad(x, paddings)函数
b = tf.constant([1,2,3,4]) # 0维数据 shape:(4,)
p = tf.constant([[1,3]]) # shape:(1, 2)
c = tf.pad(b, p) # 一维数据 的 pad填充 ,tf.Tensor([0 1 2 3 4 0 0 0], shape=(8,), dtype=int32),分别在左(1)右(3)填充
b = tf.constant([[1,2,3,4]]) # 一维数据 shape: (1, 4)
p = tf.constant([[1,3],[1,2]]) # shape:(2, 2)
c = tf.pad(b, p)# 填充 tf.Tensor([[0 0 0 0 0 0 0][0 1 2 3 4 0 0][0 0 0 0 0 0 0][0 0 0 0 0 0 0][0 0 0 0 0 0 0]], shape=(5, 7), dtype=int32) 分别在上(1)下(3)左(1)右(2)填充
b = tf.constant([[1,3],[1,2]]) # 二维数据 shape:(2, 2)
p = tf.constant([[1,3],[1,2]]) # shape:(2, 2)
c = tf.pad(b, p)# 填充 tf.Tensor([[0 0 0 0 0][0 1 3 0 0][0 1 2 0 0][0 0 0 0 0][0 0 0 0 0][0 0 0 0 0]], shape=(6, 5), dtype=int32) 分别在上(1)下(3)左(1)右(2)填充
复制(tf.tile)
x = tf.random.normal([4,32,32,3])
y=tf.tile(x,[2,3,3,1]) # 数据复制 y.shape:(8, 96, 96, 3),对应维度进行倍数复制
数据限幅--下限幅tf.maximum(x,a) 上限幅tf.minimum(x,a)
x=tf.range(10) # tf.Tensor([0 1 2 3 4 5 6 7 8 9], shape=(10,), dtype=int32)
y=tf.maximum(x,4) # 下限幅 tf.Tensor([4 4 4 4 4 5 6 7 8 9], shape=(10,), dtype=int32)
z=tf.minimum(x,6) # 上限幅 tf.Tensor([0 1 2 3 4 5 6 6 6 6], shape=(10,), dtype=int32)
m=tf.clip_by_value(x,4,6) # 下限幅 和 上限幅 tf.Tensor([4 4 4 4 4 5 6 6 6 6], shape=(10,), dtype=int32)
收集tf.gather
x = tf.random.uniform([4,35,8],maxval=100,dtype=tf.int32)# 4 个班级,每个班级 35 个学生,8 门科目,保存成绩册的张量 shape 为[4,35,8]。
y=tf.gather(x,[0,1],axis=0) # 在班级维度收集第 1-2 号班级成绩册 shape 为(2, 35, 8)
y=tf.gather(x,[0,1],axis=0) 等价于 切片𝑥[: 2],但gather支持不规则索引收集
tf.gather(x,[0,3,8,11,12,26],axis=1) # 收集第 1,4,9,12,13,27 号同学成绩
多维度收集tf.gather_nd
tf.gather_nd(x,[[1,1],[2,2],[3,3]]) # 根据多维度坐标收集数据
掩码 tf.boolean_mask
x = tf.random.uniform([4,35,8],maxval=100,dtype=tf.int32)# 4 个班级,每个班级 35 个学生,8 门科目,保存成绩册的张量 shape 为[4,35,8]。
y=tf.boolean_mask(x,mask=[True, False,False,True],axis=0)# 根据掩码方式采样班级(第 1 和第 4 个班级) shape=(2, 35, 8)。掩码的长度必须与对应维度的长度一致
# tf.boolean_mask 的用法其实与 tf.gather 非常类似,只不过一个通过掩码方式采样,一个直接给出索引号采样。y=tf.gather(x,[0,3],axis=0) 和 y=tf.boolean_mask(x,mask=[True, False,False,True],axis=0) 等价
x = tf.random.uniform([2,3,8],maxval=100,dtype=tf.int32)
y=tf.boolean_mask(x,[[True,True,False],[False,True,True]]) # shape=(4, 8)
z=tf.gather_nd(x,[[0,0],[0,1],[1,1],[1,2]]) # shape=(4, 8) y和z等价。收集0行0列、0行1列、1行1列、1行2列
tf.where ?
tf.scatter_nd?
tf.meshgrid?
六、神经网络
6.1 激活函数
1、tf.nn.sigmoid
到𝑥 ∈ [0,1]区间。 Sigmoid 函数在输入值较大或较小时容易出现梯度值接 近于 0 的现象,称为梯度弥散现象
z = tf.constant([2.,1.,0.1])
y=tf.nn.sigmoid(z) # tf.Tensor([0.880797 0.7310586 0.5249792], shape=(3,), dtype=float32)
2、tf.nn.relu
ReLU(REctified Linear Unit,修正线性单元)激活函数。𝑥 ∈ [0,x]区间。ReLU 函数在𝑥 < 0时梯度值恒为 0,也可能会造成梯度弥散现象
3、tf.nn.leaky_relu
tf.nn.leaky_relu(x, alpha=0.1) # 通过 LeakyReLU激活函数。其中 alpha 参数即𝑝参数
4、tf.nn.tanh
Tanh 函数能够将𝑥 ∈ 𝑅的输入“压缩”到[−1,1]区间。tanh 激活函数可通过 Sigmoid 函数缩放平移后实现
输出函数
1、Softmax 函数
z = tf.constant([2.,1.,0.1])
tf.nn.softmax(z) # 通过 Softmax 函数 tf.Tensor([0.6590012 0.24243298 0.09856589], shape=(3,), dtype=float32) 元素和为1
6.2 误差函数
1、均方差
均方差误差(Mean Squared Error, MSE)函数把输出向量和真实向量的两个点之间的欧式距离
均方差广泛应用在回归问题中,在分类问题中也可以应用均方差误差
loss = keras.losses.MSE(y_onehot, o) # 计算均方差,返回每个维度的均方差 shape=(2,)
loss = tf.reduce_mean(loss) # 计算batch均方差 shape=()
criteon = keras.losses.MeanSquaredError() # 创建 MSE 类 计算均方差
loss = criteon(y_onehot,o) # 计算 batch 均方差 shape=()
2、交叉熵
6.3 神经网络类型
CNN(卷积神经网络)、RNN(循环神经网络,LSTM)、DNN(深度神经网络、全连接网络)、注意力机制(Attention)网络、图神经网络(GCN)
激活函数(tf.keras.activations.*)
tf.keras.activations.relu() relu激活函数 𝑥 ∈ [0,x]区间,适合多层网络 是tf.keras中的实现 --- > relu ;tf.nn.relu是tensorflow中的实现 ---> tf.nn.leaky_relu
tf.keras.activations.tanh() tanh激活函数 𝑥 ∈ [-1,1]区间
tf.keras.activations.sigmoid() sigmoid激活函数 𝑥 ∈ [0,1]区间,适合浅层网络,多层容易出现梯度弥散现象
tf.keras.activations.softmax() softmax激活函数
tf.keras.activations.elu()指数线性激活函数
tf.keras.activations.hard_sigmoid() Hard sigmoid激活函数
tf.keras.activations.exponential()指数激活函数
tf.keras.activations.linear()线性激活函数
tf.keras.activations.selu() selu激活函数
tf.keras.activations.softplus() softplus激活函数
tf.keras.activations.softsign() softsign激活函数
损失函数(tf.keras.losses.*) 或
tf.keras.losses.categorical_crossentropy # --> categorical_crossentropy (多分类的对数损失函数,交叉熵),与 softmax 相对应的损失函数,针对于多分类问题。对应评价函数:keras.metrics.categorical_crossentropy
tf.keras.losses.binary_crossentropy # --> binary_crossentropy(对数损失函数,交叉熵),即 log loss,与 sigmoid 相对应的损失函数,针对于二分类问题。 对应评价函数:keras.metrics.binary_crossentropy。
如果使用的是类,那么别忘了后面呢还有一个括号,用来得到实例化的对象;如果是函数就只写函数名就可以了。tf.keras.losses.CategoricalCrossentropy() --> tf.keras.losses.categorical_crossentropy --> categorical_crossentropy 。
不管是BinaryCrossentropy还是CategoricalCrossentropy,其实两者都可以用于二分类或者多分类,没有那么明显的界线,后者是在前者的基础上进行扩展得来的。但是一般情况下都是按照上述例子中的默认用法进行使用的。
tf.keras.losses.sparse_categorical_crossentropy # (稀疏性多分类的对数损失函数,交叉熵) 在上面的多分类的对数损失函数的基础上,增加了稀疏性(即数据中多包含一定0数据的数据集) 对应评价函数:keras.metrics.sparse_categorical_crossentropy
tf.keras.losses.mean_squared_error --> mean_squared_error或mse(均方误差)等价 keras.losses.mse,keras.losses.MSE,tf.keras.losses.MeanSquaredError。对应评价函数:keras.metrics.mean_squared_error,keras.metrics.mse,keras.metrics.MSE
tf.keras.losses.mean_absolute_error --> mean_absolute_error ,mae (平均绝对值误差)等价 keras.losses.mae,keras.losses.MAE,tf.keras.losses.MeanAbsoluteError。对应评价函数:keras.metrics.mean_absolute_error,keras.metrics.mae,keras.metrics.MAE
tf.keras.losses.mean_absolute_percentage_error ---> mean_absolute_percentage_error或mape。等价 keras.losses.mape,keras.losses.MAPE。对应评价函数:keras.metrics.mean_absolute_percentage_error,keras.metrics.mape,keras.metrics.MAPE
tf.keras.losses.mean_squared_logarithmic_error ---> mean_squared_logarithmic_error或msle。 等价 keras.losses.msle,keras.losses.MSLE。对应评价函数:keras.metrics.mean_squared_logarithmic_error,keras.metrics.msle,keras.metrics.MSLE
tf.keras.losses.squared_hinge 对应评价函数:keras.metrics.squared_hinge
tf.keras.losses.hinge 对应评价函数:keras.metrics.hinge
tf.keras.losses.kullback_leibler_divergence 等价 keras.losses.kld,keras.losses.KLD。 对应评价函数:keras.metrics.kullback_leibler_divergence,keras.metrics.kld,keras.metrics.KLD
tf.keras.losses.poisson 对应评价函数:keras.metrics.poisson
tf.keras.losses.cosine_similarity 等价 keras.losses.cosine_proximity,keras.losses.cosine。 对应评价函数:keras.metrics.cosine_proximity,keras.metrics.cosine
tf.keras.losses.logcosh 对应评价函数:keras.losses.logcosh
tf.keras.losses.categorical_hinge 对应评价函数:keras.losses.categorical_hinge
优化器(tf.keras.optimizers.*)
tf.keras.optimizers.RMSprop --> RMSprop
tf.keras.optimizers.SGD --> SGD 、sgd
tf.keras.optimizers.Adam
tf.keras.optimizers.Adadelta
tf.keras.optimizers.Adagrad
tf.keras.optimizers.Adamax
tf.keras.optimizers.Ftrl
tf.keras.optimizers.Nadam
评价函数(metrics)
tf.keras.metrics.Accuracy --> accuracy
tf.keras.metrics.BinaryAccuracy --> binary_accuracy
tf.keras.metrics.BinaryCrossentropy --> binary_crossentropy
tf.keras.metrics.CategoricalAccuracy --> categorical_accuracy
tf.keras.metrics.CategoricalCrossentropy --> categorical_crossentropy
tf.keras.metrics.SparseCategoricalAccuracy --> sparse_categorical_accuracy
tf.keras.metrics.SparseCategoricalCrossentropy --> sparse_categorical_crossentropy
正则化
https://mp.weixin.qq.com/s/qVGd7vfhEcchOuYp8IN6Rw
dropout
# 添加 dropout 操作
x = tf.nn.dropout(x, rate=0.5)
# 添加 Dropout 层
model.add(layers.Dropout(rate=0.5))
随机打散通
Dataset.shuffle(buffer_size)