您的位置:首页 > Web前端

【Caffe实践】基于Caffe的人脸关键点检测实现

2016-01-07 10:23 726 查看
转载自:

【Caffe实践】基于Caffe的人脸关键点检测实现 - 1983的专栏 - 博客频道 - CSDN.NET
http://blog.csdn.net/chenriwei2/article/details/49706563


引言

如果关注Kaggle 机器学习项目的同学,一定很熟悉人脸关键点检测这个任务,在2013 年的时候,ICML举办一个的challgene,现在放在kaggle 上作为 一种最常规kaggle入门任务而存在。

本文的主要目的在于验证深度学习模型在人脸点检测效果,踩踩里面的坑。


任务介绍

人脸关键点检测,也称之为人脸点检测,是在一张已经被人脸检测器检测到的人脸图像中,再进一步检测出五官等关键点的二维坐标信息,以便于后期的人脸对齐(face alignment)任务。

根据不同的任务,需要检测的关键点数目有多有少,有些仅要求检测2只眼睛的坐标位置,有些要求检测眼睛、嘴巴、鼻子的5个坐标位置,还有更多的,68个位置,它包含了五官的轮廓信息。 

如图所示:

根据任务,可以把要学习的模型函数表示为: 

Y=F(X,W)

其中,X 是输入的人脸图像,W是我们要学习的模型参数,Y∈[(x1,y1),(x2,y2),(x3,y3),(x4,y4),(x5,y5)] 是我们需要检测的人脸点坐标位置。

这是一个典型的回归问题,可以采用最简单的平方误差损失函数,然后用机器学习方法学习这个模型。 

Loss=15∑i=15((xi−xi′)2+(yi−yi′)2)

其中(xi,yi)为预测的位置,(xi′,yi′) 为标注的关键点位置。

很显然,也很容易的就将该任务放到caffe中进行学习。


实验过程:


数据准备

由于港中文[1]他们有公开了训练集,所以我们就可以直接使用他们提供的图像库就好了。 

数据是需要转化的:

1、框出人脸图像部分,从新计算关键点的坐标 

2、缩放人脸框大小,同时更新计算的关键点坐标 

3、一些数据增强处理:我只采样了左右对称的增强方法(还可以采用的数据增强方法有旋转图像,图像平移部分) 

转换脚本如下:
<code class="hljs python has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"># -*- coding: utf-8 -*-</span>
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"># -*- coding: utf-8 -*-</span>
<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"""
Created on Wed Nov 04 16:36:33 2015
@author: RiweiChen <riwei.chen@outlook.com>
"""</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">import</span> skimage
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">import</span> skimage.io
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">import</span> numpy <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">as</span> np
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">import</span> cv2

<span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">def</span> <span class="hljs-title" style="box-sizing: border-box;">face_draw_point</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(filelist,savePath)</span>:</span>
<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'''
人脸的剪切
'''</span>
fid = open(filelist)
lines = fid.readlines()
fid.close()
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> line <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">in</span> lines:
words = line.split(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">' '</span>)
filename = words[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>]
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">#im=skimage.io.imread(filename)</span>
im=cv2.imread(filename)
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">#保存人脸的点,需要经过转换</span>
point = np.zeros((<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">10</span>,))

point[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>]=float(words[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">5</span>])
point[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>]=float(words[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">6</span>])
point[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>]=float(words[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">7</span>])
point[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">3</span>]=float(words[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">8</span>])
point[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">4</span>]=float(words[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">9</span>])
point[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">5</span>]=float(words[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">10</span>])
point[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">6</span>]=float(words[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">11</span>])
point[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">7</span>]=float(words[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">12</span>])
point[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">8</span>]=float(words[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">13</span>])
point[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">9</span>]=float(words[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">14</span>])

<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> i <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">in</span> range(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">10</span>,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>):
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">#skimage.draw.circle(point[i+1],point[i])</span>
cv2.circle(im, (int(point[i]),int(point[i+<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>])), <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">5</span>, [<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">255</span>])

