@nrailgun
2015-10-19T17:11:37.000000Z
字数 1601
阅读 2947
机器学习
最近在利用 Caffe 做 face landmark 检测。由于以下原因,导致了许多问题:
暂时计划方案如下:
Caffe 框架采用 C++ 实现,幸好还记得一点点。我感受到这些问题:
DataLayer
繁琐接口不稳定导致了某些学习过程中的困难,前人的经验往往不可用,必须重新阅读代码。幸好 Caffe 目前趋于稳定,就算版本不同,变化也不大。前人可以给予比较直接的帮助。
两个空格的缩进根本看不清有没有缩进,缩进了几级。LINUX
采用 8 空格 Tab 缩进,我也喜欢,大部分人认为 4 空格比较合理。
DataLayer
这个真的超级麻烦,又要写转换器,根据数据格式转换到 LMDB
数据格式,又要从 LMDB
读出转换到 Blob
。
学习率过小导致学习缓慢,学习率过大导致震荡。由于我偷懒 Copy 了 mnist 的 solver 文件,没有改动学习率。学习率过大,直接导致计算得到 NaN
。一开始出于直觉,决定调低学习率试试,于是增加了一个一位小数,不 work。于是放弃,然而经过同学提醒,再增加一位,work。
经验:从最小的学习率开始测试,一直增加到无法正常梯度下降为止。太小的话学习速度会很糟糕。
然而梯度并不下降,这是奇妙现象,无论网络和损失函数如何选取,即使不能很好地解决问题,存在 OF 或者 UF 至少损失要下降,于是我推导出,代码有 Bug:
DataLayer
读出来必然不对;DataLayer
有问题,不能正确生成训练样本和监督型号;forward
不太可能错,只能是 backward
错了;我只写了数据库写入和 DataLayer
啊,损失用的 EuclideanLoss
(贾杨清写的不能错啊)。于是我进入了三天的痛苦 Debug,因为无论怎么找,都没发现 Bug 所在。于是我冷静下来,重新分析,很可能不是实现错误,难道是网络定义错误?不对,无论如何不合理的网络,损失都要下降。也只能尝试了,我把网络减到只有一个 fully connected 层。奇迹突然出现,损失梯度下降了!这说明网络有问题,这太奇怪了。我开始尝试逐层增加网络,找出罪魁祸首。后来发现,最后的输出层设置为 TanH
之后就会收敛失败。
长久不接触微积分的我已经忘记了
手动测试也许是个快速验证的好方法,然而要准确定位问题所在,避免重复测试或者测试不全,gtest
是个更好的主意。
如果出现梯度下降失败,很可能是 loss 的 backward propagation 实现有问题。最简单的测试和 debug 手段是单样本测试,如果实现没有问题,overfit 会导致 loss 快速下降。当然还是有可能存在上文所说的 loss function 值域没有做标定的问题。