文章目录
训练数据
版本号
|
作者
|
时间
|
改动内容
|
0.1
|
Lart
|
2018年10月17日
|
创建文档
|
0.2
|
Lart
|
2018年10月18日10:41:53
|
补充关于模型保存的问题/调整部分结构
|
在最初始的学习训练中,多使用预训练好的模型.在其基础上进行微调(FineTune).
优化器选择
SGD
keras.optimizers.SGD(lr=0.01, momentum=0.0, decay=0.0, nesterov=False)
随机梯度下降优化器
包含扩展功能的支持:
- 动量(momentum)优化,
- 学习率衰减(每次参数更新后)
- Nestrov动量(NAG)优化
RMSprop
keras.optimizers.RMSprop(lr=0.001, rho=0.9, epsilon=None, decay=0.0)
RMSProp优化器.
建议使用优化器的默认参数 (除了学习率lr,它可以被自由调节)
这个优化器通常是训练循环神经网络RNN的不错选择。
Adam
keras.optimizers.Adam(lr=0.001, beta_1=0.9, beta_2=0.999, epsilon=None, decay=0.0, amsgrad=False)
Adam优化器.
实际建议 在实际操作中,我们推荐Adam作为默认的算法,一般而言跑起来比RMSProp要好一点。但是也可以试试SGD+Nesterov动量。
完整的Adam更新算法也包含了一个偏置(bias)矫正机制,因为m,v两个矩阵初始为0,在没有完全热身之前存在偏差,需要采取一些补偿措施。
补充
训练一个神经网络需要:
- 利用小批量数据对实现进行 梯度检查,还要注意各种错误。
- 进行 合理性检查,确认初始损失值是合理的,在小数据集上能得到100%的准确率。
- 在训练时,跟踪损失函数值,训练集和验证集准确率,如果愿意,还可以 跟踪更新的参数量相对于总参数量的比例(一般在1e-3左右),然后如果是对于卷积神经网络,可以将第一层的 权重可视化。
- 推荐的两个 更新方法 是SGD+Nesterov动量方法,或者Adam方法。
- 随着训练进行 学习率衰减。比如,在固定多少个周期后让学习率减半,或者当验证集准确率下降的时候。
- 使用 随机搜索 (不要用网格搜索)来搜索最优的超参数。分阶段从粗(比较宽的超参数范围训练1-5个周期)到细(窄范围训练很多个周期)地来搜索。
- 进行 模型集成 来获得额外的性能提高。
回调函数选择
回调函数是一个函数的合集,会在训练的阶段中所使用。你可以使用回调函数来查看训练模型的内在状态和统计。你可以传递一个列表的回调函数(作为 callbacks
关键字参数)到 Sequential
或 Model
类型的 .fit()
方法。在训练时,相应的回调函数的方法就会被在各自的阶段被调用。
模型保存-ModelCheckpoint
keras.callbacks.ModelCheckpoint(filepath, monitor='val_loss', verbose=0, save_best_only=False, save_weights_only=False, mode='auto', period=1)
在每个训练期之后保存模型。
filepath
可以包括命名格式选项,可以由 epoch
的值和 logs
的键(由 on_epoch_end
参数传递)来填充。
例如:如果 filepath
是 weights.{epoch:02d}-{val_loss:.2f}.hdf5
, 那么模型被保存的的文件名就会有训练轮数和验证损失。
LearningRateScheduler
keras.callbacks.LearningRateScheduler(schedule, verbose=0)
学习速率定时器。
评估标准选择
对于任何分类问题,你都希望将其设置为 metrics = ['accuracy']
。评估标准可以是现有的标准的字符串标识符,也可以是自定义的评估标准函数。
注意 回归问题可以使用mae评估
# 多分类问题
model.compile(optimizer='rmsprop',
loss='categorical_crossentropy',
metrics=['accuracy'])
# 二分类问题
model.compile(optimizer='rmsprop',
loss='binary_crossentropy',
metrics=['accuracy'])
# 均方误差回归问题
# 评估标可以选择 mae
model.compile(optimizer='rmsprop',
loss='mse')
# 自定义评估标准函数
import keras.backend as K
def mean_pred(y_true, y_pred):
return K.mean(y_pred)
model.compile(optimizer='rmsprop',
loss='binary_crossentropy',
metrics=['accuracy', mean_pred])
数据集的划分
训练集(Training Set):帮助我们训练模型,简单的说就是通过训练集的数据让我们确定拟合曲线的参数。
验证集(Validation Set):用来做模型选择(model selection),即做模型的最终优化及确定的,用来辅助我们的模型的构建,可选;
测试集(Test Set): 为了测试已经训练好的模型的精确度。当然,test set这并不能保证模型的正确性,他只是说相似的数据用此模型会得出相似的结果。因为我们在训练模型的时候,参数全是根据现有训练集里的数据进行修正、拟合,有可能会出现过拟合的情况,即这个参数仅对训练集里的数据拟合比较准确,这个时候再有一个数据需要利用模型预测结果,准确率可能就会很差。
显然越高次数的多项式模型越能够适应我们的训练数据集,但是适应训练数据集并不代表着能推广至一般情况,我们应该选择一个更能适应一般情况的模型。我们需要使用交叉验证集来帮助选择模型。
模型选择的方法为:
- 使用训练集训练出多个模型
- 用多个模型分别对交叉验证集计算得出交叉验证误差(代价函数的值)
- 选取代价函数值最小的模型
- 用步骤3中选出的模型对测试集计算得出推广误差(代价函数的值)
注意 一般而言,只有两个数据集,一个是训练集,一个是测试集,验证集可以从训练集上划分出来一部分. 但实际应用中,一般只将数据集分成两类,即训练集Training set 和测试集Test set,大多数文章并不涉及验证集Validation set。
划分比例
传统的机器学习领域中,由于收集到的数据量往往不多,比较小,所以需要将收集到的数据分为三类:训练集、验证集、测试集。若有验证集,则划为6:2:2. 这样划分确实很科学,当数据量不大的时候(万级别及以下)。
也有人分为两类,就是不需要测试集。一般将训练集和测试集划为7:3.
在大数据时代的机器学习或者深度学习领域中,如果还是按照传统的数据划分方式不是十分合理.
因为测试集和验证集用于评估模型和选择模型,所需要的数据量和传统的数据量差不多,但是由于收集到的数据远远大于传统机器学习时代的数据量,所以占的比例也就要缩小。
比如我们拥有1000000,这么多的数据,训练集:验证集:测试集=98:1:1。如果是两类,也就是相同的道理。
fit
fit(self, x=None, y=None, batch_size=None, epochs=1, verbose=1, callbacks=None, validation_split=0.0, validation_data=None, shuffle=True, class_weight=None, sample_weight=None, initial_epoch=0, steps_per_epoch=None, validation_steps=None)
以固定数量的轮次(数据集上的迭代)训练模型。
其中的参数 __validation_split __在 0 和 1 之间浮动。用作验证集的训练数据的比例。模型将分出一部分不会被训练的验证数据,并将在每一轮结束时评估这些验证数据的误差和任何其他模型指标。验证数据是混洗之前 x
和y
数据的最后一部分样本。
而参数 __validation_data 是一个__元组 (x_val,y_val)
或元组 (x_val,y_val,val_sample_weights)
,用来评估损失,以及在每轮结束时的任何模型度量指标。模型将不会在这个数据上进行训练。这个参数会覆盖 validation_split
。
实际建议
- 关于训练时的代码调试,可以先不要指定太大的Epoch,这样可以快速的完成一次完整的训练,使得尽快的查看一次完整的过程的结果.观察训练流程之外的代码设计是否有误.
- 对于使用的数据,最好在预处理后就将其保存成一个文件,比如利用
np.save()&np.load()
来使用.npy
文件,使用numpy数组.分成不同的.py
书写,可以减少每次调试具体内容的时间.
若是jupyter notebook
,则建议分开cell实现.(在实现小规模运算的时候,自身电脑可以使用它,但是稍大一点的,还是不要使用它了,容易卡死) - 关于模型的训练/预测阶段可以分离,尽可能的分离功能单元.
训练阶段保存模型,可以利用上面的ModelCheckpoint
来实现;
测试阶段使用模型,搭建相同的网络,使用load_weights
即可. - 在多GPU机器上跑代码测试的时候,建议指定GPU运行.Keras 默认是占满所有显存,这时候其他的进程就无法使用 GPU 资源了(即使keras 实际上用不完).
CUDA_VISIBLE_DEVICES=0 python test.py
关于多GPU并行处理,还需研究.一般可以只是用单卡.若是提示显存不足,可以适当降低批次.