回调函数的一些用法示例如下所示:
1.模型检查点:在训练过程中的不同时间点保存模型的当前权重
2.提前终止:如果验证损失不在改善,则中断训练
3.在训练过程中动态的调节某些参数值
4.在训练过程中记录训练指标和验证指标,或将模型学到的表示可视化
# 1.modelCheckPoint 与 EarlyStopping 回调函数
import keras
callbacks_list = [
# 如果模型不再改善就中断训练 监控模型的验证精度 如果精度在多于1轮的时间(即两轮)内不再改善,则中断训练
keras.callbacks.EarlyStopping(monitor = 'acc',patience = 1),
# 在每轮过后保存当前权重,目标模型文件的保存路径,如果val_loss没有改善,那么不需要覆盖模型文件,这就可以始终保存在训练过程中中见到的最佳模型
keras.callbacks.ModelCheckpoint(filepath = 'my_model.h5',monitor = 'val_loss',save_best_only = True)
]
# 回调函数要监控验证损失和验证精度,所以在调入fit时需要传入validation_data(验证数据)
model.fit(x,y,epochs = 10,batch_size = 32,callbacks = callbacks_list,validation_data= (x_val,y_val))
# 2.ReduceLROnPlateau回调函数
# 训练过程总验证损失不再改善,使用这个回调函数来改变学习率
callbacks_list = [
# 监控模型的验证损失,触发时将学习率乘以0.1,如果验证损失在10轮内都没有改善,则触发这个回调函数
keras.callbacks.ReduceLROnPlateau(monitor = 'val_loss',factor = 0.1,patience = 10)
]
model.fit(x,y,epochs = 10,batch_size = 32,callbacks = callbacks_list,validation_data = (x_val,y_val))
# 编写你自己的回调函数
# 示例,在每轮结束后将模型每层的激活保存到硬盘,这个激活是对验证集的第一个样本计算得到的
import keras
import numpy as np
class ActivationLogger(keras.callbacks.Callback):
def set_model(self,model):
self.model = model
layer_outputs = [layer.output for layer in model.layers]
self.activations_model = keras.models.Model(model.input,layer_outputs)
def on_epoch_end(self,epoch,logs = None):
if self.validation_data is None:
raise RuntimeError('Requires valiation_data')
validation_sample = self.validation_data[0][0:1]
activations = self.activations_model.predict(validation_sample)
f = open('activation_at_epoch' + str(epoch) + '.npz','w')
np.savez(f,activations)
f.close()
7.2.2 TensorBoard简介:TensorFlow的可视化框架
主要用途:在训练过程中帮助你以可视化的方法监控模型内部发生的一切,如果你监控了除模型最终损失之外的更多信息,那么可以更清楚的了解模型做了什么,没做什么,并且能够更快的取得进展,TensorBoard的功能如下
1.再寻过程中以可视化的方式监控指标
2.将模型架构可视化
3.将激活和梯度的直方图可视化
4.以三维的形式研究嵌入
示例:IMDB情感分析问题
import keras
from keras import layers
from keras.datasets import imdb
from keras.preprocessing import sequence
max_features = 2000
max_len = 500
(x_train,y_train),(x_test,y_test) = imdb.load_data(num_words = max_features)
x_train = sequence.pad_sequences(x_train,maxlen = max_len)
x_test = sequence.pad_sequences(x_test,maxlen = max_len)
model = keras.models.Sequential()
model.add(layers.Embedding(max_features,128,input_length = max_len,name = 'embed'))
model.add(layers.Conv1D(32,7,activation = 'relu'))
model.add(layers.MaxPooling1D(5))
model.add(layers.Conv1D(32,7,activation = 'relu'))
model.add(layers.GlobalMaxPooling1D())
model.add(layers.Dense(1))
model.summary()
model.compile(optimizer = 'rmsprop',loss = 'binary_crossentropy',metrics = ['acc'])
Layer (type) Output Shape Param #
=================================================================
embed (Embedding) (None, 500, 128) 256000
_________________________________________________________________
conv1d_1 (Conv1D) (None, 494, 32) 28704
_________________________________________________________________
max_pooling1d_1 (MaxPooling1 (None, 98, 32) 0
_________________________________________________________________
conv1d_2 (Conv1D) (None, 92, 32) 7200
_________________________________________________________________
global_max_pooling1d_1 (Glob (None, 32) 0
_________________________________________________________________
dense_1 (Dense) (None, 1) 33
=================================================================
Total params: 291,937
Trainable params: 291,937
Non-trainable params: 0
_________________________________________________________________
callbacks = [
# 日志文件被写入这个位置,每一轮之后激活直方图,每一轮之后记录嵌入数据
keras.callbacks.TensorBoard(log_dir = 'D:\study\Python\Deeplearning\ch7',histogram_freq = 1,embeddings_freq = 1)
]
history = model.fit(x_train,y_train,epochs = 20,batch_size = 128,validation_split = 0.2,callbacks = callbacks)
小结
1.keras回调函数提供了一种简单方法,可以在训练过程中,监控模型并根据模型状态自动采取行动
2.使用tensorflow时,TensorBoard是一种在浏览器中将模型活动可视化的好方法,在可让是模型中,你可以通过TensorBoard回到函数来实现这种方法
BatchNormalization层,通常在卷积层和Dense层之后使用
接受一个axis参数,表示在那个通道运用标准化,默认值为-1
SeparableConv2D层
对输入的每个通道分别执行空间卷积,然后通过逐点卷积将输出通道混合,相当于将空间特征学习和通道特征学习分开,需要的参数很少,计算量也很小
# 示例
from keras import layers
from keras.models import Sequential,Model
height = 64
width = 64
channels = 3
num_classes = 10
model = Sequential()
model.add(layers.SeparableConv2D(32,3,activation = 'relu',input_shape = (height,width,channels,)))
model.add(layers.SeparableConv2D(64,3,activation = 'relu'))
model.add(layers.MaxPooling2D(2))
model.add(layers.SeparableConv2D(64,3,activation = 'relu'))
model.add(layers.SeparableConv2D(128,3,activation='relu'))
model.add(layers.MaxPooling2D(2))
model.add(layers.SeparableConv2D(64,3,activation = 'relu'))
model.add(layers.SeparableConv2D(128,3,activation='relu'))
model.add(layers.GlobalAveragePooling2D())
model.add(layers.Dense(32,activation = 'relu'))
model.add(layers.Dense(num_classes,activation = 'softmax'))
model.summary()
model.compile(optimizer = 'rmsprop',loss = 'categorical_crossentropy')
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
separable_conv2d_7 (Separabl (None, 62, 62, 32) 155
_________________________________________________________________
separable_conv2d_8 (Separabl (None, 60, 60, 64) 2400
_________________________________________________________________
max_pooling2d_3 (MaxPooling2 (None, 30, 30, 64) 0
_________________________________________________________________
separable_conv2d_9 (Separabl (None, 28, 28, 64) 4736
_________________________________________________________________
separable_conv2d_10 (Separab (None, 26, 26, 128) 8896
_________________________________________________________________
max_pooling2d_4 (MaxPooling2 (None, 13, 13, 128) 0
_________________________________________________________________
separable_conv2d_11 (Separab (None, 11, 11, 64) 9408
_________________________________________________________________
separable_conv2d_12 (Separab (None, 9, 9, 128) 8896
_________________________________________________________________
global_average_pooling2d_2 ( (None, 128) 0
_________________________________________________________________
dense_3 (Dense) (None, 32) 4128
_________________________________________________________________
dense_4 (Dense) (None, 10) 330
=================================================================
Total params: 38,949
Trainable params: 38,949
Non-trainable params: 0
_________________________________________________________________
通常的流程:
1.选择一组超参数(自动选择)
2.构建相应的模型
3.将模型在训练数据上拟合,并衡量其在验证数据上的最佳性能
4.选择要尝试的下一组超参数(自动选择)
5.重复上述过程
6.最后,衡量模型在测试数据上的性能
超参数优化的库:Hyperopt,Hyperas
在进行大规模超参数自动优化时,有一个重要的问题需要牢记,那就是验证集过拟合,因为你是在使用一个验证数据计算出一个信号,然后根据这个信号来更新超参数,所以你实际上实在验证数据集上训练超参数,很快会对验证数据过拟合,请始终记住这一点
原则:使用尽可能多的模型,模型之间的表现都差不多,模型的类型应该多样化
1.构建高性能的卷积神经网络时,你需要使用残差连接,批标准化和深度可分离卷积。未来,无论是一维,二维,还是三维应用,深度可分离卷积可能会完全取代普通卷积,因为他的表示效率更高
2.构建深度网络需要选择许多超参数和架构,这些选择共同决定了模型的性能,与其将这些选择建立在直觉或随机性之上,不如系统的搜索超参数空间,以找到最佳选择,目前,这个搜索过程的计算代价还很高,使用的工具也不是很好,并且要小心验证集过拟合
3.模型集成:加权平均,模型多样性
1.如何将模型构建为层组成的图,层的重复使用(层权重共享),与将模型用作python函数(模型模板)
2.你可以用keras的回调函数在训练过程中监控模型,并根据模型状态采取行动
3.TensorBoard可以将指标,激活直方图甚至嵌入空间可视化
4.什么是批标准化,深度可分离卷积和残差连接
5.超参数优化和模型集成