利用Caffe做回归(regression,样例见caffe-master/examples/regression_exm/下)www.cnblogs.com/frombeijingwithlove/p/5314042.html
Caffe应该是目前深度学习领域应用最广泛的几大框架之一了,尤其是视觉领域。绝大多数用Caffe的人,应该用的都是基于分类的网络,但有的时候也许 会有基于回归的视觉应用的需要,查了一下Caffe官网,还真没有很现成的例子。这篇举个简单的小例子说明一下如何用Caffe和卷积神经网络(CNN: Convolutional Neural Networks)做基于回归的应用。
原理
最经典的CNN结构一般都是几个卷积层,后面接全连接(FC: Fully Connected)层,最后接一个Softmax层输出预测的分类概率。如果把图像的矩阵也看成是一个向量的话,CNN中无论是卷积还是FC,就是不断 地把一个向量变换成另一个向量(事实上对于单个的filter/feature channel,Caffe里最基础的卷积实现就是向量和矩阵的乘法:Convolution in Caffe: a memo),最后输出就是一个把制定分类的类目数作为维度的概率向量。因为神经网络的风格算是黑盒子学习,所以很直接的想法就是把最后输出的向量的值直接拿来做回归,最后优化的目标函数不再是cross entropy等,而是直接基于实数值的误差。
EuclideanLossLayer
Caffe内置的EuclideanLossLayer就是用来解决上面提到的实值回归的一个办法。EuclideanLossLayer计算如下的误差:
所以很简单,把标注的值和网络计算出来的值放到EuclideanLossLayer比较差异就可以了
给图像混乱程度打分的简单例子
用一个给图像混乱程度打分的简单例子来说明如何使用Caffe和EuclideanLossLayer进行回归。
生成基于Ising模型的数据
这里采用统计物理里非常经典的Ising模型的模拟来生成图片,Ising模型可能是统计物理里被人研究最多的模型之一,不过这篇不是讲物理,就略过细节,总之基于这个模型的模拟可以生成如下的图片:
图片中第一个字段是编号,第二个字段对应的分数可以大致认为是图片的有序程度,范围0~1,而这个例子要做的事情就是用一个CNN学习图片的有序程度并预测。生成图片的Python脚本源于Monte Carlo Simulation of the Ising Model using Python,基于Metropolis算法对Ising模型的模拟,做了一些并行和随机生成图片的修改,在每次模拟的时候随机取一个时间(1e3到1e7之间)点输出到图片,代码见examples/regression_exm/imageGen.py
在这个例子中一共随机生成了12000张100x100的灰度图片,命名的规则是[编号]_[有序程度].jpg。至于有序程度为什么用0~1之间 的随机数而不是模拟的时间步数,是因为虽说理论上三层神经网络就能逼近任意函数,不过具体到实际训练中还是应该对数据进行预处理,尤其是当目标函数是L2 norm的形式时,如果能保持数据分布均匀,模型的收敛性和可靠性都会提高,范围0到1之间是为了方便最后一层Sigmoid输出对比,同时也方便估算模 型误差。还有一点需要注意是,因为图片本身就是模特卡罗模拟产生的,所以即使是同样的有序度的图片,其实看上去不管是主观还是客观的有序程度都是有差别 的。
还要提一句的是。。我用Ising的模拟作为例子只是因为很喜欢这个模型,其实用随机相位的反傅里叶变换然后二值化就能得到几乎没什么差别的图像,有序程度就是截止频率,并且更快更简单。
生成训练/验证/测试集
把Ising模拟生成的12000张图片划分为三部分:1w作为训练数据;1k作为验证集;剩下1k作为测试集。下面的Python代码用来生成这样的训练集和验证集的列表,见examples/regression_exm/train_val_test_divide.py
生成HDF5文件
lmdb虽然又快又省空间,可是Caffe默认的生成lmdb的工具(convert_imageset)不支持浮点类型的数据,虽然 caffe.proto里Datum的定义似乎是支持的,不过相应的代码改动还是比较麻烦。相比起来HDF又慢又占空间,但简单好用,如果不是海量数据, 还是个不错的选择,这里用HDF来存储用于回归训练和验证的数据,下面是一个生成HDF文件和供Caffe读取文件列表的脚本(见examples/regression_exm/create_hdf5.py)
需要注意的是Caffe中HDF的DataLayer不支持transform,所以数据存储前就提前进行了减去均值的步骤。保存为gen_hdf.py,依次运行命令生成训练集和验证集:
python create_hdf5.py train.txt
python create_hdf5.py val.txt
训练
用一个简单的小网络训练这个基于回归的模型:
网络结构的train_val.prototxt如下(见examples/regression_exm/train_val.prototxt),用draw_net.py画出网络结构,见(examples/regression_exm/train_val_netimage.jpg)
weight_filler {
#权重初始化方式
type: "gaussian"
std: 0.01
}
其中回归部分由EuclideanLossLayer中比较最后一层的输出和train.txt/val.txt中的分数差并作为目标函数实现。需要提一 句的是基于实数值的回归问题,对于方差这种目标函数,SGD的性能和稳定性一般来说都不是很好,Caffe文档里也有提到过这点。不过具体到Caffe 中,能用就行。。solver.prototxt如下:(见examples/regression_exm/solver.prototxt)
然后训练:
./build/tools/caffe train –solver=solver.prototxt--gpu all
测试
随便训了10000个iteration,反正是收敛了
我估计画图收敛与否是根据val的loss画的曲线,以下是我自己的记录(1e3):
1 0.000474832 6 0.000271355
2 0.000349944 7 0.000271198
3 0.000330622 8 0.000265569
4 0.000283972 9 0.000256095
5 0.000281119 10 0.000236329
以log10来画图,见/home/echo/caffe-master/examples/regression_exm/convergence.py
把train_val.prototxt的两个data layer替换成input_shape,然后去掉最后一层EuclideanLoss就可以了,input_shape定义如下:
input: "data"
input_shape {
dim: 1
dim: 1
dim: 100
dim: 100
}
这样居然也行,why???去试试另一种跟mnist(mnist与cifar10相同)相同的形式:
结论:这个也行!!!都行啊但是第二种的input_param变化成input_shape就不行了,注意:暂时保留这两种写法,写法都行(该种方法同样试用于cifar10)
改好后另存为deploy.prototxt,然后把训好的模型拿来在测试集上做测试,pycaffe提供了非常方便的接口,用下面脚本输出一个文件列表里所有文件的预测结果(见/home/echo/caffe-master/examples/regression_exm/regress.py)
The predicted score for samples/11992_0.0930641672855.jpg is 0.0885445401073
The predicted score for samples/11993_0.0384593600931.jpg is 0.0546021051705
The predicted score for samples/11994_0.462548885487.jpg is 0.469588339329
The predicted score for samples/11995_0.486899680061.jpg is 0.494545757771
The predicted score for samples/11996_0.34953325906.jpg is 0.344901770353
The predicted score for samples/11997_0.117514559778.jpg is 0.118569657207
The predicted score for samples/11998_0.316435191664.jpg is 0.321999073029
The predicted score for samples/11999_0.104874004069.jpg is 0.0881299227476
echo@echo-PC:~/caffe-master/examples/regression_exm$ python /home/echo/caffe-master/examples/regression_exm/regress.py test.txt
看上去还不错,挑几张看看:
再输出第一层的卷积核看看:
%--------------------------------这里穿插卷积核可视化等骤--------------------------
见(/home/echo/caffe-master/python/visualize2.ipynb暂时跟原来回归的那个网站上面的卷积可视化图片有点不一样,先不管了)
http://www.cnblogs.com/louyihang-loves-baiyan/p/5134671.html(见python/visualize.py)结合http://www.mamicode.com/info-detail-1512182.html中语句解释,但是还是不够啊,真正可以的是:http://blog.csdn.net/k3832127/article/details/50781232
首先生成一个均值文件(见python/create_meanfile.py,这里对应96个卷积核)
%---------------------------------我是分界线-----------------------------------
可以看到第一层的卷积核成功学到了高频和低频的成分,这也是这个例子中判断有序程度的关键,其实就是高频的图像就混乱,低频的就相对有序一些。Ising的自旋图虽然都是二值的,不过学出来的模型也可以随便拿一些别的图片试试:
不管上面有序度,以下是我自己测的:(我的图片是截图的,差不多)
I0316 13:55:41.971153 28721 net.cpp:283] Network initialization done.
I0316 13:55:41.978664 28721 net.cpp:761] Ignoring source layer loss
The predicted score for MyTest/1.png is 0.550989866257
The predicted score for MyTest/2.png is 0.624998807907
The predicted score for MyTest/3.png is 0.749618768692
echo@echo-PC:~/caffe-master/examples/regression_exm$ python regress.py test2.txt
嗯。。定性看还是差不多的。
网友评论