自己动手从零搭建神经网络

CSDN博客地址:https://blog.csdn.net/wf96390/article/details/89437111

入门

首先,先简单的讲解一下神经网络。
我们从构建超级简单的机器开始。有一台基本的机器,接受了一个问题,做了一些“思考”,并输出了一个答案。就像我们从眼睛输入图片,使用大脑分析场景,并得出在场景中有哪些物体的结论。

试想一下将千米转化为英里的一台机器,如下图所示。我们所知道的就是,两者之间的关系是线性的。这意味着,如果英里数加倍,那么表示相同距离的千米数也是加倍的。千米和英里之间的这种线性关系,为我们提供了这种神秘计算的线索,即它的形式应该是“英里=千米×C”,其中C为常数。现在,我们还不知道这个常数C是多少。

首先,我们从尝试使用C=0.5,带入机器计算出结果。

结果比实际值少了12.137。这是计算结果与我们列出的示例真实值之间的差值,是误差。即:
误差值=真实值-计算值
=62.137-50
=12.137

让我们将C从0.5稍微增加到0.6,再次进行计算。
现在,由于将C设置为0.6,我们得到了英里=千米×C=100×0.6=60,这个答案比先前50的答案更好。我们取得了明显的进步。

让我们再次重复这个过程。输出值60还是太小了。我们再次微调C,将其从0.6调到0.7。结果超过了已知的正确答案。先前的误差值为2.137,现在的误差值为-7.863。我们为什么不使用一个较小的量,微调C,将C从0.6调到0.61呢?

这比先前得到的答案要好得多。我们得到输出值61,比起正确答案62.137,这只差了1.137。
因此,最后的这次尝试告诉我们,应该适度调整C值。如果输出值越来越接近正确答案,即误差值越来越小,那么我们就不要做那么大的调整。使用这种方式,我们就可以避免像先前那样得到超调的结果。

再换个例子,简单分析一下,比如我们希望训练线性分类器,使其能够正确分类瓢虫或毛虫。下图并不能准确的区分瓢虫和毛虫。

我们尝试修改直线的斜率,这样我们就可以精确的区分出这两种小虫。那如何使用公式进行表达呢?


回顾一下,在千米转换为英里预测器的实例中,我们有一个调整了参数的线性函数。此处,由于分界线是一条直线,因此我们也可以进行相同的处理:
y=Ax
由于严格来说,此处的直线不是一台预测器,因此我们有意使用名称y和x,而不使用名称长度和宽度。与先前我们将千米转换为英里不一样,这条直线不将宽度转换为长度。相反,它是一条分界线,是一台分类器。
同样,我们也可以采用之前的方法,根据误差来对直线进行调整,对此不再赘述。

神经网络介绍

前面简单的介绍了线性分类器,下面开始正式介绍神经网络。神经网络是机器学习中的一种模型,是一种模仿动物神经网络行为特征,进行分布式并行信息处理的算法数学模型。这种网络依靠系统的复杂程度,通过调整内部大量节点之间相互连接的关系,从而达到处理信息的目的。下图就是一个简单的神经网络。

i

神经元

神经元是神经网络中最基本的结构,也可以说是神经网络的基本单元,它的设计灵感完全来源于生物学上神经元的信息传播机制。我们学过生物的同学都知道,神经元有两种状态:兴奋和抑制。一般情况下,大多数的神经元是处于抑制状态,但是一旦某个神经元收到刺激,导致它的电位超过一个阈值,那么这个神经元就会被激活,处于“兴奋”状态,进而向其他的神经元传播化学物质(其实就是信息)。神经元是神经网络中最基本的结构,也可以说是神经网络的基本单元,它的设计灵感完全来源于生物学上神经元的信息传播机制。我们学过生物的同学都知道,神经元有两种状态:兴奋和抑制。一般情况下,大多数的神经元是处于抑制状态,但是一旦某个神经元收到刺激,导致它的电位超过一个阈值,那么这个神经元就会被激活,处于“兴奋”状态,进而向其他的神经元传播化学物质(其实就是信息)。

神经元的输出需要使用激活函数,我们更常用的方法是用sigmoid函数来表示激活函数。sigmoid函数的表达式和分布图如下所示:

(现在通常使用的是ReLU,人们起初并不觉得它的效果会好过 sigmoid 和 tanh。但是,实战中它确实做到了。)

前向传播

神经网络是一种多层的前馈神经网络,其主要的特点是:信号是前向传播的,而误差是反向传播的。
假设从左面一层结点i,j,k,…等一些结点与本层的结点w有连接,那么结点w的值怎么算呢?就是通过上一层的i,j,k等结点以及对应的连接权值进行加权和运算,最终结果再加上一个偏置项,最后在通过一个非线性函数(即激活函数),如ReLu,sigmoid等函数,最后得到的结果就是本层结点w的输出。
最终不断的通过这种方法一层层的运算,得到输出层结果。

矢量化

