[关闭]
@nrailgun 2015-10-19T17:11:37.000000Z 字数 1601 阅读 2947

利用 Caffe 编程实现神经网络

机器学习


最近在利用 Caffe 做 face landmark 检测。由于以下原因,导致了许多问题:

暂时计划方案如下:

1. Caffe

Caffe 框架采用 C++ 实现,幸好还记得一点点。我感受到这些问题:

1.1 接口不稳定

接口不稳定导致了某些学习过程中的困难,前人的经验往往不可用,必须重新阅读代码。幸好 Caffe 目前趋于稳定,就算版本不同,变化也不大。前人可以给予比较直接的帮助。

1.2 缩进

两个空格的缩进根本看不清有没有缩进,缩进了几级。LINUX 采用 8 空格 Tab 缩进,我也喜欢,大部分人认为 4 空格比较合理。

1.3 定义 DataLayer

这个真的超级麻烦,又要写转换器,根据数据格式转换到 LMDB 数据格式,又要从 LMDB 读出转换到 Blob

2. 编程经验

2.1 学习率

学习率过小导致学习缓慢,学习率过大导致震荡。由于我偷懒 Copy 了 mnist 的 solver 文件,没有改动学习率。学习率过大,直接导致计算得到 NaN。一开始出于直觉,决定调低学习率试试,于是增加了一个一位小数,不 work。于是放弃,然而经过同学提醒,再增加一位,work。

经验:从最小的学习率开始测试,一直增加到无法正常梯度下降为止。太小的话学习速度会很糟糕。

2.2 值域标定

然而梯度并不下降,这是奇妙现象,无论网络和损失函数如何选取,即使不能很好地解决问题,存在 OF 或者 UF 至少损失要下降,于是我推导出,代码有 Bug:

我只写了数据库写入和 DataLayer 啊,损失用的 EuclideanLoss(贾杨清写的不能错啊)。于是我进入了三天的痛苦 Debug,因为无论怎么找,都没发现 Bug 所在。于是我冷静下来,重新分析,很可能不是实现错误,难道是网络定义错误?不对,无论如何不合理的网络,损失都要下降。也只能尝试了,我把网络减到只有一个 fully connected 层。奇迹突然出现,损失梯度下降了!这说明网络有问题,这太奇怪了。我开始尝试逐层增加网络,找出罪魁祸首。后来发现,最后的输出层设置为 TanH 之后就会收敛失败。

长久不接触微积分的我已经忘记了 tanh 的定义:

tanh(x)=sinhxcoshx=exexex+ex

值域为 (1,1)。这真是个悲剧,我完全没有意识到值域 normalize 的问题(注:论文作者默认读者知道这点,而我并不)。而监督信号的值域是[0,39),这也就导致了欧几里得距离始终大于 372。这就是收敛失败的原因,天啊,数据要做标定

2.3 要写测试

手动测试也许是个快速验证的好方法,然而要准确定位问题所在,避免重复测试或者测试不全,gtest 是个更好的主意。

2.4 单样本测试

如果出现梯度下降失败,很可能是 loss 的 backward propagation 实现有问题。最简单的测试和 debug 手段是单样本测试,如果实现没有问题,overfit 会导致 loss 快速下降。当然还是有可能存在上文所说的 loss function 值域没有做标定的问题。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注