关于深度学习中的一则换算问题。(1-w*z^(-1))^-1的二项式展开用Σ表示是多少?

&p&我最近换工作,基本上轮了一圈大的互联网公司,下面是我的面经,希望对nlp或者机器学习深度学习感兴趣的朋友准备面试有点帮助,有些问题我答得不准希望不吝赐教;&/p&&p&&br&&/p&&p&--- 某新闻app ---&/p&&p&round1:&/p&&p&1:cnn做卷积的运算时间复杂度;&/p&&p&2;Random forest和GBT描述;&/p&&p&3:(看到kaggle项目经历)为什么xgboost效果好?&/p&&p&4:leetcode;&/p&&p&&br&&/p&&p&round2:&/p&&p&1:工程背景;&/p&&p&2: python熟悉程度;&/p&&p&3:leetcode;&/p&&p&&br&&/p&&p&round3:&/p&&p&1:项目介绍&/p&&p&2:项目最难的是什么&/p&&p&3:项目做的最有成就感的是什么&/p&&p&4:生活做的最有成就感的是什么&/p&&p&5:一天刷多少次我们的app&/p&&p&&br&&/p&&p&此公司真的真的是叼,第一轮和第二轮之间让我等了一个小时,第二次去又让我等了四十分钟;后面说我们部门不合适你,把你推给核心部门,请你再来面试两轮,我说我拿了几大offer了就不去了,贵司太叼我不想再等一两个小时了;&/p&&p&&br&&/p&&p&&br&&/p&&p&--- 打车公司 ---&/p&&p&1: LSTM结构推导,为什么比RNN好?&/p&&p&需要说明一下LSTM的结构,input forget gate, cell information hidden information这些,之前我答的是防止梯度消失爆炸,知友指正,不能防止爆炸,很有道理,感谢;&/p&&p&&br&&/p&&p&2:梯度消失爆炸为什么?&/p&&p& 答案:略&/p&&p&&br&&/p&&p&3:为什么你用的autoencoder比LSTM好?&/p&&p& 答案:我说主要还是随机化word embedding的问题,autoencoder的句子表示方法是词袋方法,虽然丢失顺序但是保留物理意义;(?)&/p&&p&&br&&/p&&p&4: overfitting怎么解决:&/p&&p& 答案:dropout, regularization, batch normalizatin;&/p&&p&&br&&/p&&p&5:dropout为什么解决overfitting,L1和L2 regularization原理,为什么L1 regularization可以使参数优化到0, batch normalizatin为什么可以防止梯度消失爆炸;&/p&&p& 答案:略&/p&&p&6: 模型欠拟合的解决方法:&/p&&p& 答案:我就说到了curriculum learning里面的sample reweight和增加模型复杂度;还有一些特征工程;然后问了常用的特征工程的方法;&/p&&p&&br&&/p&&p&7:(简历里面写了VAE和GAN还有RL,牛逼吹大了)VAE和GAN的共同点是什么,解释一下GAN或者强化学习如何引用到你工作里面的;&/p&&p& 答案:略&/p&&p&&br&&/p&&p&传统机器学习&/p&&p&1:SVM的dual problem推导;&/p&&p&2:random forest的算法描述+bias和variance的分解公式;&/p&&p&3:HMM和CRF的本质区别;&/p&&p&4:频率学派和贝叶斯派的本质区别;&/p&&p&5:常用的优化方法;&/p&&p&6: 矩阵行列式的物理意义(行列式就是矩阵对应的线性变换对空间的拉伸程度的度量,或者说物体经过变换前后的体积比)&/p&&p&7: 动态预测每个区域的用车需求量;&/p&&p&&br&&/p&&p&对于打车公司,我的感觉很好,hr态度和面试官态度都很好,包括最后跟老大打完电话约去公司聊一下确定一下;全程hr都是有问必答;&/p&&p&有一次为了去前面那个新闻app,而改了打车公司面试时间,hr态度都很好;&/p&&p&最后我已经决定了去深圳,不能去打车公司也有点遗憾了;&/p&&p&而且打车公司问的问题很专业,全程下来都是ML算法,不考脑残的leetcode;我根本没时间也不想再去刷leetcode就为了个面试;&/p&&p&&br&&/p&&p&--- 手机公司 ---&/p&&p&round1:&/p&&p&1:LSTM相关的问题;&/p&&p&2:python写k-means;&/p&&p&3:想不起来了&/p&&p&&br&&/p&&p&round2:&/p&&p&1:业务相关的问题&/p&&p&2:记不起来了&/p&&p&&br&&/p&&p&round3:&/p&&p&1:记不起来了&/p&&p&&br&&/p&&p&手机公司最近在搞发布会,面试过了一个星期再通知我去复面,我果断拒绝;&/p&&p&全程深度学习的东西基本上不问,问了一两个看来他们基本不用,然后就是leetcode;&/p&&p&手机公司做智能家居蛮有前途的;面试官态度很好;&/p&&p&&br&&/p&&p&&br&&/p&&p&--- 搜索公司 ---&/p&&p&三轮&/p&&p&1:怎么样识别文本垃圾信息;&/p&&p&2:(数据结构)树合并;&/p&&p&3:工作涉及到的业务知识;&/p&&p&4: python如何把16位进制的数转换成2进制的数;&/p&&p&5:MySQL的键的一个问题;&/p&&p&6: linux下如何把两个文件按照列合并&/p&&p&7:map-reduce的原理(问的基础,因为我简历没有mapreduce);&/p&&p&8:NLP方面的想法;&/p&&p&9:职业规划,专家型还是领导型;&/p&&p&10:如果给offer是不是直接来此公司;&/p&&p&&br&&/p&&p&说实话,搜索公司最耿直,一下午面玩完全没有任何磨磨唧唧就给了口头offer;&/p&&p&如果留在北京,首选肯定是它了;&/p&&p&后面问我在面其他哪些公司,如果给了offer去哪家,我说就这家,那时候也没想到后面的两家深圳公司也过了,感觉蛮愧疚的,就冲这个态度也应该去此公司的;&/p&&p&真的不像网上流传的那些;而且此公司最后面的manager是我见过态度很好而且感觉可以依靠人;&/p&&p&&br&&/p&&p&&br&&/p&&p&&br&&/p&&p&-- 大厂 ---&/p&&p&1: 链表逆转&/p&&p&2:1亿的文本如何放在100台机器上两两做相似度计算&/p&&p&3:40亿数据如何用2G内存排序&/p&&p&4;遍历树&/p&&p&5:HMM原理&/p&&p&&br&&/p&&p&大厂来面我的人级别很高,全程碾压我,最后我说话都不利索了,完全想不到会过的;&/p&&p&感觉大厂效率很高,hr也很专业;其实就面了两轮就谈薪资了;&/p&&p&&br&&/p&&p&总体来说,面试还是很顺利,基本上投的公司都给了offer;因为要去深圳,有两个很好的北京的机会不能去,真心遗憾;&/p&
我最近换工作,基本上轮了一圈大的互联网公司,下面是我的面经,希望对nlp或者机器学习深度学习感兴趣的朋友准备面试有点帮助,有些问题我答得不准希望不吝赐教; --- 某新闻app ---round1:1:cnn做卷积的运算时间复杂度;2;Random forest和GBT描述;3:…
&img src=&/v2-4bcea029de21e47d9bc25_b.png& data-rawwidth=&570& data-rawheight=&330& class=&origin_image zh-lightbox-thumb& width=&570& data-original=&/v2-4bcea029de21e47d9bc25_r.png&&&blockquote&&a class=&member_mention& href=&/people/55b24d478d333dfe9ad95& data-hash=&55b24d478d333dfe9ad95& data-hovercard=&p$b$55b24d478d333dfe9ad95&&@王小新&/a&
编译自 Medium&br&量子位 出品 | 公众号 QbitAI&/blockquote&&p&卷积神经网络作为深度学习的典型网络,在图像处理和计算机视觉等多个领域都取得了很好的效果。&/p&&p&Paul-Louis Pr?ve在Medium上通过这篇文章快速地介绍了不同类型的卷积结构(Convolution)及优势。为了简单起见,本文仅探讨二维卷积结构。&/p&&h2&卷积&/h2&&p&首先,定义下卷积层的结构参数。&/p&&img src=&/v2-774dceabe2de_b.jpg& data-rawwidth=&395& data-rawheight=&449& data-thumbnail=&/v2-774dceabe2de_b.jpg& class=&content_image& width=&395&&&p&&b&△&/b& 卷积核为3、步幅为1和带有边界扩充的二维卷积结构&/p&&p&&b&卷积核大小(Kernel Size)&/b&:定义了卷积操作的感受野。在二维卷积中,通常设置为3,即卷积核大小为3×3。&/p&&p&&b&步幅(Stride)&/b&:定义了卷积核遍历图像时的步幅大小。其默认值通常设置为1,也可将步幅设置为2后对图像进行下采样,这种方式与最大池化类似。&/p&&p&&b&边界扩充(Padding)&/b&:定义了网络层处理样本边界的方式。当卷积核大于1且不进行边界扩充,输出尺寸将相应缩小;当卷积核以标准方式进行边界扩充,则输出数据的空间尺寸将与输入相等。&/p&&p&&b&输入与输出通道(Channels)&/b&:构建卷积层时需定义输入通道I,并由此确定输出通道O。这样,可算出每个网络层的参数量为I×O×K,其中K为卷积核的参数个数。例,某个网络层有64个大小为3×3的卷积核,则对应K值为 3×3 =9。&/p&&h2&空洞卷积&/h2&&p&空洞卷积(atrous convolutions)又名扩张卷积(dilated convolutions),向卷积层引入了一个称为 “&b&扩张率(dilation rate)&/b&”的新参数,该参数定义了卷积核处理数据时各值的间距。&/p&&img src=&/v2-a1c6b327c239bb3f893793_b.jpg& data-rawwidth=&395& data-rawheight=&381& data-thumbnail=&/v2-a1c6b327c239bb3f893793_b.jpg& class=&content_image& width=&395&&&p&&b&△&/b& 卷积核为3、扩张率为2和无边界扩充的二维空洞卷积&/p&&p&一个扩张率为2的3×3卷积核,感受野与5×5的卷积核相同,而且仅需要9个参数。你可以把它想象成一个5×5的卷积核,每隔一行或一列删除一行或一列。&/p&&p&在相同的计算条件下,空洞卷积提供了更大的感受野。空洞卷积经常用在实时图像分割中。当网络层需要较大的感受野,但计算资源有限而无法提高卷积核数量或大小时,可以考虑空洞卷积。&/p&&h2&转置卷积&/h2&&p&转置卷积(transposed Convolutions)又名反卷积(deconvolution)或是分数步长卷积(fractially straced convolutions)。&/p&&p&反卷积(deconvolutions)这种叫法是不合适的,因为它不符合反卷积的概念。在深度学习中,反卷积确实存在,但是并不常用。实际上,反卷积是卷积操作的逆过程。你可以这么理解这个过程,将某个图像输入到单个卷积层,取卷积层的输出传递到一个黑盒子中,这个黑盒子输出了原始图像。那么可以说,这个黑盒子完成了一个反卷积操作,也就是卷积操作的数学逆过程。&/p&&p&转置卷积与真正的反卷积有点相似,因为两者产生了相同的空间分辨率。然而,这两种卷积对输入数据执行的实际数学运算是不同的。转置卷积层只执行了常规的卷积操作,但是恢复了其空间分辨率。&/p&&img src=&/v2-a702eafbe90f841ca7c2_b.jpg& data-rawwidth=&294& data-rawheight=&288& data-thumbnail=&/v2-a702eafbe90f841ca7c2_b.jpg& class=&content_image& width=&294&&&p&&b&△&/b& 卷积核为3、步幅为2和无边界扩充的二维卷积结构&/p&&p&举个例子,假如将一张5×5大小的图像输入到卷积层,其中步幅为2,卷积核为3×3,无边界扩充。则卷积层会输出2×2的图像。&/p&&p&若要实现其逆过程,需要相应的数学逆运算,能根据每个输入像素来生成对应的9个值。然后,将步幅设为2,遍历输出图像,这就是反卷积操作。&/p&&img src=&/v2-f0c8518784fdefeae1a11_b.jpg& data-rawwidth=&395& data-rawheight=&449& data-thumbnail=&/v2-f0c8518784fdefeae1a11_b.jpg& class=&content_image& width=&395&&&p&&b&△&/b& 卷积核为3×3、步幅为2和无边界扩充的二维转置卷积&/p&&p&转置卷积和反卷积的唯一共同点在于两者输出都为5×5大小的图像,不过转置卷积执行的仍是常规的卷积操作。为了实现扩充目的,需要对输入以某种方式进行填充。&/p&&p&你可以理解成,至少在数值方面上,转置卷积不能实现卷积操作的逆过程。&/p&&p&转置卷积只是为了重建先前的空间分辨率,执行了卷积操作。这不是卷积的数学逆过程,但是用于编码器-解码器结构中,效果仍然很好。这样,转置卷积可以同时实现图像的粗粒化和卷积操作,而不是通过两个单独过程来完成。&/p&&h2&可分离卷积&/h2&&p&在可分离卷积(separable convolution)中,可将卷积核操作拆分成多个步骤。卷积操作用y=conv(x, k)来表示,其中输出图像为y,输入图像为x,卷积核为k。接着,假设k可以由下式计算得出:k=k1.dot(k2)。这就实现了一个可分离卷积操作,因为不用k执行二维卷积操作,而是通过k1和k2分别实现两次一维卷积来取得相同效果。&/p&&img src=&/v2-c040f1e0bd860ace6e7a_b.png& data-rawwidth=&430& data-rawheight=&224& class=&origin_image zh-lightbox-thumb& width=&430& data-original=&/v2-c040f1e0bd860ace6e7a_r.png&&&p&&b&△&/b& X、Y方向上的Sobel滤波器&/p&&p&Sobel算子通常被用于图像处理中,这里以它为例。你可以分别乘以矢量[1,0,-1]和[1,2,1]的转置矢量后得到相同的滤波器。完成这个操作,只需要6个参数,而不是二维卷积中的9个参数。&/p&&p&这个例子说明了什么叫做空间可分离卷积,这种方法并不应用在深度学习中,只是用来帮你理解这种结构。&/p&&p&在神经网络中,我们通常会使用&b&深度可分离卷积结构&/b&(depthwise separable convolution)。&/p&&p&这种方法在保持通道分离的前提下,接上一个深度卷积结构,即可实现空间卷积。接下来通过一个例子让大家更好地理解。&/p&&p&假设有一个3×3大小的卷积层,其输入通道为16、输出通道为32。具体为,32个3×3大小的卷积核会遍历16个通道中的每个数据,从而产生16×32=512个特征图谱。进而通过叠加每个输入通道对应的特征图谱后融合得到1个特征图谱。最后可得到所需的32个输出通道。&/p&&p&针对这个例子应用深度可分离卷积,用1个3×3大小的卷积核遍历16通道的数据,得到了16个特征图谱。在融合操作之前,接着用32个1×1大小的卷积核遍历这16个特征图谱,进行相加融合。这个过程使用了16×3×3+16×32×1×1=656个参数,远少于上面的16×32×3×3=4608个参数。&/p&&p&这个例子就是深度可分离卷积的具体操作,其中上面的深度乘数(depth multiplier)设为1,这也是目前这类网络层的通用参数。&/p&&p&这么做是为了对空间信息和深度信息进行去耦。从Xception模型的效果可以看出,这种方法是比较有效的。由于能够有效利用参数,因此深度可分离卷积也可以用于移动设备中。&/p&&h2&相关阅读&/h2&&p&原文:&/p&&p&&a href=&/?target=https%3A///towards-data-science/types-of-convolutions-in-deep-learning-d& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&https://&/span&&span class=&visible&&/towards-data&/span&&span class=&invisible&&-science/types-of-convolutions-in-deep-learning-d&/span&&span class=&ellipsis&&&/span&&i class=&icon-external&&&/i&&/a&&/p&&p&更多卷积动画:&/p&&p&&a href=&/?target=https%3A///vdumoulin/conv_arithmetic& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&https://&/span&&span class=&visible&&/vdumoulin/co&/span&&span class=&invisible&&nv_arithmetic&/span&&span class=&ellipsis&&&/span&&i class=&icon-external&&&/i&&/a&&/p&&p&【完】&/p&&p&欢迎大家关注我们的专栏:&a href=&/qbitai& class=&internal&&量子位 - 知乎专栏&/a&&/p&
编译自 Medium 量子位 出品 | 公众号 QbitAI卷积神经网络作为深度学习的典型网络,在图像处理和计算机视觉等多个领域都取得了很好的效果。Paul-Louis Pr?ve在Medium上通过这篇文章快速地介绍了不同类型的卷积结构(Convolution)及优势。为了简…
&img src=&/v2-7ded5c2c50c6d0b2c1a4b1f96c56190e_b.png& data-rawwidth=&1920& data-rawheight=&1080& class=&origin_image zh-lightbox-thumb& width=&1920& data-original=&/v2-7ded5c2c50c6d0b2c1a4b1f96c56190e_r.png&&&blockquote&&i&近日,Slav Ivanov 在 Medium 上发表了一篇题为《37 Reasons why your Neural Network is not working》的文章,从四个方面(数据集、数据归一化/增强、实现、训练),对自己长久以来的神经网络调试经验做了 37 条总结,并穿插了不少出色的个人想法和思考,希望能帮助你跨过神经网络训练中的 37 个大坑。机器之心对该文进行了编译,原文链接请见文末。&/i&&/blockquote&&p&&br&&/p&&p&神经网络已经持续训练了 12 个小时。它看起来很好:梯度在变化,损失也在下降。但是预测结果出来了:全部都是零值,全部都是背景,什么也检测不到。我质问我的计算机:「我做错了什么?」,它却无法回答。&/p&&p&&br&&/p&&p&如果你的模型正在输出垃圾(比如预测所有输出的平均值,或者它的精确度真的很低),那么你从哪里开始检查呢?&/p&&p&&br&&/p&&p&无法训练神经网络的原因有很多,因此通过总结诸多调试,作者发现有一些检查是经常做的。这张列表汇总了作者的经验以及最好的想法,希望也对读者有所帮助。&/p&&p&&br&&/p&&p&I. 数据集问题&/p&&p&&br&&/p&&img src=&/v2-fcc4fdcd7eb844ba61924cedb11f8e92_b.png& data-rawwidth=&900& data-rawheight=&280& class=&origin_image zh-lightbox-thumb& width=&900& data-original=&/v2-fcc4fdcd7eb844ba61924cedb11f8e92_r.png&&&p&&br&&/p&&p&1. 检查你的输入数据&/p&&p&&br&&/p&&p&检查馈送到网络的输入数据是否正确。例如,我不止一次混淆了图像的宽度和高度。有时,我错误地令输入数据全部为零,或者一遍遍地使用同一批数据执行梯度下降。因此打印/显示若干批量的输入和目标输出,并确保它们正确。&/p&&p&&br&&/p&&p&2. 尝试随机输入&/p&&p&&br&&/p&&p&尝试传递随机数而不是真实数据,看看错误的产生方式是否相同。如果是,说明在某些时候你的网络把数据转化为了垃圾。试着逐层调试,并查看出错的地方。&/p&&p&&br&&/p&&p&3. 检查数据加载器&/p&&p&&br&&/p&&p&你的数据也许很好,但是读取输入数据到网络的代码可能有问题,所以我们应该在所有操作之前打印第一层的输入并进行检查。&/p&&p&&br&&/p&&p&4. 确保输入与输出相关联&/p&&p&&br&&/p&&p&检查少许输入样本是否有正确的标签,同样也确保 shuffling 输入样本同样对输出标签有效。&/p&&p&&br&&/p&&p&5. 输入与输出之间的关系是否太随机?&/p&&p&&br&&/p&&p&相较于随机的部分(可以认为股票价格也是这种情况),输入与输出之间的非随机部分也许太小,即输入与输出的关联度太低。没有一个统一的方法来检测它,因为这要看数据的性质。&/p&&p&&br&&/p&&p&6. 数据集中是否有太多的噪音?&/p&&p&&br&&/p&&p&我曾经遇到过这种情况,当我从一个食品网站抓取一个图像数据集时,错误标签太多以至于网络无法学习。手动检查一些输入样本并查看标签是否大致正确。&/p&&p&&br&&/p&&p&7. Shuffle 数据集&/p&&p&&br&&/p&&p&如果你的数据集没有被 shuffle,并且有特定的序列(按标签排序),这可能给学习带来不利影响。你可以 shuffle 数据集来避免它,并确保输入和标签都被重新排列。&/p&&p&&br&&/p&&p&8. 减少类别失衡&/p&&p&&br&&/p&&p&一张类别 B 图像和 1000 张类别 A 图像?如果是这种情况,那么你也许需要平衡你的损失函数或者尝试其他解决类别失衡的方法。&/p&&p&&br&&/p&&p&9. 你有足够的训练实例吗?&/p&&p&&br&&/p&&p&如果你在从头开始训练一个网络(即不是调试),你很可能需要大量数据。对于图像分类,每个类别你需要 1000 张图像甚至更多。&/p&&p&&br&&/p&&p&10. 确保你采用的批量数据不是单一标签&/p&&p&&br&&/p&&p&这可能发生在排序数据集中(即前 10000 个样本属于同一个分类)。可通过 shuffle 数据集轻松修复。&/p&&p&&br&&/p&&p&11. 缩减批量大小&/p&&p&&br&&/p&&p&巨大的批量大小会降低模型的泛化能力(参阅:&a href=&/?target=https%3A//arxiv.org/abs/%25EF%25BC%2589& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&https://arxiv.org/abs/)&i class=&icon-external&&&/i&&/a&&/p&&p&&br&&/p&&p&II. 数据归一化/增强&/p&&p&&br&&/p&&p&12. 归一化特征&/p&&p&&br&&/p&&p&你的输入已经归一化到零均值和单位方差了吗?&/p&&p&&br&&/p&&p&13. 你是否应用了过量的数据增强?&/p&&p&&br&&/p&&p&数据增强有正则化效果(regularizing effect)。过量的数据增强,加上其它形式的正则化(权重 L2,中途退出效应等)可能会导致网络欠拟合(underfit)。&/p&&p&&br&&/p&&p&14. 检查你的预训练模型的预处理过程&/p&&p&&br&&/p&&p&如果你正在使用一个已经预训练过的模型,确保你现在正在使用的归一化和预处理与之前训练模型时的情况相同。例如,一个图像像素应该在 [0, 1],[-1, 1] 或 [0, 255] 的范围内吗?&/p&&p&&br&&/p&&p&15. 检查训练、验证、测试集的预处理&/p&&p&&br&&/p&&p&CS231n 指出了一个常见的陷阱:「任何预处理数据(例如数据均值)必须只在训练数据上进行计算,然后再应用到验证、测试数据中。例如计算均值,然后在整个数据集的每个图像中都减去它,再把数据分发进训练、验证、测试集中,这是一个典型的错误。」此外,要在每一个样本或批量(batch)中检查不同的预处理。&/p&&p&&br&&/p&&p&III. 实现的问题&/p&&p&&br&&/p&&p&16. 试着解决某一问题的更简易的版本。&/p&&p&&br&&/p&&p&这将会有助于找到问题的根源究竟在哪里。例如,如果目标输出是一个物体类别和坐标,那就试着把预测结果仅限制在物体类别当中(尝试去掉坐标)。&/p&&p&&br&&/p&&p&17.「碰巧」寻找正确的损失&/p&&p&&br&&/p&&p&还是来源于 CS231n 的技巧:用小参数进行初始化,不使用正则化。例如,如果我们有 10 个类别,「碰巧」就意味着我们将会在 10% 的时间里得到正确类别,Softmax 损失是正确类别的负 log 概率: -ln(0.1) = 2.302。然后,试着增加正则化的强度,这样应该会增加损失。&/p&&p&&br&&/p&&p&18. 检查你的损失函数&/p&&p&&br&&/p&&p&如果你执行的是你自己的损失函数,那么就要检查错误,并且添加单元测试。通常情况下,损失可能会有些不正确,并且损害网络的性能表现。&/p&&p&&br&&/p&&p&19. 核实损失输入&/p&&p&&br&&/p&&p&如果你正在使用的是框架提供的损失函数,那么要确保你传递给它的东西是它所期望的。例如,在 PyTorch 中,我会混淆 NLLLoss 和 CrossEntropyLoss,因为一个需要 softmax 输入,而另一个不需要。&/p&&p&&br&&/p&&p&20. 调整损失权重&/p&&p&&br&&/p&&p&如果你的损失由几个更小的损失函数组成,那么确保它们每一个的相应幅值都是正确的。这可能会涉及到测试损失权重的不同组合。&/p&&p&&br&&/p&&p&21. 监控其它指标&/p&&p&&br&&/p&&p&有时损失并不是衡量你的网络是否被正确训练的最佳预测器。如果可以的话,使用其它指标来帮助你,比如精度。&/p&&p&&br&&/p&&p&22. 测试任意的自定义层&/p&&p&&br&&/p&&p&你自己在网络中实现过任意层吗?检查并且复核以确保它们的运行符合预期。&/p&&p&&br&&/p&&p&23. 检查「冷冻」层或变量&/p&&p&&br&&/p&&p&检查你是否无意中阻止了一些层或变量的梯度更新,这些层或变量本来应该是可学的。&/p&&p&&br&&/p&&p&24. 扩大网络规模&/p&&p&&br&&/p&&p&可能你的网络的表现力不足以采集目标函数。试着加入更多的层,或在全连层中增加更多的隐藏单元。&/p&&p&&br&&/p&&p&25. 检查隐维度误差&/p&&p&&br&&/p&&p&如果你的输入看上去像(k,H,W)= (64, 64, 64),那么很容易错过与错误维度相关的误差。给输入维度使用一些「奇怪」的数值(例如,每一个维度使用不同的质数),并且检查它们是如何通过网络传播的。&/p&&p&&br&&/p&&p&26. 探索梯度检查(Gradient checking)&/p&&p&&br&&/p&&p&如果你手动实现梯度下降,梯度检查会确保你的反向传播(backpropagation)能像预期中一样工作。&/p&&p&&br&&/p&&p&IV. 训练问题&/p&&p&&br&&/p&&img src=&/v2-1f6298603efa05daa7178_b.png& data-rawwidth=&448& data-rawheight=&299& class=&origin_image zh-lightbox-thumb& width=&448& data-original=&/v2-1f6298603efa05daa7178_r.png&&&p&&br&&/p&&p&27. 一个真正小的数据集&/p&&p&&br&&/p&&p&过拟合数据的一个小子集,并确保其工作。例如,仅使用 1 或 2 个实例训练,并查看你的网络是否学习了区分它们。然后再训练每个分类的更多实例。&/p&&p&&br&&/p&&p&28. 检查权重初始化&/p&&p&&br&&/p&&p&如果不确定,请使用 Xavier 或 He 初始化。同样,初始化也许会给你带来坏的局部最小值,因此尝试不同的初始化,看看是否有效。&/p&&p&&br&&/p&&p&29. 改变你的超参数&/p&&p&&br&&/p&&p&或许你正在使用一个很糟糕的超参数集。如果可行,尝试一下网格搜索。&/p&&p&&br&&/p&&p&30. 减少正则化&/p&&p&&br&&/p&&p&太多的正则化可致使网络严重地欠拟合。减少正则化,比如 dropout、批规范、权重/偏差 L2 正则化等。在优秀课程《编程人员的深度学习实战》(&a href=&/?target=http%3A//course.fast.ai& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Practical Deep Learning For Coders-18 hours of lessons for free&i class=&icon-external&&&/i&&/a&)中,Jeremy Howard 建议首先解决欠拟合。这意味着你充分地过拟合数据,并且只有在那时处理过拟合。&/p&&p&&br&&/p&&p&31. 给它一些时间&/p&&p&&br&&/p&&p&也许你的网络需要更多的时间来训练,在它能做出有意义的预测之前。如果你的损失在稳步下降,那就再多训练一会儿。&/p&&p&&br&&/p&&p&32. 从训练模式转换为测试模式&/p&&p&&br&&/p&&p&一些框架的层很像批规范、Dropout,而其他的层在训练和测试时表现并不同。转换到适当的模式有助于网络更好地预测。&/p&&p&&br&&/p&&p&33. 可视化训练&/p&&p&&br&&/p&&p&监督每一层的激活值、权重和更新。确保它们的大小匹配。例如,参数更新的大小(权重和偏差)应该是 1-e3。&/p&&p&考虑可视化库,比如 Tensorboard 和 Crayon。紧要时你也可以打印权重/偏差/激活值。&/p&&p&寻找平均值远大于 0 的层激活。尝试批规范或者 ELUs。&/p&&p&&br&&/p&&p&Deeplearning4j 指出了权重和偏差柱状图中的期望值:对于权重,一些时间之后这些柱状图应该有一个近似高斯的(正常)分布。对于偏差,这些柱状图通常会从 0 开始,并经常以近似高斯(这种情况的一个例外是 LSTM)结束。留意那些向 +/- 无限发散的参数。留意那些变得很大的偏差。这有时可能发生在分类的输出层,如果类别的分布不均匀。&/p&&p&&br&&/p&&p&检查层更新,它们应该有一个高斯分布。&/p&&p&&br&&/p&&p&34. 尝试不同的优化器&/p&&p&&br&&/p&&p&优化器的选择不应当妨碍网络的训练,除非你选择了一个特别糟糕的参数。但是,为任务选择一个合适的优化器非常有助于在最短的时间内获得最多的训练。描述你正在使用的算法的论文应当指定优化器;如果没有,我倾向于选择 Adam 或者带有动量的朴素 SGD。&/p&&p&&br&&/p&&p&35. 梯度爆炸、梯度消失&/p&&p&&br&&/p&&p&检查隐蔽层的最新情况,过大的值可能代表梯度爆炸。这时,梯度截断(Gradient clipping)可能会有所帮助。&/p&&p&检查隐蔽层的激活值。Deeplearning4j 中有一个很好的指导方针:「一个好的激活值标准差大约在 0.5 到 2.0 之间。明显超过这一范围可能就代表着激活值消失或爆炸。」&/p&&p&&br&&/p&&p&36. 增加、减少学习速率&/p&&p&&br&&/p&&p&低学习速率将会导致你的模型收敛很慢;&/p&&p&高学习速率将会在开始阶段减少你的损失,但是可能会导致你很难找到一个好的解决方案。&/p&&p&试着把你当前的学习速率乘以 0.1 或 10。&/p&&p&&br&&/p&&p&37. 克服 NaNs&/p&&p&&br&&/p&&p&据我所知,在训练 RNNs 时得到 NaN(Non-a-Number)是一个很大的问题。一些解决它的方法:&/p&&p&&br&&/p&&p&减小学习速率,尤其是如果你在前 100 次迭代中就得到了 NaNs。&/p&&p&NaNs 的出现可能是由于用零作了除数,或用零或负数作了自然对数。&/p&&p&Russell Stewart 对如何处理 NaNs 很有心得(&a href=&/?target=http%3A///notes/0.html%25EF%25BC%%& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&/notes/0.html)。&i class=&icon-external&&&/i&&/a&&/p&&p&尝试逐层评估你的网络,这样就会看见 NaNs 到底出现在了哪里。&/p&&p&&br&&/p&&p&资源:&/p&&p&&br&&/p&&p&&a href=&/?target=http%3A//cs231n.github.io/neural-networks-3/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&CS231n Convolutional Neural Networks for Visual Recognition&i class=&icon-external&&&/i&&/a&&/p&&p&&a href=&/?target=http%3A///notes/0.html& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&/not&/span&&span class=&invisible&&es/0.html&/span&&span class=&ellipsis&&&/span&&i class=&icon-external&&&/i&&/a&&/p&&p&&a href=&/?target=https%3A///questions//neural-network-always-predicts-the-same-class& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Neural network always predicts the same class&i class=&icon-external&&&/i&&/a&&/p&&p&&a href=&/?target=https%3A//deeplearning4j.org/visualization& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&How to Visualize, Monitor and Debug Neural Network Learning&i class=&icon-external&&&/i&&/a&&/p&&p&&a href=&/?target=https%3A///r/MachineLearning/comments/46b8dz/what_does_debugging_a_deep_net_look_like/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&What does &debugging& a deep net look like? o r/MachineLearning&i class=&icon-external&&&/i&&/a&&/p&&p&&a href=&/?target=https%3A//www.researchgate.net/post/why_the_prediction_or_the_output_of_neural_network_does_not_change_during_the_test_phase& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Why the prediction or the output of neural network does not change during the test phase?&i class=&icon-external&&&/i&&/a&&/p&&p&&a href=&/?target=http%3A//book.caltech.edu/bookforum/showthread.php%3Ft%3D4113& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Neural Network predictions converging to one value&i class=&icon-external&&&/i&&/a&&/p&&p&&a href=&/?target=https%3A//gab41.lab41.org/some-tips-for-debugging-deep-learning-3f69e56ea134& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&https://&/span&&span class=&visible&&gab41.lab41.org/some-ti&/span&&span class=&invisible&&ps-for-debugging-deep-learning-3f69e56ea134&/span&&span class=&ellipsis&&&/span&&i class=&icon-external&&&/i&&/a&&/p&&p&&a href=&/?target=https%3A///How-do-I-debug-an-artificial-neural-network-algorithm& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&How to debug an artificial neural network algorithm&i class=&icon-external&&&/i&&/a&&/p&&p&&br&&/p&&p&选自&a href=&/?target=https%3A///%40slavivanov/7& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Medium&i class=&icon-external&&&/i&&/a&
&b&机器之心编译&/b&&/p&&p&&/p&
近日,Slav Ivanov 在 Medium 上发表了一篇题为《37 Reasons why your Neural Network is not working》的文章,从四个方面(数据集、数据归一化/增强、实现、训练),对自己长久以来的神经网络调试经验做了 37 条总结,并穿插了不少出色的个人想法和思考…
&h2&背景介绍&/h2&
&p&不知道大家是否用过prisma,就算没有用过,也一定看见别人用过这个软件,下面是一张这个软件得到的一个效果图&br&&/p&&img src=&/v2-f4f01cab46b6532dbfcb3a521d16adb0_b.jpg& data-rawwidth=&1080& data-rawheight=&1080& class=&origin_image zh-lightbox-thumb& width=&1080& data-original=&/v2-f4f01cab46b6532dbfcb3a521d16adb0_r.jpg&&&br&&p&官方宣传的卖点是一秒钟让你的作品拥有名家风格,什么毕加索,梵高,都不在话下。通过这个效果再将你的照片发到朋友圈,是不是效果爆棚,简直是各种装逼界的一股清流,秒杀各种修图ps好吗。而且可以完美的掩饰掉一些瑕疵,又比ps更自然,更有逼格,是不是很棒。&/p&
&p&这个软件将使用的方法发了一篇论文,并且这个软件在发布的时候就取得了上千万的融资,是不是瞬间感觉现在学习了知识也能成为千万富豪了。如今在这个高速发展的时代,知识付费的时代确实已经到来了,所以我们现在努力学习各种知识就是在赚钱啊,有木有。这样大家的学习的时候就能够有着更大的动力了。&/p&
&p&这篇&a href=&/?target=https%3A//arxiv.org/pdf/.pdf& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&论文&i class=&icon-external&&&/i&&/a&感兴趣的同学可以去查看一下,里面主要涉及的是卷积神经网络。今天这篇文章要做的是什么呢?我们希望自己能够简单的实现这个风格迁移算法,并且用自己的算法来得到新的风格图片。一想到我们放到朋友圈的照片是自己写的算法来实现的就感觉成就感爆棚,有没有。&/p&
&h2&环境配置&/h2&
&p&废话不多说,我们先来看看需要的基本配置。首先需要python环境,建议使用anaconda;然后我们使用的深度学习框架是pytorch,当然你也可以用tensorflow,具体框架的介绍可以去看看之前写的文章,需要安装pytorch和torchvision,&a href=&/?target=http%3A//pytorch.org/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&这里&i class=&icon-external&&&/i&&/a&查看安装帮助;同时需要一些其他的包,如果缺什么就pip安装就好。&/p&
&p&这篇文章主要参考于pytorch的官方&a href=&/?target=http%3A//pytorch.org/tutorials/advanced/neural_style_tutorial.html%23sphx-glr-advanced-neural-style-tutorial-py& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&tutorial&i class=&icon-external&&&/i&&/a&,感兴趣的同学可以直接移步至官方教程的地方,这篇文章我会说一些自己的理解,代码部分基本都是参考这个教程,但是我会做一些说明,力求更加清楚。&/p&
&h2&原理分析&/h2&
&p&其实要实现的东西很清晰,就是需要将两张图片融合在一起,这个时候就需要定义怎么才算融合在一起。首先需要的就是内容上是相近的,然后风格上是相似的。这样来我们就知道我们需要做的事情是什么了,我们需要计算融合图片和内容图片的相似度,或者说差异性,然后尽可能降低这个差异性;同时我们也需要计算融合图片和风格图片在风格上的差异性,然后也降低这个差异性就可以了。这样我们就能够量化我们的目标了。&/p&
&p&对于内容的差异性我们该如何定义呢?其实我们能够很简答的想到就是两张图片每个像素点进行比较,也就是求一下差,因为简单的计算他们之间的差会有正负,所以我们可以加一个平方,使得差全部是正的,也可以加绝对值,但是数学上绝对值会破坏函数的可微性,所以大家都用平方,这个地方不理解也没关系,记住普遍都是使用平方就行了。&/p&
&p&对于风格的差异性我们该如何定义呢?这才是一个难点。这也是这篇文章提出的创新点,引入了Gram矩阵计算风格的差异。我尽量不使用数学的语言来解释,而使用通俗的语言。&br&首先需要的预先知识是卷积网络的知识,这里不细讲了,不了解的同学可以看之前的卷积网络的文章。我们知道一张图片通过卷积网络之后可以的到一个特征图,Gram矩阵就是在这个特征图上面定义出来的。每个特征图的大小一般是 MxNxC 或者是 CxMxN 这种大小,这里C表示的时候厚度,放在前面和后面都可以,MxN 表示的是一个矩阵的大小,其实就是有 C 个 MxN 这样的矩阵叠在一起。
&p&Gram矩阵是如何定义的呢?首先Gram矩阵的大小是有特征图的厚度决定的,等于 CxC,那么每一个Gram矩阵的元素,也就是 Gram(i, j) 等于多少呢?先把特征图中第 i 层和第 j 层取出来,这样就得到了两个 MxN的矩阵,然后将这两个矩阵对应元素相乘然后求和就得到了 Gram(i, j),同理 Gram 的所有元素都可以通过这个方式得到。这样 Gram 中每个元素都可以表示两层特征图的一种组合,就可以定义为它的风格。&/p&
&p&然后风格的差异就是两幅图的 Gram 矩阵的差异,就像内容的差异的计算方法一样,计算一下这两个矩阵的差就可以量化风格的差异。
&h2&实现&/h2&
&p&以下的内容都是用pytorch实现的,如果对pytorch不熟悉的同学可以看一下我之前的pytorch介绍文章,看看官方教程,如果不想了解pytorch的同学可以用自己熟悉的框架实现这个算法,理论部分前面已经讲完了。&/p&
&h3&内容差异的loss定义&/h3&
&div class=&highlight&&&pre&&code class=&language-python&&&span&&/span&&span class=&k&&class&/span& &span class=&nc&&Content_Loss&/span&&span class=&p&&(&/span&&span class=&n&&nn&/span&&span class=&o&&.&/span&&span class=&n&&Module&/span&&span class=&p&&):&/span&
&span class=&k&&def&/span& &span class=&nf&&__init__&/span&&span class=&p&&(&/span&&span class=&bp&&self&/span&&span class=&p&&,&/span& &span class=&n&&target&/span&&span class=&p&&,&/span& &span class=&n&&weight&/span&&span class=&p&&):&/span&
&span class=&nb&&super&/span&&span class=&p&&(&/span&&span class=&n&&Content_Loss&/span&&span class=&p&&,&/span& &span class=&bp&&self&/span&&span class=&p&&)&/span&&span class=&o&&.&/span&&span class=&n&&__init__&/span&&span class=&p&&()&/span&
&span class=&bp&&self&/span&&span class=&o&&.&/span&&span class=&n&&weight&/span& &span class=&o&&=&/span& &span class=&n&&weight&/span&
&span class=&bp&&self&/span&&span class=&o&&.&/span&&span class=&n&&target&/span& &span class=&o&&=&/span& &span class=&n&&target&/span&&span class=&o&&.&/span&&span class=&n&&detach&/span&&span class=&p&&()&/span& &span class=&o&&*&/span& &span class=&bp&&self&/span&&span class=&o&&.&/span&&span class=&n&&weight&/span&
&span class=&c1&&# 必须要用detach来分离出target,这时候target不再是一个Variable,这是为了动态计算梯度,否则forward会出错,不能向前传播&/span&
&span class=&bp&&self&/span&&span class=&o&&.&/span&&span class=&n&&criterion&/span& &span class=&o&&=&/span& &span class=&n&&nn&/span&&span class=&o&&.&/span&&span class=&n&&MSELoss&/span&&span class=&p&&()&/span&
&span class=&k&&def&/span& &span class=&nf&&forward&/span&&span class=&p&&(&/span&&span class=&bp&&self&/span&&span class=&p&&,&/span& &span class=&nb&&input&/span&&span class=&p&&):&/span&
&span class=&bp&&self&/span&&span class=&o&&.&/span&&span class=&n&&loss&/span& &span class=&o&&=&/span& &span class=&bp&&self&/span&&span class=&o&&.&/span&&span class=&n&&criterion&/span&&span class=&p&&(&/span&&span class=&nb&&input&/span& &span class=&o&&*&/span& &span class=&bp&&self&/span&&span class=&o&&.&/span&&span class=&n&&weight&/span&&span class=&p&&,&/span& &span class=&bp&&self&/span&&span class=&o&&.&/span&&span class=&n&&target&/span&&span class=&p&&)&/span&
&span class=&n&&out&/span& &span class=&o&&=&/span& &span class=&nb&&input&/span&&span class=&o&&.&/span&&span class=&n&&clone&/span&&span class=&p&&()&/span&
&span class=&k&&return&/span& &span class=&n&&out&/span&
&span class=&k&&def&/span& &span class=&nf&&backward&/span&&span class=&p&&(&/span&&span class=&bp&&self&/span&&span class=&p&&,&/span& &span class=&n&&retain_variabels&/span&&span class=&o&&=&/span&&span class=&bp&&True&/span&&span class=&p&&):&/span&
&span class=&bp&&self&/span&&span class=&o&&.&/span&&span class=&n&&loss&/span&&span class=&o&&.&/span&&span class=&n&&backward&/span&&span class=&p&&(&/span&&span class=&n&&retain_variables&/span&&span class=&o&&=&/span&&span class=&n&&retain_variabels&/span&&span class=&p&&)&/span&
&span class=&k&&return&/span& &span class=&bp&&self&/span&&span class=&o&&.&/span&&span class=&n&&loss&/span&
&/code&&/pre&&/div&&br&&p&其中有个变量weight,这个是表示权重,内容和风格你可以选择一个权重,比如你想风格上更像,内容上多一点差别没关系,那么内容的权重你可以定义小一点,风格的权重可以定义大一点;反之你可以把风格的权重定义小一点,内容的权重定义大一点。&/p&
&h3&风格差异的loss定义&/h3&
&h4&Gram 矩阵的定义&/h4&
&div class=&highlight&&&pre&&code class=&language-python&&&span&&/span&&span class=&k&&class&/span& &span class=&nc&&Gram&/span&&span class=&p&&(&/span&&span class=&n&&nn&/span&&span class=&o&&.&/span&&span class=&n&&Module&/span&&span class=&p&&):&/span&
&span class=&k&&def&/span& &span class=&nf&&__init__&/span&&span class=&p&&(&/span&&span class=&bp&&self&/span&&span class=&p&&):&/span&
&span class=&nb&&super&/span&&span class=&p&&(&/span&&span class=&n&&Gram&/span&&span class=&p&&,&/span& &span class=&bp&&self&/span&&span class=&p&&)&/span&&span class=&o&&.&/span&&span class=&n&&__init__&/span&&span class=&p&&()&/span&
&span class=&k&&def&/span& &span class=&nf&&forward&/span&&span class=&p&&(&/span&&span class=&bp&&self&/span&&span class=&p&&,&/span& &span class=&nb&&input&/span&&span class=&p&&):&/span&
&span class=&n&&a&/span&&span class=&p&&,&/span& &span class=&n&&b&/span&&span class=&p&&,&/span& &span class=&n&&c&/span&&span class=&p&&,&/span& &span class=&n&&d&/span& &span class=&o&&=&/span& &span class=&nb&&input&/span&&span class=&o&&.&/span&&span class=&n&&size&/span&&span class=&p&&()&/span&
&span class=&n&&feature&/span& &span class=&o&&=&/span& &span class=&nb&&input&/span&&span class=&o&&.&/span&&span class=&n&&view&/span&&span class=&p&&(&/span&&span class=&n&&a&/span& &span class=&o&&*&/span& &span class=&n&&b&/span&&span class=&p&&,&/span& &span class=&n&&c&/span& &span class=&o&&*&/span& &span class=&n&&d&/span&&span class=&p&&)&/span&
&span class=&n&&gram&/span& &span class=&o&&=&/span& &span class=&n&&torch&/span&&span class=&o&&.&/span&&span class=&n&&mm&/span&&span class=&p&&(&/span&&span class=&n&&feature&/span&&span class=&p&&,&/span& &span class=&n&&feature&/span&&span class=&o&&.&/span&&span class=&n&&t&/span&&span class=&p&&())&/span&
&span class=&n&&gram&/span& &span class=&o&&/=&/span& &span class=&p&&(&/span&&span class=&n&&a&/span& &span class=&o&&*&/span& &span class=&n&&b&/span& &span class=&o&&*&/span& &span class=&n&&c&/span& &span class=&o&&*&/span& &span class=&n&&d&/span&&span class=&p&&)&/span&
&span class=&k&&return&/span& &span class=&n&&gram&/span&
&/code&&/pre&&/div&
&h4&style loss定义&/h4&
&div class=&highlight&&&pre&&code class=&language-python&&&span&&/span&&span class=&k&&class&/span& &span class=&nc&&Style_Loss&/span&&span class=&p&&(&/span&&span class=&n&&nn&/span&&span class=&o&&.&/span&&span class=&n&&Module&/span&&span class=&p&&):&/span&
&span class=&k&&def&/span& &span class=&nf&&__init__&/span&&span class=&p&&(&/span&&span class=&bp&&self&/span&&span class=&p&&,&/span& &span class=&n&&target&/span&&span class=&p&&,&/span& &span class=&n&&weight&/span&&span class=&p&&):&/span&
&span class=&nb&&super&/span&&span class=&p&&(&/span&&span class=&n&&Style_Loss&/span&&span class=&p&&,&/span& &span class=&bp&&self&/span&&span class=&p&&)&/span&&span class=&o&&.&/span&&span class=&n&&__init__&/span&&span class=&p&&()&/span&
&span class=&bp&&self&/span&&span class=&o&&.&/span&&span class=&n&&weight&/span& &span class=&o&&=&/span& &span class=&n&&weight&/span&
&span class=&bp&&self&/span&&span class=&o&&.&/span&&span class=&n&&target&/span& &span class=&o&&=&/span& &span class=&n&&target&/span&&span class=&o&&.&/span&&span class=&n&&detach&/span&&span class=&p&&()&/span& &span class=&o&&*&/span& &span class=&bp&&self&/span&&span class=&o&&.&/span&&span class=&n&&weight&/span&
&span class=&bp&&self&/span&&span class=&o&&.&/span&&span class=&n&&gram&/span& &span class=&o&&=&/span& &span class=&n&&Gram&/span&&span class=&p&&()&/span&
&span class=&bp&&self&/span&&span class=&o&&.&/span&&span class=&n&&criterion&/span& &span class=&o&&=&/span& &span class=&n&&nn&/span&&span class=&o&&.&/span&&span class=&n&&MSELoss&/span&&span class=&p&&()&/span&
&span class=&k&&def&/span& &span class=&nf&&forward&/span&&span class=&p&&(&/span&&span class=&bp&&self&/span&&span class=&p&&,&/span& &span class=&nb&&input&/span&&span class=&p&&):&/span&
&span class=&n&&G&/span& &span class=&o&&=&/span& &span class=&bp&&self&/span&&span class=&o&&.&/span&&span class=&n&&gram&/span&&span class=&p&&(&/span&&span class=&nb&&input&/span&&span class=&p&&)&/span& &span class=&o&&*&/span& &span class=&bp&&self&/span&&span class=&o&&.&/span&&span class=&n&&weight&/span&
&span class=&bp&&self&/span&&span class=&o&&.&/span&&span class=&n&&loss&/span& &span class=&o&&=&/span& &span class=&bp&&self&/span&&span class=&o&&.&/span&&span class=&n&&criterion&/span&&span class=&p&&(&/span&&span class=&n&&G&/span&&span class=&p&&,&/span& &span class=&bp&&self&/span&&span class=&o&&.&/span&&span class=&n&&target&/span&&span class=&p&&)&/span&
&span class=&n&&out&/span& &span class=&o&&=&/span& &span class=&nb&&input&/span&&span class=&o&&.&/span&&span class=&n&&clone&/span&&span class=&p&&()&/span&
&span class=&k&&return&/span& &span class=&n&&out&/span&
&span class=&k&&def&/span& &span class=&nf&&backward&/span&&span class=&p&&(&/span&&span class=&bp&&self&/span&&span class=&p&&,&/span& &span class=&n&&retain_variabels&/span&&span class=&o&&=&/span&&span class=&bp&&True&/span&&span class=&p&&):&/span&
&span class=&bp&&self&/span&&span class=&o&&.&/span&&span class=&n&&loss&/span&&span class=&o&&.&/span&&span class=&n&&backward&/span&&span class=&p&&(&/span&&span class=&n&&retain_variables&/span&&span class=&o&&=&/span&&span class=&n&&retain_variabels&/span&&span class=&p&&)&/span&
&span class=&k&&return&/span& &span class=&bp&&self&/span&&span class=&o&&.&/span&&span class=&n&&loss&/span&
&/code&&/pre&&/div&
&h3&建立模型&/h3&
&p&使用19层的 vgg 作为提取特征的卷积网络,并且定义哪几层为需要的特征。&/p&
&div class=&highlight&&&pre&&code class=&language-python&&&span&&/span&&span class=&n&&vgg&/span& &span class=&o&&=&/span& &span class=&n&&models&/span&&span class=&o&&.&/span&&span class=&n&&vgg19&/span&&span class=&p&&(&/span&&span class=&n&&pretrained&/span&&span class=&o&&=&/span&&span class=&bp&&True&/span&&span class=&p&&)&/span&&span class=&o&&.&/span&&span class=&n&&features&/span&
&span class=&n&&vgg&/span& &span class=&o&&=&/span& &span class=&n&&vgg&/span&&span class=&o&&.&/span&&span class=&n&&cuda&/span&&span class=&p&&()&/span&
&span class=&n&&content_layers_default&/span& &span class=&o&&=&/span& &span class=&p&&[&/span&&span class=&s1&&'conv_4'&/span&&span class=&p&&]&/span&
&span class=&n&&style_layers_default&/span& &span class=&o&&=&/span& &span class=&p&&[&/span&&span class=&s1&&'conv_1'&/span&&span class=&p&&,&/span& &span class=&s1&&'conv_2'&/span&&span class=&p&&,&/span& &span class=&s1&&'conv_3'&/span&&span class=&p&&,&/span& &span class=&s1&&'conv_4'&/span&&span class=&p&&,&/span& &span class=&s1&&'conv_5'&/span&&span class=&p&&]&/span&
&span class=&k&&def&/span& &span class=&nf&&get_style_model_and_loss&/span&&span class=&p&&(&/span&&span class=&n&&style_img&/span&&span class=&p&&,&/span& &span class=&n&&content_img&/span&&span class=&p&&,&/span& &span class=&n&&cnn&/span&&span class=&o&&=&/span&&span class=&n&&vgg&/span&&span class=&p&&,&/span&
&span class=&n&&style_weight&/span&&span class=&o&&=&/span&&span class=&mi&&1000&/span&&span class=&p&&,&/span&
&span class=&n&&content_weight&/span&&span class=&o&&=&/span&&span class=&mi&&1&/span&&span class=&p&&,&/span&
&span class=&n&&content_layers&/span&&span class=&o&&=&/span&&span class=&n&&content_layers_default&/span&&span class=&p&&,&/span&
&span class=&n&&style_layers&/span&&span class=&o&&=&/span&&span class=&n&&style_layers_default&/span&&span class=&p&&):&/span&
&span class=&n&&content_loss_list&/span& &span class=&o&&=&/span& &span class=&p&&[]&/span&
&span class=&n&&style_loss_list&/span& &span class=&o&&=&/span& &span class=&p&&[]&/span&
&span class=&n&&model&/span& &span class=&o&&=&/span& &span class=&n&&nn&/span&&span class=&o&&.&/span&&span class=&n&&Sequential&/span&&span class=&p&&()&/span&
&span class=&n&&model&/span& &span class=&o&&=&/span& &span class=&n&&model&/span&&span class=&o&&.&/span&&span class=&n&&cuda&/span&&span class=&p&&()&/span&
&span class=&n&&gram&/span& &span class=&o&&=&/span& &span class=&n&&loss&/span&&span class=&o&&.&/span&&span class=&n&&Gram&/span&&span class=&p&&()&/span&
&span class=&n&&gram&/span& &span class=&o&&=&/span& &span class=&n&&gram&/span&&span class=&o&&.&/span&&span class=&n&&cuda&/span&&span class=&p&&()&/span&
&span class=&n&&i&/span& &span class=&o&&=&/span& &span class=&mi&&1&/span&
&span class=&k&&for&/span& &span class=&n&&layer&/span& &span class=&ow&&in&/span& &span class=&n&&cnn&/span&&span class=&p&&:&/span&
&span class=&k&&if&/span& &span class=&nb&&isinstance&/span&&span class=&p&&(&/span&&span class=&n&&layer&/span&&span class=&p&&,&/span& &span class=&n&&nn&/span&&span class=&o&&.&/span&&span class=&n&&Conv2d&/span&&span class=&p&&):&/span&
&span class=&n&&name&/span& &span class=&o&&=&/span& &span class=&s1&&'conv_'&/span& &span class=&o&&+&/span& &span class=&nb&&str&/span&&span class=&p&&(&/span&&span class=&n&&i&/span&&span class=&p&&)&/span&
&span class=&n&&model&/span&&span class=&o&&.&/span&&span class=&n&&add_module&/span&&span class=&p&&(&/span&&span class=&n&&name&/span&&span class=&p&&,&/span& &span class=&n&&layer&/span&&span class=&p&&)&/span&
&span class=&k&&if&/span& &span class=&n&&name&/span& &span class=&ow&&in&/span& &span class=&n&&content_layers_default&/span&&span class=&p&&:&/span&
&span class=&n&&target&/span& &span class=&o&&=&/span& &span class=&n&&model&/span&&span class=&p&&(&/span&&span class=&n&&content_img&/span&&span class=&p&&)&/span&
&span class=&n&&content_loss&/span& &span class=&o&&=&/span& &span class=&n&&loss&/span&&span class=&o&&.&/span&&span class=&n&&Content_Loss&/span&&span class=&p&&(&/span&&span class=&n&&target&/span&&span class=&p&&,&/span& &span class=&n&&content_weight&/span&&span class=&p&&)&/span&
&span class=&n&&model&/span&&span class=&o&&.&/span&&span class=&n&&add_module&/span&&span class=&p&&(&/span&&span class=&s1&&'content_loss_'&/span& &span class=&o&&+&/span& &span class=&nb&&str&/span&&span class=&p&&(&/span&&span class=&n&&i&/span&&span class=&p&&),&/span& &span class=&n&&content_loss&/span&&span class=&p&&)&/span&
&span class=&n&&content_loss_list&/span&&span class=&o&&.&/span&&span class=&n&&append&/span&&span class=&p&&(&/span&&span class=&n&&content_loss&/span&&span class=&p&&)&/span&
&span class=&k&&if&/span& &span class=&n&&name&/span& &span class=&ow&&in&/span& &span class=&n&&style_layers_default&/span&&span class=&p&&:&/span&
&span class=&n&&target&/span& &span class=&o&&=&/span& &span class=&n&&model&/span&&span class=&p&&(&/span&&span class=&n&&style_img&/span&&span class=&p&&)&/span&
&span class=&n&&target&/span& &span class=&o&&=&/span& &span class=&n&&gram&/span&&span class=&p&&(&/span&&span class=&n&&target&/span&&span class=&p&&)&/span&
&span class=&n&&style_loss&/span& &span class=&o&&=&/span& &span class=&n&&loss&/span&&span class=&o&&.&/span&&span class=&n&&Style_Loss&/span&&span class=&p&&(&/span&&span class=&n&&target&/span&&span class=&p&&,&/span& &span class=&n&&style_weight&/span&&span class=&p&&)&/span&
&span class=&n&&model&/span&&span class=&o&&.&/span&&span class=&n&&add_module&/span&&span class=&p&&(&/span&&span class=&s1&&'style_loss_'&/span& &span class=&o&&+&/span& &span class=&nb&&str&/span&&span class=&p&&(&/span&&span class=&n&&i&/span&&span class=&p&&),&/span& &span class=&n&&style_loss&/span&&span class=&p&&)&/span&
&span class=&n&&style_loss_list&/span&&span class=&o&&.&/span&&span class=&n&&append&/span&&span class=&p&&(&/span&&span class=&n&&style_loss&/span&&span class=&p&&)&/span&
&span class=&n&&i&/span& &span class=&o&&+=&/span& &span class=&mi&&1&/span&
&span class=&k&&if&/span& &span class=&nb&&isinstance&/span&&span class=&p&&(&/span&&span class=&n&&layer&/span&&span class=&p&&,&/span& &span class=&n&&nn&/span&&span class=&o&&.&/span&&span class=&n&&MaxPool2d&/span&&span class=&p&&):&/span&
&span class=&n&&name&/span& &span class=&o&&=&/span& &span class=&s1&&'pool_'&/span& &span class=&o&&+&/span& &span class=&nb&&str&/span&&span class=&p&&(&/span&&span class=&n&&i&/span&&span class=&p&&)&/span&
&span class=&n&&model&/span&&span class=&o&&.&/span&&span class=&n&&add_module&/span&&span class=&p&&(&/span&&span class=&n&&name&/span&&span class=&p&&,&/span& &span class=&n&&layer&/span&&span class=&p&&)&/span&
&span class=&k&&if&/span& &span class=&nb&&isinstance&/span&&span class=&p&&(&/span&&span class=&n&&layer&/span&&span class=&p&&,&/span& &span class=&n&&nn&/span&&span class=&o&&.&/span&&span class=&n&&ReLU&/span&&span class=&p&&):&/span&
&span class=&n&&name&/span& &span class=&o&&=&/span& &span class=&s1&&'relu'&/span& &span class=&o&&+&/span& &span class=&nb&&str&/span&&span class=&p&&(&/span&&span class=&n&&i&/span&&span class=&p&&)&/span&
&span class=&n&&model&/span&&span class=&o&&.&/span&&span class=&n&&add_module&/span&&span class=&p&&(&/span&&span class=&n&&name&/span&&span class=&p&&,&/span& &span class=&n&&layer&/span&&span class=&p&&)&/span&
&span class=&k&&return&/span& &span class=&n&&model&/span&&span class=&p&&,&/span& &span class=&n&&style_loss_list&/span&&span class=&p&&,&/span& &span class=&n&&content_loss_list&/span&
&/code&&/pre&&/div&
&h3&训练模型&/h3&
&div class=&highlight&&&pre&&code class=&language-python&&&span&&/span&&span class=&k&&def&/span& &span class=&nf&&get_input_param_optimier&/span&&span class=&p&&(&/span&&span class=&n&&input_img&/span&&span class=&p&&):&/span&
&span class=&sd&&&&&&/span&
&span class=&sd&&
input_img is a Variable&/span&
&span class=&sd&&
&&&&/span&
&span class=&n&&input_param&/span& &span class=&o&&=&/span& &span class=&n&&nn&/span&&span class=&o&&.&/span&&span class=&n&&Parameter&/span&&span class=&p&&(&/span&&span class=&n&&input_img&/span&&span class=&o&&.&/span&&span class=&n&&data&/span&&span class=&p&&)&/span&
&span class=&n&&optimizer&/span& &span class=&o&&=&/span& &span class=&n&&optim&/span&&span class=&o&&.&/span&&span class=&n&&LBFGS&/span&&span class=&p&&([&/span&&span class=&n&&input_param&/span&&span class=&p&&])&/span&
&span class=&k&&return&/span& &span class=&n&&input_param&/span&&span class=&p&&,&/span& &span class=&n&&optimizer&/span&
&span class=&k&&def&/span& &span class=&nf&&run_style_transfer&/span&&span class=&p&&(&/span&&span class=&n&&content_img&/span&&span class=&p&&,&/span& &span class=&n&&style_img&/span&&span class=&p&&,&/span& &span class=&n&&input_img&/span&&span class=&p&&,&/span&
&span class=&n&&num_epoches&/span&&span class=&o&&=&/span&&span class=&mi&&300&/span&&span class=&p&&):&/span&
&span class=&k&&print&/span&&span class=&p&&(&/span&&span class=&s1&&'Building the style transfer model..'&/span&&span class=&p&&)&/span&
&span class=&n&&model&/span&&span class=&p&&,&/span& &span class=&n&&style_loss_list&/span&&span class=&p&&,&/span& &span class=&n&&content_loss_list&/span& &span class=&o&&=&/span& &span class=&n&&get_style_model_and_loss&/span&&span class=&p&&(&/span&
&span class=&n&&style_img&/span&&span class=&p&&,&/span& &span class=&n&&content_img&/span&
&span class=&p&&)&/span&
&span class=&n&&input_param&/span&&span class=&p&&,&/span& &span class=&n&&optimizer&/span& &span class=&o&&=&/span& &span class=&n&&get_input_param_optimier&/span&&span class=&p&&(&/span&&span class=&n&&input_img&/span&&span class=&p&&)&/span&
&span class=&k&&print&/span&&span class=&p&&(&/span&&span class=&s1&&'Opimizing...'&/span&&span class=&p&&)&/span&
&span class=&n&&epoch&/span& &span class=&o&&=&/span& &span class=&p&&[&/span&&span class=&mi&&0&/span&&span class=&p&&]&/span&
&span class=&k&&while&/span& &span class=&n&&epoch&/span&&span class=&p&&[&/span&&span class=&mi&&0&/span&&span class=&p&&]&/span& &span class=&o&&&&/span& &span class=&n&&num_epoches&/span&&span class=&p&&:&/span&
&span class=&k&&def&/span& &span class=&nf&&closure&/span&&span class=&p&&():&/span&
&span class=&n&&input_param&/span&&span class=&o&&.&/span&&span class=&n&&data&/span&&span class=&o&&.&/span&&span class=&n&&clamp_&/span&&span class=&p&&(&/span&&span class=&mi&&0&/span&&span class=&p&&,&/span& &span class=&mi&&1&/span&&span class=&p&&)&/span&
&span class=&n&&model&/span&&span class=&p&&(&/span&&span class=&n&&input_param&/span&&span class=&p&&)&/span&
&span class=&n&&style_score&/span& &span class=&o&&=&/span& &span class=&mi&&0&/span&
&span class=&n&&content_score&/span& &span class=&o&&=&/span& &span class=&mi&&0&/span&
&span class=&n&&optimizer&/span&&span class=&o&&.&/span&&span class=&n&&zero_grad&/span&&span class=&p&&()&/span&
&span class=&k&&for&/span& &span class=&n&&sl&/span& &span class=&ow&&in&/span& &span class=&n&&style_loss_list&/span&&span class=&p&&:&/span&
&span class=&n&&style_score&/span& &span class=&o&&+=&/span& &span class=&n&&sl&/span&&span class=&o&&.&/span&&span class=&n&&backward&/span&&span class=&p&&()&/span&
&span class=&k&&for&/span& &span class=&n&&cl&/span& &span class=&ow&&in&/span& &span class=&n&&content_loss_list&/span&&span class=&p&&:&/span&
&span class=&n&&content_score&/span& &span class=&o&&+=&/span& &span class=&n&&cl&/span&&span class=&o&&.&/span&&span class=&n&&backward&/span&&span class=&p&&()&/span&
&span class=&n&&epoch&/span&&span class=&p&&[&/span&&span class=&mi&&0&/span&&span class=&p&&]&/span& &span class=&o&&+=&/span& &span class=&mi&&1&/span&
&span class=&k&&if&/span& &span class=&n&&epoch&/span&&span class=&p&&[&/span&&span class=&mi&&0&/span&&span class=&p&&]&/span& &span class=&o&&%&/span& &span class=&mi&&50&/span& &span class=&o&&==&/span& &span class=&mi&&0&/span&&span class=&p&&:&/span&
&span class=&k&&print&/span&&span class=&p&&(&/span&&span class=&s1&&'run {}'&/span&&span class=&o&&.&/span&&span class=&n&&format&/span&&span class=&p&&(&/span&&span class=&n&&epoch&/span&&span class=&p&&))&/span&
&span class=&k&&print&/span&&span class=&p&&(&/span&&span class=&s1&&'Style Loss: {:.4f} Content Loss: {:.4f}'&/span&&span class=&o&&.&/span&&span class=&n&&format&/span&&span class=&p&&(&/span&
&span class=&n&&style_score&/span&&span class=&o&&.&/span&&span class=&n&&data&/span&&span class=&p&&[&/span&&span class=&mi&&0&/span&&span class=&p&&],&/span& &span class=&n&&content_score&/span&&span class=&o&&.&/span&&span class=&n&&data&/span&&span class=&p&&[&/span&&span class=&mi&&0&/span&&span class=&p&&]&/span&
&span class=&p&&))&/span&
&span class=&k&&print&/span&&span class=&p&&()&/span&
&span class=&k&&return&/span& &span class=&n&&style_score&/span& &span class=&o&&+&/span& &span class=&n&&content_score&/span&
&span class=&n&&optimizer&/span&&span class=&o&&.&/span&&span class=&n&&step&/span&&span class=&p&&(&/span&&span class=&n&&closure&/span&&span class=&p&&)&/span&
&span class=&n&&input_param&/span&&span class=&o&&.&/span&&span class=&n&&data&/span&&span class=&o&&.&/span&&span class=&n&&clamp_&/span&&span class=&p&&(&/span&&span class=&mi&&0&/span&&span class=&p&&,&/span& &span class=&mi&&1&/span&&span class=&p&&)&/span&
&span class=&k&&return&/span& &span class=&n&&input_param&/span&&span class=&o&&.&/span&&span class=&n&&data&/span&
&/code&&/pre&&/div&
&p&需要特别注意的是这个模型里面参数不再是网络里面的参数,因为网络使用的是已经预训练好的 vgg 网络,这个算法里面的参数是合成图片里面的每个像素点,我们可以将内容图片直接 copy 成合成图片,然后训练使得他的风格和我们的风格图片相似,同时也可以随机化一张图片作为合成图片,然后训练他使得他与内容图片以及风格图片具有相似性。&/p&
&h3&实验结果&/h3&
&p&我们使用的风格图片为&/p&&img src=&/v2-9babd96caee2de5efc1c39_b.png& data-rawwidth=&512& data-rawheight=&512& class=&origin_image zh-lightbox-thumb& width=&512& data-original=&/v2-9babd96caee2de5efc1c39_r.png&&&br&&p&内容图片为&/p&&img src=&/v2-c6fa8b46ef226abc4c8ac_b.png& data-rawwidth=&512& data-rawheight=&512& class=&origin_image zh-lightbox-thumb& width=&512& data-original=&/v2-c6fa8b46ef226abc4c8ac_r.png&&&br&&p&得到的合成效果为&/p&&img src=&/v2-68bf0e26ef_b.png& data-rawwidth=&512& data-rawheight=&512& class=&origin_image zh-lightbox-thumb& width=&512& data-original=&/v2-68bf0e26ef_r.png&&&br&&h2&结语&/h2&
&p&通过这篇文章,我们利用pytorch实现了基本的风格转移算法,得到的效果也是满意的,所以我们可以把自己的图片通过这个算法做一个风格转移,实现你想要的作品的风格,逼格满满,大家学习之后肯定会有特别大的成就感,在完成项目的同时也学习到了新的知识,同时也会对这个产生更浓厚的感兴趣,兴趣才是各种的动力,比任何鸡汤都有用,希望大家都能够找到自己的兴趣,热爱自己所做的事。&/p&
&p&本文代码已经上传到了&a href=&/?target=https%3A///SherlockLiao/neural-transfer& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&github&i class=&icon-external&&&/i&&/a&上&/p&
&p&欢迎查看我的知乎专栏,&a href=&/c_& class=&internal&&深度炼丹&/a&&/p&
&p&欢迎访问我的&a href=&/?target=https%3A//sherlockliao.github.io/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&博客&i class=&icon-external&&&/i&&/a&&/p&
不知道大家是否用过prisma,就算没有用过,也一定看见别人用过这个软件,下面是一张这个软件得到的一个效果图 官方宣传的卖点是一秒钟让你的作品拥有名家风格,什么毕加索,梵高,都不在话下。通过这个效果再将你的照片发到朋友圈,是不是效果爆棚…
&p&首先,我感觉不必像 @李Shawn 同学一样认为DNN、CNN、RNN完全不能相提并论。从广义上来说,NN(或是更美的DNN)确实可以认为包含了CNN、RNN这些具体的变种形式。在实际应用中,所谓的深度神经网络DNN,往往融合了多种已知的结构,包括卷积层或是LSTM单元。但是就题主的意思来看,这里的DNN应该特指全连接的神经元结构,并不包含卷积单元或是时间上的关联。因此,题主一定要将DNN、CNN、RNN等进行对比,也未尝不可。&/p&&p&其实,如果我们顺着神经网络技术发展的脉络,就很容易弄清这几种网络结构发明的初衷,和他们之间本质的区别,希望对题主有所帮助。&/p&&p&=========================== 分 割 线 就 是 我
================================&/p&&br&&p&神经网络技术起源于上世纪五、六十年代,当时叫&b&感知机&/b&(perceptron),拥有输入层、输出层和一个隐含层。输入的特征向量通过隐含层变换达到输出层,在输出层得到分类结果。早期感知机的推动者是Rosenblatt。&i&(扯一个不相关的:由于计算技术的落后,当时感知器传输函数是用线拉动变阻器改变电阻的方法机械实现的,脑补一下科学家们扯着密密麻麻的导线的样子…)&/i&&/p&&p&但是,Rosenblatt的单层感知机有一个严重得不能再严重的问题,即它对稍复杂一些的函数都无能为力(比如最为典型的“异或”操作)。连异或都不能拟合,你还能指望这货有什么实际用途么o(╯□╰)o&/p&&br&&p&随着数学的发展,这个缺点直到上世纪八十年代才被Rumelhart、Williams、Hinton、LeCun等人(反正就是一票大牛)发明的&b&多层感知机&/b&(multilayer
perceptron)克服。多层感知机,顾名思义,就是有多个隐含层的感知机(废话……)。好好,我们看一下多层感知机的结构:&/p&&img src=&/e186f18d73fdafa8d4a5e75ed55ed4a3_b.png& data-rawwidth=&866& data-rawheight=&249& class=&origin_image zh-lightbox-thumb& width=&866& data-original=&/e186f18d73fdafa8d4a5e75ed55ed4a3_r.png&&&br&&p&&b&&i&图1&/i&&/b&&i&上下层神经元全部相连的神经网络——多层感知机&/i&&/p&&br&&p&多层感知机可以摆脱早期离散传输函数的束缚,使用sigmoid或tanh等连续函数模拟神经元对激励的响应,在训练算法上则使用Werbos发明的反向传播BP算法。对,这货就是我们现在所说的&b&神经网络&/b&&b&NN&/b&——神经网络听起来不知道比感知机高端到哪里去了!这再次告诉我们起一个好听的名字对于研(zhuang)究(bi)很重要!&/p&&br&&p&多层感知机解决了之前无法模拟异或逻辑的缺陷,同时更多的层数也让网络更能够刻画现实世界中的复杂情形。相信年轻如Hinton当时一定是春风得意。&/p&&br&&p&多层感知机给我们带来的启示是,&b&神经网络的层数直接决定了它对现实的刻画能力&/b&——利用每层更少的神经元拟合更加复杂的函数[1]。&/p&&p&(Bengio如是说:functions that can be compactly
represented by a depth k architecture might require an exponential number of
computational elements to be represented by a depth k - 1 architecture.)&/p&&br&&p&即便大牛们早就预料到神经网络需要变得更深,但是有一个梦魇总是萦绕左右。随着神经网络层数的加深,&b&优化函数越来越容易陷入局部最优解&/b&,并且这个“陷阱”越来越偏离真正的全局最优。利用有限数据训练的深层网络,性能还不如较浅层网络。同时,另一个不可忽略的问题是随着网络层数增加,&b&“梯度消失”现象更加严重&/b&。具体来说,我们常常使用sigmoid作为神经元的输入输出函数。对于幅度为1的信号,在BP反向传播梯度时,每传递一层,梯度衰减为原来的0.25。层数一多,梯度指数衰减后低层基本上接受不到有效的训练信号。&/p&&br&&p&2006年,Hinton利用预训练方法缓解了局部最优解问题,将隐含层推动到了7层[2],神经网络真正意义上有了“深度”,由此揭开了深度学习的热潮。这里的“深度”并没有固定的定义——在语音识别中4层网络就能够被认为是“较深的”,而在图像识别中20层以上的网络屡见不鲜。为了克服梯度消失,ReLU、maxout等传输函数代替了sigmoid,形成了如今DNN的基本形式。单从结构上来说,&b&全连接的&/b&&b&DNN&/b&&b&和图&/b&&b&1&/b&&b&的多层感知机是没有任何区别的&/b&。&/p&&br&&p&值得一提的是,今年出现的高速公路网络(highway network)和深度残差学习(deep residual learning)进一步避免了梯度消失,网络层数达到了前所未有的一百多层(深度残差学习:152层)[3,4]!具体结构题主可自行搜索了解。如果你之前在怀疑是不是有很多方法打上了“深度学习”的噱头,这个结果真是深得让人心服口服。&/p&&br&&img src=&/7b3ee9e4f4a2e61acfcc12_b.png& data-rawwidth=&866& data-rawheight=&1228& class=&origin_image zh-lightbox-thumb& width=&866& data-original=&/7b3ee9e4f4a2e61acfcc12_r.png&&&br&&p&&b&&i&图2&/i&&/b&&i&缩减版的深度残差学习网络,仅有34&/i&&i&层,终极版有152&/i&&i&层,自行感受一下&/i&&/p&&br&&p&如图1所示,我们看到&b&全连接&/b&&b&DNN&/b&&b&的结构里下层神经元和所有上层神经元都能够形成连接&/b&,带来的潜在问题是&b&参数数量的膨胀&/b&。假设输入的是一幅像素为1K*1K的图像,隐含层有1M个节点,光这一层就有10^12个权重需要训练,这不仅容易过拟合,而且极容易陷入局部最优。另外,图像中有固有的局部模式(比如轮廓、边界,人的眼睛、鼻子、嘴等)可以利用,显然应该将图像处理中的概念和神经网络技术相结合。此时我们可以祭出题主所说的卷积神经网络CNN。对于CNN来说,并不是所有上下层神经元都能直接相连,而是&b&通过“卷积核”作为中介。同一个卷积核在所有图像内是共享的,图像通过卷积操作后仍然保留原先的位置关系。&/b&两层之间的卷积传输的示意图如下:&/p&&br&&img src=&/440765dbaabd_b.png& data-rawwidth=&866& data-rawheight=&457& class=&origin_image zh-lightbox-thumb& width=&866& data-original=&/440765dbaabd_r.png&&&p&&b&&i&图3&/i&&/b&&i&卷积神经网络隐含层(摘自Theano&/i&&i&教程)&/i&&/p&&br&&p&通过一个例子简单说明卷积神经网络的结构。假设图3中m-1=1是输入层,我们需要识别一幅彩色图像,这幅图像具有四个通道ARGB(透明度和红绿蓝,对应了四幅相同大小的图像),假设卷积核大小为100*100,共使用100个卷积核w1到w100(从直觉来看,每个卷积核应该学习到不同的结构特征)。用w1在ARGB图像上进行卷积操作,可以得到隐含层的第一幅图像;这幅隐含层图像左上角第一个像素是四幅输入图像左上角100*100区域内像素的加权求和,以此类推。同理,算上其他卷积核,隐含层对应100幅“图像”。每幅图像对是对原始图像中不同特征的响应。按照这样的结构继续传递下去。CNN中还有max-pooling等操作进一步提高鲁棒性。&/p&&br&&img src=&/c71cd39abe8b0dd29e229fda_b.png& data-rawwidth=&866& data-rawheight=&203& class=&origin_image zh-lightbox-thumb& width=&866& data-original=&/c71cd39abe8b0dd29e229fda_r.png&&&br&&p&&b&&i&图4&/i&&/b&&i&一个典型的卷积神经网络结构,注意到最后一层实际上是一个全连接层(摘自Theano&/i&&i&教程)&/i&&/p&&br&&p&在这个例子里,我们注意到&b&输入层到隐含层的参数瞬间降低到了&/b&&b&100*100*100=10^6&/b&&b&个&/b&!这使得我们能够用已有的训练数据得到良好的模型。题主所说的适用于图像识别,正是由于&b&CNN&/b&&b&模型限制参数了个数并挖掘了局部结构的这个特点&/b&。顺着同样的思路,利用语音语谱结构中的局部信息,CNN照样能应用在语音识别中。&/p&&br&&p&全连接的DNN还存在着另一个问题——无法对时间序列上的变化进行建模。然而,&b&样本出现的时间顺序对于自然语言处理、语音识别、手写体识别等应用非常重要&/b&。对了适应这种需求,就出现了题主所说的另一种神经网络结构——循环神经网络RNN。&/p&&br&&p&在普通的全连接网络或CNN中,每层神经元的信号只能向上一层传播,样本的处理在各个时刻独立,因此又被成为前向神经网络(Feed-forward Neural Networks)。而在&b&RNN&/b&&b&中,神经元的输出可以在下一个时间戳直接作用到自身&/b&,即第i层神经元在m时刻的输入,除了(i-1)层神经元在该时刻的输出外,还包括其自身在(m-1)时刻的输出!表示成图就是这样的:&/p&&br&&img src=&/bef6acad53eb47757af9d_b.png& data-rawwidth=&866& data-rawheight=&441& class=&origin_image zh-lightbox-thumb& width=&866& data-original=&/bef6acad53eb47757af9d_r.png&&&p&&b&&i&图5&/i&&/b&&i& RNN&/i&&i&网络结构&/i&&/p&&br&&p&我们可以看到在隐含层节点之间增加了互连。为了分析方便,我们常将RNN在时间上进行展开,得到如图6所示的结构:&/p&&br&&img src=&/c2ebfd25f0e90aa66d363a_b.png& data-rawwidth=&866& data-rawheight=&348& class=&origin_image zh-lightbox-thumb& width=&866& data-original=&/c2ebfd25f0e90aa66d363a_r.png&&&p&&b&&i&图6&/i&&/b&&i& RNN&/i&&i&在时间上进行展开&/i&&/p&&br&&p&Cool,&b&(&/b&&b&t+1&/b&&b&)时刻网络的最终结果O(t+1)&/b&&b&是该时刻输入和所有历史共同作用的结果&/b&!这就达到了对时间序列建模的目的。&/p&&br&&p&不知题主是否发现,RNN可以看成一个在时间上传递的神经网络,它的深度是时间的长度!正如我们上面所说,&b&“梯度消失”现象又要出现了,只不过这次发生在时间轴上&/b&。对于t时刻来说,它产生的梯度在时间轴上向历史传播几层之后就消失了,根本就无法影响太遥远的过去。因此,之前说“所有历史”共同作用只是理想的情况,在实际中,这种影响也就只能维持若干个时间戳。&/p&&br&&p&为了解决时间上的梯度消失,机器学习领域发展出了&b&长短时记忆单元&/b&&b&LSTM&/b&&b&,通过门的开关实现时间上记忆功能,并防止梯度消失&/b&,一个LSTM单元长这个样子:&/p&&br&&img src=&/a8fd41f250fdf0a43812fb_b.png& data-rawwidth=&866& data-rawheight=&555& class=&origin_image zh-lightbox-thumb& width=&866& data-original=&/a8fd41f250fdf0a43812fb_r.png&&&p&&b&&i&图7 &/i&&/b&&i&LSTM&/i&&i&的模样&/i&&/p&&br&&p&除了题主疑惑的三种网络,和我之前提到的深度残差学习、LSTM外,深度学习还有许多其他的结构。举个例子,RNN既然能继承历史信息,是不是也能吸收点未来的信息呢?因为在序列信号分析中,如果我能预知未来,对识别一定也是有所帮助的。因此就有了&b&双向&/b&&b&RNN&/b&&b&、双向&/b&&b&LSTM&/b&&b&,同时利用历史和未来的信息。&/b&&/p&&br&&img src=&/a3ab3ac8ecdafda617db0c_b.png& data-rawwidth=&866& data-rawheight=&365& class=&origin_image zh-lightbox-thumb& width=&866& data-original=&/a3ab3ac8ecdafda617db0c_r.png&&&p&&b&&i&图8&/i&&/b&&i&双向RNN&/i&&/p&&br&&p&事实上,&b&不论是那种网络,他们在实际应用中常常都混合着使用,比如&/b&&b&CNN&/b&&b&和RNN&/b&&b&在上层输出之前往往会接上全连接层,很难说某个网络到底属于哪个类别。&/b&不难想象随着深度学习热度的延续,更灵活的组合方式、更多的网络结构将被发展出来。尽管看起来千变万化,但研究者们的出发点肯定都是为了解决特定的问题。题主如果想进行这方面的研究,不妨仔细分析一下这些结构各自的特点以及它们达成目标的手段。入门的话可以参考:&/p&&p&Ng写的Ufldl:&a href=&///?target=http%3A//ufldl.stanford.edu/wiki/index.php/UFLDL%25E6%E7%25A8%258B& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&UFLDL教程 - Ufldl&i class=&icon-external&&&/i&&/a&&/p&&p&也可以看Theano内自带的教程,例子非常具体:&a href=&///?target=http%3A//www.deeplearning.net/tutorial/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Deep Learning Tutorials&i class=&icon-external&&&/i&&/a&&/p&&p&欢迎大家继续推荐补充。&/p&&p&当然啦,如果题主只是想凑个热闹时髦一把,或者大概了解一下方便以后把妹使,这样看看也就罢了吧。&/p&&br&&br&&p&&b&参考文献:&/b&&/p&&p&[1]
Bengio Y. Learning Deep
Architectures for AI[J]. Foundations & Trends(R) in Machine Learning, 2009,
2(1):1-127.&/p&&p&[2]
Hinton G E, Salakhutdinov R R.
Reducing the Dimensionality of Data with Neural Networks[J]. Science, 2006,
313(7.&/p&&p&[3]
He K, Zhang X, Ren S, Sun J. Deep
Residual Learning for Image Recognition. arXiv:, 2015.&/p&&p&[4]
Srivastava R K, Greff K,
Schmidhuber J. Highway networks. arXiv:, 2015.&/p&&br&&br&&br&【“科研君”公众号初衷始终是希望聚集各专业一线科研人员和工作者,在进行科学研究的同时也作为知识的传播者,利用自己的专业知识解释和普及生活中的 一些现象和原理,展现科学有趣生动的一面。该公众号由清华大学一群在校博士生发起,目前参与的作者人数有10人,但我们感觉这远远不能覆盖所以想科普的领域,并且由于空闲时间有限,导致我们只能每周发布一篇文章。我们期待更多的战友加入,认识更多志同道合的人,每个人都是科研君,每个人都是知识的传播者。我们期待大家的参与,想加入我们,进QQ群吧~:】&br&&br&&br&&br&&p&【非常高兴看到大家喜欢并赞同我们的回答。应许多知友的建议,最近我们开通了同名公众号:&b&PhDer&/b&,也会定期更新我们的文章,如果您不想错过我们的每篇回答,欢迎扫码关注~ 】&br&&/p&&br&&p&&a href=&///?target=http%3A///r/5zsuNoHEZdwarcVV9271& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&/r/5zsuNoH&/span&&span class=&invisible&&EZdwarcVV9271&/span&&span class=&ellipsis&&&/span&&i class=&icon-external&&&/i&&/a& (二维码自动识别)&/p&
首先,我感觉不必像 @李Shawn 同学一样认为DNN、CNN、RNN完全不能相提并论。从广义上来说,NN(或是更美的DNN)确实可以认为包含了CNN、RNN这些具体的变种形式。在实际应用中,所谓的深度神经网络DNN,往往融合了多种已知的结构,包括卷积层或是LSTM单元。…
&img src=&/7f202ede10d05e06b6a2_b.png& data-rawwidth=&449& data-rawheight=&171& class=&origin_image zh-lightbox-thumb& width=&449& data-original=&/7f202ede10d05e06b6a2_r.png&&&p&近些年来,深度卷积神经网络(DCNN)在图像分类和识别上取得了很显著的提高。回顾从这两年多的时间,先后涌现出了R-CNN,Fast R-CNN, Faster R-CNN, ION, HyperNet, SDP-CRC, YOLO,G-CNN, SSD等越来越快速和准确的目标检测方法。&/p&&ol&&li&基于Region Proposal的方法&/li&&/ol&&p&该类方法的基本思想是:先得到候选区域再对候选区域进行分类和边框回归。 &br&&/p&&p&1.1 R-CNN [1]&br&&/p&&p&R-CNN是较早地将DCNN用到目标检测中的方法。其中心思想是对图像中的各个候选区域先用DCNN进行特征提取并使用一个SVM进行分类,分类的结果是一个初略的检测结果,之后再次使用DCNN的特征,结合另一个SVM回归模型得到更精确的边界框。&/p&&img data-rawheight=&179& data-rawwidth=&501& src=&/8bdf7f9df9dbbe996a0a_b.png& class=&origin_image zh-lightbox-thumb& width=&501& data-original=&/8bdf

我要回帖

 

随机推荐