先前,我们手工对两层、每一层只有两节点的神经网络进行计算。对人类而言,这样的工作量也是足够大了,但是如果要对五层、每层100个节点的网络进行相同的计算,单单是写下所有必要的计算,也是一个艰巨的任务……对每一层每一个节点,计算所有这些组合信号的组合,乘以正确的权重,应用S激活函数……
那么,矩阵如何帮助我们简化计算呢?其实,矩阵在两个方面帮助了我们。首先,矩阵允许我们压缩所有这些计算,把它们变成一种非常简单的缩写形式。由于人类不擅长于做大量枯燥的工作,而且也很容易出错,因此矩阵对人类帮助很大。第二个好处是,许多计算机编程语言理解如何与矩阵一起工作,计算机编程语言能够认识到实际的工作是重复性的,因此能够高效高速地进行计算。
总之,矩阵允许我们简洁、方便地表示我们所需的工作,同时计算机可以快速高效地完成计算。

神经网络中的误差

先前,我们通过调整节点线性函数的斜率参数,来调整简单的线性分类器。我们使用误差值,也就是节点生成了答案与所知正确答案之间的差值,引导我们进行调整。实践证明,误差与所必须进行的斜率调整量之间的关系非常简单,调整过程非常容易。
当输出和误差是多个节点共同作用的结果时,我们如何更新链接权重呢?下图详细阐释了这个问题。

反向传播

神经网络的运作过程如下。

  1. 确定输入和输出
  2. 找到一种或多种算法,可以从输入得到输出
  3. 找到一组已知答案的数据集,用来训练模型,估算w和b
  4. 一旦新的数据产生,输入模型,就可以得到结果,同时对w和b进行校正

通过反向传播把误差传播到每一层,但是怎么调整权重w
使用数学公式计算,解数学方程特别复杂
暴力枚举,当数据量过大时不可行
这时就需要使用梯度下降

梯度下降

简单的公式计算如下:

## 深度学习

深度学习(DeepLearning)的概念由Hinton等人于2006年提出。此外Lecun等人提出的卷积神经网络是第一个真正多层结构学习算法,它利用空间相对关系减少参数数目以提高训练性能。深度学习(DL)是机器学习中一种基于对数据进行表征学习的方法,是一种能够模拟出人脑的神经结构的机器学习方法。(PS:两位大牛因为对深度学习的巨大贡献,因此获得2018年图灵奖)

说白了就是,深度学习就是深层的神经网络,比上面介绍的三层神经网络要复杂的多。

深度学习研究的热潮持续高涨,各种开源深度学习框架也层出不穷,其中包括TensorFlow、Caffe、Keras、CNTK、Torch7、MXNet、Leaf、Theano、DeepLearning4、Lasagne、Neon,等等。但是上图所示的简单的三层神经网络不需要使用任何深度学习框架,可以通过简单的 Python 代码就可以实现,下面主要讲一下实现过程。

Python实现

激动人心的时刻到了,下面直接使用Python代码,实现简单的神经网络。代码的主要框架如下:


# neural network class definition      

class neuralNetwork :     

     # initialise the neural network     

     def __init__() :     

         pass       

    # train the neural network          

    def train() :     

         pass      

    # query the neural network      

    def query() :   

           pass

· 初始化函数—设定输入层节点、隐藏层节点和输出层节点的数量。

· 训练—学习给定训练集样本后,优化权重。

· 查询—给定输入,从输出节点给出答案。

实现的内容为识别mnist库中的手写数字,完整的代码如下:

https://github.com/makeyourownneuralnetwork/makeyourownneuralnetwork

可以查看 part2_neural_network.ipynb ,如果想训练自己手写的图片,可以看part3部分的代码,另外为了增加数据集,也可以对mnist中的图片进行旋转等操作。

向后查询

最后做个有意思的事情,在通常情况下,我们馈送给已受训练的神经网络一个问题,神经网络弹出一个答案。在我们的例子中,这个问题是人类的手写数字图像。答案是表示数字0到9中的某个标签。

如果将这种方式反转,向后操作,会发生什么呢?如果馈送一个标签到输出节点,通过已受训练的网络反向输入信号,直到输入节点弹出一个图像,那会怎么样?下图显示了正常的正向查询和疯狂的反向向后查询的想法。

逻辑S函数接受了任何数值,输出0和1之间的某个值,但是不包括0和1本身。逆函数必须接受相同的范围0和1之间的某个值,不包括0和1,弹出任何正值或负值。为了实现这一目标,我们将输入层重新调整到有效范围,选择的范围为0.01至0.99。

标签0的结果,从图中可以隐约的看到数字0

上图表示了从0-9的结果,是不是有点理解神经网络了呢?

主要参考《python神经网络编程》,感谢作者的讲解。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,923评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,154评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,775评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,960评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,976评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,972评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,893评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,709评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,159评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,400评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,552评论 1 346
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,265评论 5 341
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,876评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,528评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,701评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,552评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,451评论 2 352

推荐阅读更多精彩内容