<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">#skimage.io.imsave(savePath+filename,imcrop)</span>
cv2.imwrite(savePath+filename,im)
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">#print words[0]</span>
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">#print words[1]</span>

<span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">def</span> <span class="hljs-title" style="box-sizing: border-box;">face_prepare</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(filelist,fileout,savePath,w,h)</span>:</span>
<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'''
人脸的剪切

@debug: 谢谢网友@cyq0122 指出图像镜像过后,左右眼睛和嘴角都需要跟着改变的大BUG
'''</span>
fid = open(filelist)
lines = fid.readlines()
fid.close()

fid = open(fileout,<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'w'</span>)

count = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> line <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">in</span> lines:
words = line.split(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">' '</span>)
filename = words[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>]
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">#im=skimage.io.imread(filename)</span>
im=cv2.imread(filename)
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">print</span> np.shape(im)
x1 = int(words[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>])
y1 = int(words[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>])
x2 = int(words[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">3</span>])
y2 = int(words[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">4</span>])
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">#缩放的比例</span>
rate = float(y1-x1)/w
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">#imcrop = im[x2:y2,x1:y1,:]</span>
imcrop = im[x2:y2,x1:y1,:]
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">print</span> np.shape(imcrop)
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">#保存人脸的点,需要经过转换</span>
point = np.zeros((<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">10</span>,))

point[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>]=(float(words[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">5</span>])-x1)/rate
point[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>]=(float(words[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">6</span>])-x2)/rate
point[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>]=(float(words[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">7</span>])-x1)/rate
point[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">3</span>]=(float(words[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">8</span>])-x2)/rate
point[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">4</span>]=(float(words[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">9</span>])-x1)/rate
point[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">5</span>]=(float(words[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">10</span>])-x2)/rate
point[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">6</span>]=(float(words[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">11</span>])-x1)/rate
point[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">7</span>]=(float(words[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">12</span>])-x2)/rate
point[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">8</span>]=(float(words[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">13</span>])-x1)/rate
point[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">9</span>]=(float(words[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">14</span>])-x2)/rate
imcrop = cv2.resize(imcrop,(w,h))
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">#原始图像</span>
fid.write(str(count)+<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'.jpg'</span>)
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> i <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">in</span> range(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">10</span>,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>):
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">#cv2.circle(imcrop, (int(point[i]),int(point[i+1])), 5, [0,0,255])  </span>
fid.write(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'\t'</span>+str(point[i]))
fid.write(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'\t'</span>+str(point[i+<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>]))
fid.write(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'\n'</span>)

<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"># 翻转图像</span>
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"># @cyq0122 指出,左右眼睛需要交换,嘴巴也一样。</span>
imcrop_flip = cv2.flip(imcrop,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>)
fid.write(str(count)+<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'_flip.jpg'</span>)
fid.write(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'\t'</span>+str(w-point[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>]-<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>))
fid.write(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'\t'</span>+str(point[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">3</span>]))
fid.write(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'\t'</span>+str(w-point[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>]-<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>))
fid.write(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'\t'</span>+str(point[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>]))
fid.write(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'\t'</span>+str(w-point[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">4</span>]-<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>))
fid.write(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'\t'</span>+str(point[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">5</span>]))
fid.write(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'\t'</span>+str(w-point[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">8</span>]-<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>))
fid.write(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'\t'</span>+str(point[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">9</span>]))
fid.write(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'\t'</span>+str(w-point[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">6</span>]-<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>))
fid.write(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'\t'</span>+str(point[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">7</span>]))
fid.write(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'\n'</span>)
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">#skimage.io.imsave(savePath+filename,imcrop)</span>
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">#cv2.imwrite(savePath+filename,imcrop)</span>
cv2.imwrite(savePath+str(count)+<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'_flip.jpg'</span>,imcrop_flip)
cv2.imwrite(savePath+str(count)+<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'.jpg'</span>,imcrop)
count = count + <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>
fid.close()
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">#print words[0]</span>
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">#print words[1]</span>

<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> __name__ == <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"__main__"</span>:
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">#train</span>
w = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">39</span>
h = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">39</span>
filelist=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">r"F:\Dataset\FacePoints\train\trainImageList.txt"</span>
filelistesave = <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">r"F:\\MyDataset\\FacePoint\\train39X39\\train.list"</span>
savePath=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'F:\\MyDataset\\FacePoint\\train39X39\\'</span>

face_prepare(filelist,filelistesave,savePath,w,h)
filelist=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">r"F:\Dataset\FacePoints\train\testImageList.txt"</span>
filelistesave = <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">r"F:\\MyDataset\\FacePoint\\test39X39\\test.list"</span>
savePath=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'F:\\MyDataset\\FacePoint\\test39X39\\'</span>
face_prepare(filelist,filelistesave,savePath,w,h)
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">#face_draw_point(filelist,savePath)</span>
</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li><li style="box-sizing: border-box; padding: 0px 5px;">48</li><li style="box-sizing: border-box; padding: 0px 5px;">49</li><li style="box-sizing: border-box; padding: 0px 5px;">50</li><li style="box-sizing: border-box; padding: 0px 5px;">51</li><li style="box-sizing: border-box; padding: 0px 5px;">52</li><li style="box-sizing: border-box; padding: 0px 5px;">53</li><li style="box-sizing: border-box; padding: 0px 5px;">54</li><li style="box-sizing: border-box; padding: 0px 5px;">55</li><li style="box-sizing: border-box; padding: 0px 5px;">56</li><li style="box-sizing: border-box; padding: 0px 5px;">57</li><li style="box-sizing: border-box; padding: 0px 5px;">58</li><li style="box-sizing: border-box; padding: 0px 5px;">59</li><li style="box-sizing: border-box; padding: 0px 5px;">60</li><li style="box-sizing: border-box; padding: 0px 5px;">61</li><li style="box-sizing: border-box; padding: 0px 5px;">62</li><li style="box-sizing: border-box; padding: 0px 5px;">63</li><li style="box-sizing: border-box; padding: 0px 5px;">64</li><li style="box-sizing: border-box; padding: 0px 5px;">65</li><li style="box-sizing: border-box; padding: 0px 5px;">66</li><li style="box-sizing: border-box; padding: 0px 5px;">67</li><li style="box-sizing: border-box; padding: 0px 5px;">68</li><li style="box-sizing: border-box; padding: 0px 5px;">69</li><li style="box-sizing: border-box; padding: 0px 5px;">70</li><li style="box-sizing: border-box; padding: 0px 5px;">71</li><li style="box-sizing: border-box; padding: 0px 5px;">72</li><li style="box-sizing: border-box; padding: 0px 5px;">73</li><li style="box-sizing: border-box; padding: 0px 5px;">74</li><li style="box-sizing: border-box; padding: 0px 5px;">75</li><li style="box-sizing: border-box; padding: 0px 5px;">76</li><li style="box-sizing: border-box; padding: 0px 5px;">77</li><li style="box-sizing: border-box; padding: 0px 5px;">78</li><li style="box-sizing: border-box; padding: 0px 5px;">79</li><li style="box-sizing: border-box; padding: 0px 5px;">80</li><li style="box-sizing: border-box; padding: 0px 5px;">81</li><li style="box-sizing: border-box; padding: 0px 5px;">82</li><li style="box-sizing: border-box; padding: 0px 5px;">83</li><li style="box-sizing: border-box; padding: 0px 5px;">84</li><li style="box-sizing: border-box; padding: 0px 5px;">85</li><li style="box-sizing: border-box; padding: 0px 5px;">86</li><li style="box-sizing: border-box; padding: 0px 5px;">87</li><li style="box-sizing: border-box; padding: 0px 5px;">88</li><li style="box-sizing: border-box; padding: 0px 5px;">89</li><li style="box-sizing: border-box; padding: 0px 5px;">90</li><li style="box-sizing: border-box; padding: 0px 5px;">91</li><li style="box-sizing: border-box; padding: 0px 5px;">92</li><li style="box-sizing: border-box; padding: 0px 5px;">93</li><li style="box-sizing: border-box; padding: 0px 5px;">94</li><li style="box-sizing: border-box; padding: 0px 5px;">95</li><li style="box-sizing: border-box; padding: 0px 5px;">96</li><li style="box-sizing: border-box; padding: 0px 5px;">97</li><li style="box-sizing: border-box; padding: 0px 5px;">98</li><li style="box-sizing: border-box; padding: 0px 5px;">99</li><li style="box-sizing: border-box; padding: 0px 5px;">100</li><li style="box-sizing: border-box; padding: 0px 5px;">101</li><li style="box-sizing: border-box; padding: 0px 5px;">102</li><li style="box-sizing: border-box; padding: 0px 5px;">103</li><li style="box-sizing: border-box; padding: 0px 5px;">104</li><li style="box-sizing: border-box; padding: 0px 5px;">105</li><li style="box-sizing: border-box; padding: 0px 5px;">106</li><li style="box-sizing: border-box; padding: 0px 5px;">107</li><li style="box-sizing: border-box; padding: 0px 5px;">108</li><li style="box-sizing: border-box; padding: 0px 5px;">109</li><li style="box-sizing: border-box; padding: 0px 5px;">110</li><li style="box-sizing: border-box; padding: 0px 5px;">111</li><li style="box-sizing: border-box; padding: 0px 5px;">112</li><li style="box-sizing: border-box; padding: 0px 5px;">113</li><li style="box-sizing: border-box; padding: 0px 5px;">114</li><li style="box-sizing: border-box; padding: 0px 5px;">115</li><li style="box-sizing: border-box; padding: 0px 5px;">116</li><li style="box-sizing: border-box; padding: 0px 5px;">117</li><li style="box-sizing: border-box; padding: 0px 5px;">118</li><li style="box-sizing: border-box; padding: 0px 5px;">119</li><li style="box-sizing: border-box; padding: 0px 5px;">120</li><li style="box-sizing: border-box; padding: 0px 5px;">121</li><li style="box-sizing: border-box; padding: 0px 5px;">122</li><li style="box-sizing: border-box; padding: 0px 5px;">123</li><li style="box-sizing: border-box; padding: 0px 5px;">124</li><li style="box-sizing: border-box; padding: 0px 5px;">125</li><li style="box-sizing: border-box; padding: 0px 5px;">126</li><li style="box-sizing: border-box; padding: 0px 5px;">127</li><li style="box-sizing: border-box; padding: 0px 5px;">128</li><li style="box-sizing: border-box; padding: 0px 5px;">129</li><li style="box-sizing: border-box; padding: 0px 5px;">130</li><li style="box-sizing: border-box; padding: 0px 5px;">131</li><li style="box-sizing: border-box; padding: 0px 5px;">132</li><li style="box-sizing: border-box; padding: 0px 5px;">133</li><li style="box-sizing: border-box; padding: 0px 5px;">134</li><li style="box-sizing: border-box; padding: 0px 5px;">135</li><li style="box-sizing: border-box; padding: 0px 5px;">136</li><li style="box-sizing: border-box; padding: 0px 5px;">137</li><li style="box-sizing: border-box; padding: 0px 5px;">138</li></ul>


数据转化

跟以往的图像分类采用LMDB或者LevelDB 作为数据处理不同,这里我们的标签是一个向量,而不是一个值,所以不能直接用LMDB来作为存储,还好,caffe提供了另外一种数据存储方法来处理这种需求,那就是HDF5, 直观的差别就在于LMDB的标签是一个数,而HDF5 的标签可以是任意(blob),也就是说对于分类任务,我们也可以采样HDF5作为存储的数据模式,但是HDF5直接读取文件,相比LMDB 速度上有所损失。

脚本如下:
<code class="hljs python has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"># -*- coding: utf-8 -*-</span>
<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"""
Created on Wed Apr 29 20:53:14 2015

@author: crw
"""</span>

<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">import</span> os
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">import</span> random
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">import</span> h5py
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">import</span> numpy <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">as</span> np
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">from</span> skimage <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">import</span> io
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">from</span> skimage <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">import</span> transform <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">as</span> tf
trainpairlist=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">''</span>
testpairlist=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">''</span>
<span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">def</span> <span class="hljs-title" style="box-sizing: border-box;">savehdf5</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(X,Y,filename)</span>:</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">with</span> h5py.File(filename, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'w'</span>) <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">as</span> f:
f[<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'data'</span>] = X
f[<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'label'</span>] = Y
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">print</span> <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'having saving a hdf5 file !'</span>

<span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">def</span> <span class="hljs-title" style="box-sizing: border-box;">convert</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(source_path,pairlist,savepath,hdf5list,w,h)</span>:</span>
<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'''
@brief: 将图像列表里的图像转化为矩阵,

@return: X,Y
'''</span>
step = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">5000</span>

fid=open(pairlist)
lines= fid.readlines()
fid.close()
X=np.empty((step,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">3</span>,w,h),dtype=np.float)
Y=np.empty((step,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">10</span>,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>),dtype=np.float)
i=<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>
t=<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">#记得HDF5需要实现shuffle.</span>
random.shuffle(lines)
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> line <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">in</span> lines:
words=line.split(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'\t'</span>)
inputimage=words[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>]
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">#image  标签</span>
points = np.zeros((<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">10</span>,))

points[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>]=float(words[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>])
points[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>]=float(words[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>])
points[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>]=float(words[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">3</span>])
points[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">3</span>]=float(words[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">4</span>])
points[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">4</span>]=float(words[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">5</span>])
points[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">5</span>]=float(words[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">6</span>])
points[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">6</span>]=float(words[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">7</span>])
points[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">7</span>]=float(words[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">8</span>])
points[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">8</span>]=float(words[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">9</span>])
points[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">9</span>]=float(words[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">10</span>])

im=io.imread(source_path+inputimage,as_grey=<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">False</span>)
im=tf.resize(im,(w,h))

X[i,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>,:,:]=im[:,:,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>]
X[i,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>,:,:]=im[:,:,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>]
X[i,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>,:,:]=im[:,:,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>]
Y[i,:,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>]=points
i=i+<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> i==step:
filename = os.path.join(savepath, str(t)+ <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'.h5'</span>)
savehdf5(X,Y,filename)
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">with</span> open(os.path.join(savepath,hdf5list), <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'a'</span>) <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">as</span> f:
f.write(filename + <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'\n'</span>)
i=<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>
t=t+<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> i > <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>:
filename = os.path.join(savepath, str(t)+ <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'.h5'</span>)
savehdf5(X[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>:i,:,:,:],Y[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>:i,:,:,:],filename)
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">with</span> open(os.path.join(savepath,hdf5list), <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'a'</span>) <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">as</span> f:
f.write(filename + <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'\n'</span>)

<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> __name__==<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'__main__'</span>:
w=<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">39</span>
h=<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">39</span>
source_path = <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'/media/crw/MyBook/MyDataset/FacePoint/test39X39/'</span>
save_path = <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'/media/crw/MyBook/TrainData/HDF5/FacePoint/10000_39X39/test/'</span>
hdf5list=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'/media/crw/MyBook/TrainData/HDF5/FacePoint/10000_39X39/test/test.txt'</span>
filelist = <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'/media/crw/MyBook/MyDataset/FacePoint/test39X39/test.list'</span>
convert(source_path,filelist,save_path,hdf5list,w,h)

</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li><li style="box-sizing: border-box; padding: 0px 5px;">48</li><li style="box-sizing: border-box; padding: 0px 5px;">49</li><li style="box-sizing: border-box; padding: 0px 5px;">50</li><li style="box-sizing: border-box; padding: 0px 5px;">51</li><li style="box-sizing: border-box; padding: 0px 5px;">52</li><li style="box-sizing: border-box; padding: 0px 5px;">53</li><li style="box-sizing: border-box; padding: 0px 5px;">54</li><li style="box-sizing: border-box; padding: 0px 5px;">55</li><li style="box-sizing: border-box; padding: 0px 5px;">56</li><li style="box-sizing: border-box; padding: 0px 5px;">57</li><li style="box-sizing: border-box; padding: 0px 5px;">58</li><li style="box-sizing: border-box; padding: 0px 5px;">59</li><li style="box-sizing: border-box; padding: 0px 5px;">60</li><li style="box-sizing: border-box; padding: 0px 5px;">61</li><li style="box-sizing: border-box; padding: 0px 5px;">62</li><li style="box-sizing: border-box; padding: 0px 5px;">63</li><li style="box-sizing: border-box; padding: 0px 5px;">64</li><li style="box-sizing: border-box; padding: 0px 5px;">65</li><li style="box-sizing: border-box; padding: 0px 5px;">66</li><li style="box-sizing: border-box; padding: 0px 5px;">67</li><li style="box-sizing: border-box; padding: 0px 5px;">68</li><li style="box-sizing: border-box; padding: 0px 5px;">69</li><li style="box-sizing: border-box; padding: 0px 5px;">70</li><li style="box-sizing: border-box; padding: 0px 5px;">71</li><li style="box-sizing: border-box; padding: 0px 5px;">72</li><li style="box-sizing: border-box; padding: 0px 5px;">73</li><li style="box-sizing: border-box; padding: 0px 5px;">74</li><li style="box-sizing: border-box; padding: 0px 5px;">75</li><li style="box-sizing: border-box; padding: 0px 5px;">76</li><li style="box-sizing: border-box; padding: 0px 5px;">77</li><li style="box-sizing: border-box; padding: 0px 5px;">78</li><li style="box-sizing: border-box; padding: 0px 5px;">79</li><li style="box-sizing: border-box; padding: 0px 5px;">80</li><li style="box-sizing: border-box; padding: 0px 5px;">81</li><li style="box-sizing: border-box; padding: 0px 5px;">82</li><li style="box-sizing: border-box; padding: 0px 5px;">83</li><li style="box-sizing: border-box; padding: 0px 5px;">84</li><li style="box-sizing: border-box; padding: 0px 5px;">85</li><li style="box-sizing: border-box; padding: 0px 5px;">86</li></ul>


网络结构

数据处理好之后,就可以开始设计网络结构了。 

网络结构采样的是参照[1]的网络结构,相比于其它的大型的网络的特点在于: 

1,输入图像小。 

2,权值非共享。 

这样的网络相比ImageNet 上的那些模型的优点很明显,参数比较少,学习相对快一些,

图片1:是论文中描绘的网络结构: 


 

图片2:是caffe实现的网络结构: 



需要注意的是,caffe 的master分支是没有local 层的,这个local 层去年(Caffe Local)就已经请求合并,然而由于各种原因却一直未能合入正式的版本。大家可以从上面那个链接里面clone 版本进行实验。


实验结果

正确的结果 


 
失败的结果 

//update 2015.11.19://由于之前实验人脸镜面对称的时候,没有将左右眼睛和嘴巴的坐标也对换,导致嘴巴和眼睛都不准的情况出现。感谢 @cyq0122 指出


实验分析

用深度学习来做回归任务,很容易出现回归到均值的问题,在人脸关键点检测的任务中,就是检测到的人脸点是所有值的平均值。在上面失败的例子中,两只眼睛和嘴巴预测的都比较靠近。//修正bug 过后就不会出现这个问题了。

这篇文章中,我只是尝试复现人脸关键点检测文章[1]的第一步,后面有时间的话,也会考虑用caffe 复现所有的结果。

要想完全的复现文章的结果,还需要: 

1,级联,从粗到细的检测 

2,训练多个网络取平均值(各个网络的输入图像块不一样)


代码托管

DeepFace GitHub 托管 欢迎提改进建议~

//update 2015.11.18:添加了数据处理的python文件。


引用

[1] Y. Sun, X. Wang, and X. Tang. Deep Convolutional Network Cascade for Facial Point Detection. In Proceedings of IEEE Conference on Computer Vision and Pattern Recognition (CVPR), 2013.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: