手把手 | 初学者如何用Chainer为漫画上色 深度学习帮你逆袭漫画家(附代码)

简介:


0?wx_fmt=gif

最近一直有人说深度学习(Deep Learning)的附加价值高,于是我也在一两个月前开始学习chainer了。机会难得就想试着用chainer做一些各种各样的尝试,比如写个给线描上色的小程序之类的。

线描上色这个任务的性质是监督式学习(supervised learning),因此需要大量的线稿和上完色的图片,越多越好。

这次是用opencv用角色的画像把线稿生成了出来。生成例子如下:

0?wx_fmt=jpeg

0?wx_fmt=jpeg

收集了角色们的画像,将其转化为线稿之后数据集(dataset)就完成了。这次用了约60万张图片。

关于神经网络(neural network)的结构,我用了一种叫做U-net的网络。它的特点是会把卷积(convolution)和反卷积(deconvolution)的层混合着连接在一起。这样就可以做到参照着一开始的线稿来上色。(译者注:有兴趣的可以看一下unet的论文以及文末提供的神经网络代码。)

这样生成出来的图像和原来上完色的图像对比然后取平方差,神经网络的训练让平方差最小即可。

只要保证网络每一层的输入和下一层的输出相匹配就大体ok,但是自己定义的数据如何制作这方面,因为没有什么例子所以可能对各位来说有些难懂。

花了整整一晚上时间使劲用data喂饱了neural net(掩面)的结果↓

0?wx_fmt=jpeg

嗯~神经网络这边大概是想说“肌肤的颜色我大概能搞懂但是除此之外的实在不知道啊,发色啊衣服颜色啊我当然不可能知道吧。”

这里要登场的是叫对抗网络(adversarial net)的神经网络,简称“怼”。

“怼”要做的是学习真正的图像和被神经网络生成出来的图像之间的颜色差别,然后找出两个图像中的那个叛徒。

所以如果神经网络一直生成老照片那样颜色的图像的话“怼”只要学一会儿就能准确的找出哪一张是神经网络生成的。

但是如果“怼”太用力的话上色的神经网络会拼命反抗导致上色失败请多加注意。

0?wx_fmt=jpeg

这样的颜色都已经说不上是线稿上色后的东西而更加接近艺术了。(嘛,顺着这条道走,把上色用神经网络怼成艺术生也不是不可以。。。现在暂时还是回到学习和原画之间的差别上面吧)

0?wx_fmt=jpeg

呼,上色终于完成了!照着这个势头下去再接着干吧。

第一阶段是学习了128x128的图像,第二阶段是给512x512的图像学习上色。以下是没“怼”过的训练结果↓

0?wx_fmt=jpeg

还不错哟

0?wx_fmt=jpeg

不错不错。

0?wx_fmt=jpeg

把实际的线稿拿来喂给神经网络如何?我从pixiv上借用来了线稿类的画

0?wx_fmt=jpeg

(因为神经网络大部分都是卷积神经网络(cnn),宽高比有一些变化也没关系)

0?wx_fmt=jpeg

好棒!

变成了彩色的怪物了,嘛这种怪物也是有的。

平安收工。

说回来,果然还是会想亲手在线稿上上一些色吧?于是稍微改变一下输入,和一阶段不同的是在原来的线稿之外多加了三个输入层(rgb),给神经网络一些用色上的提示吧。

总之:

0?wx_fmt=jpeg

茶色的头发淡蓝的水手服和藏青的裙子,之类的要求也可以提了。

稍微霸气的像这样画上一笔也是可以的。

0?wx_fmt=jpeg0?wx_fmt=jpeg

不管是大概的提示也好非常用心的每个细节都提示也好效果都不错。(可能有些难懂,就是用不同的颜色在各种地方点一下来提示,比如下面)

0?wx_fmt=jpeg

这样我也从工程师升职成画师了!

至此,我觉得线稿的自动上色和带提示的上色已经做的还不错了。

虽然还不如画师们认真画出来的,如果想随随便便涂个色还是非常方便的(译者:比如在经费不够的情况下。。。)。

漫画之类的也是,比起用网点贴纸(Screen tone)还是大致的上一个色比较快速方便的。(这次的神经网络非常擅长给肤色上色。。。我想说的各位懂得吧~)

顺便补充一下,弱点还是有几个的。

例如同时用对抗网络和上色提示一起训练的时候,上色提示会干涉到对抗网络,有时会导致训练结果不稳定。

0?wx_fmt=jpeg

↑明明只是想给泳装上一个不同的颜色,结果其他部分的颜色也跟着变了。

如果只是作为一个简单的上色工具的话,只加提示来训练神经网络可能会更加稳定。

另外,如果线稿的线太粗或者太细的情况下,线会崩坏掉导致结果不怎么样的情况也有,仔细的给了上色提示但是没有反应在结果上的情况也有。

不同的细节都用同一个神经网络来对付虽然比较厉害,但是作为工具使用的时候需要根据用途来做一些调整。

借鉴的线稿原画:

「【プリンセスロワイヤル】パンドラ」/「鉛筆工房【IRITH】」[pixiv] (http://www.pixiv.net/member_illust.php?mode=medium&illust;_id=31274285)

線画詰め(http://www.pixiv.net/member_illust.php?mode=manga&illust;_id=43369404)

「改弐」/「炬燵魂」[pixiv](http://www.pixiv.net/member_illust.php?mode=medium&illust;_id=56689287)

「めりくり線画」/「タマコ」[pixiv](http://www.pixiv.net/member_illust.php?mode=medium&illust;_id=40487409)

「泰1」/「20100301」[pixiv](http://www.pixiv.net/member_illust.php?mode=medium&illust;_id=10552795)

※生成的线稿的训练材料和原画一时半会儿找不到,实在抱歉,还请多包涵。


顺便,这次的神经网络第一阶段和第二阶段的构造都是一样的,基本上感觉如下:


unet.py

class UNET(chainer.Chain):
def __init__(self):
super(UNET, self).__init__(
c0 = L.Convolution2D(4, 32, 3, 1, 1),
c1 = L.Convolution2D(32, 64, 4, 2, 1),
c2 = L.Convolution2D(64, 64, 3, 1, 1),
c3 = L.Convolution2D(64, 128, 4, 2, 1),
c4 = L.Convolution2D(128, 128, 3, 1, 1),
c5 = L.Convolution2D(128, 256, 4, 2, 1),
c6 = L.Convolution2D(256, 256, 3, 1, 1),
c7 = L.Convolution2D(256, 512, 4, 2, 1),
c8 = L.Convolution2D(512, 512, 3, 1, 1),

dc8 = L.Deconvolution2D(1024, 512, 4, 2, 1),
dc7 = L.Convolution2D(512, 256, 3, 1, 1),
dc6 = L.Deconvolution2D(512, 256, 4, 2, 1),
dc5 = L.Convolution2D(256, 128, 3, 1, 1),
dc4 = L.Deconvolution2D(256, 128, 4, 2, 1),
dc3 = L.Convolution2D(128, 64, 3, 1, 1),
dc2 = L.Deconvolution2D(128, 64, 4, 2, 1),
dc1 = L.Convolution2D(64, 32, 3, 1, 1),
dc0 = L.Convolution2D(64, 3, 3, 1, 1),

bnc0 = L.BatchNormalization(32),
bnc1 = L.BatchNormalization(64),
bnc2 = L.BatchNormalization(64),
bnc3 = L.BatchNormalization(128),
bnc4 = L.BatchNormalization(128),
bnc5 = L.BatchNormalization(256),
bnc6 = L.BatchNormalization(256),
bnc7 = L.BatchNormalization(512),
bnc8 = L.BatchNormalization(512),

bnd8 = L.BatchNormalization(512),
bnd7 = L.BatchNormalization(256),
bnd6 = L.BatchNormalization(256),
bnd5 = L.BatchNormalization(128),
bnd4 = L.BatchNormalization(128),
bnd3 = L.BatchNormalization(64),
bnd2 = L.BatchNormalization(64),
bnd1 = L.BatchNormalization(32)
)

def calc(self,x, test = False):
e0 = F.relu(self.bnc0(self.c0(x), test=test))
e1 = F.relu(self.bnc1(self.c1(e0), test=test))
e2 = F.relu(self.bnc2(self.c2(e1), test=test))
e3 = F.relu(self.bnc3(self.c3(e2), test=test))
e4 = F.relu(self.bnc4(self.c4(e3), test=test))
e5 = F.relu(self.bnc5(self.c5(e4), test=test))
e6 = F.relu(self.bnc6(self.c6(e5), test=test))
e7 = F.relu(self.bnc7(self.c7(e6), test=test))
e8 = F.relu(self.bnc8(self.c8(e7), test=test))

d8 = F.relu(self.bnd8(self.dc8(F.concat([e7, e8])), test=test))
d7 = F.relu(self.bnd7(self.dc7(d8), test=test))
d6 = F.relu(self.bnd6(self.dc6(F.concat([e6, d7])), test=test))
d5 = F.relu(self.bnd5(self.dc5(d6), test=test))
d4 = F.relu(self.bnd4(self.dc4(F.concat([e4, d5])), test=test))
d3 = F.relu(self.bnd3(self.dc3(d4), test=test))
d2 = F.relu(self.bnd2(self.dc2(F.concat([e2, d3])), test=test))
d1 = F.relu(self.bnd1(self.dc1(d2), test=test))
d0 = self.dc0(F.concat([e0, d1]))

return d0

“怼”

adv.py

class DIS(chainer.Chain):
def __init__(self):
super(DIS, self).__init__(
c1 = L.Convolution2D(3, 32, 4, 2, 1),
c2 = L.Convolution2D(32, 32, 3, 1, 1),
c3 = L.Convolution2D(32, 64, 4, 2, 1),
c4 = L.Convolution2D(64, 64, 3, 1, 1),
c5 = L.Convolution2D(64, 128, 4, 2, 1),
c6 = L.Convolution2D(128, 128, 3, 1, 1),
c7 = L.Convolution2D(128, 256, 4, 2, 1),
l8l = L.Linear(None, 2, wscale=0.02*math.sqrt(8*8*256)),

bnc1 = L.BatchNormalization(32),
bnc2 = L.BatchNormalization(32),
bnc3 = L.BatchNormalization(64),
bnc4 = L.BatchNormalization(64),
bnc5 = L.BatchNormalization(128),
bnc6 = L.BatchNormalization(128),
bnc7 = L.BatchNormalization(256),
)

def calc(self,x, test = False):
h = F.relu(self.bnc1(self.c1(x), test=test))
h = F.relu(self.bnc2(self.c2(h), test=test))
h = F.relu(self.bnc3(self.c3(h), test=test))
h = F.relu(self.bnc4(self.c4(h), test=test))
h = F.relu(self.bnc5(self.c5(h), test=test))
h = F.relu(self.bnc6(self.c6(h), test=test))
h = F.relu(self.bnc7(self.c7(h), test=test))
return self.l8l(h)

原文发布时间为:2017-03-04

本文来自云栖社区合作伙伴“大数据文摘”,了解相关信息可以关注“BigDataDigest”微信公众号

相关文章
|
2月前
|
人工智能 自然语言处理
Sora如何用?小白教程,一文带你看清
仅仅凭借文字就可以生成一段视频!近日,OpenAI的一款新产品又火出圈了。当地时间周四(2月15日),OpenAI发布了首个文生视频模型Sora。 2024年2月16日,OpenAI在官网上正式宣布推出**文本生成视频**的[大模型 Sora](https://openai.com/sora),该工具可以通过使用文本迅速制作出一段长达60秒的视频,视频中可以呈现多个角色、特定动作、以及复杂场景。OpenAI的官网上现已更新了48个视频案例,可以说是效果逼真,能展现艳丽的色彩,呈现准确的细节,连人物角色都是表情丰富。
|
1月前
|
机器学习/深度学习 人工智能 算法
机器学习的魔法(一)从零开始理解吴恩达的精炼笔记
机器学习的魔法(一)从零开始理解吴恩达的精炼笔记
|
8月前
|
机器学习/深度学习 开发框架 决策智能
计算机视觉实战 (一) 开个视觉实战专栏
计算机视觉实战 (一) 开个视觉实战专栏
243 0
|
9月前
|
人工智能 自然语言处理 机器人
如何用ChatGPT学Python
关于ChatGPT的能力,大家想必都已听说,很多同学应该都亲自体验过了。其在自然语言处理方面的出色表现,绝对是颠覆了之前大众对人工智能的印象
|
机器学习/深度学习 存储
本科生学深度学习-史上最容易懂的RNN文章,小白也能看得懂
最近写了一些基础的东西,总是理解性的,没有看到实例,今天就讲一个基础的网络结构RNN,然后写个实例,体验下深度神经网络的牛逼,这次学习下rnn神经网络,虽然看起来好高深,不过不用慌,没有理论,全是大白话,大家都可以懂的。
256 0
本科生学深度学习-史上最容易懂的RNN文章,小白也能看得懂
|
机器学习/深度学习
《动手学深度学习》学习随笔
《动手学深度学习》学习随笔
53 0
《动手学深度学习》学习随笔
|
机器学习/深度学习 人工智能 算法
强化学习入门-第一课【笔记】(下)
强化学习入门-第一课【笔记】(下)
385 0
强化学习入门-第一课【笔记】(下)
|
机器学习/深度学习 算法 数据挖掘
周志华《机器学习》西瓜书精炼版笔记来了!16 章完整版
周志华《机器学习》西瓜书精炼版笔记来了!16 章完整版
1489 0
周志华《机器学习》西瓜书精炼版笔记来了!16 章完整版
|
机器学习/深度学习 PyTorch 算法框架/工具
【从零开始学习深度学习】10.自己动手从零开始实现一个多层感知机
【从零开始学习深度学习】10.自己动手从零开始实现一个多层感知机
|
机器学习/深度学习 人工智能
吴恩达知乎开课:谢邀,我来教你系统学习机器学习
吴恩达知乎开课:谢邀,我来教你系统学习机器学习
166 0
吴恩达知乎开课:谢邀,我来教你系统学习机器学习