网站首页 > 投资时机> 文章内容

Neurogram:浏览器中的神经网络演化出抽象艺术

※发布时间:2017-12-4 14:24:42   ※发布作者:habao   ※出自何处: 
【编者按】机器学习开发者hardmu基于CPPN-NEAT算法,使用javascript开发了使用神经网络演化抽象艺术的web应用。打开浏览器,点按几下鼠标,就可以让神经网络自行演化出各种抽象艺术风格的图像。一起来看看这个应用是怎么实现的吧。

Walking Fish

最近,我对使用神经网络生成图像很感兴趣,并尝试通过随机化多层前馈网络的初始权重来生成艺术作品。 为了扩展这件工作,我也试过使用生成对抗网络,并使用反向传播来微调生成网络的权重,以得到更逼真的效果来欺骗判别网络(判别网络通过训练来区分真实世界的图像和虚假的生成图像)。这种方法的效果并不好,因为判别网络手头的工作更容易(借助一些带有丢弃机制的卷积层),而生成网络最终花费很长时间才能达到平平无奇的分数和平平无奇的照片,所以我卡住了,我转而去阅读更多相关内容。

CPPN-NEAT

Stanley的NEAT算法一直让我很着迷。NEAT是从简单原始的单层网络逐步演化成复杂神经网络拓扑结构的一种方法。基于CPPN(compositional pattern-producing network,组合模式生产网络)运用NEAT方法的工作给了我一个借口,让我使用javascript来实现NEAT,并重用我在上述失败的试验中使用的CPPN代码来生成图像。Stanley创造了一个称为picbreeder的CPPN-NEAT版本,这是一个网站,允许用户运用CPPN-NEAT技术来演化图像。不过,这个网站是在现代web技术流行之前,Java applets的全盛期编写的。我真的不想在我的电脑上安装一个Java SVM,我觉得在一个现代风格的web应用中使用javascript来实现CPPN-NEAT是一个有趣而又有教益的练习。到今天为止我还没有真正使用过picbreeder,所以我的大部分工作都直接参考CPPN-NEAT原论文。

CPPN用于生成模式,也就是我们的例子中的图像。CNN将输入系数传给一个黑盒函数,这个黑盒函数将计算出一个实数输出,实数输出表示对应输入系数的像素的亮度(灰度值)。在我们的例子中,黑盒函数是一个神经网络。下面是这个过程如何运作的示意图:

cppn-diagram

Stanley GPEM07
对每个像素而言,我们向CPPN传入该像素的(x, y)坐标,到坐标系原点的距离,以及神经网络偏置输入的典型值1.0。传入距离的效果是CPPN-NEAT论文中的一个绝妙的发现。我不太确定是他们发现了这一点,还是原本的基因艺术软件设计者发现了这一点,但我也认为它是一种聪明的作弊方式,因为它可以让网络轻松地产生循环的形状,使图像看起来更自然、更有趣。CPPN可以是一个非常通用的神经网络,通过某些操作,网络的输出值可以被限制在[0, 1]这一区间,以表示位于(x, y)的像素的值。Stanley的论文在最终输出上使用了双曲正切函数,并对tanh()的输出取绝对值。我将在本文后面的部分讨论一个替代方案。

GPEM07-image-samples

Stanley GPEM07论文中的样例图片
在Stanley的CPPN-NEAT论文中,有一个带有3个隐藏节点的简单网络的例子,这个网络最终生成了上图几何上不完美的类似眼镜的形状。该网络的输出是[0, 1]区间之内的实数值,它将确定每个像素的亮度以构建灰度图像。之后,通过将输出转化为3个颜色通道的向量来生成彩色图像。在我的实现中,我还要求网络为每个像素输出3个值来表示红色、绿色和蓝色通道,以生成全彩图片。在下一节中,我将介绍这一web应用的实现细节。

Neurogram

