神经网络 订阅
人工神经网络(Artificial Neural Networks,简写为ANNs)也简称为神经网络(NNs)或称作连接模型(Connection Model),它是一种模仿动物神经网络行为特征,进行分布式并行信息处理的算法数学模型。这种网络依靠系统的复杂程度,通过调整内部大量节点之间相互连接的关系,从而达到处理信息的目的。 [1] 展开全文
人工神经网络(Artificial Neural Networks,简写为ANNs)也简称为神经网络(NNs)或称作连接模型(Connection Model),它是一种模仿动物神经网络行为特征,进行分布式并行信息处理的算法数学模型。这种网络依靠系统的复杂程度,通过调整内部大量节点之间相互连接的关系,从而达到处理信息的目的。 [1]
信息
简    称
神经网络(NNs)
应用学科
通信
中文名
神经网络
外文名
neural networks
神经网络定义
生物神经网络主要是指人脑的神经网络,它是人工神经网络的技术原型。人脑是人类思维的物质基础,思维的功能定位在大脑皮层,后者含有大约10^11个神经元,每个神经元又通过神经突触与大约103个其它神经元相连,形成一个高度复杂高度灵活的动态网络。作为一门学科,生物神经网络主要研究人脑神经网络的结构、功能及其工作机制,意在探索人脑思维和智能活动的规律。人工神经网络是生物神经网络在某种简化意义下的技术复现,作为一门学科,它的主要任务是根据生物神经网络的原理和实际应用的需要建造实用的人工神经网络模型,设计相应的学习算法,模拟人脑的某种智能活动,然后在技术上实现出来用以解决实际问题。因此,生物神经网络主要研究智能的机理;人工神经网络主要研究智能机理的实现,两者相辅相成。 [2] 
收起全文
精华内容
下载资源
问答
  • 神经网络
    千次阅读
    2022-03-23 12:33:42

    Convolutional Neural Network(CNN)

    • 卷积层
    • 池化层(Pooling)
    • 归一化
    • 全连接
    • 把全连接层转化成卷积层

    ConvNets

    卷积神经网络的结构基于一个假设,即输入数据是图像,基于该假设,我们就向结构中添加了一些特有的性质。这些特有属性使得前向传播函数实现起来更高效,并且大幅度降低了网络中参数的数量。

    常规神经网络

    常规神经网络,神经网络的输入是一个向量,然后在一系列的隐层中对它做变换。每个隐层都是由若干的神经元组成,每个神经元都与前一层中的所有神经元连接。
    在这里插入图片描述

    举例说来,一个尺寸为200x200x3的图像,会让神经元包含200x200x3=120,000个权重值。而网络中肯定不止一个神经元,那么参数的量就会快速增加!显而易见,这种全连接方式效率低下,大量的参数也很快会导致网络过拟合。

    ConvNets

    在这里插入图片描述

    计算机认识的图片:一个有长宽的矩阵,再加上一个通道数;在RGB图片里有3个通道,R\G\B.

    一个简单的卷积神经网络是由各种层按照顺序排列组成,网络中的每个层使用一个可以微分的函数将激活数据从一个层传递到另一个层。卷积神经网络主要由三种类型的层构成:卷积层,池化(Pooling)层和全连接层(全连接层和常规神经网络中的一样)。通过将这些层叠加起来,就可以构建一个完整的卷积神经网络。

    卷积层

    卷积层是构建卷积神经网络的核心层,它产生了网络中大部分的计算量。

    如何简化计算?
    • 让不同的神经元守备不同区域
    • 共享参数
    input
    41008102
    41018002
    41008102
    40018202
    40008002
    41018102
    filter
    010
    010
    010

    在这里插入图片描述

    在前向传播的时候,让每个filter都在输入数据的宽度和高度上滑动(更精确地说是卷积),然后计算整个filter和输入数据任一处的内积。当filter沿着输入数据的宽度和高度滑过后,会生成一个2维的激活图(activation map),激活图给出了在每个空间位置处Receptive field的反应。直观地来说,网络会让filter学习到当它看到某些类型的视觉特征时就激活,具体的视觉特征可能是某些方位上的边界,或者在第一层上某些颜色的斑点.

    在这里插入图片描述

    一个channel的卷积

    在这里插入图片描述

    在每个卷积层上,我们会有一排的filter(比如16个、32、64个,需要多少个,自己定,你开心就好),每个都会生成一个不同的二维激活图。将这些激活映射在深度方向上层叠起来就生成了输出数据。

    在这里插入图片描述

    例如,在100 * 100 * 3的输入下,我定了第一层的 filter 为64个,stride=1,那么输出将是 98 * 98 * 64的矩阵

    一个filter就是一个神经元,当它滑向下一区域时,就相当于切换到下一区域的神经元,这些神经元共享同一组参数也就是filter里的参数,你定了64个filter那么将有64组filter分别扫过一整张图片.

    动画演示

    https://cs231n.github.io/assets/conv-demo/index.html

    例1:假设输入数据体尺寸为[32x32x3](比如CIFAR-10的RGB图像),如果Receptive field是5x5,那么卷积层中的每个神经元会有输入数据体中[5x5x3]区域的权重,共5x5x3=75个权重(还要加一个偏差参数)。注意这个连接在深度维度上的大小必须为3,和输入数据体的深度一致。

    例2:假设输入数据体的尺寸是[16x16x20],filter尺寸是3x3,那么卷积层中每个神经元和输入数据体就有3x3x20=180个连接。再次提示:在空间上连接是局部的(3x3),但是在深度上是和输入数据体一致的(20)。

    怎么控制输出数据?

    3个超参数控制着输出数据体的尺寸:深度(depth),步长(stride)和填充(padding)。

    • 首先,输出数据体的深度是一个超参数:它和使用的filter的数量一致,而每个filter在输入数据中寻找一些不同的东西。举例来说,如果第一个卷积层的输入是原始图像,那么在深度维度上的不同神经元将可能被不同方向的边界,或者是颜色斑点激活。我们将这些沿着深度方向排列、filter相同的神经元集合称为深度列(depth column),也有人使用纤维(fibre)来称呼它们。
    • 其次,在滑动filter的时候,必须指定步长。当步长为1,滤波器每次移动1个像素。当步长为2(或者不常用的3,或者更多,这些在实际中很少使用),filter滑动时每次移动2个像素。这个操作会让输出数据体在空间上变小。
    • 在下文可以看到,有时候将输入数据体用0在边缘处进行填充是很方便的。这个零填充(zero-padding)的尺寸是一个超参数。零填充有一个良好性质,即可以控制输出数据体的空间尺寸(最常用的是用来保持输入数据体在空间上的尺寸,这样输入和输出的宽高都相等)(你可以用0填充,也可以用均值填充,根据需求,你喜欢就好)。

    如何抓取特征

    在这里插入图片描述

    当图片上出现与filter相似的特征时,输出的值会有明显变化,训练时根据这种变化,网络会调整参数,让filter记住这个特征.

    池化层

    在这里插入图片描述

    为了控制数据体的大小,通常,在连续的卷积层之间会周期性地插入一个池化层。这样的话就能减少网络中参数的数量,使得计算资源耗费变少,也能有效控制过拟合。池化层使用MAX操作(不一定非要MAX Pooling也可以mean等等,你喜欢),对输入数据体的每一个深度切片独立进行操作,改变它的空间尺寸。最常见的形式是池化层使用尺寸2x2的filter,以步长为2来对每个深度切片进行降采样,将其中75%的激活信息都丢掉。每个MAX操作是从4个数字中取最大值(也就是在深度切片中某个2x2的区域)。深度保持不变。

    在这里插入图片描述

    是不是一定非要用池化层?

    答案是否定的。不是非得用池化,我用池化就一定好。举个栗子,Alpha Go论文中有提到,网络是19 * 19的输入,而恰巧围棋棋盘就是19*19路,Alpha Go设计者就把每一步棋子在棋盘的位置当成一张图片,那么网络就可以用CNN,而确实是用的CNN,那么在这上面使用池化的话会发生什么?会丢了棋子信息,因为每一个棋子都会影响棋局的走势,所有不能丢失任一处的棋子信息。

    归一化层

    在卷积神经网络的结构中,提出了很多不同类型的归一化层,有时候是为了实现在生物大脑中观测到的抑制机制。但是这些层渐渐都不再流行,因为实践证明它们的效果即使存在,也是极其有限的。

    全连接层

    在全连接层中,神经元对于前一层中的所有激活数据是全部连接的,这个常规神经网络中一样。

    在这里插入图片描述

    网络结构

    卷积神经网络通常是由三种层构成:卷积层,池化层(除非特别说明,一般就是最大值池化)和全连接层(简称FC)。ReLU激活函数也应该算是是一层,它逐元素地进行激活函数操作。在本节中将讨论在卷积神经网络中这些层通常是如何组合在一起的。

    层的排列规律

    卷积神经网络最常见的形式就是将一些卷积层和ReLU层放在一起,其后紧跟池化层,然后重复如此直到图像在空间上被缩小到一个足够小的尺寸,在某个地方过渡成成全连接层也较为常见。最后的全连接层得到输出,比如分类评分等。

    • INPUT -> FC,实现一个线性分类器,此处N = M = K = 0。
    • INPUT -> CONV -> RELU -> FC
    • INPUT -> [CONV -> RELU -> POOL]*2 -> FC -> RELU -> FC。此处在每个汇聚层之间有一个卷积层。
    • INPUT -> [CONV -> RELU -> CONV -> RELU -> POOL]*3 -> [FC -> RELU]*2 -> FC。此处每个汇聚层前有两个卷积层,这个思路适用于更大更深的网络,因为在执行具有破坏性的池化操作前,多重的卷积层可以从输入数据中学习到更多的复杂特征。

    层的尺寸设置规律

    • 输入层(包含图像的)应该能被2整除很多次。常用数字包括32(比如CIFAR-10),64,96(比如STL-10)或224(比如ImageNet卷积神经网络),384和512。
    • 卷积层 应该使用小尺寸滤波器(比如3x3或最多5x5),使用步长1 。还有一点非常重要,就是对输入数据进行零填充,这样卷积层就不会改变输入数据在空间维度上的尺寸。
    • 池化层 负责对输入数据的空间维度进行降采样。最常用的设置是用用2x2Receptive field的最大值池化,步长为2。注意这一操作将会把输入数据中75%的激活数据丢弃(因为对宽度和高度都进行了2的降采样)。 另一个不那么常用的设置是使用3x3的Receptive field,步长为2。最大值池化的Receptive field尺寸很少有超过3的,因为池化操作过于激烈,易造成数据信息丢失,这通常会导致算法性能变差。

    减少尺寸设置的问题:上文中展示的两种设置是很好的,因为所有的卷积层都能保持其输入数据的空间尺寸,汇聚层只负责对数据体从空间维度进行降采样。如果使用的步长大于1并且不对卷积层的输入数据使用零填充,那么就必须非常仔细地监督输入数据体通过整个卷积神经网络结构的过程,确认所有的步长和滤波器都尺寸互相吻合

    为什么在卷积层使用1的步长? 在实际应用中,更小的步长效果更好。上文也已经提过,步长为1可以让空间维度的降采样全部由汇聚层负责,卷积层只负责对输入数据体的深度进行变换。
    为何使用零填充? 使用零填充除了前面提到的可以让卷积层的输出数据保持和输入数据在空间维度的不变,还可以提高算法性能。如果卷积层值进行卷积而不进行零填充,那么数据体的尺寸就会略微减小,那么图像边缘的信息就会过快地损失掉。

    网络结构例子:

    一个用于CIFAR-10图像数据分类的卷积神经网络的结构可以是[输入层-卷积层-ReLU层-汇聚层-全连接层]。细节如下:

    • 输入[32x32x3]存有图像的原始像素值,本例中图像宽高均为32,有3个颜色通道。
    • 卷积层中,神经元与输入层中的一个局部区域相连,每个神经元都计算自己与输入层相连的小区域与自己权重的内积。卷积层会计算所有神经元的输出。如果我们使用12个滤波器(也叫作核),得到的输出数据体的维度就是[32x32x12]。
    • ReLU层将会逐个元素地进行激活函数操作,比如使用以0为阈值的 作为激活函数。该层对数据尺寸没有改变,还是[32x32x12]。
    • 池化层在在空间维度(宽度和高度)上进行降采样(downsampling)操作,数据尺寸变为[16x16x12]。
    • 全连接层将会计算分类评分,数据尺寸变为[1x1x10],其中10个数字对应的就是CIFAR-10中10个类别的分类评分值。正如其名,全连接层与常规神经网络一样,其中每个神经元都与前一层中所有神经元相连接。

    由此看来,卷积神经网络一层一层地将图像从原始像素值变换成最终的分类评分值。其中有的层含有参数,有的没有。具体说来,卷积层和全连接层(CONV/FC)对输入执行变换操作的时候,不仅会用到激活函数,还会用到很多参数(神经元的突触权值和偏差)。而ReLU层和汇聚层则是进行一个固定不变的函数操作。卷积层和全连接层中的参数会随着梯度下降被训练,这样卷积神经网络计算出的分类评分就能和训练集中的每个图像的标签吻合了。

    小结:
    • 简单案例中卷积神经网络的结构,就是一系列的层将输入数据变换为输出数据(比如分类评分)。
    • 卷积神经网络结构中有几种不同类型的层(目前最流行的有卷积层、全连接层、ReLU层和汇聚层)。
    • 每个层的输入是3D数据,然后使用一个可导的函数将其变换为3D的输出数据。
    • 有的层有参数,有的没有(卷积层和全连接层有,ReLU层和汇聚层没有)。

    案例学习

    下面是卷积神经网络领域中比较有名的几种结构:

    • LeNet: 第一个成功的卷积神经网络应用,是Yann LeCun在上世纪90年代实现的。当然,最著名还是被应用在识别数字和邮政编码等的LeNet结构。
    • AlexNet: AlexNet卷积神经网络在计算机视觉领域中受到欢迎,它由Alex Krizhevsky,Ilya Sutskever和Geoff Hinton实现。AlexNet在2012年的ImageNet ILSVRC 竞赛中夺冠,性能远远超出第二名(16%的top5错误率,第二名是26%的top5错误率)。这个网络的结构和LeNet非常类似,但是更深更大,并且使用了层叠的卷积层来获取特征(之前通常是只用一个卷积层并且在其后马上跟着一个汇聚层)。
    • ZF Net: Matthew Zeiler和Rob Fergus发明的网络在ILSVRC 2013比赛中夺冠,它被称为ZFNet(Zeiler &Fergus Net的简称)。它通过修改结构中的超参数来实现对AlexNet的改良,具体说来就是增加了中间卷积层的尺寸,让第一层的步长和滤波器尺寸更小。
    • GoogLeNet: ILSVRC 2014的胜利者是谷歌的Szeged等实现的卷积神经网络。它主要的贡献就是实现了一个奠基模块,它能够显著地减少网络中参数的数量(AlexNet中有60M,该网络中只有4M)。还有,这个论文中没有使用卷积神经网络顶部使用全连接层,而是使用了一个平均汇聚,把大量不是很重要的参数都去除掉了。GooLeNet还有几种改进的版本,最新的一个是Inception-v4。
    • VGGNet: ILSVRC 2014的第二名是Karen Simonyan和 Andrew Zisserman实现的卷积神经网络,现在称其为VGGNet。它主要的贡献是展示出网络的深度是算法优良性能的关键部分。他们最好的网络包含了16个卷积/全连接层。网络的结构非常一致,从头到尾全部使用的是3x3的卷积和2x2的汇聚。他们的预训练模型是可以在网络上获得并在Caffe中使用的。VGGNet不好的一点是它耗费更多计算资源,并且使用了更多的参数,导致更多的内存占用(140M)。其中绝大多数的参数都是来自于第一个全连接层。后来发现这些全连接层即使被去除,对于性能也没有什么影响,这样就显著降低了参数数量。
    • ResNet: 残差网络(Residual Network)是ILSVRC2015的胜利者,由何恺明等实现。它使用了特殊的跳跃链接,大量使用了批量归一化(batch normalization)。这个结构同样在最后没有使用全连接层。读者可以查看何恺明的的演讲(视频,PPT),以及一些使用Torch重现网络的实验。ResNet当前最好的卷积神经网络模型(2016年五月)。何开明等最近的工作是对原始结构做一些优化,可以看论文 Identity Mappings in Deep Residual Networks,2016年3月发表。

    把全连接层转化成卷积层(摘自CS231n课程笔记翻译:卷积神经网络笔记)

    全连接层和卷积层之间唯一的不同就是卷积层中的神经元只与输入数据中的一个局部区域连接,并且在卷积列中的神经元共享参数。然而在两类层中,神经元都是计算点积,所以它们的函数形式是一样的。因此,将此两者相互转化是可能的:

    • 对于任一个卷积层,都存在一个能实现和它一样的前向传播函数的全连接层。权重矩阵是一个巨大的矩阵,除了某些特定块(这是因为有局部连接),其余部分都是零。而在其中大部分块中,元素都是相等的(因为参数共享)。
    • 相反,任何全连接层都可以被转化为卷积层。比如,一个 的全连接层,输入数据体的尺寸是,这个全连接层可以被等效地看做一个的 卷积层。换句话说,就是将滤波器的尺寸设置为和输入数据体的尺寸一致了。因为只有一个单独的深度列覆盖并滑过输入数据体,所以输出将变成 ,这个结果就和使用初始的那个全连接层一样了。

    全连接层转化为卷积层:在两种变换中,将全连接层转化为卷积层在实际运用中更加有用。假设一个卷积神经网络的输入是224x224x3的图像,一系列的卷积层和汇聚层将图像数据变为尺寸为7x7x512的激活数据体(在AlexNet中就是这样,通过使用5个汇聚层来对输入数据进行空间上的降采样,每次尺寸下降一半,所以最终空间尺寸为224/2/2/2/2/2=7)。从这里可以看到,AlexNet使用了两个尺寸为4096的全连接层,最后一个有1000个神经元的全连接层用于计算分类评分。我们可以将这3个全连接层中的任意一个转化为卷积层:

    • 针对第一个连接区域是[7x7x512]的全连接层,令其滤波器尺寸为 ,这样输出数据体就为[1x1x4096]了。
    • 针对第二个全连接层,令其滤波器尺寸为 ,这样输出数据体为[1x1x4096]。
    • 对最后一个全连接层也做类似的,令其 ,最终输出为[1x1x1000]

    实际操作中,每次这样的变换都需要把全连接层的权重W重塑成卷积层的滤波器。那么这样的转化有什么作用呢?
    它在下面的情况下可以更高效:让卷积网络在一张更大的输入图片上滑动(译者注:即把一张更大的图片的不同区域都分别带入到卷积网络,得到每个区域的得分),得到多个输出,这样的转化可以让我们在单个向前传播的过程中完成上述的操作。

    举个例子,如果我们想让224x224尺寸的浮窗,以步长为32在384x384的图片上滑动,把每个经停的位置都带入卷积网络,最后得到6x6个位置的类别得分。上述的把全连接层转换成卷积层的做法会更简便。如果224x224的输入图片经过卷积层和汇聚层之后得到了[7x7x512]的数组,那么,384x384的大图片直接经过同样的卷积层和汇聚层之后会得到[12x12x512]的数组(因为途径5个汇聚层,尺寸变为384/2/2/2/2/2 = 12)。然后再经过上面由3个全连接层转化得到的3个卷积层,最终得到[6x6x1000]的输出(因为(12 - 7)/1 + 1 = 6)。这个结果正是浮窗在原图经停的6x6个位置的得分!(译者注:这一段的翻译与原文不同,经过了译者较多的修改,使更容易理解)

    面对384x384的图像,让(含全连接层)的初始卷积神经网络以32像素的步长独立对图像中的224x224块进行多次评价,其效果和使用把全连接层变换为卷积层后的卷积神经网络进行一次前向传播是一样的。

    自然,相较于使用被转化前的原始卷积神经网络对所有36个位置进行迭代计算,使用转化后的卷积神经网络进行一次前向传播计算要高效得多,因为36次计算都在共享计算资源。这一技巧在实践中经常使用,一次来获得更好的结果。比如,通常将一张图像尺寸变得更大,然后使用变换后的卷积神经网络来对空间上很多不同位置进行评价得到
    分类评分,然后在求这些分值的平均值。

    最后,如果我们想用步长小于32的浮窗怎么办?用多次的向前传播就可以解决。比如我们想用步长为16的浮窗。那么先使用原图在转化后的卷积网络执行向前传播,然后分别沿宽度,沿高度,最后同时沿宽度和高度,把原始图片分别平移16个像素,然后把这些平移之后的图分别带入卷积网络。(译者注:这一段的翻译与原文不同,经过了译者较多的修改,使更容易理解)

    参考台湾大学李宏毅老师的机器学习课程
    参考由杜客和猴子翻译,堃堃和李艺颖进行校对修改的cs231n笔记。来自网址:https://zhuanlan.zhihu.com/p/22038289
    图片分别平移16个像素,然后把这些平移之后的图分别带入卷积网络。(译者注:这一段的翻译与原文不同,经过了译者较多的修改,使更容易理解)
    
    
    

    参考台湾大学李宏毅老师的机器学习课程
    参考由杜客和猴子翻译,堃堃和李艺颖进行校对修改的cs231n笔记。来自网址:https://zhuanlan.zhihu.com/p/22038289

    2021-6-15
    
    更多相关内容
  • 神经网络——最易懂最清晰的一篇文章

    万次阅读 多人点赞 2018-08-24 15:43:20
    神经网络是一门重要的机器学习技术。它是目前最为火热的研究方向--深度学习的基础。学习神经网络不仅可以让你掌握一门强大的机器学习方法,同时也可以更好地帮助你理解深度学习技术。  本文以一种简单的,循序的...

    神经网络是一门重要的机器学习技术。它是目前最为火热的研究方向--深度学习的基础。学习神经网络不仅可以让你掌握一门强大的机器学习方法,同时也可以更好地帮助你理解深度学习技术。

      本文以一种简单的,循序的方式讲解神经网络。适合对神经网络了解不多的同学。本文对阅读没有一定的前提要求,但是懂一些机器学习基础会更好地帮助理解本文。

      神经网络是一种模拟人脑的神经网络以期能够实现类人工智能的机器学习技术。人脑中的神经网络是一个非常复杂的组织。成人的大脑中估计有1000亿个神经元之多。

    图1 人脑神经网络

     

      那么机器学习中的神经网络是如何实现这种模拟的,并且达到一个惊人的良好效果的?通过本文,你可以了解到这些问题的答案,同时还能知道神经网络的历史,以及如何较好地学习它。

      由于本文较长,为方便读者,以下是本文的目录:

      一.前言

      二.神经元

      三.单层神经网络(感知器)

      四.两层神经网络(多层感知器)

      五.多层神经网络(深度学习)

      六.回顾

      七.展望

      八.总结

      九.后记

      十.备注

     

    一. 前言

      让我们来看一个经典的神经网络。这是一个包含三个层次的神经网络。红色的是输入层,绿色的是输出层,紫色的是中间层(也叫隐藏层)。输入层有3个输入单元,隐藏层有4个单元,输出层有2个单元。后文中,我们统一使用这种颜色来表达神经网络的结构。

    图2 神经网络结构图

     

      在开始介绍前,有一些知识可以先记在心里:

    1. 设计一个神经网络时,输入层与输出层的节点数往往是固定的,中间层则可以自由指定;
    2. 神经网络结构图中的拓扑与箭头代表着预测过程时数据的流向,跟训练时的数据流有一定的区别;
    3. 结构图里的关键不是圆圈(代表“神经元”),而是连接线(代表“神经元”之间的连接)。每个连接线对应一个不同的权重(其值称为权值),这是需要训练得到的。  

      除了从左到右的形式表达的结构图,还有一种常见的表达形式是从下到上来表示一个神经网络。这时候,输入层在图的最下方。输出层则在图的最上方,如下图:

    图3 从下到上的神经网络结构图 

     

      从左到右的表达形式以Andrew Ng和LeCun的文献使用较多,Caffe里使用的则是从下到上的表达。在本文中使用Andrew Ng代表的从左到右的表达形式。

      下面从简单的神经元开始说起,一步一步介绍神经网络复杂结构的形成。

     

    二. 神经元

      1.引子 

      对于神经元的研究由来已久,1904年生物学家就已经知晓了神经元的组成结构。

      一个神经元通常具有多个树突,主要用来接受传入信息;而轴突只有一条,轴突尾端有许多轴突末梢可以给其他多个神经元传递信息。轴突末梢跟其他神经元的树突产生连接,从而传递信号。这个连接的位置在生物学上叫做“突触”。

      人脑中的神经元形状可以用下图做简单的说明:

    图4 神经元

     

       1943年,心理学家McCulloch和数学家Pitts参考了生物神经元的结构,发表了抽象的神经元模型MP。在下文中,我们会具体介绍神经元模型。

       

    图5 Warren McCulloch(左)和 Walter Pitts(右)  

      2.结构 

      神经元模型是一个包含输入,输出与计算功能的模型。输入可以类比为神经元的树突,而输出可以类比为神经元的轴突,计算则可以类比为细胞核。

      下图是一个典型的神经元模型:包含有3个输入,1个输出,以及2个计算功能。

      注意中间的箭头线。这些线称为“连接”。每个上有一个“权值”。

    图6 神经元模型 

     

      连接是神经元中最重要的东西。每一个连接上都有一个权重。

      一个神经网络的训练算法就是让权重的值调整到最佳,以使得整个网络的预测效果最好。

      我们使用a来表示输入,用w来表示权值。一个表示连接的有向箭头可以这样理解:在初端,传递的信号大小仍然是a,端中间有加权参数w,经过这个加权后的信号会变成a*w,因此在连接的末端,信号的大小就变成了a*w。

      在其他绘图模型里,有向箭头可能表示的是值的不变传递。而在神经元模型里,每个有向箭头表示的是值的加权传递。

    图7 连接(connection)  

     

      如果我们将神经元图中的所有变量用符号表示,并且写出输出的计算公式的话,就是下图。

    图8 神经元计算  

     

      可见z是在输入和权值的线性加权和叠加了一个函数g的值。在MP模型里,函数g是sgn函数,也就是取符号函数。这个函数当输入大于0时,输出1,否则输出0。

      下面对神经元模型的图进行一些扩展。首先将sum函数与sgn函数合并到一个圆圈里,代表神经元的内部计算。其次,把输入a与输出z写到连接线的左上方,便于后面画复杂的网络。最后说明,一个神经元可以引出多个代表输出的有向箭头,但值都是一样的。

      神经元可以看作一个计算与存储单元。计算是神经元对其的输入进行计算功能。存储是神经元会暂存计算结果,并传递到下一层。

    图9 神经元扩展 

     

      当我们用“神经元”组成网络以后,描述网络中的某个“神经元”时,我们更多地会用“单元”(unit)来指代。同时由于神经网络的表现形式是一个有向图,有时也会用“节点”(node)来表达同样的意思。 

      3.效果 

      神经元模型的使用可以这样理解:

      我们有一个数据,称之为样本。样本有四个属性,其中三个属性已知,一个属性未知。我们需要做的就是通过三个已知属性预测未知属性。

      具体办法就是使用神经元的公式进行计算。三个已知属性的值是a1,a2,a3,未知属性的值是z。z可以通过公式计算出来。

      这里,已知的属性称之为特征,未知的属性称之为目标。假设特征与目标之间确实是线性关系,并且我们已经得到表示这个关系的权值w1,w2,w3。那么,我们就可以通过神经元模型预测新样本的目标。

      4.影响

      1943年发布的MP模型,虽然简单,但已经建立了神经网络大厦的地基。但是,MP模型中,权重的值都是预先设置的,因此不能学习。

      1949年心理学家Hebb提出了Hebb学习率,认为人脑神经细胞的突触(也就是连接)上的强度上可以变化的。于是计算科学家们开始考虑用调整权值的方法来让机器学习。这为后面的学习算法奠定了基础。

    图10 Donald Olding Hebb 

     

      尽管神经元模型与Hebb学习律都已诞生,但限于当时的计算机能力,直到接近10年后,第一个真正意义的神经网络才诞生。

     

    三. 单层神经网络(感知器)

      1.引子  

      1958年,计算科学家Rosenblatt提出了由两层神经元组成的神经网络。他给它起了一个名字--“感知器”(Perceptron)(有的文献翻译成“感知机”,下文统一用“感知器”来指代)。

      感知器是当时首个可以学习的人工神经网络。Rosenblatt现场演示了其学习识别简单图像的过程,在当时的社会引起了轰动。

      人们认为已经发现了智能的奥秘,许多学者和科研机构纷纷投入到神经网络的研究中。美国军方大力资助了神经网络的研究,并认为神经网络比“原子弹工程”更重要。这段时间直到1969年才结束,这个时期可以看作神经网络的第一次高潮。

    图11 Rosenblat与感知器 

      2.结构

      下面来说明感知器模型。

      在原来MP模型的“输入”位置添加神经元节点,标志其为“输入单元”。其余不变,于是我们就有了下图:从本图开始,我们将权值w1, w2, w3写到“连接线”的中间。

    图12 单层神经网络 

     

      在“感知器”中,有两个层次。分别是输入层和输出层。输入层里的“输入单元”只负责传输数据,不做计算。输出层里的“输出单元”则需要对前面一层的输入进行计算。

      我们把需要计算的层次称之为“计算层”,并把拥有一个计算层的网络称之为“单层神经网络”。有一些文献会按照网络拥有的层数来命名,例如把“感知器”称为两层神经网络。但在本文里,我们根据计算层的数量来命名。

      假如我们要预测的目标不再是一个值,而是一个向量,例如[2,3]。那么可以在输出层再增加一个“输出单元”。

      下图显示了带有两个输出单元的单层神经网络,其中输出单元z1的计算公式如下图。

    图13 单层神经网络(Z1)

     

      可以看到,z1的计算跟原先的z并没有区别。

      我们已知一个神经元的输出可以向多个神经元传递,因此z2的计算公式如下图。

    图14 单层神经网络(Z2)

     

      可以看到,z2的计算中除了三个新的权值:w4,w5,w6以外,其他与z1是一样的。

      整个网络的输出如下图。

    图15 单层神经网络(Z1和Z2)

     

      目前的表达公式有一点不让人满意的就是:w4,w5,w6是后来加的,很难表现出跟原先的w1,w2,w3的关系。

      因此我们改用二维的下标,用wx,y来表达一个权值。下标中的x代表后一层神经元的序号,而y代表前一层神经元的序号(序号的顺序从上到下)。

      例如,w1,2代表后一层的第1个神经元与前一层的第2个神经元的连接的权值(这种标记方式参照了Andrew Ng的课件)。根据以上方法标记,我们有了下图。

    图16 单层神经网络(扩展)

     

      如果我们仔细看输出的计算公式,会发现这两个公式就是线性代数方程组。因此可以用矩阵乘法来表达这两个公式。

      例如,输入的变量是[a1,a2,a3]T(代表由a1,a2,a3组成的列向量),用向量a来表示。方程的左边是[z1,z2]T,用向量z来表示。

      系数则是矩阵W(2行3列的矩阵,排列形式与公式中的一样)。

      于是,输出公式可以改写成:

    g(W * a) = z;

     

      这个公式就是神经网络中从前一层计算后一层的矩阵运算。

      3.效果

      与神经元模型不同,感知器中的权值是通过训练得到的。因此,根据以前的知识我们知道,感知器类似一个逻辑回归模型,可以做线性分类任务。

      我们可以用决策分界来形象的表达分类的效果。决策分界就是在二维的数据平面中划出一条直线,当数据的维度是3维的时候,就是划出一个平面,当数据的维度是n维时,就是划出一个n-1维的超平面。

      下图显示了在二维平面中划出决策分界的效果,也就是感知器的分类效果。

    图17 单层神经网络(决策分界)

      

      4.影响 

      感知器只能做简单的线性分类任务。但是当时的人们热情太过于高涨,并没有人清醒的认识到这点。于是,当人工智能领域的巨擘Minsky指出这点时,事态就发生了变化。

      Minsky在1969年出版了一本叫《Perceptron》的书,里面用详细的数学证明了感知器的弱点,尤其是感知器对XOR(异或)这样的简单分类任务都无法解决。

      Minsky认为,如果将计算层增加到两层,计算量则过大,而且没有有效的学习算法。所以,他认为研究更深层的网络是没有价值的。(本文成文后一个月,即2016年1月,Minsky在美国去世。谨在本文中纪念这位著名的计算机研究专家与大拿。)

       

    图18 Marvin Minsky

      

      由于Minsky的巨大影响力以及书中呈现的悲观态度,让很多学者和实验室纷纷放弃了神经网络的研究。神经网络的研究陷入了冰河期。这个时期又被称为“AI winter”。

      接近10年以后,对于两层神经网络的研究才带来神经网络的复苏。

     

    四. 两层神经网络(多层感知器)

      1.引子

      两层神经网络是本文的重点,因为正是在这时候,神经网络开始了大范围的推广与使用。

      Minsky说过单层神经网络无法解决异或问题。但是当增加一个计算层以后,两层神经网络不仅可以解决异或问题,而且具有非常好的非线性分类效果。不过两层神经网络的计算是一个问题,没有一个较好的解法。

      1986年,Rumelhar和Hinton等人提出了反向传播(Backpropagation,BP)算法,解决了两层神经网络所需要的复杂计算量问题,从而带动了业界使用两层神经网络研究的热潮。目前,大量的教授神经网络的教材,都是重点介绍两层(带一个隐藏层)神经网络的内容。 

      这时候的Hinton还很年轻,30年以后,正是他重新定义了神经网络,带来了神经网络复苏的又一春。

            

    图19 David Rumelhart(左)以及 Geoffery Hinton(右)

     

      2.结构

      两层神经网络除了包含一个输入层,一个输出层以外,还增加了一个中间层。此时,中间层和输出层都是计算层。我们扩展上节的单层神经网络,在右边新加一个层次(只含有一个节点)。

      现在,我们的权值矩阵增加到了两个,我们用上标来区分不同层次之间的变量。

      例如ax(y)代表第y层的第x个节点。z1,z2变成了a1(2),a2(2)。下图给出了a1(2),a2(2)的计算公式。

    图20 两层神经网络(中间层计算)

     

      计算最终输出z的方式是利用了中间层的a1(2),a2(2)和第二个权值矩阵计算得到的,如下图。

    图21 两层神经网络(输出层计算)

     

      假设我们的预测目标是一个向量,那么与前面类似,只需要在“输出层”再增加节点即可。

      我们使用向量和矩阵来表示层次中的变量。a(1),a(2),z是网络中传输的向量数据。W(1)和W(2)是网络的矩阵参数。如下图。

    图22 两层神经网络(向量形式)

     

      使用矩阵运算来表达整个计算公式的话如下:

      g(W(1) * a(1)) = a(2); 

    g(W(2) * a(2)) = z;

     

      由此可见,使用矩阵运算来表达是很简洁的,而且也不会受到节点数增多的影响(无论有多少节点参与运算,乘法两端都只有一个变量)。因此神经网络的教程中大量使用矩阵运算来描述。

      需要说明的是,至今为止,我们对神经网络的结构图的讨论中都没有提到偏置节点(bias unit)。事实上,这些节点是默认存在的。它本质上是一个只含有存储功能,且存储值永远为1的单元。在神经网络的每个层次中,除了输出层以外,都会含有这样一个偏置单元。正如线性回归模型与逻辑回归模型中的一样。

      偏置单元与后一层的所有节点都有连接,我们设这些参数值为向量b,称之为偏置。如下图。

    图23 两层神经网络(考虑偏置节点)

     

      可以看出,偏置节点很好认,因为其没有输入(前一层中没有箭头指向它)。有些神经网络的结构图中会把偏置节点明显画出来,有些不会。一般情况下,我们都不会明确画出偏置节点。 

      在考虑了偏置以后的一个神经网络的矩阵运算如下:

      g(W(1) * a(1) + b(1)) = a(2); 

    g(W(2) * a(2) + b(2)) = z;

     

      需要说明的是,在两层神经网络中,我们不再使用sgn函数作为函数g,而是使用平滑函数sigmoid作为函数g。我们把函数g也称作激活函数(active function)。

      事实上,神经网络的本质就是通过参数与激活函数来拟合特征与目标之间的真实函数关系。初学者可能认为画神经网络的结构图是为了在程序中实现这些圆圈与线,但在一个神经网络的程序中,既没有“线”这个对象,也没有“单元”这个对象。实现一个神经网络最需要的是线性代数库。

      3.效果

      与单层神经网络不同。理论证明,两层神经网络可以无限逼近任意连续函数。

      这是什么意思呢?也就是说,面对复杂的非线性分类任务,两层(带一个隐藏层)神经网络可以分类的很好。

      下面就是一个例子(此两图来自colah的博客),红色的线与蓝色的线代表数据。而红色区域和蓝色区域代表由神经网络划开的区域,两者的分界线就是决策分界。

    图24 两层神经网络(决策分界)

      

      可以看到,这个两层神经网络的决策分界是非常平滑的曲线,而且分类的很好。有趣的是,前面已经学到过,单层网络只能做线性分类任务。而两层神经网络中的后一层也是线性分类层,应该只能做线性分类任务。为什么两个线性分类任务结合就可以做非线性分类任务?

      我们可以把输出层的决策分界单独拿出来看一下。就是下图。

    图25 两层神经网络(空间变换)

     

      可以看到,输出层的决策分界仍然是直线。关键就是,从输入层到隐藏层时,数据发生了空间变换。也就是说,两层神经网络中,隐藏层对原始的数据进行了一个空间变换,使其可以被线性分类,然后输出层的决策分界划出了一个线性分类分界线,对其进行分类。

      这样就导出了两层神经网络可以做非线性分类的关键--隐藏层。联想到我们一开始推导出的矩阵公式,我们知道,矩阵和向量相乘,本质上就是对向量的坐标空间进行一个变换。因此,隐藏层的参数矩阵的作用就是使得数据的原始坐标空间从线性不可分,转换成了线性可分。

      两层神经网络通过两层的线性模型模拟了数据内真实的非线性函数。因此,多层的神经网络的本质就是复杂函数拟合。

      下面来讨论一下隐藏层的节点数设计。在设计一个神经网络时,输入层的节点数需要与特征的维度匹配,输出层的节点数要与目标的维度匹配。而中间层的节点数,却是由设计者指定的。因此,“自由”把握在设计者的手中。但是,节点数设置的多少,却会影响到整个模型的效果。如何决定这个自由层的节点数呢?目前业界没有完善的理论来指导这个决策。一般是根据经验来设置。较好的方法就是预先设定几个可选值,通过切换这几个值来看整个模型的预测效果,选择效果最好的值作为最终选择。这种方法又叫做Grid Search(网格搜索)。

      了解了两层神经网络的结构以后,我们就可以看懂其它类似的结构图。例如EasyPR字符识别网络架构(下图)。

    图26 EasyPR字符识别网络

     

      EasyPR使用了字符的图像去进行字符文字的识别。输入是120维的向量。输出是要预测的文字类别,共有65类。根据实验,我们测试了一些隐藏层数目,发现当值为40时,整个网络在测试集上的效果较好,因此选择网络的最终结构就是120,40,65。

      4.训练

      下面简单介绍一下两层神经网络的训练。

      在Rosenblat提出的感知器模型中,模型中的参数可以被训练,但是使用的方法较为简单,并没有使用目前机器学习中通用的方法,这导致其扩展性与适用性非常有限。从两层神经网络开始,神经网络的研究人员开始使用机器学习相关的技术进行神经网络的训练。例如用大量的数据(1000-10000左右),使用算法进行优化等等,从而使得模型训练可以获得性能与数据利用上的双重优势。

      机器学习模型训练的目的,就是使得参数尽可能的与真实的模型逼近。具体做法是这样的。首先给所有参数赋上随机值。我们使用这些随机生成的参数值,来预测训练数据中的样本。样本的预测目标为yp,真实目标为y。那么,定义一个值loss,计算公式如下。

    loss = (yp - y)2

     

      这个值称之为损失(loss),我们的目标就是使对所有训练数据的损失和尽可能的小。

      如果将先前的神经网络预测的矩阵公式带入到yp中(因为有z=yp),那么我们可以把损失写为关于参数(parameter)的函数,这个函数称之为损失函数(loss function)。下面的问题就是求:如何优化参数,能够让损失函数的值最小。

      此时这个问题就被转化为一个优化问题。一个常用方法就是高等数学中的求导,但是这里的问题由于参数不止一个,求导后计算导数等于0的运算量很大,所以一般来说解决这个优化问题使用的是梯度下降算法。梯度下降算法每次计算参数在当前的梯度,然后让参数向着梯度的反方向前进一段距离,不断重复,直到梯度接近零时截止。一般这个时候,所有的参数恰好达到使损失函数达到一个最低值的状态。

      在神经网络模型中,由于结构复杂,每次计算梯度的代价很大。因此还需要使用反向传播算法。反向传播算法是利用了神经网络的结构进行的计算。不一次计算所有参数的梯度,而是从后往前。首先计算输出层的梯度,然后是第二个参数矩阵的梯度,接着是中间层的梯度,再然后是第一个参数矩阵的梯度,最后是输入层的梯度。计算结束以后,所要的两个参数矩阵的梯度就都有了。

      反向传播算法可以直观的理解为下图。梯度的计算从后往前,一层层反向传播。前缀E代表着相对导数的意思。

    图27 反向传播算法

     

      反向传播算法的启示是数学中的链式法则。在此需要说明的是,尽管早期神经网络的研究人员努力从生物学中得到启发,但从BP算法开始,研究者们更多地从数学上寻求问题的最优解。不再盲目模拟人脑网络是神经网络研究走向成熟的标志。正如科学家们可以从鸟类的飞行中得到启发,但没有必要一定要完全模拟鸟类的飞行方式,也能制造可以飞天的飞机。

      优化问题只是训练中的一个部分。机器学习问题之所以称为学习问题,而不是优化问题,就是因为它不仅要求数据在训练集上求得一个较小的误差,在测试集上也要表现好。因为模型最终是要部署到没有见过训练数据的真实场景。提升模型在测试集上的预测效果的主题叫做泛化(generalization),相关方法被称作正则化(regularization)。神经网络中常用的泛化技术有权重衰减等。

      5.影响

      两层神经网络在多个地方的应用说明了其效用与价值。10年前困扰神经网络界的异或问题被轻松解决。神经网络在这个时候,已经可以发力于语音识别,图像识别,自动驾驶等多个领域。

      历史总是惊人的相似,神经网络的学者们再次登上了《纽约时报》的专访。人们认为神经网络可以解决许多问题。就连娱乐界都开始受到了影响,当年的《终结者》电影中的阿诺都赶时髦地说一句:我的CPU是一个神经网络处理器,一个会学习的计算机。

      但是神经网络仍然存在若干的问题:尽管使用了BP算法,一次神经网络的训练仍然耗时太久,而且困扰训练优化的一个问题就是局部最优解问题,这使得神经网络的优化较为困难。同时,隐藏层的节点数需要调参,这使得使用不太方便,工程和研究人员对此多有抱怨。

      90年代中期,由Vapnik等人发明的SVM(Support Vector Machines,支持向量机)算法诞生,很快就在若干个方面体现出了对比神经网络的优势:无需调参;高效;全局最优解。基于以上种种理由,SVM迅速打败了神经网络算法成为主流。

    图28 Vladimir Vapnik

     

      神经网络的研究再次陷入了冰河期。当时,只要你的论文中包含神经网络相关的字眼,非常容易被会议和期刊拒收,研究界那时对神经网络的不待见可想而知。

     

    五. 多层神经网络(深度学习)

      1.引子  

      在被人摒弃的10年中,有几个学者仍然在坚持研究。这其中的棋手就是加拿大多伦多大学的Geoffery Hinton教授。

      2006年,Hinton在《Science》和相关期刊上发表了论文,首次提出了“深度信念网络”的概念。与传统的训练方式不同,“深度信念网络”有一个“预训练”(pre-training)的过程,这可以方便的让神经网络中的权值找到一个接近最优解的值,之后再使用“微调”(fine-tuning)技术来对整个网络进行优化训练。这两个技术的运用大幅度减少了训练多层神经网络的时间。他给多层神经网络相关的学习方法赋予了一个新名词--“深度学习”。

       很快,深度学习在语音识别领域暂露头角。接着,2012年,深度学习技术又在图像识别领域大展拳脚。Hinton与他的学生在ImageNet竞赛中,用多层的卷积神经网络成功地对包含一千类别的一百万张图片进行了训练,取得了分类错误率15%的好成绩,这个成绩比第二名高了近11个百分点,充分证明了多层神经网络识别效果的优越性。

      在这之后,关于深度神经网络的研究与应用不断涌现。

    图29 Geoffery Hinton 

     

      由于篇幅原因,本文不介绍CNN(Conventional Neural Network,卷积神经网络)与RNN(Recurrent Neural Network,递归神经网络)的架构,下面我们只讨论普通的多层神经网络。

      2.结构

      我们延续两层神经网络的方式来设计一个多层神经网络。

      在两层神经网络的输出层后面,继续添加层次。原来的输出层变成中间层,新加的层次成为新的输出层。所以可以得到下图。

    图30 多层神经网络

     

      依照这样的方式不断添加,我们可以得到更多层的多层神经网络。公式推导的话其实跟两层神经网络类似,使用矩阵运算的话就仅仅是加一个公式而已。

      在已知输入a(1),参数W(1),W(2),W(3)的情况下,输出z的推导公式如下:

         g(W(1) * a(1)) = a(2); 

        g(W(2) * a(2)) = a(3);

    g(W(3) * a(3)) = z;

     

      多层神经网络中,输出也是按照一层一层的方式来计算。从最外面的层开始,算出所有单元的值以后,再继续计算更深一层。只有当前层所有单元的值都计算完毕以后,才会算下一层。有点像计算向前不断推进的感觉。所以这个过程叫做“正向传播”。

      下面讨论一下多层神经网络中的参数。

      首先我们看第一张图,可以看出W(1)中有6个参数,W(2)中有4个参数,W(3)中有6个参数,所以整个神经网络中的参数有16个(这里我们不考虑偏置节点,下同)。

    图31 多层神经网络(较少参数)

     

      假设我们将中间层的节点数做一下调整。第一个中间层改为3个单元,第二个中间层改为4个单元。

      经过调整以后,整个网络的参数变成了33个。

    图32 多层神经网络(较多参数)

     

      虽然层数保持不变,但是第二个神经网络的参数数量却是第一个神经网络的接近两倍之多,从而带来了更好的表示(represention)能力。表示能力是多层神经网络的一个重要性质,下面会做介绍。

      在参数一致的情况下,我们也可以获得一个“更深”的网络。

    图33 多层神经网络(更深的层次)

     

      上图的网络中,虽然参数数量仍然是33,但却有4个中间层,是原来层数的接近两倍。这意味着一样的参数数量,可以用更深的层次去表达。

      3.效果

      与两层层神经网络不同。多层神经网络中的层数增加了很多。

      增加更多的层次有什么好处?更深入的表示特征,以及更强的函数模拟能力。

      更深入的表示特征可以这样理解,随着网络的层数增加,每一层对于前一层次的抽象表示更深入。在神经网络中,每一层神经元学习到的是前一层神经元值的更抽象的表示。例如第一个隐藏层学习到的是“边缘”的特征,第二个隐藏层学习到的是由“边缘”组成的“形状”的特征,第三个隐藏层学习到的是由“形状”组成的“图案”的特征,最后的隐藏层学习到的是由“图案”组成的“目标”的特征。通过抽取更抽象的特征来对事物进行区分,从而获得更好的区分与分类能力。

      关于逐层特征学习的例子,可以参考下图。

    图34 多层神经网络(特征学习)

     

      更强的函数模拟能力是由于随着层数的增加,整个网络的参数就越多。而神经网络其实本质就是模拟特征与目标之间的真实关系函数的方法,更多的参数意味着其模拟的函数可以更加的复杂,可以有更多的容量(capcity)去拟合真正的关系。

      通过研究发现,在参数数量一样的情况下,更深的网络往往具有比浅层的网络更好的识别效率。这点也在ImageNet的多次大赛中得到了证实。从2012年起,每年获得ImageNet冠军的深度神经网络的层数逐年增加,2015年最好的方法GoogleNet是一个多达22层的神经网络。

      在最新一届的ImageNet大赛上,目前拿到最好成绩的MSRA团队的方法使用的更是一个深达152层的网络!关于这个方法更多的信息有兴趣的可以查阅ImageNet网站。

      4.训练

      在单层神经网络时,我们使用的激活函数是sgn函数。到了两层神经网络时,我们使用的最多的是sigmoid函数。而到了多层神经网络时,通过一系列的研究发现,ReLU函数在训练多层神经网络时,更容易收敛,并且预测性能更好。因此,目前在深度学习中,最流行的非线性函数是ReLU函数。ReLU函数不是传统的非线性函数,而是分段线性函数。其表达式非常简单,就是y=max(x,0)。简而言之,在x大于0,输出就是输入,而在x小于0时,输出就保持为0。这种函数的设计启发来自于生物神经元对于激励的线性响应,以及当低于某个阈值后就不再响应的模拟。

      在多层神经网络中,训练的主题仍然是优化和泛化。当使用足够强的计算芯片(例如GPU图形加速卡)时,梯度下降算法以及反向传播算法在多层神经网络中的训练中仍然工作的很好。目前学术界主要的研究既在于开发新的算法,也在于对这两个算法进行不断的优化,例如,增加了一种带动量因子(momentum)的梯度下降算法。 

      在深度学习中,泛化技术变的比以往更加的重要。这主要是因为神经网络的层数增加了,参数也增加了,表示能力大幅度增强,很容易出现过拟合现象。因此正则化技术就显得十分重要。目前,Dropout技术,以及数据扩容(Data-Augmentation)技术是目前使用的最多的正则化技术。

      5.影响

      目前,深度神经网络在人工智能界占据统治地位。但凡有关人工智能的产业报道,必然离不开深度学习。神经网络界当下的四位引领者除了前文所说的Ng,Hinton以外,还有CNN的发明人Yann Lecun,以及《Deep Learning》的作者Bengio。

      前段时间一直对人工智能持谨慎态度的马斯克,搞了一个OpenAI项目,邀请Bengio作为高级顾问。马斯克认为,人工智能技术不应该掌握在大公司如Google,Facebook的手里,更应该作为一种开放技术,让所有人都可以参与研究。马斯克的这种精神值得让人敬佩。

       

    图35 Yann LeCun(左)和 Yoshua Bengio(右)

     

      多层神经网络的研究仍在进行中。现在最为火热的研究技术包括RNN,LSTM等,研究方向则是图像理解方面。图像理解技术是给计算机一幅图片,让它用语言来表达这幅图片的意思。ImageNet竞赛也在不断召开,有更多的方法涌现出来,刷新以往的正确率。

     

    六. 回顾

      1.影响  

      我们回顾一下神经网络发展的历程。神经网络的发展历史曲折荡漾,既有被人捧上天的时刻,也有摔落在街头无人问津的时段,中间经历了数次大起大落。

      从单层神经网络(感知器)开始,到包含一个隐藏层的两层神经网络,再到多层的深度神经网络,一共有三次兴起过程。详见下图。

    图36 三起三落的神经网络

     

      上图中的顶点与谷底可以看作神经网络发展的高峰与低谷。图中的横轴是时间,以年为单位。纵轴是一个神经网络影响力的示意表示。如果把1949年Hebb模型提出到1958年的感知机诞生这个10年视为落下(没有兴起)的话,那么神经网络算是经历了“三起三落”这样一个过程,跟“小平”同志类似。俗话说,天将降大任于斯人也,必先苦其心志,劳其筋骨。经历过如此多波折的神经网络能够在现阶段取得成功也可以被看做是磨砺的积累吧。

      历史最大的好处是可以给现在做参考。科学的研究呈现螺旋形上升的过程,不可能一帆风顺。同时,这也给现在过分热衷深度学习与人工智能的人敲响警钟,因为这不是第一次人们因为神经网络而疯狂了。1958年到1969年,以及1985年到1995,这两个十年间人们对于神经网络以及人工智能的期待并不现在低,可结果如何大家也能看的很清楚。

      因此,冷静才是对待目前深度学习热潮的最好办法。如果因为深度学习火热,或者可以有“钱景”就一窝蜂的涌入,那么最终的受害人只能是自己。神经网络界已经两次有被人们捧上天了的境况,相信也对于捧得越高,摔得越惨这句话深有体会。因此,神经网络界的学者也必须给这股热潮浇上一盆水,不要让媒体以及投资家们过分的高看这门技术。很有可能,三十年河东,三十年河西,在几年后,神经网络就再次陷入谷底。根据上图的历史曲线图,这是很有可能的。

      2.效果  

      下面说一下神经网络为什么能这么火热?简而言之,就是其学习效果的强大。随着神经网络的发展,其表示性能越来越强。

      从单层神经网络,到两层神经网络,再到多层神经网络,下图说明了,随着网络层数的增加,以及激活函数的调整,神经网络所能拟合的决策分界平面的能力。

    图37 表示能力不断增强

     

      可以看出,随着层数增加,其非线性分界拟合能力不断增强。图中的分界线并不代表真实训练出的效果,更多的是示意效果。

      神经网络的研究与应用之所以能够不断地火热发展下去,与其强大的函数拟合能力是分不开关系的。

      3.外因  

      当然,光有强大的内在能力,并不一定能成功。一个成功的技术与方法,不仅需要内因的作用,还需要时势与环境的配合。神经网络的发展背后的外在原因可以被总结为:更强的计算性能,更多的数据,以及更好的训练方法。只有满足这些条件时,神经网络的函数拟合能力才能得已体现,见下图。

    图38 发展的外在原因

     

      之所以在单层神经网络年代,Rosenblat无法制作一个双层分类器,就在于当时的计算性能不足,Minsky也以此来打压神经网络。但是Minsky没有料到,仅仅10年以后,计算机CPU的快速发展已经使得我们可以做两层神经网络的训练,并且还有快速的学习算法BP。

      但是在两层神经网络快速流行的年代。更高层的神经网络由于计算性能的问题,以及一些计算方法的问题,其优势无法得到体现。直到2012年,研究人员发现,用于高性能计算的图形加速卡(GPU)可以极佳地匹配神经网络训练所需要的要求:高并行性,高存储,没有太多的控制需求,配合预训练等算法,神经网络才得以大放光彩。

      互联网时代,大量的数据被收集整理,更好的训练方法不断被发现。所有这一切都满足了多层神经网络发挥能力的条件。

      “时势造英雄”,正如Hinton在2006年的论文里说道的

      “... provided that computers were fast enough, data sets were big enough, and the initial weights were close enough to a good solution. All three conditions are now satisfied.”,

     

      外在条件的满足也是神经网络从神经元得以发展到目前的深度神经网络的重要因素。

      除此以外,一门技术的发扬没有“伯乐”也是不行的。在神经网络漫长的历史中,正是由于许多研究人员的锲而不舍,不断钻研,才能有了现在的成就。前期的Rosenblat,Rumelhart没有见证到神经网络如今的流行与地位。但是在那个时代,他们为神经网络的发展所打下的基础,却会永远流传下去,不会退色。

     

    七. 展望

      1.量子计算

      回到我们对神经网络历史的讨论,根据历史趋势图来看,神经网络以及深度学习会不会像以往一样再次陷入谷底?作者认为,这个过程可能取决于量子计算机的发展。

      根据一些最近的研究发现,人脑内部进行的计算可能是类似于量子计算形态的东西。而且目前已知的最大神经网络跟人脑的神经元数量相比,仍然显得非常小,仅不及1%左右。所以未来真正想实现人脑神经网络的模拟,可能需要借助量子计算的强大计算能力。

      各大研究组也已经认识到了量子计算的重要性。谷歌就在开展量子计算机D-wave的研究,希望用量子计算来进行机器学习,并且在前段时间有了突破性的进展。国内方面,阿里和中科院合作成立了量子计算实验室,意图进行量子计算的研究。

      如果量子计算发展不力,仍然需要数十年才能使我们的计算能力得以突飞猛进的发展,那么缺少了强大计算能力的神经网络可能会无法一帆风顺的发展下去。这种情况可以类比为80-90年时期神经网络因为计算能力的限制而被低估与忽视。假设量子计算机真的能够与神经网络结合,并且助力真正的人工智能技术的诞生,而且量子计算机发展需要10年的话,那么神经网络可能还有10年的发展期。直到那时期以后,神经网络才能真正接近实现AI这一目标。

    图39 量子计算

     

      2.人工智能

      最后,作者想简单地谈谈对目前人工智能的看法。虽然现在人工智能非常火热,但是距离真正的人工智能还有很大的距离。就拿计算机视觉方向来说,面对稍微复杂一些的场景,以及易于混淆的图像,计算机就可能难以识别。因此,这个方向还有很多的工作要做。

      就普通人看来,这么辛苦的做各种实验,以及投入大量的人力就是为了实现一些不及孩童能力的视觉能力,未免有些不值。但是这只是第一步。虽然计算机需要很大的运算量才能完成一个普通人简单能完成的识图工作,但计算机最大的优势在于并行化与批量推广能力。使用计算机以后,我们可以很轻易地将以前需要人眼去判断的工作交给计算机做,而且几乎没有任何的推广成本。这就具有很大的价值。正如火车刚诞生的时候,有人嘲笑它又笨又重,速度还没有马快。但是很快规模化推广的火车就替代了马车的使用。人工智能也是如此。这也是为什么目前世界上各著名公司以及政府都对此热衷的原因。

      目前看来,神经网络要想实现人工智能还有很多的路要走,但方向至少是正确的,下面就要看后来者的不断努力了。

    图40 人工智能

     

    八 总结

      本文回顾了神经网络的发展历史,从神经元开始,历经单层神经网络,两层神经网络,直到多层神经网络。在历史介绍中穿插讲解神经网络的结构,分类效果以及训练方法等。本文说明了神经网络内部实际上就是矩阵计算,在程序中的实现没有“点”和“线”的对象。本文说明了神经网络强大预测能力的根本,就是多层的神经网络可以无限逼近真实的对应函数,从而模拟数据之间的真实关系。除此之外,本文回顾了神经网络发展的历程,分析了神经网络发展的外在原因,包括计算能力的增强,数据的增多,以及方法的创新等。最后,本文对神经网络的未来进行了展望,包括量子计算与神经网络结合的可能性,以及探讨未来人工智能发展的前景与价值。

     

    九. 后记

      本篇文章可以视为作者一年来对神经网络的理解与总结,包括实验的体会,书籍的阅读,以及思考的火花等。神经网络虽然重要,但学习并不容易。这主要是由于其结构图较为难懂,以及历史发展的原因,导致概念容易混淆,一些介绍的博客与网站内容新旧不齐。本篇文章着眼于这些问题,没有太多的数学推导,意图以一种简单的,直观的方式对神经网络进行讲解。在2015年最后一天终于写完。希望本文可以对各位有所帮助。

     

     

      作者很感谢能够阅读到这里的读者。如果看完觉得好的话,还请轻轻点一下赞,你们的鼓励就是作者继续行文的动力。本文的备注部分是一些对神经网络学习的建议,供补充阅读与参考。

      

      目前为止,EasyPR的1.4版已经将神经网络(ANN)训练的模块加以开放,开发者们可以使用这个模块来进行自己的字符模型的训练。有兴趣的可以下载

     

    十. 备注

      神经网络虽然很重要,但是对于神经网络的学习,却并不容易。这些学习困难主要来自以下三个方面:概念,类别,教程。下面简单说明这三点。

      1.概念

      对于一门技术的学习而言,首先最重要的是弄清概念。只有将概念理解清楚,才能顺畅的进行后面的学习。由于神经网络漫长的发展历史,经常会有一些概念容易混淆,让人学习中产生困惑。这里面包括历史的术语,不一致的说法,以及被遗忘的研究等。 

      历史的术语

      这个的代表就是多层感知器(MLP)这个术语。起初看文献时很难理解的一个问题就是,为什么神经网络又有另一个名称:MLP。其实MLP(Multi-Layer Perceptron)的名称起源于50-60年代的感知器(Perceptron)。由于我们在感知器之上又增加了一个计算层,因此称为多层感知器。值得注意的是,虽然叫“多层”,MLP一般都指的是两层(带一个隐藏层的)神经网络。

      MLP这个术语属于历史遗留的产物。现在我们一般就说神经网络,以及深度神经网络。前者代表带一个隐藏层的两层神经网络,也是EasyPR目前使用的识别网络,后者指深度学习的网络。

      不一致的说法

      这个最明显的代表就是损失函数loss function,这个还有两个说法是跟它完全一致的意思,分别是残差函数error function,以及代价函数cost function。loss function是目前深度学习里用的较多的一种说法,caffe里也是这么叫的。cost function则是Ng在coursera教学视频里用到的统一说法。这三者都是同一个意思,都是优化问题所需要求解的方程。虽然在使用的时候不做规定,但是在听到各种讲解时要心里明白。

      再来就是权重weight和参数parameter的说法,神经网络界由于以前的惯例,一般会将训练得到的参数称之为权重,而不像其他机器学习方法就称之为参数。这个需要记住就好。不过在目前的使用惯例中,也有这样一种规定。那就是非偏置节点连接上的值称之为权重,而偏置节点上的值称之为偏置,两者统一起来称之为参数。

      另外一个同义词就是激活函数active function和转移函数transfer function了。同样,他们代表一个意思,都是叠加的非线性函数的说法。

      被遗忘的研究

      由于神经网络发展历史已经有70年的漫长历史,因此在研究过程中,必然有一些研究分支属于被遗忘阶段。这里面包括各种不同的网络,例如SOM(Self-Organizing Map,自组织特征映射网络),SNN(Synergetic Neural Network,协同神经网络),ART(Adaptive Resonance Theory,自适应共振理论网络)等等。所以看历史文献时会看到许多没见过的概念与名词。

      有些历史网络甚至会重新成为新的研究热点,例如RNN与LSTM就是80年代左右开始的研究,目前已经是深度学习研究中的重要一门技术,在语音与文字识别中有很好的效果。 

      对于这些易于混淆以及弄错的概念,务必需要多方参考文献,理清上下文,这样才不会在学习与阅读过程中迷糊。

      2.类别

      下面谈一下关于神经网络中的不同类别。

      其实本文的名字“神经网络浅讲”并不合适,因为本文并不是讲的是“神经网络”的内容,而是其中的一个子类,也是目前最常说的前馈神经网络。根据下图的分类可以看出。

    图41 神经网络的类别

     

      神经网络其实是一个非常宽泛的称呼,它包括两类,一类是用计算机的方式去模拟人脑,这就是我们常说的ANN(人工神经网络),另一类是研究生物学上的神经网络,又叫生物神经网络。对于我们计算机人士而言,肯定是研究前者。

      在人工神经网络之中,又分为前馈神经网络和反馈神经网络这两种。那么它们两者的区别是什么呢?这个其实在于它们的结构图。我们可以把结构图看作是一个有向图。其中神经元代表顶点,连接代表有向边。对于前馈神经网络中,这个有向图是没有回路的。你可以仔细观察本文中出现的所有神经网络的结构图,确认一下。而对于反馈神经网络中,结构图的有向图是有回路的。反馈神经网络也是一类重要的神经网络。其中Hopfield网络就是反馈神经网络。深度学习中的RNN也属于一种反馈神经网络。

      具体到前馈神经网络中,就有了本文中所分别描述的三个网络:单层神经网络,双层神经网络,以及多层神经网络。深度学习中的CNN属于一种特殊的多层神经网络。另外,在一些Blog中和文献中看到的BP神经网络是什么?其实它们就是使用了反向传播BP算法的两层前馈神经网络。也是最普遍的一种两层神经网络。

      通过以上分析可以看出,神经网络这种说法其实是非常广义的,具体在文章中说的是什么网络,需要根据文中的内容加以区分。

      3.教程

      如何更好的学习神经网络,认真的学习一门课程或者看一本著作都是很有必要的。

      说到网络教程的话,这里必须说一下Ng的机器学习课程。对于一个初学者而言,Ng的课程视频是非常有帮助的。Ng一共开设过两门机器学习公开课程:一个是2003年在Standford开设的,面向全球的学生,这个视频现在可以在网易公开课上找到;另一个是2010年专门为Coursera上的用户开设的,需要登陆Coursera上才能学习。

      但是,需要注意点是,这两个课程对待神经网络的态度有点不同。早些的课程一共有20节课,Ng花了若干节课去专门讲SVM以及SVM的推导,而当时的神经网络,仅仅放了几段视频,花了大概不到20分钟(一节课60分钟左右)。而到了后来的课程时,总共10节的课程中,Ng给了完整的两节给神经网络,详细介绍了神经网络的反向传播算法。同时给SVM只有一节课,并且没有再讲SVM的推导过程。下面两张图分别是Ng介绍神经网络的开篇,可以大致看出一些端倪。

    图42 Ng与神经网络

     

      为什么Ng对待神经网络的反应前后相差那么大?事实上就是深度学习的原因。Ng实践了深度学习的效果,认识到深度学习的基础--神经网络的重要性。这就是他在后面重点介绍神经网络的原因。总之,对于神经网络的学习而言,我更推荐Coursera上的。因为在那个时候,Ng才是真正的把神经网络作为一门重要的机器学习方法去传授。你可以从他上课的态度中感受到他的重视,以及他希望你能学好的期望。

     

    版权说明:

      本文中的所有文字,图片,代码的版权都是属于作者和博客园共同所有。欢迎转载,但是务必注明作者与出处。任何未经允许的剽窃以及爬虫抓取都属于侵权,作者和博客园保留所有权利。

      

    参考文献:

      1.Neural Networks

      2.Andrew Ng Neural Networks 

      3.神经网络简史

      4.中科院 史忠植 神经网络 讲义

      5.深度学习 胡晓林

     

     

     这是转发博客园的一篇文章,博主:计算机的潜意识,目前是南大的人工智能方向的在读博士。博客里写了一些机器学习入门的内容,以及分享了他在github上的一个开源项目EasyPR,车牌识别系统。能为初学者提供非常大的帮助,有兴趣的朋友请务必移步前往,一看究竟。

    原文链接:https://www.cnblogs.com/subconscious/p/5058741.html

    展开全文
  • 卷积神经网络图像识别python代码
  • 神经网络LSTM 时间预测

    千次下载 热门讨论 2017-08-03 09:50:05
    RNN全称循环神经网络(Recurrent Neural Networks),是用来处理序列数据的。在传统的神经网络模型中,从输入层到隐含层再到输出层,层与层之间是全连接的,每层之间的节点是无连接的。但是这种普通的神经网络对于很...
  • bp神经网络预测matlab代码实现过程 辛烷值的预测 【改编】辛烷值是汽油最重要的品质指标,传统的实验室检测方法存在样品用量大,测试周期长和费用高等问题,不适用于生产控制,特别是在线测试。近年发展起来的近红外...

    参考学习b站资源:

    数学建模学习交流

    bp神经网络预测matlab代码实现过程

    神经网络简介

    1.项目源码

    可在github下载(含原始样品数据):

    https://github.com/chenshunpeng/BP-neural-network

    2.神经网络介绍

    最早的神经网络模型, 单层感知器perceptron,结构如下:
    在这里插入图片描述
    这是一个两层的神经网络,第一层为输入层,第二层为输出层。因为只有在输出层需要进行计算,就是说只有一层计算层,所以称之为单层感知器。从形式上看,仅仅是将MP模型中的输入信号当作了独立的一层神经元,但是本质上却有很大差别。

    感知器模型中权重和阈值不再是固定的了,而是计算机"学习"出来的结果。引入了损失函数的概念,通过迭代不断调整权重和阈值,使得损失函数最小,以此来寻找最佳的权重和阈值。

    单层感知器只可以解决线性可分的问题,在单层感知器的基础上,再引入一层神经元,构成一个2层的神经网络(要刨去输入层),结构如下:
    在这里插入图片描述
    这样的一个神经网络模型,适用范围更广,涵盖了线性和非线性可分的场景。其中的每一层称之为layer, 除了输出层和输出层之外,还有中间的隐藏层。这样的神经网络模型,通过反向传播算法来求解。

    增加一层的好处在于更好的数据表示和函数拟合的能力,在3层的基础上,再引入更多的隐藏层,就变成了深度神经网络,图示如下:
    在这里插入图片描述
    可以看到,每增加一层,模型的参数数量急剧增加,所以深度学习对计算资源的要求特别高,在实际使用中,模型训练时间非常的久。

    虽然耗费计算资源,但是深度学习的优点也很突出,相比机器学习,模型自动完成特征提取,不需要人工的特征工程,这一点对于高维数据的处理特别重要

    3.辛烷值的预测

    【改编】辛烷值是汽油最重要的品质指标,传统的实验室检测方法存在样品用量大,测试周期长和费用高等问题,不适用于生产控制,特别是在线测试。近年发展起来的近红外光谱分析方法(NIR),作为一种快速分析方法,已广泛应用于农业、制药、生物化工、石油产品等领域。其优越性是无损检测、低成本、无污染,能在线分析,更适合于生产和控制的需要。

    实验采集得到50组汽油样品(辛烷值已通过其他方法测量),并利用傅里叶近红外变换光谱仪对其进行扫描,扫描范围900~1700nm,扫描间隔为2nm,即每个样品的光谱曲线共含401个波长点,每个波长点对应一个吸光度。

    1. 请利用这50组样品的数据,建立这401个吸光度和辛烷值之间的模型。
    2. 现给你10组新的样本,这10组样本均已经过近红外变换光谱仪扫描,请预测这10组新样本的辛烷值。

    Excel截图:
    在这里插入图片描述
    在这里插入图片描述


    3.1.原始样品数据

    因为数据太多,博客只放了一部分,完整Excel可以在github项目中下载:

    https://github.com/chenshunpeng/BP-neural-network

    首先导入数据:

    new_X:需要预测的输入层数据
    X:样品的输入层数据
    Y:样品的输出层数据

    在这里插入图片描述

    3.2.matlab代码实现

    %% 此程序为matlab编程实现的BP神经网络
    % 清空环境变量
    % clear
    close all  %关闭所有图形窗口
    clc
    
    %%第一步 读取数据
    input=X;   %载入输入数据
    output=Y;  %载入输出数据
    
    %% 第二步 设置训练数据和预测数据
    % 注意要将指标变为列向量
    input_train = input(1:40,:)';
    output_train =output(1:40,:)';
    input_test = input(41:50,:)';
    output_test =output(41:50,:)';
    %节点个数
    inputnum=401; % 输入层节点数量
    hiddennum=10; % 隐含层节点数量
    outputnum=1;  % 输出层节点数量
    %% 第三本 训练样本数据归一化
    [inputn,inputps]=mapminmax(input_train);%归一化到[-1,1]之间,inputps用来作下一次同样的归一化
    [outputn,outputps]=mapminmax(output_train);
    %% 第四步 构建BP神经网络
    net=newff(inputn,outputn,hiddennum,{'tansig','purelin'},'trainlm');% 建立模型,传递函数使用purelin,采用梯度下降法训练
    
    W1= net. iw{1, 1};                  %输入层到中间层的权值
    B1 = net.b{1};                      %中间各层神经元阈值
    
    W2 = net.lw{2,1};                   %中间层到输出层的权值
    B2 = net. b{2};                     %输出层各神经元阈值
    
    %% 第五步 网络参数配置( 训练次数,学习速率,训练目标最小误差等)
    net.trainParam.epochs=1000;         % 训练次数,这里设置为1000次
    net.trainParam.lr=0.01;             % 学习速率,这里设置为0.01
    net.trainParam.goal=0.00001;        % 训练目标最小误差,这里设置为0.00001
    
    %% 第六步 BP神经网络训练
    net=train(net,inputn,outputn);%开始训练,其中inputn,outputn分别为输入输出样本
    
    %% 第七步 测试样本归一化
    inputn_test=mapminmax('apply',input_test,inputps); % 对样本数据进行归一化
    
    %% 第八步 BP神经网络预测
    an=sim(net,inputn_test);                           %用训练好的模型进行仿真
    
    %% 第九步 预测结果反归一化与误差计算     
    test_simu=mapminmax('reverse',an,outputps);        %把仿真得到的数据还原为原始的数量级
    error=test_simu-output_test;                       %预测值和真实值的误差
    
    %%第十步 真实值与预测值误差比较
    figure('units','normalized','position',[0.119 0.2 0.38 0.5])
    plot(output_test,'bo-')
    hold on
    plot(test_simu,'r*-')
    hold on
    plot(error,'square','MarkerFaceColor','b')
    legend('期望值','预测值','误差')
    xlabel('数据组数')
    ylabel('样本值')
    title('BP神经网络测试集的预测值与实际值对比图')
    
    [c,l]=size(output_test);
    MAE1=sum(abs(error))/l;
    MSE1=error*error'/l;
    RMSE1=MSE1^(1/2);
    disp(['-----------------------误差计算--------------------------'])
    disp(['隐含层节点数为',num2str(hiddennum),'时的误差结果如下:'])
    disp(['平均绝对误差MAE为:',num2str(MAE1)])
    disp(['均方误差MSE为:       ',num2str(MSE1)])
    disp(['均方根误差RMSE为:  ',num2str(RMSE1)])
    

    关于隐含层数的确定(这里是10),需要注意的是:

    • 如果不用公式的话,可以逐步试验得到隐层节点数,就是先设置一个初始值,然后在这个值的基础上逐渐增加,比较每次网络的预测性能,选择性能最好的对应的节点数作为隐含层神经元节点数(逐步增加是因为确定隐含层节点数的基本原则是:在满足精度的前提下,取尽可能紧凑的结构,即取尽可能少的隐含层节点数)
    • 如果用公式的话,一般有几个经验公式(建议了解一下神经网络的数学/理论部分),带入看哪个效果好,就取哪个为基准,再结合逐步试验法确定隐层节点数,但因为权值和阈值是每训练一次,调整一次,所以只能尽量趋于最优(好像也可以通过遗传算法、粒子群算法这样的优化算法来确定,就比较高深了)

    训练结果:

    -----------------------误差计算--------------------------
    隐含层节点数为10时的误差结果如下:
    平均绝对误差MAE为:0.30444
    均方误差MSE为:       0.14714
    均方根误差RMSE为:  0.38359
    

    在这里插入图片描述
    进行预测:

    predict_y = zeros(10,1); % 初始化predict_y
    pre_test=mapminmax('apply',new_X(:,:)',inputps);% 对预测数据进行归一化
    for i = 1: 10
        result = sim(net, pre_test(:,i));
        predict_y(i) = result;
    end
    disp('预测值为:')
    predict_y=mapminmax('reverse',predict_y,outputps); %把预测结果还原
    disp(predict_y)
    

    结果:

    预测值为:
       87.9633
       87.8581
       88.8067
       85.4666
       85.3155
       83.1005
       86.3266
       86.7106
       89.1940
       87.0632
    

    需要注意的是,不同的神经网络模型参数会对预测值有影响,比如隐含层的个数(默认为10),测试集比例,训练方法等,另一方面,样本数量的局限或是模型的质量也都有可能对结果有很大的影响

    3.3.工具箱实现

    3.3.1.莱文贝格-马夸特方法

    在Matlab的菜单栏点击APP,再点击Neural Fitting app(神经网络工具箱):

    注意到左下角有一个模块:
    在这里插入图片描述
    点击后出现:
    在这里插入图片描述
    我们可以在这里看到对它的介绍:
    在这里插入图片描述
    可以简单了解一下:
    在这里插入图片描述
    之后接着进行操作:

    注意选择样本在上面(Matrix rows),也就是说每一行对应一个样本的所有数据
    在这里插入图片描述

    之后出现:
    在这里插入图片描述
    解释:

    训练集(Training set) —— 用于模型拟合的数据样本。

    验证集(Validation set)—— 是模型训练过程中单独留出的样本集,它可以用于调整模型的超参数和用于对模型的能力进行初步评估。在神经网络中,我们用验证数据集去寻找最优的网络深度,或者决定反向传播算法的停止点或者在神经网络中选择隐藏层神经元的数量;

    测试集(Testing set) —— 用来评估模最终模型的泛化能力。但不能作为调参、选择特征等算法相关的选择的依据。

    之后默认选择隐含层的个数为10(就是说有10个神经元进行预测,即output部分有10个):
    在这里插入图片描述
    之后选择训练方法:
    在这里插入图片描述
    解释:

    三种训练方法:

    莱文贝格-马夸特方法(Levenberg–Marquardt algorithm)
    贝叶斯正则化方法(Bayesian‐regularization)
    量化共轭梯度法(Scaled Conjugate Gradient )

    选择合适的进行训练即可

    训练结果:

    在时刻9(训练了9次)验证集valiadation出现了最低的均方误差,选择时刻9的模型为最佳模型:

    横坐标:训练结束时的epochs数(神经网络一次前向传播+一次反向传播=一个epoch)
    纵坐标:均方误差

    在这里插入图片描述

    这三条线分别是:训练集(train)、验证集(validation)和测试集(test)
    训练集(蓝线所用数据集):训练模型,得到模型参数
    验证集(绿线所用数据集):评估模型,得到的最优网络
    测试集(红线所用数据集):用之前得到的最优网络来评估模最终模型的泛化能力

    解释一下为什么最佳模型的标注在绿线上:

    首先使用训练集训练多个网络模型(假设为t1,t2,t3 … tn),再使用验证集测试这些网络,找到得分最高的那个网络(假设为t9)作为我们选择的最佳网络,所以最佳模型的标注在绿线上,红线则是网络模型将训练集和验证集合并训练而产生的(其实,绿线类似Kaggle中的Private Testing Set)

    将拟合值对真实值回归,拟合优度越高,说明拟合的的效果越好:

    在这里插入图片描述
    对应的神经网络图:
    在这里插入图片描述
    最后保存训练出来的神经网络模型:
    在这里插入图片描述
    在这里插入图片描述

    其中 net 即训练出来的神经网络模型

    进行预测:

    % 写一个循环,预测接下来的十个样本的辛烷值
    % 注意要将指标变为列向量,然后再用sim函数预测
    predict_y = zeros(10,1); % 初始化predict_y
    for i = 1: 10
        result = sim(net, new_X(i,:)');
        predict_y(i) = result;
    end
    disp('预测值为:')
    disp(predict_y)
    

    结果:

    预测值为:
       87.3547
       87.1239
       88.1194
       84.9958
       84.5796
       85.4275
       87.8986
       86.4921
       89.0483
       87.4444
    

    3.3.2.贝叶斯正则化方法

    之后我们换一种训练方法(从 莱文贝格-马夸特方法 换到 贝叶斯正则化方法),发现训练了391次还没有结束,于是我就手动停止了(训练了长达19min):

    在这里插入图片描述
    我们点击 (trainbr) 可以看到对贝叶斯正则化方法的详细介绍,及其局限性:

    该函数使用雅可比矩阵进行计算,该函数假设性能是误差的平均值或平方和。
    因此,使用该函数训练的网络必须使用mse或sse性能函数。

    在这里插入图片描述

    我们看训练的表现:

    训练的MSE图(左图),回归图(右图):

    在这里插入图片描述

    MSE图(左图)

    横坐标: 训练结束时的epochs数【神经网络一次前向传播+一次反向传播=一个epoch】
    纵坐标: 均方误差

    从图中可以发现训练集最小均方误差一直在变小,测试集略微轻微增大,趋于稳定(但误差其实都已经非常非常小了)


    回归图(右图)

    横坐标: 样本原目标值
    纵坐标: 神经网络输出预测值

    可以得到原目标值和预测值的相关度;用系数R表示,若R越接近1,则表示线性化程度越高,结果越好

    我们惊奇的发现没有validation,训检查了一下训练集(train)、验证集(validation)和测试集(test)在matlab工具箱中分别是70%,15%,15%的比例,没有问题,仔细看了一下原来是因为均方误差MSE和R指标在精度范围内已经为0,所以都不需要考虑它了!

    在这里插入图片描述

    训练的状态图(左图),误差直方图(右图):

    在这里插入图片描述

    状态图(左图)

    可以观察网络训练状态,判断是否终止训练

    横坐标: epoch
    纵坐标:
    gradient:梯度,若梯度为0,则为图像最低点,即最优位置
    mu:超参数 μ \mu μ(具体待研究)
    val fail:可以理解为误差值(具体待研究)

    validation check=0, at epoch 391:代表到第391次训练时,训练误差的 连续增大epoch数 为0(其实就是第390次训练时训练误差比第391次大),设置 validation checks 是为了防止被训练的网络过拟合的

    状态图的详细介绍可看帮助文档:

    在这里插入图片描述


    误差直方图(右图)

    可以得到神经网络的输出值与样本原目标值的误差

    横坐标: 误差区间的中位数;
    纵坐标: 位于该误差区间的样本个数

    之后可以通过这2个看训练的matlab代码:

    在这里插入图片描述

    可以在这里体验神经网络的模拟部署:

    在这里插入图片描述

    大概是这样(具体功能可以自己了解)

    在这里插入图片描述

    可以看到神经网络图:

    在这里插入图片描述

    如下:

    在这里插入图片描述

    我们可以生成脚本,方便以后解决相同的问题:

    在这里插入图片描述

    代码:

    % Solve an Input-Output Fitting problem with a Neural Network
    % Script generated by Neural Fitting app
    % Created 23-Jul-2022 19:10:11
    %
    % This script assumes these variables are defined:
    %
    %   X - input data.
    %   Y - target data.
    
    x = X';
    t = Y';
    
    % Choose a Training Function
    % For a list of all training functions type: help nntrain
    % 'trainlm' is usually fastest.
    % 'trainbr' takes longer but may be better for challenging problems.
    % 'trainscg' uses less memory. Suitable in low memory situations.
    trainFcn = 'trainbr';  % Bayesian Regularization backpropagation.
    
    % Create a Fitting Network
    hiddenLayerSize = 10;
    net = fitnet(hiddenLayerSize,trainFcn);
    
    % Choose Input and Output Pre/Post-Processing Functions
    % For a list of all processing functions type: help nnprocess
    net.input.processFcns = {'removeconstantrows','mapminmax'};
    net.output.processFcns = {'removeconstantrows','mapminmax'};
    
    % Setup Division of Data for Training, Validation, Testing
    % For a list of all data division functions type: help nndivision
    net.divideFcn = 'dividerand';  % Divide data randomly
    net.divideMode = 'sample';  % Divide up every sample
    net.divideParam.trainRatio = 70/100;
    net.divideParam.valRatio = 15/100;
    net.divideParam.testRatio = 15/100;
    
    % Choose a Performance Function
    % For a list of all performance functions type: help nnperformance
    net.performFcn = 'mse';  % Mean Squared Error
    
    % Choose Plot Functions
    % For a list of all plot functions type: help nnplot
    net.plotFcns = {'plotperform','plottrainstate','ploterrhist', ...
        'plotregression', 'plotfit'};
    
    % Train the Network
    [net,tr] = train(net,x,t);
    
    % Test the Network
    y = net(x);
    e = gsubtract(t,y);
    performance = perform(net,t,y)
    
    % Recalculate Training, Validation and Test Performance
    trainTargets = t .* tr.trainMask{1};
    valTargets = t .* tr.valMask{1};
    testTargets = t .* tr.testMask{1};
    trainPerformance = perform(net,trainTargets,y)
    valPerformance = perform(net,valTargets,y)
    testPerformance = perform(net,testTargets,y)
    
    % View the Network
    view(net)
    
    % Plots
    % Uncomment these lines to enable various plots.
    %figure, plotperform(tr)
    %figure, plottrainstate(tr)
    %figure, ploterrhist(e)
    %figure, plotregression(t,y)
    %figure, plotfit(net,x,t)
    
    % Deployment
    % Change the (false) values to (true) to enable the following code blocks.
    % See the help for each generation function for more information.
    if (false)
        % Generate MATLAB function for neural network for application
        % deployment in MATLAB scripts or with MATLAB Compiler and Builder
        % tools, or simply to examine the calculations your trained neural
        % network performs.
        genFunction(net,'myNeuralNetworkFunction');
        y = myNeuralNetworkFunction(x);
    end
    if (false)
        % Generate a matrix-only MATLAB function for neural network code
        % generation with MATLAB Coder tools.
        genFunction(net,'myNeuralNetworkFunction','MatrixOnly','yes');
        y = myNeuralNetworkFunction(x);
    end
    if (false)
        % Generate a Simulink diagram for simulation or deployment with.
        % Simulink Coder tools.
        gensim(net);
    end
    

    之后保存数据:

    在这里插入图片描述
    进行预测:

    % 写一个循环,预测接下来的十个样本的辛烷值
    % 注意要将指标变为列向量,然后再用sim函数预测
    predict_y = zeros(10,1); % 初始化predict_y
    for i = 1: 10
        result = sim(net, new_X(i,:)');
        predict_y(i) = result;
    end
    disp('预测值为:')
    disp(predict_y)
    

    结果:

    预测值为:
       87.1550
       86.8867
       87.9137
       84.8865
       85.3341
       84.0724
       86.5032
       86.1383
       88.8628
       86.9989
    

    4.辛烷值的预测(进阶版,预测辛烷值区间)

    因为有人进行了提问:bp神经网络预测的问题,讨论区也有类似的问题,所以对辛烷值的预测进行了深入的讨论


    上一个是预测一个辛烷值,这次我们将上一次的辛烷值做一个运算,生成一个辛烷值区间(其实就是想生成个一个区间的两个端点),自定义公式:
    [ α , β ] = [ x − ∣ x r a n d i ( [ 9 , 11 ] ) ∣ , x + ∣ x r a n d i ( [ 11 , 13 ] ) ∣ ] \left[ \alpha ,\beta \right] =\left[ x-\left| \dfrac{x}{randi([9,11])}\right| ,x+\left| \dfrac{x}{randi([11,13])}\right| \right] [α,β]=[x randi([9,11])x ,x+ randi([11,13])x ]

    我们生成 [ α , β ] \left[ \alpha ,\beta \right] [α,β]

    %init(1)是初始辛烷值,init(2)是α,init(3)是β
    
    for i = 1: 50
        init(i,2) = init(1)-init(1)/randi([9,11]);
        init(i,3) = init(1)+init(1)/randi([11,13]);
    end
    

    数据如下(均保存2位小数):

    辛烷值	α	    β
    85.3	76.77	92.41
    85.25	77.55	92.41
    88.45	76.77	91.86
    83.4	77.55	92.41
    87.9	76.77	92.41
    85.5	75.82	93.05
    88.9	76.77	93.05
    88.3	77.55	93.05
    88.7	75.82	93.05
    88.45	75.82	92.41
    88.75	75.82	91.86
    88.25	76.77	93.05
    87.3	77.55	91.86
    88	    76.77	93.05
    88.7	75.82	92.41
    85.5	76.77	93.05
    88.65	76.77	91.86
    88.75	75.82	93.05
    85.4	75.82	93.05
    88.6	76.77	92.41
    87	    75.82	93.05
    87.15	77.55	93.05
    87.05	77.55	91.86
    87.25	76.77	92.41
    86.85	75.82	92.41
    88.65	77.55	92.41
    86.6	76.77	93.05
    86	    76.77	92.41
    86.1	77.55	92.41
    86.5	76.77	91.86
    86.3	75.82	91.86
    84.4	77.55	91.86
    84.7	75.82	93.05
    84.6	76.77	91.86
    84.5	75.82	91.86
    88.1	75.82	92.41
    85.25	76.77	91.86
    88.4	77.55	91.86
    88.2	77.55	92.41
    88.4	77.55	93.05
    88.55	75.82	91.86
    88.35	76.77	92.41
    88.2	77.55	92.41
    85.3	76.77	91.86
    88.5	77.55	92.41
    88.25	75.82	93.05
    88	    77.55	93.05
    88.85	76.77	93.05
    88.45	77.55	91.86
    88.7	76.77	92.41
    

    现在我们开始愉快的预测:

    首先导入数据:

    new_X:需要预测的输入层数据
    X:样品的输入层数据
    Y:样品的输出层数据

    其实就是把Y多增加1列:
    在这里插入图片描述

    4.1.matlab代码实现

    %% 此程序为matlab编程实现的BP神经网络
    % 清空环境变量
    % clear
    close all  %关闭所有图形窗口
    clc
    
    %%第一步 读取数据
    input=X;   %载入输入数据
    output=Y;  %载入输出数据
    
    %% 第二步 设置训练数据和预测数据
    % 注意要将指标变为列向量
    input_train = input(1:40,:)';
    output_train =output(1:40,:)';
    input_test = input(41:50,:)';
    output_test =output(41:50,:)';
    %节点个数
    inputnum=401; % 输入层节点数量
    hiddennum=10; % 隐含层节点数量
    outputnum=2;  % 输出层节点数量
    %% 第三本 训练样本数据归一化
    [inputn,inputps]=mapminmax(input_train);%归一化到[-1,1]之间,inputps用来作下一次同样的归一化
    [outputn,outputps]=mapminmax(output_train);
    %% 第四步 构建BP神经网络
    net=newff(inputn,outputn,hiddennum,{'tansig','purelin'},'trainlm');% 建立模型,传递函数使用purelin,采用梯度下降法训练
    
    W1= net. iw{1, 1};                  %输入层到中间层的权值
    B1 = net.b{1};                      %中间各层神经元阈值
    
    W2 = net.lw{2,1};                   %中间层到输出层的权值
    B2 = net. b{2};                     %输出层各神经元阈值
    
    %% 第五步 网络参数配置( 训练次数,学习速率,训练目标最小误差等)
    net.trainParam.epochs=1000;         % 训练次数,这里设置为1000次
    net.trainParam.lr=0.01;             % 学习速率,这里设置为0.01
    net.trainParam.goal=0.00001;        % 训练目标最小误差,这里设置为0.00001
    
    %% 第六步 BP神经网络训练
    net=train(net,inputn,outputn);%开始训练,其中inputn,outputn分别为输入输出样本
    
    %% 第七步 测试样本归一化
    inputn_test=mapminmax('apply',input_test,inputps); % 对样本数据进行归一化
    
    %% 第八步 BP神经网络预测
    an=sim(net,inputn_test);                           %用训练好的模型进行仿真
    
    %% 第九步 预测结果反归一化与误差计算     
    test_simu=mapminmax('reverse',an,outputps);        %把仿真得到的数据还原为原始的数量级
    error=test_simu-output_test;                       %预测值和真实值的误差
    
    %%第十步 真实值与预测值误差比较
    figure('units','normalized','position',[0.119 0.2 0.38 0.5])
    plot(output_test,'bo-')
    hold on
    plot(test_simu,'r*-')
    hold on
    plot(error,'square','MarkerFaceColor','b')
    legend('期望值','预测值','误差')
    xlabel('数据组数')
    ylabel('样本值')
    title('BP神经网络测试集的预测值与实际值对比图')
    
    [c,l]=size(output_test);
    MAE1=sum(abs(error))/l;
    MSE1=error*error'/l;
    RMSE1=MSE1^(1/2);
    disp(['-----------------------误差计算--------------------------'])
    disp(['隐含层节点数为',num2str(hiddennum),'时的误差结果如下:'])
    disp(['平均绝对误差MAE为:',num2str(MAE1)])
    disp(['α的均方误差MSE为:       ',num2str(MSE1(1,:))])
    disp(['β的均方误差MSE为:       ',num2str(MSE1(2,:))])
    disp(['α的均方根误差RMSE为:  ',num2str(RMSE1(1,:))])
    disp(['β的均方根误差RMSE为:  ',num2str(RMSE1(2,:))])
    

    之后开始训练:

    在这里插入图片描述

    训练结果为:

    在这里插入图片描述

    训练中间阶段:

    在这里插入图片描述

    回归结果(数据虽然是瞎生成的,但结果好像还不错呢 ):

    在这里插入图片描述

    输出结果(图像有些小问题,应该是多条曲线的对比,有空会将它优化的QAQ ,但是整体思路都没问题):

    在这里插入图片描述

    -----------------------误差计算--------------------------
    隐含层节点数为10时的误差结果如下:
    平均绝对误差MAE为:0.28223     0.28882     0.16351     0.17373    0.078239     0.15954    0.045716     0.11022     0.16083     0.16366
    α的均方误差MSE为:       1.8212   -0.021202
    β的均方误差MSE为:       -0.021202     0.42378
    α的均方根误差RMSE为:  1.3495   -0.010599
    β的均方根误差RMSE为:  -0.010599      0.6509
    

    进行预测,竟然报错了:

    在这里插入图片描述

    错误代码(就当教训了):

    clc;
    predict_y = zeros(10,2); % 初始化predict_y
    pre_test=mapminmax('apply',new_X(:,:)',inputps);% 对预测数据进行归一化
    for i = 1: 10
        result = sim(net, pre_test(:,i));
        predict_y(i,1) = result(1);
        predict_y(i,2) = result(2);
    end
    disp('预测值为:')
    predict_y=mapminmax('reverse',predict_y,outputps); %把预测结果还原
    disp(predict_y)
    

    我们查看predict_y,没问题:

    在这里插入图片描述

    那么就是mapminmax函数的问题,修改如下:

    clc;
    predict_y = zeros(10,2); % 初始化predict_y
    pre_test=mapminmax('apply',new_X(:,:)',inputps);% 对预测数据进行归一化
    for i = 1: 10
        result = sim(net, pre_test(:,i));
        predict_y(i,1) = result(1);
        predict_y(i,2) = result(2);
    end
    disp('预测值为:')
    predict_y=predict_y';
    predict_y=mapminmax('reverse',predict_y,outputps); %把预测结果还原
    disp(predict_y)
    

    结果:

    预测值为:
       77.9596   80.1580   78.4421   77.6802   79.4339   79.4779   77.8803   79.3454   78.7957   77.8469
       92.1225   91.6629   93.0518   92.4459   92.6326   92.3652   93.6457   93.1900   93.0095   93.6050
    

    看一下predict_y,也没问题:

    在这里插入图片描述

    我们再转置回来得到正确结果:

    在这里插入图片描述

    那么为啥要这么修改呢,我们细细品(#^.^#) ,这要回到神经网络构建的时候了:

    在这里插入图片描述

    这两部分要对应上哇,哈哈,完结撒花

    4.2.工具箱实现

    类比之前实现的方法,其实是不难实现的,读者可以自行完成


    目前课业压力较大,这段时间大概率会忽略博客评论,敬请谅解

    展开全文
  • 沉寂了这么久,原本说发布一个go语言无框架建站教程,结果发现由于这一年没怎么看go语言,go的工程模式貌似有了新的变化,再加上联系了导师,导师让我学习神经网络的知识,所以索性先把go语言建站的日程推后,先行...

    前言

    沉寂了这么久,原本说发布一个go语言无框架建站教程,结果发现由于这一年没怎么看go语言,go的工程模式貌似有了新的变化,再加上联系了导师,导师让我学习神经网络的知识,所以索性先把go语言建站的日程推后,先行学习神经网络再说。

    一如既往,我的目标仍然是让你看了之后就能和别人讲。

    今天,就先看看神经网络的基本概念,对它有一个初步的了解吧。(前几篇可能是理论知识多一点,后面再实操)

    什么是神经网络?

    这里不会对这一概念进行解释,让我们一步一步去理解这个神秘的东西。

    神经元?函数?

    生物中的神经元

    高中我们都学过(既然看到这篇文章,我默认您是工科的学生或者理科的学生,那么高中应该是学习了生物这门课程),生物大脑中有神经元,草图如下(单个神经细胞):

    左边是接受其他神经元传来的信号的,经过处理之后,如果需要反应,那么会在末端释放神经递质即将这个信号传递到下一个神经细胞(虽然上面的解释可能不精确,但是大概能理解到这个神经细胞的作用了)。

    简单来说,一个神经元有三个基本的功能:‘

    1. 接收刺激或者信号

    2. 处理这些信息

    3. 根据信号做出相应反应

    程序语言中的函数

    在程序中,我们经常使用到函数(function)或者方法(method)或者其他的,在这里就姑且统称为函数吧,举个例子,一个很简单的最大值函数:

    # 返回num1和num2的最大值
    def Max(num1, num2):
        if num1 > num2:
            num2 = num1
        return num2

    可以看到

    1. 这个函数接收了两个参数:num1和num2

    2. 比较了num1和num2的大小

    3. 返回了最大值

    神经元!函数!

    现在,很容易理解,其实,一个神经元就可以大致认为是一个简单的函数,这个神经元(函数)接收信号(参数),处理信息,作出反应(返回值)!多么简单,以后,我们编程时就不要说写一个功能函数了,就说,来吧,写一个比较最大最小值的神经元吧哈哈哈哈哈哈。

    神经元+神经元 = 神经网络

    高中生物课本说,很多个神经元组成了一个神经网络,人体中的神经元数量大概有几百亿个,就是简单的蚂蚁也有几十万个神经元,而这么多数量的神经元一个一个连接到一起工作,竟然产生了令人惊讶的能力:智能。而这个网络,也被称为神经网络。

    所以,神经元(函数)+神经元(函数) = 神经网络(人工神经网络)。

    虽然这句话不严格精确,但是很能帮助理解如何去使用编程语言编写神经网络,即我们需要使用函数套函数,这个函数的输出作为下一个甚至后面多个函数的输入,一个函数的输入来自一个甚至多个函数的输出,如示意图:

    理解了上面的四张图,相信我,你已经步入了神经网络编程的大门。恭喜你!

    编程中,神经网络的分类

    据我目前的知识,神经网络大致分为两类:预测机和分类机。

    但事实上,这两类神经网络应该没太大区别,比如自动驾驶,某一张道路状况的照片,我们既可以说:预测下一步的动作,左拐还是右拐或者其他,也可以说:分类这个场景,左拐,右拐还是其他,所以无需在这个分类上面纠结太多。

    但有的情况貌似有区别,比如输入华氏度,给出摄氏度,在不知道明确转换公式的情况下,这里的神经网络应该只能叫预测机,因为输入是华氏度,经过处理后,给出可能的摄氏度结果。

    如果叫分类机,那问题就太大了。比如73华氏度到74华氏度之间有无限个温度数值,不可能全部“分类”。

    函数:摄氏度转为华氏度函数

    # 将摄氏度转为华氏度
    def CToF(C):
        return 1.8 * C + 32

    上面的函数功能很简单,就是把摄氏度转为华氏度,无论我们输入什么摄氏度的值,都能得到精确的华氏度的值。

    但是,这是我们想要的吗?不是!我们需要的是神经网络!

    神经元:摄氏度->华氏度

    当我们看到一个运算时,比如 41*41,我们一眼就能看出结果大于1600,而一眼看出结果却很难,计算机却能直接计算出结果是1681。

    同样,我们知道体温大概是36.5摄氏度或者97.7摄氏度左右,但是我们并不能精准知道现在体温是多少,但是神经元能通过自己的“经验”来“推断”出我们当前的体温应该是多少。

    所以,这里有一个很有意思的事情:神经网络不需要计算精确,需要近似计算即可。编程神经网络时,不需要很精确,实际上,也不可能精确。实际生活中,无论什么方面,总能找到一些特殊的例子,有些人戏谑的称之为地球OL的BUG。

    神经网络:温度转换

    假设我们现在对 F = 1.8 * C + 32 这个公式有点模糊了,我们只知道需要加32,而忘记了C前面需要乘多少,幸运的是,我们大脑中有一个闲置的神经元可以用来处理这个转换,手里面也有一个华氏温度计和一个摄氏温度计。

    设置初始条件

    我们知道摄氏度和华氏度之间的转换关系是:F = 常数 * C + 32,要去估计这个常数的大小,所以,现在设这个常数是1,即初始转换关系是:F = 1 * C + 32。

    我们使用温度计测量了下面一组数据:

    华氏度摄氏度
    97.736.5
    7725
    212100

    经过设置,我们的闲置的神经网络设置为如下图所示:

    尝试计算

    现在准备好了一切,我们把测量的36.5输入到网络中,网络计算后,输出了68.5。

    然后计算误差:97.7 - 68.5 = 29.2。(切记,误差可正可负可为0,但误差=真实值 - 计算值,当然你也可以计算值 - 真实值,只要你自己知道,并且计算时不要弄颠倒就行。)

    29.2华氏度,这个误差还是挺大了,接下来,我们需要增大C的系数,变为1.5(系数乘以1.5,我承认这个变化太大,但是这是为了便于理解,其实变化应该小一点)。神经元变成了下面的样子:

    输入第二个摄氏度的数据(25),再次计算,网络输出为69.5。

    现在的误差为:77 - 69.5 = 7.5。误差瞬间变小了,但是误差仍然存在,所以我们要继续调整,1.5*1.5 = 2.25,于是,神经元变成了下面的样子:

    现在计算第三个摄氏度的数据(100),得到257。

    现在误差为:212 - 257 = -45(无论使用真实值-计算值还是计算值-真实值,要保证前后一致。)。误差再次变大,且现在是负的,证明我们调整的过于猛烈了,而测量数据到这里已经没了,所以我们只得选择误差相对较小的系数1.5作为神经元最终的训练结果。

    最终结果

    最终我们得到了一个摄氏度到华氏度转换的公式:F = 1.5 * C + 32,虽然和真正的公式(F = 1.8 * C + 32)相差较大,但是这种思想是神经网络的“核心”思想之一:随机初始数据(例如本例的F = 1 * C + 32),利用数据计算误差(使用测量的三组数据),调整数据重新计算(计算误差,重新计算),一次又一次的调整数据,最终得到一个较好的结果(F = 1.5 * C + 32)作为最终的网络。

    以上是我的总结,可能与官方的表述不一样,但是大致思想只要大家理解了,相信学习起来会很快的。

    上面的神经元的改进

    最开始我们参数是1 时,得到了一个大误差,调整参数后计算误差急剧减小,然而我们调整参数策略却没发生变化,仍然是乘以了1.5,导致参数变化过于剧烈,从而引起了误差剧变。

    上面计算时,第一次误差是29.2,第二次误差是7.5,如果我们每次只改变误差的一部分呢?比如,误差的百分之1?来吧,尝试一下。仍然是从最初开始!

    最初的神经元

    尝试训练

    把第一组数据的摄氏度36.5输入网络,得到输出为:68.5。

    计算误差 :97.7 - 68.5 = 29.2。此时调整参数1为:1 + 29.2 / 100 = 1.292。现在新的神经元如下:

    把第二组数据的摄氏度25输入网络,得到输出为:64.3。

    计算误差:77 - 64.3 = 12.7。可见,虽然这是的误差没有变化过于猛烈,但是至少误差是在慢慢减少了,它走上了正确的道路。

    此时调整参数为:1.292 + 12.7 / 100 = 1.419。现在新的神经元如下:

    此时将最后一组数据摄氏度100输入网络,得到输出为173.9。

    计算误差:212 - 173.9 = 38.1。调整参数为:1.419 + 38.1 / 100 = 1.8。(很抱歉,误打误撞竟然算出了一个精确的1.8,这是偶然情况,并不是所有神经网络都能算到这么精确,但是希望大家能理解这里面的思想。

    而此时新的神经元如下:

    到此,训练数据结束。

    选择最终结果

    一般来讲,我认为可以选择最后两次的任意之一作为最终的结果。本次纯属偶然得到了精确的1.8的值,实际应用中应该会比1.419更接近1.8,或者高于1.8,体现在数轴上,最后一次计算的参数应该处于黄色区域:

    所以,在未知的情况下,这两次的结果都可能是更好的,例如为改进版本直接乘以1.5,倒数第二次的1.5为更好,而改进版本中,显然最后一次更好(相对来讲)。

    写到最后

    虽然今天内容看起来极其简单,但是,这就是神经网络的核心知识之一,理解了这些,学好神经网络绝非难事,但是要记住几个有帮助的建议:

    1. 适当的改变参数,大误差大调整,小误差小调整。

    2. 神经元的参数不需要精确,只需要有一个大概值即可,哪怕看起来有点荒诞,也是一个可以使用的值。

    3. 每次训练要建立在前一次训练调整后的基础上。

    如果大家有兴趣,可以试一试将改进版本中的调整率变为2%计算最终结果,试一试吧哈哈

    最近等开学,在家里找了兼职,白天上班,抽空才能学习并记录,不定时更新,尽量周更或者两周更,希望大家多多谅解!拜谢!下期见!

    展开全文
  • 大家好,我最近刚发完论文可以稍稍放松一段时间,之前就发现越来越多的人在学习神经网络的知识,而且有些同学对其也是十分推崇。其实也不奇怪,哈哈,结合当今地时代背景,不管是在什么领域,大家都希望我们身边地...
  • 本文综合整理常用的神经网络,包括生物神经网络、人工神经网络、卷积神经网络、循环神经网络、生成对抗网络;参考了许多高校的课程、论文、博客和视频等。文章的结构是先进行概念了解,然后结合图片、结构图、一步...
  • BP神经网络预测matlab代码讲解与实现步骤

    万次阅读 多人点赞 2021-12-07 12:47:16
    BP神经网络的简介和结构参数1.1 BP神经网络的结构组成1.2 BP神经网络训练界面的参数解读2. 实现BP网络的步骤3. matlab代码编写4. BP代码运行结果4.1 预测值和真实值的误差计算(MAE、MSE、MRSE)4.2 BP网络训练的...
  • 神经网络原理&一个简单的神经网络模型搭建

    千次阅读 多人点赞 2021-03-03 09:32:29
    神经网络基本原理 文章目录神经网络基本原理前言一、神经网络是什么?1.1 神经网络的分类1.2 神经网络结构图1.3 神经元1.4 为什么神经网络能预测?二、 一个最简单的神经网络1.去不去爬山?2.案例代码2.1 引入类库2.2...
  • MATLAB神经网络30个案例分析源码

    热门讨论 2015-07-05 12:02:17
    《MATLAB神经网络30个案例分析》一书源码!
  • 先加载excel文件中的数据,再训练,最后预测出未来几步的数据走势。预测步数可以自己设定。文本和程序注释有详细说明。
  • 采用BP算法的多层感知器是至今为止应用最广泛的神经网络,在多层感知器的应用中,以图3-15所示的单隐层网络的应用最为普遍。一般习惯将单隐层前馈网称为三层感知器,所谓三层包括了输入层、隐层和输出层。 算法...
  • 卷积神经网络(CNN)原理详解

    千次阅读 多人点赞 2022-03-21 14:07:35
    在这场深度学习革命中,卷积神经网络(Convolutional Neural Networks,简称CNN)是推动这一切爆发的主力,在目前人工智能的发展中有着非常重要的地位。 【问题来了】那什么是卷积神经网络(CNN)呢? 1、什么是...
  • 卷积神经网络特别适合处理像图片、视频、音频、语言文字等,这些与相互位置有一定关系的数据。 卷积神经网络(Convolutional Nerual Network,CNN) 为什么计算机可以处理图片--因为在计算机语言中图片可以用数字...
  • 这篇文章主要整理三部分内容,一是常见的三种神经网络结构:前馈神经网络、反馈神经网络和图网络;二是整理前馈神经网络中正向传播、误差反向传播和梯度下降的原理;三是梯度消失和梯度爆炸问题的原因及解决思路。 ...
  • 神经网络中的单层神经网络

    千次阅读 多人点赞 2019-12-30 20:35:30
    单层神经网络2.1 感知器2.2 数学描述2.3 感知器分类效果2.4 单层神经网络表示2.5 单层神经网络训练算法2.6 单层神经网络中的计算公式表示 文章综合一下几位大佬的文章: 杨强AT南京: DL01-6: 单层神经网络 企鹅号 ...
  • 《Python神经网络编程》自己动手编写一个神经网络

    千次阅读 多人点赞 2020-06-15 17:57:48
    最近在看一些经典论文,想要动手复现其中的代码,无奈自己水平过于低,总感觉对于神经网络的理解不够深入,于是想补一下相关的知识。 便找到了《Python神经网络编程》这本书,若稍微有些基础看起来很快,看完之后给...
  • 由单层感知机中的信号传递机制过渡到神经网络中的信号传递机制,通过一个包含2个隐藏层的4层神经网络实现了前向信号传播,介绍了sigmoid激活函数以及输出层经常用于误差计算的softmax函数
  • 1.2.5 神经网络工具箱快速入门 1.3 神经网络发展史 1.3.1 初期阶段 1.3.2 停滞期 1.3.3 黄金时期 1.3.4 发展展望 1.4 神经网络模型 1.4.1 神经元结构模型 1.4.2 神经网络的互连模式 1.5 神经网络的特性及...
  • 神经网络(Graph Neural Network,GNN)是一类能够从图结构数据中学习特征规律的神经网络,是解决图结构数据(非欧氏空间数据)机器学习问题的最重要的技术。 1 图神经网络的基础知识 图神经网络(Graph Neural...
  • 卷积神经网络的基本结构由输入层、卷积层、池化层(也称为取样层)、全连接层及输出层构成。卷积层和池化层一般会取若干个,采用卷积层和池化层交替设置,即一个卷积层连接一个池化层,池化层后再连接一个卷积层,...
  • BP神经网络时间序列预测-附代码

    万次阅读 多人点赞 2021-12-07 13:07:37
    BP神经网络时间序列预测的MATLALB实现 文章目录BP神经网络时间序列预测的MATLALB实现1. BP神经网络预测算法简介1.1 受相关指标影响的BP神经网络算法原理1.2 基于历史值影响的BP神经网络2. MATLAB代码编写过程2.1 ...
  • BP神经网络预测(python)

    千次阅读 热门讨论 2022-04-30 08:46:23
    下边是基于Python的简单的BP神经网络预测,多输入单输出,也可以改成多输入多输出,下边是我的数据,蓝色部分预测红色(x,y,v为自变量,z为因变量) 话不多说,直接上代码 # -*- coding: utf-8 -*- """ """ ...
  • BP神经网络

    千次阅读 多人点赞 2021-07-27 10:33:42
    纯手工 一.BP神经网络 1.一图知其意 2.多言以述之 二.BP算法 1.参数初始化 2.前向传播 3.反向传播 三.具体细节 四.手工计算 5.代码实现 一.BP神经网络 1.一图知其意 2.多言以述之 BP算法包括信号的前向传播和误差的...
  • 它们分别是前馈型脉冲神经网络(feed-forward spiking neural network)、递归型脉冲神经网络(recurrent spiking neural network)和混合型脉冲神经网络(hybird spiking neural network)。 学习是人工智能领域的...
  • CNN卷积神经网络详解

    千次阅读 2021-05-25 10:28:21
    卷积神经网络(CNN),这是深度学习算法应用最成功的领域之一,卷积神经网络包括一维卷积神经网络,二维卷积神经网络以及三维卷积神经网络。一维卷积神经网络主要用于序列类的数据处理,二维卷积神经网络常应用于...
  • BP神经网络通俗教程(matlab实现方法)

    万次阅读 多人点赞 2020-09-05 21:38:19
    BP神经网络通俗教程(matlab实现方法) 黑色字体可看可不看,是帮助理解所用 红色字体是比较重要的部分,必看 BP神经网络是什么 BP(Back-propagation,反向传播)神经网络是最传统的神经网络。当下的各种神经网络的...
  • 注意力机制可以使神经网络忽略不重要的特征向量,而重点计算有用的特征向量。在抛去无用特征对拟合结果于扰的同时,又提升了运算速度。 1 注意力机制 所谓Attention机制,便是聚焦于局部信息的机制,比如图像中的...
  • 神经网络选择正确的激活函数

    千次阅读 2022-01-21 10:02:43
    我们都知道神经网络模型中使用激活函数的主要目的是将非线性特性引入到我们的网络中,强化网络的学习能力。激活函数应用于隐藏层和输出层中每个节点的称为 z 的输入加权和(此处输入可以是原始数据或前一层的输出)...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 625,269
精华内容 250,107
关键字:

神经网络