训练一个会“卸妆”的深度学习模型——集智青年

本文是集智青年精心准备的一篇文章,他跑通了整个项目后并做成了api给大家体验。

下面是集智青年给大家做的项目介绍:

《训练一个会“卸妆”的深度学习模型》

从本期开始,我会陆续地给大家推送一些有趣的深度学习项目,并且我会附加上详细的使用流程和免费的视频教程!所以,即使你没有太多深度学习的经验,只要会使用 Python,知道怎么配置 PyTorch 环境,都可以根据我的教程做出有趣好玩的深度学习模型。

今天,我要手把手的带领大家亲自训练一个会“化妆和卸妆”的深度学习模型!

先看看它自动化妆美颜的效果:

再看看它自动卸妆的效果:

厉不厉害!

是不是想知道自己女朋友卸了妆到底长什么样!

那就亲手训练一个模型吧!

视频教程:http://campus.swarma.org/gcou=10360

我现在就带领大家,从“收集处理训练数据”开始,一步步的训练这个神奇的“化妆卸妆”模型!认真阅读本教程,你不仅能掌握一个模型,还能学习到“从图片中切割出人脸”的数据处理方法!

好,那下面就让我们开始吧!

1. 确认软件依赖环境

1.1 系统需求

可运行 PyTorch 的操作系统

Python 3.x

CPU 最好有 NVIDIA GPU + CUDA CuDNN

1.2 软件需求

从官网获取 PyTorch 及 vision

安装 visdom 和 dominate