Neurogram:在javascript web应用中实现CPPN-NEAT
刚开始,使用一组简单拓扑结构的随机网络来生成一组随机的图像,用户可以选择保留一小部分的图像(最多4张),以此为基础通过NEAT算法来生成一组新的图像(点击mutate按钮)。上图是Neurogram(印迹)的初始屏幕,通过简单的网络生成相当基本的图像。用户选择1到4个图像并点击mutate按钮后,随着更多神经元和连接的增加,下一组网络将逐渐比先前的网络更复杂。这个过程将一直持续下去,直到用户最后非常喜欢某张图像为止。这时用户可以双击该图像来保存或发布它,如下图所示:

martian

吼吼,好像演化出了奇怪的外星生物!用户可以输入图像的描述,并将遗传物质发布到我的服务器上,同时可以保存图像为PNG格式。

上图中的(x, y, d, bias)和(out)标签是手动加上去的(web应用界面没有这些标签),用来说明网络代表什么以及它是如何被使用的。在web应用界面上,如果鼠标悬停在神经元上,会弹出一个标签来描述它是哪种类型的神经元(sigmoid、sine、cosine、高斯,等等)。权重较大、强度较高的连接,相比强度较低的连接,颜色更厚重。

miss fish

双击图片可以查看图像的大图,同时可视化生成图片的实际网络
为了构造更有趣的特征,除了sigmoid函数之外,CPPN-NEAT论文主要使用高斯函数作为每个神经元的激活函数,偶尔使用sine函数和cosine函数来预处理输入,从而让生成结果在视觉上更具吸引力。我扩展了一下recurrent.js库,增加了sine、cosine和高斯函数,并允许NEAT随机选择激活函数,以生成一个丰富多彩的CPPN网络。随机选择的激活函数,除了新增的sine、cosine和高斯函数外,还包括recurrent.js原有的sigmoid、tanh、relu、square、multiplication和abs函数。我希望这样能使这个网络生成很酷的抽象艺术作品。下面的图像是NEAT随机使用正弦函数(以此为主)以及网络中的其他函数生成的一个例子。

queue-up

此外,如前所述,通过在CPPN中创建输入的距离参数(“作弊”:-)可以轻易地凭运气生成蝙蝠侠标志之类的圆形图像:

batman-logo

窍门和挑战

尽管基本的CPPN-NEAT是一个简单的概念,实际上还是有不少参数和选择需要考虑的。有很多不同的参数设定组合,如果选择得当,算法能够生成范围很广的有趣图像,在我看来,这些艺术风格的图像和抽象艺术很接近。我花了不少时间,通过试错法尝试了很多配置,例如如何将像素空间拉伸至现实的坐标空间,修改的频率,修改的尺寸,哪种神经元实际上有效。我最后选择的实现,匹配了我想要的“涂鸦”风格,和picbreeder生成的图像的风格有一点不同。

生成一致的彩色图像

面临的问题之一是如何增大生成貌似合理的彩色图像的概率。如果网络最初是从输入到输出完全连接的(即12个初始连接,因为4个输入包括偏置和3个输出),或者最初不存在连接,连接必须自行发展,我们最终大概会生成3个灰度图像,并在红色、绿色和蓝色平面将它们重叠在一起。使用基于HSV或HSL的方案可能有所改善,但结果仍然不令我满意。我最终选择的是使用一个线性相加隐藏神经元(非sigmoid)来初始化网络,并让所有的输入连接到这个初始神经元上,同时将这个初始神经元连接到所有3个输出通道,这3个输出通道都具有随机的初始权重。使用这种方法,未??来增加的神经元和连接将更有可能保持更一致的图像,因为3个颜色通道更可能相互联系。下面的一个例子演示了我的想法,这是一个非常简单的网络,绘制一个类似钢琴键盘的东西。

piano keys

黄色的sine神经元被随机地加入与最初的相加神经元分离的后一代中,以产生重复的关键模式。

本文来自智能机器人网,如若转载,请注明出处:https://www.jqr.com/news/008965 
相关阅读
  • 没有资料