您的位置:首页 > 数据库

深度学习的浅实践:开源软件/数据库实现表情识别(2)

2016-02-25 21:58 786 查看

给机器准备教材

图像的像素这么多(维度这么高),现实的情况如此复杂,我们没有办法手工地定义好规则然后让计算机执行,因此需要准备足够的训练数据,设计算法让机器自己寻找其中的统计规律,然后对训练数据以外的测试样例进行预测,所谓的机器学习。可是如何表示这些训练数据,怎样描述所谓的规律,设计什么样的算法让机器去寻找规律,这些都不是容易的问题。一篇典型的计算机视觉的论文经常就这几个问题提出一两个新的方法。例如对于表情识别这个问题,在数据的表示方面,是直接使用像素值,还是图像的梯度或其他滤波结果,或是其他手工定义的特征,例如HOG?LBP?是在整张图上提取特征来表示,还是在人脸的关键点附近?是人工定义区域来提取还是让机器自己寻找和表情有关的区域?对于规律的描述,是使用一个生成(generative)模型,例如基于PCA的ASM,AAM来描述人脸的动作?还是使用判别(discriminative)模型,例如random forest,深度卷积网络(CNN)选取或学习有意义的特征来预测分类结果?如何让机器自动地寻找规律,即这些模型的参数?是通过添加约束,使得问题存在一个closed form 的解,还是直接使用梯度下降法获得有个局部最优解?

因此,这里头的学问也是五花八门。在此,我们使用深度卷积网络(deep convolutional network, CNN) 直接从整张图像的像素值学习特征,同时通过线性分类器进行表情的分类。

表情数据库

表情分类在计算机视觉领域一直是个不冷不热的话题。怎么说呢?情感分析应该是人机交互里面一个非常重要的问题,可是情感分析简单地表示成表情分类会带来以下问题。

问题定义困难。人的表情应该分为几类?目前学术界使用7个类别:无表情、生气、厌恶、惊讶、开心、伤心、害怕。可是仔细想想,这7个类既不是正交的也不能完全表示人的表情。例如一个人既可以同时惊讶和害怕。又例如人除了这7个表情,还可以有其他表情,例如嘲笑算什么?

数据收集困难。一些开心的图片网上一搜一大堆。可是某些表情,例如厌恶、害怕,不太好找。

话虽如此,即便表情分类这个提法有自己的限制,能学习出一个表情分类器仍然是有作用的,例如至少我们能判断一个人是否开心或者伤心啊(否则Microsoft Oxford Projectindico的表情接口就白做啦:))。

这里我们采用的训练数据来自Kaggle的一个表情分类比赛。其中包含三万多张来自网上的人脸图片,每张图片被标注为“无表情、生气、厌恶、惊讶、开心、伤心、害怕”的其中一种。

开源深度学习库

有了数据,我们还需要一个快速的深度卷积网络的库(否则自己实现可是一大工程的)。目前我所知道的流行的库有Caffe, Torch, Theano, MXNet, Cuda-convnet2CNTK, TensorFlow. 下面简单说说我用过的几个:

Caffe: 计算机视觉的community使用最广泛的CNN框架之一。使用C++实现,有Matlab,Python以及命令行接口。网络的定义使用prototxt文件。这对于复杂的网络不太友好,当然python接口提供了通过代码生成prototxt的功能,然而在训练的接口再输入生成的prototxt文件,整体上实在说不上优雅。不过扩展相对容易,文档比较完善,而且用户多,社区支持容易(国内还有个中文论坛专门讨论他的),这些都是优点。

Cuda-convnet2: Cuda-convnet的第二代,主要是提供了多GPU的支持。想当年Caffe还没有的时候,搞CV的基本上要deep都是使用这玩意了。速度极快。这里有个帖子专门对各种深度学习库进行了速度测试。但也因为注重速度,编码设计方面没有过多地考虑扩展性,因此代码可读性以及扩展比较困难。近来似乎使用的人渐少了。

MXNet: 几个华人大牛打造的深度学习库。有Python和R的接口。接口上融合了声明式(declarative)和命令式(imperative)的编程风格。扩展和定制都比较容易。这里有个该作者给的talk

训练数据准备

对于训练图像,MXNet可以接受三种形式的输入:CSV文件、Record 文件,NDArray (类似于numpy的array)。其中Record文件是MXNet把图像数据以二进制的方式存储,可以实现多线程读取和解码。相比于CSV文件,更利于读取,相比于NDArray,适合数据量大内存放不下的情况。而且MXNet对于这种数据输入形式,自带实现了训练时的数据增广(augmentation),例如旋转、平移。因此,这里需要把图像准备成Record文件。

转换步骤分为两步,首先生成一个列表文件,文件中每一行记录了图像路径以及label.第二步调用MXNet的im2rec,读入列表文件生成record文件。代码如下:

首先,因为表情数据库有自己的格式,我们先将其准备成方便进一步处理的形式。包括:a)把每个图片文件单独存储出来 b)使用一个pickle文件记录每个图片的路径和label

import csv
import numpy as np
import skimage.io as io
import skimage.transform as transform
import matplotlib as plt
import h5py
import os
import pickle

#fer2013是数据集本来的存储形式
fer_csv_file = 'fer2013.csv'
fi = open(fer_csv_file,'r')
image_directory = 'image'
save_file_name = 'FER.pkl'
if not os.path.exists(image_directory):
os.mkdir(image_directory)

cnt = 0
faces = []
for row in csv.DictReader(fi):
usage = str(row['Usage'])
if usage=='PrivateTest':
continue
cnt+=1
emotion = int(row['emotion'])
#raw_input('test')
pixels =  row['pixels']
pixels = (pixels.split(' '))
pixels = [int(x) for x in pixels]
pixels = np.asarray(pixels).reshape((48,48)).astype(np.float32)
pixels = transform.resize(pixels/float(255),(96,96))
image_path=os.path.join(image_directory,str(cnt).zfill(5)+'.bmp')
io.imsave(image_path,(pixels*255).astype(np.uint8))

face_strcture = {}
face_strcture['file_path'] = image_path
face_strcture['expression'] = emotion
faces.append(face_strcture)
print cnt

pickle.dump(faces,open(save_file_name,'w'))


然后,我们读取刚才存储的pickle文件,生成MXNet中im2rec能接收的列表文件,然后调用im2rec生成二进制的record文件。至此,机器的教材准备完毕,代码如下:

import pickle
import random
import csv
import os

data_type = 'train'
lst_file = 'lst/fer_train.lst'
IM2REC_PATH = '../../lib/mxnet/bin/im2rec'
output_bin_file = 'bin/fer_train.bin'
img_root_dir = '../../FER/'
fo = open(lst_file,'w')
fwtr = csv.writer(fo,delimiter='\t',lineterminator='\n')

if data_type=='train':
pkl_file = '../../FER/FER.pkl'
else:
pkl_file = '../../FER/FER_test.pkl'

faces = pickle.load(open(pkl_file,'r'))

sample_lst=[]
for idx,face in enumerate(faces):
sample_lst.append((idx,face['expression'],face['file_path']))

random.shuffle(sample_lst)
for item in sample_lst:
fwtr.writerow(item)

fo.close()

os.system(IM2REC_PATH+' '+lst_file+' '+img_root_dir+' '+output_bin_file+' color=0')


代码托管于Github: https://github.com/zhzhanp/facial_expression_recognition/blob/master/FER/gather_fer.py

https://github.com/zhzhanp/facial_expression_recognition/blob/master/mxnet/data_preparation/gen_fer_bin.py
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: