Fw: [创作] 训练了一个根据草稿画一个固定角色的模型

楼主: kirimaru73 (雾丸)   2022-10-02 12:32:56
※ [本文转录自 C_Chat 看板 #1ZEHHD2t ]
作者: kirimaru73 (雾丸) 看板: C_Chat
标题: [创作] 训练了一个根据草稿画一个固定角色的模型
时间: Sun Oct 2 12:32:10 2022
前言:这并不是那个现在几乎每天都有新话题的AI根据关键字自动绘图。
一来那种研究已经有很多人做了,我手上的资源也不可能把它做好。
二来我对AI无法通灵的问题也不是很满意。我还是宁愿主动给予较明确的资讯。
我的目标是给予一张低分辨率的黑白草稿图片(非黑即白,没有中间灰阶值),
输出一张较高分辨率,且与特定主题相符的彩色图片。
目前的版本中,草稿图片的分辨率为64x64,远低于一般描绘草稿的尺寸。
输出彩色图片的分辨率则为256x256,老实说这有点太小了。
但受限于手上的资源与花费时间,目前只能达到这个尺寸。
至于“特定主题”的限制,则与这个问题本身的难度有关。
即使是给予“二次元人物大头照”这么明确的设定,也有各种不同的配色。
无论AI再怎么厉害,也绝不可能在无额外资讯的情况下通灵出你想要的配色。
当然已经存在许多额外输入颜色的应用范例,但终究还是要提供额外资讯。
一种只需要给草稿,不需要额外资讯的应用方法,就是请AI画某个特定角色。
而这种吃力不讨好的研究,当然就要选自己最喜欢的角色了:
https://dic.pixiv.net/a/%E6%98%9F%E7%86%8A%E5%8B%87%E5%84%80
示范影片:
https://www.youtube.com/watch?v=_3o_YFQoWDo
在目前的成果中,可以看到AI确实认得发色、瞳色、以及那根明显的角。
而在许多可见的问题中,最严重的就是那有如核废料般的背景。
这其实是可想而知的结果,在下面的细节中会特别解释。
而它其实也有解决方法,但目前的版本还无法处理,应该会是下一个研究主题。
训练出这么一个只能画特定角色的模型有什么用?老实说,没什么用。
现在都2202年了,一个只能画一颗头的玩具最多就只是个玩具。
虽然还是好像有点东西出来,但笔触方面仍旧不太自然,颜色变化也单调。
与处理训练资料所花的时间相比(准备草稿非常耗时,后续细节部分有说明),
这个种程度的结果相当相当成比例,直接去练绘图似乎还比较好。
所以我才在一开始就选定这个角色,至少这样我就绝对不会后悔。
以下是一些与人工智能研究直接相关的细节,没兴趣的读者们可以忽略。
训练资料
训练AI需要收集大量的资料,而我总共收集了2400张图片。
虽然这个角色的人气很低,不过在Pixiv上也有接近两万张图片。
(其他绘图网站当然也有不少,但还是Pixiv数量最多。)
由于主题是脸部特写,所以我需要排除以下的图片:
1. 有一只眼睛完全被挡住的侧脸(这会产生过大的变化度,使AI训练困难)
2. 一只或两只眼睛闭上(比1.简单一点,但还是有影响,先排除)
3. 脸部被太过夸张的装饰或前景遮挡
4. 脸部被角色自己的CP贴上来遮挡
5. 画风过于特殊,与一般的二次元绘图相去太远
6. 上车图(我不希望未来哪一天时在展示资料时突然就手滑了)
7. 主推绘师所产出的大量图片(资料重复性太高对训练不妥,我只会从中挑几张)
过滤完后的可用图片只剩下2400张(当然每一两天会有新的,不过缓不济急)。
以AI绘图的主题来说,这个量其实根本不够,不过更多的我也生不出来。
要标示原始图片的脸部区域,并获得旋转与裁切后的内容并不困难。
如果你要玩的是GAN或Diffusion Model,那你已经可以拿去用了。
不过我的主题是给予对应的草稿,将这些图片做为输出的标准答案。
由于AI无法通灵出没有给的资讯,例如图片环境的明暗,以及作者习惯的配色。
因此我以脸部附近的颜色分布为参考,将所有图片的明暗与颜色调整至一致。
(实作上我只是分别调整RGB三色频道的平均值与标准差而已。)
接下来的重点是准备这些图片的输入草稿,而这就是另一个恶梦的开始。
草稿输入
我将每张图片的脸部旋转至水平方向,以产生2400张256x256的脸部特写。
对于每一张图片,我需要给予一张对应的64x64草稿,像这样:
https://i.imgur.com/qQEvoHP.png
右边是256x256的图片,左边是64x64的草稿放大成256x256的尺寸。
很明显地,草稿绝对不可能表达出所有的完整的细节,一定要做大幅度的简化。
当然如果是256x256的草稿就可以描绘更多细节,但这与我一开始的目标不符。
虽然我愿意给AI输入资料,但还是希望它能用非常精简的内容产生复杂结果。
怎样的内容该用怎样的草稿代表?这完全没有标准答案。
我只能用自己的一套标准,并尽量从头到尾保持一致。
例如,背景的内容与角色本身无关,所以无论细节为何都保持空白。
角色脸部以下自然延伸的脖子、肩膀部分会提供对应的草稿。
但如果是举起的手脚或不相干的背景,则只标示出边界,以外则保持空白。
虽然草稿只有64x64,但如果是逐个像素慢慢点,点个几张就要出人命了。
所以我用了一个简单的边缘侦测算法来产生一个作为起始的自动草稿:
https://i.imgur.com/JAsJMNK.png
当然这种自动草稿的可靠性还是很差,每一张图都有许多地方需要手动修改。
而来源不同的图片有各种不同的画风,有时候会出现差异明显较大者:
https://i.imgur.com/rYM7MDd.png
这种画风与线稿上色明显不同,在训练时有引发混乱的风险。
然而,在训练资料缺乏的状况下,我还是有使用这类型的资料。
(当然更极端的案例,例如水墨画风格,则还是舍弃不用。)
另一个比较严重的问题是位于图片边界的脸部:
https://i.imgur.com/EAJ8mnH.png
如果想像头型画出完整的草稿,则AI会看到正常的草稿以及缺乏部分内容的图片。
(图片外的区域我以随机颜色填补,所以才会出现亮绿色,这似乎不是好做法)
所以我只把草稿画在有效区域内,外部区域以及图片边界上都不标示,
然后祈祷AI至少能在有效区域内学到有用的东西(AI训练师常有的信仰)。
在现实上,这个边界问题,以及图片中不固定的背景内容,
就是造成了范例影片中背景颜色有如核废料一般的原因。
一种可能的解决办法是在标示草稿时,也额外标示一个背景与无效区域。
然后在训练时要求AI把该区域填成白色,这样至少可以得到一致的结果。
更进一步的策略是,在AI训练小有成果后,
把这些有边界问题的图片之草稿画成完整的样子,然后请AI重新画一张。
这样或许可以在本人还没有原作者绘图功力的前提下补出完整的头型。
不过这个做法目前还在想像阶段,无法保证能得到堪用的结果。
Augmentation(资料增补)
用图片进行AI训练时不可能只使用固定内容的一份训练资料,
必须对其进行小幅随机变化,使AI能看到较有多样性的内容。
最简单的做法就是图片的缩放与旋转,很遗憾地,这非常不适用于本主题。
一张256x256彩色图片的对应输入资料为64x64黑白草稿图。
每一个草稿的黑色像素都对应到图片中4x4的区域。
如果将图片进行例如1.10倍的放大,或5度的旋转,
则草稿也要作相同的转换,使得绝大部分的像素移动到非整数座标的位置上。
这时候有两种策略:
(1) 用Bilinear Interpolation让草稿变成有灰阶渐层的内容
由于本应用希望输入的是非黑即白的草稿(如范例影片),这样作并不适合。
(2) 用Nearest Neighbor Interpolation让草稿保持非黑即白状态
可想而知草稿会变得破破烂烂,结果应该很不堪用
不过从后面提到的其他资料增补方法看来,或许可以考虑这样做。
总之,目前的资料增补方式排除了图片的缩放与旋转。
当然也不能就这样什么都不做,至少平移还是可以做的。
草稿图每移动一像素,原始图片就要移动四个像素,否则会有同样的问题。
因此我在裁剪脸部图片时,将256x256的范围往上下左右各放大八格。
所产生的272x272图片就可以供草稿图片上下左右随机平移最多两格。
下图为一范例,上半部是原本位置,下半部随机平移:
https://i.imgur.com/nO2x2iR.png
草稿图片平移产生的空隙目前就先留白,但其实有另一种更好的处理方法。
如果在标示图片时,就已经根据272x272的范围标好68x68的草稿,
那么只要是在限定的范围内随机平移,都可以得到完整的64x64草稿。
不过我在做到一半时才想到这点,所以目前只有用留白的简单方法。
另外,对于草稿本身也需要做一点随机变化。
当你使用一只鼠标当画笔,假装这种东西叫做绘图板时,
画出的线段一定会破破烂烂,或是在曲线上有不自然的转折。
收集资料时产生的草稿图片都经过仔细修补,实际上不可能一口气画成。
所以在训练时,必须在草稿图片上随机增加像素或移除像素。
以模拟实际画草稿时断断续续的结果,或是曲线上如同阶梯一般不自然的连接。
同时还加上另一种更激进的做法,擦除草稿内随机数量与位置的小块区域。
下图为一范例,上半部是原本的完整草稿,下半部是扰动后的结果:
https://i.imgur.com/YJk0SNb.png
扰动后的残破草稿,在训练时仍然对应到内容完整的彩色图片。
这当然是期望AI能在输入尚未完成时,就产生接近完整的结果。
实际看到的结果当然没有这么理想,但也有大致的趋势。
例如眼睛的草稿还没有画完时,会出现一团颜色偏黑带红(瞳色)的物体。
一般来说,对于输出图片的内容也需要进行位置以外的随机调整。
常见作法有亮度(整体或三色频道分开)随机变化,或将整张图片模糊/清晰化。
在本应用中,这个做法并不太合理,它会使同一张草稿对应到不同的输出图片。
这在训练上除了使AI混乱外没有好处,因此我没有采用这种做法。
最后,最简单也不用担心技术上问题的做法,是随机将图片左右翻转。
只要将草稿图片也跟着左右翻转,就能轻松满足对应关系。
然而这其实有与研究“主题”高度相关的限制:
以这个角色来说,没有任何因素会阻碍左右翻转的策略。
但如果是像凯留这种挑染固定挑在左边的角色,翻转后就会发生问题:
https://i.imgur.com/AFgxajC.png
要让AI同时学会“只有一条挑染,但可能出现在左边或右边”其实并非难事。
但一个挑染在相反方向的角色还有灵魂吗?这种哲学问题就会产生许多争议了。
模型架构
输入一张图片,输出一张图片,这怎么看都是U-net。
所以我使用的模型也跟教科书上随处可见的U-net完全一样,没什么新奇的。
唯一的小变化是原本Concatenate的地方,我用1x1 Convolution+Add取代。
因为实际测起来没什么差别,我就选比较省计算量的版本了。
(Concatenate下一次的Convolution复杂度会变大,比替代的做法还耗时)
至于什么Resnet block, Bottleneck的小变化也都试过,
但是并没有在训练/测试速度都已经变得更慢的情况下得到更好的结果。
前面提供的范例图片中,输入的草稿图片都是白底黑线。
但在图片资料处理中,黑色代表的数字是0.0,白色则是1.0。
白底黑线的图片中绝大多数都是非零的值,有笔画的地方才是0。
黑白颠倒后的黑底白线图片则绝大多数都是0,有笔画的地方才有非零的值。
后者观感上明显比较合理(数学上我不敢肯定),
所以草稿图片会进行黑白颠倒,以黑底白线的内容做为模型的输入。
令我比较好奇的是,一般即使是输入单频道图片,也会有不同的灰阶值。
而这个应用的输入格式比较特殊,只有0.0和1.0两种数值。
比起一般U-net接上的3x3 Convolution,是否需要一些特殊的前端Layer,
才能让模型更有效率地从这个内容相对比较单调的输入抽取资讯。
不过这边能搞怪的地方我也稍微玩过,目前还没发现什么值得一提的做法。
作者: dces6107 (爻文˙疯癫˙卫生股长)   2022-10-03 13:11:00
推永仪勇仪
作者: pairslipper (博乐居士。)   2022-10-05 22:08:00
推凯留 (?)_
作者: dces6107 (爻文˙疯癫˙卫生股长)   2022-10-03 21:11:00
推永仪勇仪
作者: pairslipper (博乐居士。)   2022-10-06 06:08:00
推凯留 (?)_
作者: wayneshih (漂流虚海的雁太保)   2022-10-10 17:37:00
时代演进
作者: Phantasnix (凰响)   2022-10-12 06:37:00
推勇仪魂~
作者: wayneshih (漂流虚海的雁太保)   2022-10-10 09:37:00
时代演进
作者: Phantasnix (凰响)   2022-10-11 22:37:00
推勇仪魂~

Links booklink

Contact Us: admin [ a t ] ucptt.com