有时候你需要很长时间从头开始搭建神经网络并且进行训练和调整,但是如果是从一个类似的项目上把神经网络移植过来并且进行调整相对来说能省很多时间,这就是transfer learning,一个很重要的技能。
理由:类似项目已经经过大量训练,很多有用的经验已经存储在里面了,可以为我们所用;而且如果我们的数据集比较小的话,我们可以用已有的神经网络来取得更好的训练效果。
放两个能轻松打开的链接:https://developer.nvidia.com/cudnn
https://developer.nvidia.com/developer-program
cuDNN是很多深度学习神经网络的基石,开发者曾经用它在百度做中文和英语的语音识别。
GPU:在图像处理任务重的游戏中很重要,在深度学习中也很重要,主要在并行任务处理上进行了优化(throughput吞吐量 computing)
CPU:在处理单线任务上低延迟
所以训练神经网络上,一般来说GPU会比CPU快5倍,所以要好好利用GPU的性能和transfer learning,制造出更好更合适的神经网络。
Transfer Learning取决于新数据集的大小和新数据集与原数据集的相似程度,所以一般分为4种情况:
1. 新数据集较小,新数据集与原数据集类似 -> End of ConvNet
2. 新数据集较小,新数据集与原数据集不同 -> Start of ConvNet
3. 新数据集较大,新数据集与原数据集类似 -> Fine-tune
4. 新数据集较大,新数据集与原数据集不同 -> Fine-tune or Retrain
注意:数据集大小的判断比较主观,若用于较小数据集,需注意避免过拟合
狗的图片与狼的图片可以认为比较类似,因为有类似特征,但是狗的图片与花的图片就会比较不同。
假设原训练好的神经网络是3层CNN(边界,形状,高阶特征)+ 3层全连接NN + 最后softmax激活函数,那么4种情况的修改:
1. Feature Extraction
1)只去掉最后一个全连接NN,加一个成新的有新数据集分类全连接层 + 最后softmax激活函数
2) 给新的NN分配随机权重并且保持所有来自之前网络的权重不变(避免过拟合)
3) 训练新的神经网络使最后一层的新权重更新
2.
1) 去掉第二个CNN以后的所有东西,加一个新的有新数据集分类全连接层 + 最后softmax激活函数(因为数据集内容不同所以高阶特征这里开始就都不一样了所以都不需要了)
2) 给新的NN分配随机权重并且保持所有来自之前网络的权重不变(避免过拟合)
3) 训练新的神经网络使最后一层的新权重更新
3. Finetuning
1)只去掉最后一个全连接NN,加一个成新的有新数据集分类全连接层 + 最后softmax激活函数
2) 给新的NN分配随机权重并且将所有来自之前网络的权重设置为初始值(不会过拟合所以可以重新训练)
3) 训练整个神经网络使所有的权重更新
4. 考虑从头开始训练,当然也可以试着用训练过的权重+finetune
1)只去掉最后一个全连接NN,加一个成新的有新数据集分类全连接层 + 最后softmax激活函数
2) 给新的NN分配随机权重并且将所有来自之前网络的权重设置为初始值(不会过拟合所以可以重新训练)
这样训练的速度会比较快,如果这样训练出来的模型不成功,那么可以把所有的权重全部设成随机初始值,从头开始训练
3) 训练整个神经网络使所有的权重更新
深度学习是这几年才发展起来的,虽然1950+就有了。因为这几年互联网的发展,有标记的数据才足够多,才能使深度学习有用。以及处理器也足够强大能够处理这么多数据。
ImageNet:拥有很多手工标记的图片,会举办比赛看谁的神经网络厉害,让大家学习与探索如何创造优秀的神经网络。比如AlexNet,很像Yan LeCun的手写字体识别神经网络LeNet
AlexNet:用了2012年最厉害的GPU做并行运算,并且用了ReLU作为激活函数,还用了dropout的方法,把错误率从之前的26%降到了15%,是一个非常大的进步
【对成为特征提取者】有用的函数:重新设置图片大小以符合神经网络输入要求 - tf.image.resize_images(images, size)
获得全连接层的总参数个数就可以知道输出的行数:fc7.get_shape().as_list()[-1],输出的列数就是类的个数了
X_train, X_val, y_train, y_val = train_test_split(data['features'], data['labels'], test_size=0.33, random_state=0)
cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits(logits=logits, labels=labels)
loss_op = tf.reduce_mean(cross_entropy)
opt = tf.train.AdamOptimizer()
train_op = opt.minimize(loss_op, var_list=[fc8W, fc8b])
init_op = tf.initialize_all_variables()
preds = tf.arg_max(logits, 1)
accuracy_op = tf.reduce_mean(tf.cast(tf.equal(preds, labels), tf.float32))
现在的AlexNet:(网上能找到的)有简化版的AlexNet,因为原网络中有部分被证明没什么用,现在也有一些更好的类似AlexNet的神经网络能有更好的准确率,不过AlexNet一般被认为是入门用的好网络。
VGG Net (VGG):Visual Geometry Group
构成:(3*3卷积 + 2*2pooling)* n + 3*全连接层
用途:图像分类刚开始时
优点:灵活
忠告:不要钻理论太深,实践能带来很多有用的经验,建立假设之后动手实践,验证理论,做的就是科学家的工作而不是工程师的工作了
GoogLeNet:谷歌开发的,速度快,可用于实时神经网络如自动驾驶车上
提出概念inception module:(虽然之前提到过)把下一层神经网络的设立方法改为我全都要(如‘avg pooling’+‘1*1+3*3’+‘1*1+5*5’),总的变量数很少
ResNet:微软的,有152层(超多!),AlexNet有8层,VGG有19层,GoogLeNet有22层
和VGG类似,都是相同结构的层叠加,意图是加上非相邻层的神经网络的连接,能够有一个非常非常深的神经网络。