1、Tensor 张量=多维数组
2、常量 tf.constant(12,(tf.float32))
3、常用的精度类型有 tf.int16、tf.int32、tf.int64、tf.float16、tf.float32、 tf.float64,bool 等
4、读取精度: a.dtype()
5、类型转换 :tf.cast(a,tf.float32)
6、待优化张量(变量):aa=tf.Variable(a,(name="aa")), name,trainable 等属性
7、创建全 0 或全 1 张量:tf.zeros([5]),tf.ones([])
8、通过 tf.zeros_like, tf.ones_like 可以方便地新建与某个张量 shape 一致,且内容为全 0 或
全 1 的张量。
9、通过 tf.fill(shape, value)可以创建全为自定义数值 value 的张量,形状由 shape 参数指
定。:b=tf.fill([2,3],-1)
10、创建已知分布的张量:b=tf.random.normal([2,3],(mean=1,stddev=2)) #正态
b=tf.random.uniform([2,3],maxval=100) #均匀
b=tf.range(10,delta=2) 0~10 步长2
11、切片:x[start: end: step],start默认0,可随意省略x[::],x[0,::]==x[0],::可简写为:,[8:0:-1]
12、改变视图:x=tf.reshape(x,[2,4,4,3]) , shape=(2, 4, 4, 3)
改变视图操作的默认前提是存储不需要改变,否则改变视图操作就是非法的
13、 x.ndim,x.shape # 获取张量的维度数和形状列表
14、插入删除维度tf.expand_dims(x, axis)可在指定的 axis 轴前可以插入一个新的维度, x = tf.squeeze(x, axis=0) # 删除图片数量维度,只能变维度为1的
15、 tf.tile(b, multiples=[2,1])即可在 axis=0 维度复制 1 次,在 axis=1 维度不复制标量
16、Broadcasting 称为广播机制(或自动扩展机制),它是一种轻量级的张量复制手段,在逻辑上扩展张量数据的形状: 直接将 shape 为[2,3]与[3]的矩阵相加也是合法,因为它自动调用tf.broadcast_to(x, new_shape),将两者 shape 扩张为相同的[2,3]
17、数学运算:+,-,*,/,//,%,**(乘方、开方分数),也可平方 tf.square(x)开平tf.sqrt(x)
,e^x=tf.exp(x),lnx=tf.math.log(x),其他底用换底公式,矩阵相乘@或 tf.matmul(a, b)
18、拼接:tf.concat([a,b],axis=0),非合并维度的长度必须一致
19、产生新维度:tf.stack([a,b],axis=0),需要所有待合并的张量 shape 完全一致
20、分割: tf.split(x, num_or_size_splits=10, axis=0)
tf.split(x, num_or_size_splits=[4,2,2,2] ,axis=0)
21、均方差误差函数:loss=tf.keras.losses.mse(y,b),
22、向量范数:L0 范数‖x‖0 定义为xi中非零元素的个数
L1 范数:对值之和 ‖x‖1 = ∑|xi |
L2 范数:平方和,再开根号: ‖x‖2 =√ ∑|xi |^2
∞ −范数: 绝对值的最大值: ‖x‖∞ = max(|xi|)
矩阵和张量的范数等价于将矩阵和张量打平成向量后计算。 tf.norm(x, ord)
ord 指定为 1、2 时计算 L1、L2 范数,指定为 np.inf 时计算∞−范数
23、最值、均值、和:tf.reduce_max、tf.reduce_min、tf.reduce_mean、tf.reduce_sum,
例:x = shape([4,10]) ,tf.reduce_max(x,axis=1) # 第二维度上的最大值
tf.argmax(x, axis)和 tf.argmin(x, axis)求在 axis 轴上,x 的最大值、最小值所在的索引号。
24、张量比较:
tf.equal(a, b)可以比较这 2 个张量是否相等,返回布尔类型的张量比较结果
tf.math.greater a > b
tf.math.less a < b
tf.math.greater_equal a ≥ b
tf.math.less_equal a ≤b
tf.math.not_equal a ≠b
tf.math.is_nan a = nan
25、填充: tf.pad(x, paddings),paddings=[[0,0],[2,1]]表示第一个维度不填充,第二个
维度左边(起始处)填充两个单元,右边(结束处)填充一个单元
26、数据限幅: tf.maximum(x, a)下限幅,即x∈ [a,+∞);tf.minimum(x, a)上限幅
relu(x): tf.maximum(x,0.), tf.clip_by_value(2,7) 上下限幅为2-7
27、高级操作:tf.gather(x,[2,4],axis=2) # 收集第 3,5 科目的成绩
tf.gather_nd(x,[[1,1],[2,2],[3,3]]) #多维坐标采样多个点
tf.boolean_mask(x,mask=[True, False,False,True],axis=0)#掩码采样第1,4号
tf.where(cond, a, b)=cond==True? a:b tf.where(x>0)#所有正数的索引
tf.scatter_nd(indices, updates, shape)函数可以高效地刷新张量的部分数据
tf.meshgrid 函数可以方便地生成二维网格的采样点坐标,方便可视化等应用场合,z=sin(x^2+y^2)/(x^2+y^2)
27、经典数据集:Boston Housing,波士顿房价趋势数据集,用于回归模型训练与测试。
❑ CIFAR10/100,真实图片数据集,用于图片分类任务。
❑ MNIST/Fashion_MNIST,手写数字图片数据集,用于图片分类任务。
❑ IMDB,情感分类任务数据集,用于文本分类任务。
通过 datasets.xxx.load_data()函数即可实现经典数据集的自动加载
(x, y), (x_test, y_test) = datasets.mnist.load_data()
tf.data.Dataset.from_tensor_slices((x, y)) # 构建 Dataset 对象才好利用
28、随机打散:Dataset.shuffle(buffer_size)设置 Dataset 对象随机打散数据之间的顺序
buffer_size 参数指定缓冲池的大小,一般设置为一个较大的常数即可,
例:db=train_db.shuffle(10000),db=db.step1().step2().step3.()遍历
29、批训练:为了利用显卡的并行计算能力,train_db = train_db.batch(128) # 设置批训练,batch size 为 128
30、预处理:从 keras.datasets 中加载的数据集的格式大部分情况都不能直接满足模型的输入要求,因此需要根据用户的逻辑自行实现预处理步骤。例如:
train_db = train_db.map(preprocess)# 预处理函数实现在 preprocess 中,传入函数名即可
def preprocess(x, y): # 自定义的预处理函数
# 调用此函数时会自动传入 x,y 对象,shape 为[b, 28, 28], [b]
# 标准化到 0~1
x = tf.cast(x, dtype=tf.float32) / 255.
x = tf.reshape(x, [-1, 28*28]) # 打平
y = tf.cast(y, dtype=tf.int32) # 转成整型张量
y = tf.one_hot(y, depth=10) # one-hot 编码
# 返回的 x,y 将替换传入的 x,y 参数,从而实现数据的预处理功能
return x,y
31、循环训练:for step, (x,y) in enumerate(train_db): # 迭代数据集对象,带 step 参数
或for x,y in train_db: # 迭代数据集对象,
每次返回的 x 和 y 对象即为批量样本和标签,通过多个 step 来完成整个训练集的一次迭代,叫做一个 Epoch。在实际训练时,通常需要对数据集迭代多个 Epoch 才能取得较好地训练效果。例:train_db = train_db.repeat(20) # 数据集迭代 20 遍才终止
或:for epoch in range(20): # 训练 Epoch 数
for step, (x,y) in enumerate(train_db): # 迭代 Step 数
# training...
with tf.GradientTape() as tape: # 梯度记录器, gradient()方法自动求解参数的梯度
32、网络层:σ(x@w+b)或 layers.Dense(units, activation) ,units输出数,输入数自动赋
例:from tensorflow.keras import layers # 导入层模块
fc = layers.Dense(512, activation=tf.nn.relu) # 创建全连接层,指定输出节点数和激活函数
h1 = fc(x)
fc.kernel # 获取 Dense 类的权值矩阵
fc.bias # 获取 Dense 类的偏置向量
fc.trainable_variables # 返回待优化参数列表(包含上两个),fc.non_trainable_variables
fc.variables # 返回所有参数列表
33、层方式实现:通过 Sequential 容器
from tensorflow.keras import layers,Sequential # 导入 Sequential 容器
model = Sequential([ # 通过 Sequential 容器封装为一个网络类
layers.Dense(256, activation=tf.nn.relu) , # 创建隐藏层 1
layers.Dense(128, activation=tf.nn.relu) , # 创建隐藏层 2
layers.Dense(64, activation=tf.nn.relu) , # 创建隐藏层 3
layers.Dense(10, activation=None) , # 创建输出层
])
out = model(x) # 前向计算得到输出
34、激活函数:Sigmoid 函数(Logistic):Sigmoid(x)=1/(1+exp(-x)) ,tf.nn.sigmoid(x)
ReLU(REctified Linear Unit,修正线性单元), max(0,x),tf.nn.relu(x)
p=alpha为用户自行设置的某较小数值的超参数,如 0.02 等,tf.nn.leaky_relu(x, alpha=0.1)
35、输出层设计:常见的几种输出类型包括:实数空间,[0,1],[-1,1]等
普通实数空间:输出层可不加激活函数,误差可采用均方差误差函数 MSE等
[0,1]区间:激活函数Sigmoid 等
[0,1] 区间且和为1:Softmax 函数不仅可以将输出值映射到[0,1]区 间,还满足所有的输出值之和为 1 的特性,tf.nn.softmax(z)。Softmax 函数也可以作为网络层类使用,layers.Softmax(axis=-1)可添加 Softmax 层,其中 axis 指定需要进行计算的维度。
为解决数值溢出稳定性问题,可将 Softmax 与交叉熵损失函数同时实现,tf.keras.losses.categorical_crossentropy(y_true, y_pred, from_logits=False),其中 y_true 代表了
One-hot 编码后的真实标签,y_pred 表示网络的预测值,当 from_logits 设置为 True 时,
y_pred 表示须为未经过 Softmax 函数的变量 z,一般都选True
例:loss = keras.losses.categorical_crossentropy(y_onehot,z,from_logits=True)
loss = tf.reduce_mean(loss) # 计算平均交叉熵损失
或:criteon = keras.losses.CategoricalCrossentropy(from_logits=True)
loss = criteon(y_onehot,z) # 计算损失
36、误差计算:均方差、交叉熵、KL 散度、Hinge Loss 函数等,均方差回归,交叉熵分类
均方差(Mean Squared Error,简称 MSE)
例:loss = keras.losses.MSE(y_onehot, o) # 计算均方差
loss = tf.reduce_mean(loss) # 计算 batch 均方差
或:criteon = keras.losses.MeanSquaredError()
loss = criteon(y_onehot,o) # 计算 batch 均方差
KL 散度,交叉熵可以很好地衡量 2 个分布之间的“距离”
p采用 One-hot 编码时:只与真实的类别上概率有关
37、模型装配、训练与测试:在训练网络时,一般的流程是通过前向计算获得网络的输出值,再通过损失函数计算网络误差,然后通过自动求导工具计算梯度并更新,同时间隔性地测试网络的性能。
37.1、模型装配: keras.layers.Layer 类,定义了网络层的一些常见功能,如添加权值、管理权值列表等,keras.Model,除了具有 Layer 类的功能,还添加了保存模型、加载模型、训练与测试模型等便捷功能。Sequential 也是 Model 的子类
# 创建 5 层的全连接网络
network = Sequential([layers.Dense(256, activation='relu'),
layers.Dense(128, activation='relu'),
layers.Dense(64, activation='relu'),
layers.Dense(32, activation='relu'),
layers.Dense(10)])
network.build(input_shape=(4, 28*28))
network.summary()
from tensorflow.keras import optimizers,losses # 导入优化器,损失函数模块
# 采用 Adam 优化器,学习率为 0.01;采用交叉熵损失函数,包含 Softmax
network.compile(optimizer=optimizers.Adam(lr=0.01),
loss=losses.CategoricalCrossentropy(from_logits=True),
metrics=['accuracy'] # 设置测量指标为准确率
)
37.2模型训练:fit()函数, train_db 为 tf.data.Dataset 对象
# 训练集train_db,验证集val_db,训练 5个epochs,每2个epoch 验证一次
# 返回训练轨迹信息保存在 history 对象中
history = network.fit(train_db, epochs=5, validation_data=val_db,validation_freq=2)
history.history # 打印训练记录,字典对象,包含了训练过程中的 loss、测量指标等
37.3模型测试:通过 Model.predict(x)方法即可完成模型的预测
x,y = next(iter(db_test)) # 加载一个 batch 的测试数据
print('predict x:', x.shape) # 打印当前 batch 的形状
out = network.predict(x) # 模型预测,预测结果保存在 out 中
print(out)
或:network.evaluate(db_test) # 只可模型测试,测试在 db_test 上的性能表现
38、模型保存与加载:
(1)张量方式:network.save_weights('weights.ckpt') # 保存模型的所有张量数据
network.load_weights('weights.ckpt') # 从参数文件中读取数据并写入当前网络
network = keras.models.load_model('model.h5') # 从文件恢复网络结构与网络参数
tf.saved_model.save(network, 'model-savedmodel') # 保存模型结构与模型参数到文件
network = tf.saved_model.load('model-savedmodel') # 从文件恢复网络结构与网络参数
# 准确率计量器
acc_meter = metrics.CategoricalAccuracy()
for x,y in ds_val: # 遍历测试集
pred = network(x) # 前向计算
acc_meter.update_state(y_true=y, y_pred=pred) # 更新准确率统计
print("Test Accuracy:%f" % acc_meter.result()) # 打印准确率
39、新建测量器:在 keras.metrics 模块中,提供了如平均值Mean 类,统
计准确率的 Accuracy 类,统计余弦相似度的 CosineSimilarity 类等。
loss_meter = metrics.Mean() # 新建平均测量器,适合 Loss 数据
# 记录采样的数据,通过 float()函数将张量转换为普通数值
loss_meter.update_state(float(loss)) #放置在每个 Batch 运算结束后
print(step, 'loss:', loss_meter.result()) # 打印统计期间的平均 loss
loss_meter.reset_states() # 打印完后清零测量器,由于测量器会统计所有历史记录数据
准确率实例:acc_meter = metrics.Accuracy() # 创建准确率测量器
# [b, 784] => [b, 10],网络输出值
out = network(x)
# [b, 10] => [b],经过 argmax 后计算预测值
pred = tf.argmax(out, axis=1)
pred = tf.cast(pred, dtype=tf.int32)
# 根据预测值与真实值写入测量器
acc_meter.update_state(y, pred)
# 读取统计结果
print(step, 'Evaluate Acc:', acc_meter.result().numpy())
acc_meter.reset_states() # 清零测量器
40、可视化:TensorBoard
# 创建监控类,监控数据将写入 log_dir 目录
summary_writer = tf.summary.create_file_writer(log_dir)
#监控误差数据和可视化图片数据
with summary_writer.as_default(): # 写入环境
tf.summary.scalar('test-acc', float(total_correct/total),step=step)# 写入测试准确率
# 可视化测试用的图片,设置最多可视化 9 张图片
tf.summary.image("val-onebyone-images:", val_images,max_outputs=9, step=step)
#查看张量数据的直方图分布,以及通过 tf.summary.text 打印文本信息
with summary_writer.as_default():
# 当前时间戳 step 上的数据为 loss,写入到 ID 位 train-loss 对象中
tf.summary.scalar('train-loss', float(loss), step=step)
# 可视化真实标签的直方图分布
tf.summary.histogram('y-hist',y, step=step)
# 查看文本信息
tf.summary.text('loss-text',str(float(loss)))
41、过拟合:41.1提前停止:数据集分为训练集、验证集和测试集,验证集连续n次下降
41.2模型设计:减少层数、阶数等减少容量
41.3正则化惩罚项、加权范数
41.4Dropout: tf.nn.dropout(x, rate),model.add(layers.Dropout(rate=0.5))
41.5数据增强:缩放:x = tf.image.resize(x, [244, 244])
旋转:x = tf.image.rot90(x,k) #按逆时针方式旋转 k 个 90 度
翻转: x = tf.image.random_flip_left_right(x) # 随机水平翻转
x = tf.image.random_flip_up_down(x) # 随机竖直翻转
裁剪:x = tf.image.random_crop(x, [224,224,3]) #稍放大后裁剪
生成数据、添加高斯噪声、变换视角、 随机擦除等
42、卷积大小关系:卷积核的大小k,步长s,上下填充数量pℎ相同,
输入X的高宽ℎ,向下取整。通过设置padding='SAME'、strides=1 可以直接得到输入、输出同大小的卷积层,当s> 时,padding='SAME'将使得输出高、宽将成1/s倍地减少
out = tf.nn.conv2d(x,w,strides=3,padding='SAME')
43、卷积层类: #创建了4个3×3大小的卷积核的卷积层,步长为1,padding方案为'SAME'
layer = layers.Conv2D(4,kernel_size=3,strides=1,padding='SAME')
#卷积核高宽、步长行列方向不等,kernel_size参数为tuple格式(kh,kw),#strides参数为(Sh,Sw)
layer = layers.Conv2D(4,kernel_size=(3,4),strides=(2,1),padding='SAME')
例:layer = layers.Conv2D(4,kernel_size=3,strides=1,padding='SAME')
out = layer(x) # 前向计算
out.shape # 输出张量的 shape
layer.trainable_variables # 返回所有待优化张量列表
44、转置卷积运算:xx = tf.nn.conv2d_transpose(out, w, strides=2,padding='VALID',
output_shape=[1,5,5,1])
转置卷积矩阵角度:tf.nn.conv2d_transpose(out, w, strides=1, padding='VALID',
output_shape=[1,4,4,1])
在使用 tf.nn.conv2d_transpose 进行转置卷积运算时,需要额外手动设置输出的高宽。
tf.nn.conv2d_transpose 并不支持自定义 padding 设置,只能设置为 VALID 或者 SAME 。
当设置 padding=’VALID’时,输出大小表达为: o = (i−1)s +k
当设置 padding=’SAME’时,输出大小表达为:o =i*s
# 创建转置卷积类
layer = layers.Conv2DTranspose(1,kernel_size=3,strides=1,padding='VALID')
迁移学习模型性能