最近一直都在自己动手实现一些CNN的小案例, 正所谓纸上得来终觉浅,绝知此事要躬行。
一味地看书看论文, 让我觉得很是迷茫,各种乱七八糟的网络, 东拼西凑的框架到底有什么用?
还是一些最基础,最经典的网络比较有说服力, 能够站得住脚。
我最近实现了其中的一些, 例如AlexNet, Vgg, GoogLENet 和VGGNet, 总结出了一些网络训练的大致流程,
写在这里和大家分享一下。
这是网络训练的最核心步骤, 没有好的网络结构, 什么都是白谈,但是这部分网络上的经典框架以及变形的结构有
成千上万, 在学习的时候还是要仔细分辨清楚再用。
对我来说, 神经网络的作用就是处理一些图像, 所以在这部分,我的数据全部都是图像。
首先, 肯定是图像的采集工作了, 这个没什么好说的,各显神通吧。
第二, 图像的预处理, 这里的预处理指的是两个事情,一个是基于图形处理的预处理,譬如滤波等操作; 另一个则是
做有利于神经网络计算的预处理。 前者我们这里暂且不提, 因为根据任务的性质不同,这个部分也就不相同,但后者基本上
都是一致的。 也就是对训练用的图像做归一化的处理, 对label 做one-hot的处理。(具体的一些方法可以看一下我的这两篇博客; https://blog.csdn.net/Pierce_KK/article/details/90489397 ; https://blog.csdn.net/Pierce_KK/article/details/90640172 )
(关于数据增强的内容我暂时放到后面,我认为它并不属于数据处理的这部分,而是一种训练技巧)
第三, 数据的划分,也就是一组完整的数据要划分为 train, val , test 这三部分, 相应的label 也要划分成为这三部分,
就是来配置的我们用于训练的模型,
我们都知道, 模型training就是一个 使用 优化器 来优化我们的损失函数(loss or cost)的一个过程,以梯度下降为例,
每下降一步,更新一次参数, 循环往复,直到达到了一个局部 / 全局最小值。
所以,在这步,我们要指定我们的 优化器 (optimizer) 和 损失函数(loss)
你可能还会见到这个 ‘ metrics ’ 参数, 这是测量指标的意思 通常赋值为 ['accuracy'], 也就是准确率。
准确率的计算方式如下:
# 这个可能还有查准率, 查全率, f1 等这些参数有关,待会再看
模型的结构和损失函数,优化器等这些都配置好, 数据也准备妥当之后,我们就可以开始 training 了
在keras中, 我们使用 fit 或者是 fit_generation 来训练我们的网络,
这两者的作用是相同的,都是Trains the model for a given number of epochs (iterations on a dataset).
但是后需要与 keras 的数据生成器来搭配使用,来实现数据增强(关于数据增强可以在这里看到: https://blog.csdn.net/Pierce_KK/article/details/98475181)
根据 fit 的参数列表来传入相关的内容,就可以开始训练了。。。
熟悉Python的你曾经可能接触过 pickle 和 cpickle 这两种方法, 他们用来将object以文件的形式来保存到磁盘上,
但是在这里, 我并不推荐这样做(或者说是keras 的官方文档并不推荐这样做), 因为我们的keras 内置了
模型的保存于加载的方法,下面我们就来看一下。
5.1 通常情况下的模型保存
这里说的通常情况是指保存 模型的结构, 权重, 优化器和损失函数的种类, 以及优化器的状态(从中断的地方继续训练)
这四项内容。 我们使用 model . save( filepath ) 的方法。 将 Keras 模型的这些内容保存到单个 HDF5 文件中,
如果你指向保存模型的结构, 那么可以使用如下的方法
# 保存为 JSON
json_string = model.to_json()
# 保存为 YAML
yaml_string = model.to_yaml()
5.2 部分保存
如果说你只保存模型的权重,方法如下
model.save_weights('my_model_weights.h5')
5.3 其他形式
可能你还在keras 当中见到过其他的模型保存的方法, 使用的是 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
, 那么模型被保存的的文件名就会有训练轮数和验证损失。
matplot的功能实在是太多了,但是使用起来相对简单,这里不再赘述 tutorial部分,
只说一些和神经网络训练相关的内容。
我们训练的时候无论是使用 fit 还是 fit_generation 的方法,其返回的都是 A History
object.
Its History.history
attribute is a record of training loss values and metrics values at successive epochs, as well as validation loss values and validation metrics values (if applicable) .
我们就可以使用这个 History object 来绘图,
N = EPOCHS
plt.plot(np.arange(0, N), H.history['loss'],
label='train_loss')
plt.plot(np.arange(0, N), H.history["val_loss"],
label="val_loss")
plt.plot(np.arange(0, N), H.history["acc"],
label="train_acc")
plt.plot(np.arange(0, N), H.history["val_acc"],
label="val_acc")
plt.title('Training loss and accuracy')
plt.xlabel('Epoch #')
plt.ylabel('Loss/Accuracy')
’
7.1 模型加载
如果你使用的是 model . save( filepath ) 的方法保存的模型, 那么你需要使用 load_file 的方法来重新实例化它。
具体的使用方法如下 :
from keras.models import load_model
model.save('my_model.h5') # 创建 HDF5 文件 'my_model.h5'
# 记载model用于测试部分
model2 = load_model('my_model.h5')
相应的, 如果你只保存了模型的结构,你需要使用如下的方法来加载;
# 从 JSON 重建模型:
from keras.models import model_from_json
model = model_from_json(json_string)
# 从 YAML 重建模型:
from keras.models import model_from_yaml
model = model_from_yaml(yaml_string)
同样的,单独加载权重的方式如下:
model.load_weights('my_model_weights.h5')
有些时候你可能只想要 加载一部分的权重 , 或者是将这里的权重加载给别的地方,
这时候你就需要按照权重所在的层的 name 来对其进行加载,
(这在迁移学习中用的很多, 你可以只加载不需要进行finetune的部分,然后对需要finetune的部分进行训练。)
例子如下:
"""
假设原始模型如下所示:
model = Sequential()
model.add(Dense(2, input_dim=3, name='dense_1'))
model.add(Dense(3, name='dense_2'))
...
model.save_weights(fname)
"""
# 新模型
model = Sequential()
model.add(Dense(2, input_dim=3, name='dense_1')) # 将被加载
model.add(Dense(10, name='new_dense')) # 将不被加载
# 从第一个模型加载权重;只会影响第一层,dense_1
model.load_weights(fname, by_name=True)
7.2 数据的加载与预测
model. predict ()
predict(x, batch_size=None, verbose=0, steps=None)
为输入样本生成输出预测。 计算是分批进行的