前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >神经图

神经图

作者头像
QiqiHe
发布2018-02-05 16:07:54
1.2K0
发布2018-02-05 16:07:54
  “散步鱼” (walking fish)
“散步鱼” (walking fish)

我们可以通过在Javascript中逐步形成神经网络来发展抽象艺术。见这里的画廊(gallery)。点这里尝试Web应用程序,并从头开始不断发展自己的艺术作品!

我将带有一些变化的 CPPN-NEAT(Stanley,GPEM-07)算法的实现了,借助了karpathy 杰出的recurrent.js 表达图库和cola.js来进行神经网络的交互式可视化。

我最近对使用神经网络的图像生成感兴趣,并试图通过在前一篇文章中随机化多层前馈网络的初始权重来产生艺术作品。为了扩大这项工作,我也尝试使用生成对抗网络并试图用反向传播来微调生成网络的权重,以在现实主义中得到的高分来欺骗经过训练的歧视性网络,从而达到从虚假网络中识别真实世界图像的目的。这种方法效果并不好,因为歧视性的网络会有一个优先的任务(借助一些丢失了信号的隐形层),并且需要花费很长时间才能生成可以达到中等分数和并不出众的图像的网络。这让我很困扰,所以我扩展了关于这方面的阅读......

CPPN—NEAT

我一直对斯坦利的NEAT算法着迷。NEAT是从简单的单层网络逐步演化成复杂的神经网络拓扑结构的一种方法。使用NEAT作为 组合模式生成网络所做的工作给了我一个借口,即使用Javascript中的NEAT算法实现,并在上述失败的实验中重用我的CPPN代码来生成图像。斯坦利已经制作了一个称为picbreeder的CPPN-NEAT版本,该版本 允许用户使用这种技术来演示图像,但是它是在Java的鼎盛时期编写的现代网络技术流行之前的小程序。我真的不想在我的电脑上安装一个Java SVM,我认为在一个现代的Web应用程序中使用Javascript实现CPPN-NEAT可能是一个有趣的教育练习。到目前为止我还没有真正使用过picbreeder,所以我的大部分工作都是通过阅读CPPN-NEAT原文。

通过将输入坐标信息馈送到一个黑盒子函数(branched out)中,CPPN被用于生成图案或者在这种情况下的图像,该黑盒子函数将计算表示输入坐标处的像素的强度(即,灰度值)的实数输出。在我们的例子中,黑箱功能是一个神经网络。下面是这个过程如何工作的流程图:

     CPPN流程图(来源:斯坦利GPEM07)
CPPN流程图(来源:斯坦利GPEM07)

在每个像素处,我们向CPPN馈送该像素的(x,y)坐标。为了使得事情更有趣,我馈送从原点到(x,y)的距离,这也是一种是典型的神经网络的偏差输入。“馈送距离”的效果在这篇CPPN-NEAT的论文中是一个辉煌的发现。我不确定他们是否发现了它,或者原始的遗传艺术软件设计师是否发现了它,但是我也认为它是一种聪明的作弊方式,因为它可以让网络轻松地产生循环的形状,使图像看起来自然更有意思。CPPN可以是一个非常普遍的神经网络,并且通过某些操作将网络的输出设置为[0,1]之间,以表示(x,y)处的像素值。在斯坦利的论文中,他在最终输出中使用了双曲正切函数,并将绝对值应用于tanh()输出来实现此目的。我将在后面的帖子中讨论替代方案。

     在(Stanley,GPEM07)论文中生成的示例图像
在(Stanley,GPEM07)论文中生成的示例图像

在Stanley的CPPN-NEAT论文中,我们看到这个带有3个隐藏节点的简单网络的例子,这个网络最终产生了这种具有某种不完美几何图形的眼镜外形。网络的输出是从[0,1]的实际值,其将确定每个像素的强度以构建灰度图像。之后,通过使输出成为3色通道的矢量来产生彩色图像。在我的实现中,我还要求网络输出每个像素的3个值来表示红色,绿色和蓝色通道,以生成全彩色图片。在下一节中,我将介绍Web应用程序Neurogram和实现细节。

Neurogram:在Javascript Webapp中实现CPPN-NEAT

用户通过点击“mutate”按钮来选择最多4个图像。

