使用CNN(convolutional neural nets)关键的一点是检测到的面部教程(四):学习率,学习潜能,dropout
第七部分 让 学习率 和 学习潜能 随时间的变化
光训练就花了一个小时的时间。等结果并非一个令人心情愉快的事情。这一部分。我们将讨论将两个技巧结合让网络训练的更快!
直觉上的解决的方法是,開始训练时取一个较高的学习率,随着迭代次数的增多不停的减小这个值。这是有道理的,由于開始的时候我们距离全局最长处很远。我们想要朝着最长处的方向大步前进;然而里最长处越近,我们就前进的越慎重,以免一步跨过去。举个样例说就是你乘火车回家,但你进家门的时候肯定是走进去。不能让火车开进去。
从讨论深度学习中初始化和学习势的重要性的资料,我们得到了一种新的技巧来加速网络的训练:添加最优化方法的“动量參数”。假设你还不知道什么是学习势,请阅读【參考】。
在我们上一个模型中,我们将学习率和学习势初始化为0.01和0.9。让我们来改变这两个參数,使得学习率随着迭代次数线性减小。同一时候让学习势增大。
NeuralNet同意我们在训练时通过on_epoch_finished钩子函数来更新參数。于是我们传一个函数给on_epoch_finished,使得这个函数在每次迭代之后被调用。
然而。在我们改变学习率和学习势这两个參数之前,我们必须将这两个參数改变为Theano shared variables。
好在这很easy。
import theano
def float32(k):
return np.cast['float32'](k)
net4 = NeuralNet(
# ...
update_learning_rate=theano.shared(float32(0.03)),
update_momentum=theano.shared(float32(0.9)),
# ...
)
我们传递的回调函数在调用时,须要两个參数:nn 是NeuralNet的实例,train_history,和nn.history是同一个值。
我们使用一个可參数化的类,在当中定义一个call函数来作为我们的回调函数。让我们把这个类叫做AdjustVariable,看一下这个类的实现:
class AdjustVariable(object):
def __init__(self, name, start=0.03, stop=0.001):
self.name = name
self.start, self.stop = start, stop
self.ls = None
def __call__(self, nn, train_history):
if self.ls is None:
self.ls = np.linspace(self.start, self.stop, nn.max_epochs)
epoch = train_history[-1]['epoch']
new_value = float32(self.ls[epoch - 1])
getattr(nn, self.name).set_value(new_value)
如今让我们把这些变化放到一起:
net4 = NeuralNet(
# ...
update_learning_rate=theano.shared(float32(0.03)),
update_momentum=theano.shared(float32(0.9)),
# ...
regression=True,
# batch_iterator_train=FlipBatchIterator(batch_size=128),
on_epoch_finished=[
AdjustVariable('update_learning_rate', start=0.03, stop=0.0001),
AdjustVariable('update_momentum', start=0.9, stop=0.999),
],
max_epochs=3000,
verbose=1,
)
X, y = load2d()
net4.fit(X, y)
with open('net4.pickle', 'wb') as f:
pickle.dump(net4, f, -1)
我们将训练两个网络:net4不适用之前的FlipBatchIterator。net5採用了。
除了这一点之外,两个网络全然相同。
Net4的学习步骤例如以下:
Epoch | Train loss | Valid loss | Train / Val |
---|---|---|---|
50 | 0.004216 | 0.003996 | 1.055011 |
100 | 0.003533 | 0.003382 | 1.044791 |
250 | 0.001557 | 0.001781 | 0.874249 |
500 | 0.000915 | 0.001433 | 0.638702 |
750 | 0.000653 | 0.001355 | 0.481806 |
1000 | 0.000496 | 0.001387 | 0.357917 |
能够看到,训练速度快多了。
第500次、1000次迭代的训练错误。net4都比net2低了一半。可是泛华程度到750次就不再变好了,所以看起来没有必要训练这么多次。
看看打开了数据扩充之后的net5表现怎样:
Epoch | Train loss | Valid loss | Train / Val |
---|---|---|---|
50 | 0.004317 | 0.004081 | 1.057609 |
100 | 0.003756 | 0.003535 | 1.062619 |
250 | 0.001765 | 0.001845 | 0.956560 |
500 | 0.001135 | 0.001437 | 0.790225 |
750 | 0.000878 | 0.001313 | 0.668903 |
1000 | 0.000705 | 0.001260 | 0.559591 |
1500 | 0.000492 | 0.001199 | 0.410526 |
2000 | 0.000373 | 0.001184 | 0.315353 |
相同的,和net3相比net5训练的快多了。并且获得了更好的结果。
在1000次迭代后,结果比net3迭代了3000次的效果还要好。此外,使用了数据扩充的网络的验证错误也比不使用数据扩充好了10%。
第八部分 丢弃技巧(Dropout)
2012年。这篇paper中引入了一种叫做“Dropout”的技巧,作为正则化方法,dropout工作的出奇的好。这里不会讲dropout之所以好用的细节,只是你能够阅读这些參考。
和其它的正则化技巧一样。dropout仅仅有当网络过拟合的时候才有意义。上个部分我们训练的net5是明显过拟合的。注意一定要使你的网络过拟合,再使用正则化。
在Lasagne中使用正则化技巧。我们仅仅要在网络中加入DropoutLayer并指定每层dropout的概率。
这里是我们最新网络的完整定义,我在新加入的行后面加入了#。来标识与net5的不同。
net6 = NeuralNet(
layers=[
('input', layers.InputLayer),
('conv1', layers.Conv2DLayer),
('pool1', layers.MaxPool2DLayer),
('dropout1', layers.DropoutLayer), # !
('conv2', layers.Conv2DLayer),
('pool2', layers.MaxPool2DLayer),
('dropout2', layers.DropoutLayer), # !
('conv3', layers.Conv2DLayer),
('pool3', layers.MaxPool2DLayer),
('dropout3', layers.DropoutLayer), # !
('hidden4', layers.DenseLayer),
('dropout4', layers.DropoutLayer), # !
('hidden5', layers.DenseLayer),
('output', layers.DenseLayer),
],
input_shape=(None, 1, 96, 96),
conv1_num_filters=32, conv1_filter_size=(3, 3), pool1_pool_size=(2, 2),
dropout1_p=0.1, # !
conv2_num_filters=64, conv2_filter_size=(2, 2), pool2_pool_size=(2, 2),
dropout2_p=0.2, # !
conv3_num_filters=128, conv3_filter_size=(2, 2), pool3_pool_size=(2, 2),
dropout3_p=0.3, # !
hidden4_num_units=500,
dropout4_p=0.5, # !
hidden5_num_units=500,
output_num_units=30, output_nonlinearity=None,
update_learning_rate=theano.shared(float32(0.03)),
update_momentum=theano.shared(float32(0.9)),
regression=True,
batch_iterator_train=FlipBatchIterator(batch_size=128),
on_epoch_finished=[
AdjustVariable('update_learning_rate', start=0.03, stop=0.0001),
AdjustVariable('update_momentum', start=0.9, stop=0.999),
],
max_epochs=3000,
verbose=1,
)
我们的网路如今已经大到能够让python报一个“超过最大递归限制”错误了。所以为了避免这一点。我们最好添加python的递归限制。
import sys
sys.setrecursionlimit(10000)
X, y = load2d()
net6.fit(X, y)
import cPickle as pickle
with open('net6.pickle', 'wb') as f:
pickle.dump(net6, f, -1)
看一下我们如今的训练,我们注意到训练速度又变慢了,以为加入了dropout。这是不出意料的效果。然而。整个网络的表现其实超过了net5:
Epoch | Train loss | Valid loss | Train / Val |
---|---|---|---|
50 | 0.004619 | 0.005198 | 0.888566 |
100 | 0.004369 | 0.004182 | 1.044874 |
250 | 0.003821 | 0.003577 | 1.068229 |
500 | 0.002598 | 0.002236 | 1.161854 |
1000 | 0.001902 | 0.001607 | 1.183391 |
1500 | 0.001660 | 0.001383 | 1.200238 |
2000 | 0.001496 | 0.001262 | 1.185684 |
2500 | 0.001383 | 0.001181 | 1.171006 |
3000 | 0.001306 | 0.001121 | 1.164100 |
仍然过拟合不一定是坏事,虽然我们必须小心这些数字:训练错误和验证错误的比率如今的意义稍有不同,由于训练错误是受过dropout调制的,而验证错误没有。更有比較意义的数值是:
from sklearn.metrics import mean_squared_error
print mean_squared_error(net6.predict(X), y)
# prints something like 0.0010073791
在我们上一个没有dropout的模型里,训练集上的错误是0.00373。所以如今我们的dropout net不但表现稍好,并且过拟合水平更低。
这是好消息,由于我们能够通过使得网络更大获得更好的效果。这也正是我们接下来要做的。我们加倍网络最后两个隐层的单元个数。更新这两行:
net7 = NeuralNet(
# ...
hidden4_num_units=1000, # !
dropout4_p=0.5,
hidden5_num_units=1000, # !
# ...
)
相比于没有dropout的网络,改进效果更加明显:
Epoch | Train loss | Valid loss | Train / Val |
---|---|---|---|
50 | 0.004756 | 0.007043 | 0.675330 |
100 | 0.004440 | 0.005321 | 0.834432 |
250 | 0.003974 | 0.003928 | 1.011598 |
500 | 0.002574 | 0.002347 | 1.096366 |
1000 | 0.001861 | 0.001613 | 1.153796 |
1500 | 0.001558 | 0.001372 | 1.135849 |
2000 | 0.001409 | 0.001230 | 1.144821 |
2500 | 0.001295 | 0.001146 | 1.130188 |
3000 | 0.001195 | 0.001087 | 1.099271 |
有一点过拟合,但效果着实不错。我的感觉是,假设继续添加训练次数,模型效果会变得更棒。
试一下:
net12 = NeuralNet(
# ...
max_epochs=10000,
# ...
)
Epoch | Train loss | Valid loss | Train / Val |
---|---|---|---|
50 | 0.004756 | 0.007027 | 0.676810 |
100 | 0.004439 | 0.005321 | 0.834323 |
500 | 0.002576 | 0.002346 | 1.097795 |
1000 | 0.001863 | 0.001614 | 1.154038 |
2000 | 0.001406 | 0.001233 | 1.140188 |
3000 | 0.001184 | 0.001074 | 1.102168 |
4000 | 0.001068 | 0.000983 | 1.086193 |
5000 | 0.000981 | 0.000920 | 1.066288 |
6000 | 0.000904 | 0.000884 | 1.021837 |
7000 | 0.000851 | 0.000849 | 1.002314 |
8000 | 0.000810 | 0.000821 | 0.985769 |
9000 | 0.000769 | 0.000803 | 0.957842 |
10000 | 0.000760 | 0.000787 | 0.966583 |
如今你是dropout魔力的见证者了。:-)
让我们比較一下到眼下为止我们训练过的网络:
Name | Description | Epochs | Train loss | Valid loss |
---|---|---|---|---|
net1 | single hidden | 400 | 0.002244 | 0.003255 |
net2 | convolutions | 1000 | 0.001079 | 0.001566 |
net3 | augmentation | 3000 | 0.000678 | 0.001288 |
net4 | mom + lr adj | 1000 | 0.000496 | 0.001387 |
net5 | net4 + augment | 2000 | 0.000373 | 0.001184 |
net6 | net5 + dropout | 3000 | 0.001306 | 0.001121 |
net7 | net6 + epochs | 10000 | 0.000760 | 0.000787 |
使用CNN(convolutional neural nets)检測脸部关键点教程(一):环境搭建和数据
使用CNN(convolutional neural nets)检測脸部关键点教程(二):浅层网络训练和測试
使用CNN(convolutional neural nets)检測脸部关键点教程(三):卷积神经网络训练和数据扩充
使用CNN(convolutional neural nets)检測脸部关键点教程(五):通过前训练(pre-train)训练专项网络
使用CNN(convolutional neural nets)关键的一点是检测到的面部教程(四):学习率,学习潜能,dropout的更多相关文章
- (zhuan) Using convolutional neural nets to detect facial keypoints tutorial
Using convolutional neural nets to detect facial keypoints tutorial this blog from: http://danieln ...
- CNN(Convolutional Neural Network)
CNN(Convolutional Neural Network) 卷积神经网络(简称CNN)最早可以追溯到20世纪60年代,Hubel等人通过对猫视觉皮层细胞的研究表明,大脑对外界获取的信息由多层的 ...
- 卷积神经网络CNN(Convolutional Neural Networks)没有原理只有实现
零.说明: 本文的所有代码均可在 DML 找到,欢迎点星星. 注.CNN的这份代码非常慢,基本上没有实际使用的可能,所以我只是发出来,代表我还是实践过而已 一.引入: CNN这个模型实在是有些年份了, ...
- Large-Scale Oil Palm Tree Detection from High-Resolution Satellite Images Using Two-Stage Convolutional Neural Networks(worldview油棕树检测)
不是目标检测也不是语义分割,两步CNN指的是,采集的数据是一堆点,以点为中心的65*65和17*17图像范围大小来判断这个点是否是油棕树.第一步就是判断65*65的范围是否为(油棕树植被群,其他植被/ ...
- 一目了然卷积神经网络 - An Intuitive Explanation of Convolutional Neural Networks
An Intuitive Explanation of Convolutional Neural Networks 原文地址:https://ujjwalkarn.me/2016/08/11/intu ...
- [转]An Intuitive Explanation of Convolutional Neural Networks
An Intuitive Explanation of Convolutional Neural Networks https://ujjwalkarn.me/2016/08/11/intuitive ...
- An Intuitive Explanation of Convolutional Neural Networks
https://ujjwalkarn.me/2016/08/11/intuitive-explanation-convnets/ An Intuitive Explanation of Convolu ...
- Deep learning_CNN_Review:A Survey of the Recent Architectures of Deep Convolutional Neural Networks——2019
CNN综述文章 的翻译 [2019 CVPR] A Survey of the Recent Architectures of Deep Convolutional Neural Networks 翻 ...
- 卷积神经网络(Convolutional Neural Network, CNN)简析
目录 1 神经网络 2 卷积神经网络 2.1 局部感知 2.2 参数共享 2.3 多卷积核 2.4 Down-pooling 2.5 多层卷积 3 ImageNet-2010网络结构 4 DeepID ...
随机推荐
- 移动web:图片切换(焦点图)
在web页面上图片切换(焦点图)效果实在是太常见了,PC端.移动端到处都有它的身影. 上次写了个tab选项卡的效果,在这里延续一下,改成图片切换的效果. 如果不需要自动播放,稍微修改下html标签.和 ...
- 两个文件中的配置项设置方法和C比较程序处理
在实际的软件开发项目.程序经常需要翻阅了一些资料可能会改变从外部,我们需要读出的信息到一个统一的文件(一般ini档),而此文件被称为个人资料. 考虑这样一个场景,程序须要与多个数据库打交道,要从配置文 ...
- C# winForm里窗体嵌套
ShowAllPage sAllPage = new ShowAllPage(); sAllPage.FormBorderStyle = FormBorderStyle.None ...
- Git Flow流程
# 1. clone远程仓库到本地 git clone git@git.oschina.net:huogh/muzhifm_xxx.git # 2. 使用远程分支origin/dev创建本地分支d ...
- cocos2dx3.1-lua移植android流程
我很懒惰,写这篇博客只是为了能够转出后,当忘记查看,所以我写了下面非常简单的内容.假设完全没有经验的学生请找另一篇文章 一.环境配置(win7): 用户变量如下面: ANDROID_SDK_ROOT: ...
- 编hadoop-1.X源代码
满足需要在不久的将来windows调试Linux下一个hadoop问题,Linux检查时需要的文件权限.和windows在没有必要,因此,有必要修改hadoop源代码,再次编译,过程例如以下: (1) ...
- linux权限和ntfs知识文件系统权限
左右ntfs权限的问题 文件权限: [-dcbps][u:rwx][g:rwx][a:rwx] 当中: r=4, w=2, x=1, u=owner, g=group, a=all user ...
- 职业选择測试(A/B卷)
不同性格的人适合从事不同的职业.职业选择对于每一个人都是很重要的事情.假设能选一个既可以发挥潜能又有兴趣的工作,会使整个团队的效率逐倍增长.想了解你更适合什么职业吗?一起来測试一下吧.本套測试分为A卷 ...
- 【SSH2(实用文章)】--Struts2文件上传和下载的例子
回想一下,再上一篇文章Struts2实现机制,该步骤做一步一步来解决,这种决心不仅要理清再次Struts2用法.映射机制及其在深入分析.最后一个例子来介绍Struts2一种用法,这里将做一个有关文件上 ...
- NOI第一天感想&小结
嘛...中午总算是到了深圳了--在虹桥机场和飞机上和市队大神们一起讨论各种各样奇(sang)葩(bing)的算(ren)法(lei)还是非常开心的,在此再各种膜拜一下尽管没来比赛的FFT大神@陈中瑞 ...