PyTorch 及其附属包 vison 可从官网获取(http://pytorch.org)。

visdom 是 PyTorch 独有的训练过程中可视化工具。安装 visdom 和 dominate 的命令如下:

pip install visdom

pip install dominate

2. 收集和处理训练数据

这一步重要了!我们今天要训练的模型呀,它需要两种图片数据才可以训练。哪两种图片嘞?根据功能,肯定是需要“化了妆的图片”和“卸了妆的图片”。我们把这两种图片“喂”给今天深度学习模型以后,模型会努力学习两种图片之间的关系与特征,最终实现在两种图片之间进行转换!

2.1 收集数据

其实化妆和卸妆图片是非常好找的,只需要百度搜索“化妆前后对比”,即可找到大量图片。我们只需要筛选一些图片保存到本地即可。

我是采用纯手动的方式把图片保存到本地的,共收集了 168 张。有能力的同学还可以使用爬虫“爬”出更多数据。

2.2 切分数据

从网上收集的图片效果杂乱,所以在使用这些图片训练模型之前,先要对图片进行处理。

从网上下载的图片是“化了妆”和“没化妆”的人脸在一张图片上,所以第一步就是把“化了妆”和“没化妆”的图片切分开来。

其实分割算法很简单,只要从原图一半宽度的位置把图片“劈”开就好了。我们使用 Python 的 Pillow 包实现图片的分割,代码如下:

importImage

defcut_photo(filename,outputname):

im=Image.open(filename)

# 获得原图的宽高

im_wid,im_hei=im.size

# 指定切分区域的位置,0,0为图片左上角

box_a=(0,0,im_wid/2,im_hei)

# 第二个切分区域

box_b=(im_wid/2,0,im_wid,im_hei)

# 执行切分,保存图片

region_a=im.crop(box_a)

region_a.save(outputname+'_a.jpg')

region_b=im.crop(box_b)

region_b.save(outputname+'_b.jpg')

2.3 “收割”人脸

在上一步将图片一分为二后,我们会得到两张“长图”。观察两张图,可以发现图中除了“人脸”之外还包含人物背景啊、上身啊等信息。我们是要做“化妆”和“卸妆”呀,所以除了人脸之外的信息都是多余的,而多余的信息传入模型后会影响训练的效果。所以,我们要把人脸单独切割出来!

我从世界上最大的同性交友网站 GitHub 上找到了 cropman 这个工具来切割人脸。在使用时,cropman 可以自动定位人脸的中心位置,但仍需我们指定高宽,从而按照指定的大小把人脸切割出来。

执行切割的代码很简单,我是根据 cropman 的示例代码修改的。

fromcropman.cropperimportCropper

importcv2

# 输入、输出图片的路径,以及指定的高宽

defcut_face(inputImg,targetImg,targetWidth,targetHeight):

input_filename=inputImg

target_filename=targetImg

target_width=int(targetWidth)

target_height=int(targetHeight)

# 人脸收割者!

cropper=Cropper()

# 下面的程序是切割图片后保存

input_image=cv2.imread(input_filename)

ifinput_imageisNone:

print'Invalid input image. Please check %s'%input_filename

else:

target_image=cropper.crop(input_image,target_width,target_height)

iftarget_imageisNone:

print'Cropping failed.'

else:

cv2.imwrite(target_filename,target_image)

print'\nDone. \nResult: %s'%target_filename

有时候以固定的大小切割分辨率较大的图片时会出现无法切割完整的情况。如果这样的图片占少数,则可以手动 PS 进行调整,如果这样的图片较多,建议大家先使用程序把图片缩放到相似的大小再进行人脸切割。

2.4 通过“图片增强”增加数据量!

经过上面的处理,我们已经拥有了高质量的人脸图片,但是嘞,化妆卸妆的图片各有168张,这对训练深度学习模型来说太少了。

对于这种情况,我们可以使用图片增强技术生成数据集。什么是图像增强嘞?其实就是对图片进行旋转、镜像、调整对比度、亮度、饱和度、锐度等处理,将经过处理过的图片当成“新数据”,原有的图片一起传入神经网络进行训练。

这样做的原理是人工模拟自然存在的图片的多样性,虽然效果比不上真正的数据,但是还是能在一定程度上提高深度学习模型的“普适性”,让模型学习的效果更好。

我是使用 Pillow 实现的图片增强,随机选择效果对图片进行处理:

importImageEnhance

# 对图片随机进行旋转和左右置换

defphoto_transform(filename,savename,trans_type):

im=Image.open(filename)

#旋转与平移的量也是随机的

rand=random.randrange(15,46)

rand_choice=random.randrange(0,2)

iftrans_type==0:

# 旋转

out=im.rotate(rand)

ifrand_choice==0:

#左右置换

out=out.transpose(Image.FLIP_LEFT_RIGHT)

out.save(savename)

eliftrans_type==1:

out=im.transpose(Image.FLIP_LEFT_RIGHT)

ifrand_choice==0:

rand=random.randrange(0,15)

out=im.rotate(rand)

out.save(savename)

eliftrans_type==2:

out=im.rotate(-rand)

ifrand_choice==0:

out=out.transpose(Image.FLIP_LEFT_RIGHT)

out.save(savename)

else:

pass

# 随机调整图片的对比度、色彩等属性

defphoto_enhance(filename,savename,enhance_type):

im=Image.open(filename)

ifenhance_type==0:

enh_bri=ImageEnhance.Brightness(im)

brightness=random.uniform(0.7,1.2)

out=enh_bri.enhance(brightness)

out.save(savename)

elifenhance_type==1:

enh_col=ImageEnhance.Color(im)

color=random.uniform(0.7,1.5)

out=enh_col.enhance(color)

out.save(savename)

elifenhance_type==2:

enh_con=ImageEnhance.Contrast(im)

contrast=random.uniform(0.7,1.5)

out=enh_con.enhance(contrast)

out.save(savename)

elifenhance_type==3:

enh_sha=ImageEnhance.Sharpness(im)

sharpness=random.uniform(0.7,3.0)

out=enh_sha.enhance(sharpness)

out.save(savename)

else:

pass

至此,包括原有的168张图片,我共有1008张“上妆/卸妆”图片,可以运行模型进行训练了。

3. 使用数据,开始训练!

3.1 将训练数据放入指定位置

在训练前要把训练数据放到指定位置以方便使用。

在 CycleGAN 源码目录中找到./datasets目录.

在 datasets 目录下创建“上妆/卸妆”数据文件夹:makeup2

在 makeup2 中创建子目录

trainA 训练数据A(素颜图片)

trainB 训练数据B(美妆图片)

testA 测试数据A(测试用素颜图片)

testB 测试数据B(测试用美妆图片)

将之前加工过的数据放置在相应文件夹中即可。

3.2 开始训练

运行实时训练监控程序

python-m visdom.server&

运行命令后,访问下面的网址,即可打开训练过程实时监控平台。

http://localhost:8097

然后再运行开始训练的命令:

python train.py--dataroot./datasets/makeup2--name makeup_cyclegan--model cycle_gan--no_dropout

其中:

dataroot 表示训练数据目录

name 表示模型训练完成后的名字

model 表示要使用的基本模型框架

命令运行后即开始训练,我在一块 Titan X 平台上训练了12个小时左右,在 Floyd 平台上会需要更多一点时间。

4. 使用模型!

训练结束后,即可测试验证模型,在保证测试图片已经放在相应目录的情况下,运行命令:

python test.py--dataroot./datasets/makeup2--name makeup_cyclegan--model cycle_gan--phase test

--no_dropout

在这里注意,训练好的模型都在 ./checkpoints 目录下,测试结果生成在 ./results 目录下。

让我们看一下效果!

可以看到给素颜图片化妆的效果非常好!而对于卸妆,尽管这位艺人进行了极夸张的美颜,但是我们的模型还是在一定程度上进行了还原!

总体来说,我们这次训练的模型,成功!

如果你不想错过更多的有趣的深度学习应用,那就快快关注 集智AI学园 公众号吧!

今天有彩蛋!

api.swarma.org

体验模型效果

(PS:可能会有些慢,且效果并没有某些APP那么理想,我们本次实验的重点是模型的实现

下面是本次项目的小教程

有兴趣的同学可以跟着做一下~

微信公众号:swarmAI

集智AI学园QQ群:426390994

学园网站:campus.swarma.org

推荐阅读更多精彩内容