在这个过程的开始,一批简单的拓扑结构的随机网络被用来产生一串随机的图像,用户可以选择保留一小部分的图像,通过基因算法(NEAT)来产生新一系列的图像。上面的屏幕是Neurogram的初始屏幕,通过简单的网络生成相当基本的图像。在用户选择1到4个图像并改变它们之后,随着更多的神经元和连接被添加,下一组网络将逐渐比先前的组更复杂。这个过程一直持续到用户最终真的喜欢某个图像并双击该图像来保存或发布它,如下面的两个图像:

这里有一些奇怪的外星生物进化而来了!用户可以输入最终图像的描述,并将基因组发布到我的服务器,并将图像保存为.png

(x,y,d,bias)和(out)标签手动添加,仅在上图中说明网络代表什么以及如何使用。如果鼠标悬停在神经元上,会弹出一个标签来描述它是哪种类型的神经元(S形,正弦,余弦,高斯等)。具有大重量级的连接将具有比光连接更暗且更厚的颜色。

Neurogram允许用户看到更大版本的图像,并可视化生成图像的实际网络。

为了构造更有趣的特征,除了S形,CPPN-NEAT论文主要使用高斯函数作为每个神经元的激活函数,偶尔使用正弦函数和余弦函数对输入进行预处理,以允许产生更多视觉吸引力。我所做的是扩展recurrent.js库,以包括正弦,余弦,高斯函数,并允许NEAT随机选择这些函数,除了sigmoid函数,tanh,relu,square,multiplication,abs函数都被用来来生成一个丰富的CPPN网络,希望能够产生很酷的抽象艺术作品。下面的图像是NEAT随机使用正弦函数以及网络中其他函数的一个例子。

另外,如前所述,通过在CPPN(“cheat”:-)的输入中构建距离参数,像这些蝙蝙蝠侠logo的圆形图像可以容易地被偶然地生成:

技巧,挑战和实施问题

虽然CPPN-NEAT的基本思想很简单,但实际上还有大量的参数和选择。许多不同的参数设置是可用的。在我看来,如果选择得当,算法就可以产生各种有趣的、类似抽象艺术的艺术图像。我花了一些时间来试验和尝试各种各样的设置,比如从像素空间到实际坐标空间的比例,突变率,突变大小,冲击的大小以及什么类型的神经元实际上是重要的。这个算法最终的实现是为了适应一种能够产生符合我想要的“涂鸦”风格,这种风格与picbreeder上生成的图像有点不同。

生成连贯的彩色图像

出现的问题之一是如何增加生成合理的彩色图像的可能性。如果网络最初是从输入到输出(即12个初始连接,由于包括偏置和3个输出的4个输入)完全连接,或者如果最初没有连接,并且连接必须发展自己,我们最终可能生成3个灰度图像,在红色,绿色和蓝色的平面上重叠在一起。使用另一套基础,如HSV或HSL模式可能会改善情况,但结果仍然不令人满意。我最终做的是用一个单线性加隐藏神经元(不是sigmoid)来初始化网络,并且把所有的输入连接到这个初始神经元,并且把这个初始神经元连接到所有三个输出通道,所有这三个输出通道都具有随机的初始权值。使用这种方法,未​​来增加的神经元和连接将更有可能保持更连贯的图像,因为三个颜色通道可能更加相互联系。下面是我的意思的一个例子,如一个非常简单的网络,画一个类似钢琴键盘的东西。

黄色的正弦神经元已被随机添加在与最初的加性神经元分离的后一代中,以产生重复的关键模式。

网络建设和传播

我还决定限制隐藏的神经元的类型,并且启动乘法神经元(在想要具有记忆状态的网络中使用,例如LSTM),因为发生的事情是,当我们将正弦波相乘时,我们只是结束了另一个具有更高频率的正弦曲线,并且随着我们演进更多的步骤而趋于导致大多数低频图像消失。因为我们已经有了relu's,所以我也去掉了绝对运算符。

在CPPN-NEAT论文中,笔者认为作者可能限制了新的连接,使得最终的网络不会经常允许直接的输入 - 输出传播。对于我的网络,我实际上允许所有隐藏的神经元自由地与网络中的另一个非输入神经元连接,所以实际上我们很可能最终得到循环网络。感谢recurrent.js中的Graph对象,这不是很难做到。诀窍在于选择如何转发网络,因为我们可以通过多种方式来实现,并且仍然可以获得一组输出值。我写了另一篇文章关于这个话题,当我想到如何遍历网络,却没有任何正确的答案时。我决定在我的文章中选择(3),因为它很容易实现,并产生良好的结果。有趣的是,在这个框架中,我还可以在NEAT演变的网络中使用高效的反向传播!在(近)未来可能会导致一些非常有趣的工作。

我们还需要确保网络的最终输出在每个颜色通道的[0,1]之间。正如我刚才提到的那样,CPPN-NEAT文件先通过tanh()函数,然后是另一个abs()函数,因此输出层中接近零的值将对应于黑暗区域,而值都是正面的,负面的会对应一个浅色或白色的区域。这使得图像在进化的早期阶段变得更加有趣和复杂,甚至2-3步,正如文章中提到的那样,我也能看到这种效果。

然而,我注意到输出的sigmoid()滤波器,而不是论文中的方法,生成的图像往往具有更自然的颜色,但有趣的图像出现了几代的进化。另外,即使在输出中使用gaussian()滤镜,也会产生看起来很酷的黑色图像,形成霓虹般的图像。我很难确定哪个滤镜是最好的,因为所有这三个滤镜都产生了自己独特的艺术风格,所以我最终允许使用所有三个滤镜,并且为每个图像随机选择它们,而对于S形滤镜则有更高的概率。

Web应用程序实现问题

我决定使用bootstrap和jQuery开发Web应用程序的接口,因为这是相当小的一步。如果情况复杂得多,那么我可能会使用一些框架(但是我并不是那些真正感兴趣的人)。由于没有太多的交互需要,这不是一个游戏或物理模拟,我没有像在其他项目中使用p5.js,只是使用普通的旧画布,因为它很快。而且在没有浏览器的情况下我也可以因为node.js使用画布。整个响应式Web应用程序开发的挑战是,虽然它可能适用于自动调整大小的图像,但画布卡住了相同的大小,所以有很多黑客需要我选择一组不同的图像大小取决于是使用移动设备还是使用桌面。我也利用了画布。scale()功能在移动设备上创建速度太慢的更大图像。另外对于这个练习,我觉得我真的了解了Image对象在Web浏览器中的工作方式,并且知道如何有效地存储和操作像素数据。

当我们的网络太大时,也有内存问题。我所做的并不是将个体(x,y,d,bias)作为单个值一次性生成一个像素,而是创建包含整个图像的所有输入的整体向量——X,Y,D,Bias ,并将它们送入recurrent.js图形机,用以在一个转发通道中获得整个输出图像。这通常要高效得多,因为我们不需要为每个像素执行图形对象创建步骤,对于320x320x3图像,可能会有相当多的像素。对于每个神经元,它会创建一个320x320x3的权重和权重导数值,因此对于大型网络来说,这将损毁计算机的内存。在不久的将来,我可以通过分割每一行图像的传播来修复它,所以现在如果我们在iPhone上使用这个Web应用程序,或者在没有很多RAM的机器上使用它,那么在经过20-30代的演变之后,它可能会遇到麻烦。所以希望你能够谨慎对待并且不要说你没有收到此警告。

[08/03更新:内存问题已解决。]

未来的工作

  1. NEAT的Backpropable版本可能非常有趣,因为现在我有一个演进随机网络的框架,而机器使用recurrent.js来执行反向传播,以便有效地调整权重以在本地优化。
  2. 可以探索使用对抗生成型框架的新颖艺术创作。我之前仅使用前馈网络的实验并不能与那些训练有素的能识别自然现实图像与伪造图像的强大的“bouncer”的歧视性网络相比,但这种做法是可能做到的!此外,我可以每次重新训练歧视性网络,以便在CPPN-NEAT每次迭代时,都必须生成异于过去生成的图像,从而导致的新颖的自动艺术发现。我的目标实际上不是使用这种方法来生成逼真的图像,但我想看看在这种受限制的网络中可以产生哪些图像,以获得艺术价值。
  3. 结合前两种方法可能会导致更有效的新颖艺术作品的生成。我们也许能够测试拉马克与达尔文的艺术进化!
  4. 从长远来看,不断发展壮大的小型“核心”复发网络层,在大型深度网络中反复重复,这是完全可以区分的。换句话说,应用NEAT来发现能够在backprop环境中工作的子网络以用于其他机器学习任务。看看我们是否能通过进化发现下一个LSTM,并拥有所有这些额外可区分的门类型!
评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云开发 CloudBase
云开发(Tencent CloudBase,TCB)是腾讯云提供的云原生一体化开发环境和工具平台,为200万+企业和开发者提供高可用、自动弹性扩缩的后端云服务,可用于云端一体化开发多种端应用(小程序、公众号、Web 应用等),避免了应用开发过程中繁琐的服务器搭建及运维,开发者可以专注于业务逻辑的实现,开发门槛更低,效率更高。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档