zoukankan      html  css  js  c++  java
  • 神经网络的初识

    序:

             本系列是以NeuralNetwork and Deep Learning书为基础,加上自己的见解写得,第一次写系列,不好之处。请指出哦!

    接下来我们会先对神经网络有一个介绍。好让大家明确神经网络是一个什么东西。为了更好的进行学习,在后面会以识别数字为引导,让我们循序渐进学习吧!

             先说些有的没的吧!

    有时候你会不会认为人的视觉系统在这个世界上,是多么伟大的杰作,请看以下的图:

    当我们看到这些数字的时候。我们立即便能够知道这些数字是什么,为什么我们能够这么快的就能够了解呢,难道我们天生就能识别数字吗?我想答案是no。

    我们大脑的神经网络是一个非常复杂的系统(拜托。这但是用了几十亿年进化得来的产物呐!),在这样伟大奇妙的系统的帮助下,我们得以非常快的识别上面的数字。

    接下来,我们遇到的问题是,怎样让计算机来识别这些数字。

    我们不是一直提倡数字化,信息化吗?识别这些数字的功效我想大家都能想到。那么,怎样做呢?或许你会说,上面的数字比較简单啦。不就几张图而已嘛。那么我会说。同学,请看以下的图:

    惊倒了吧!这么多,有时候,事实上有一些数字写得比較草的时候,人也不是立即能够识别这些数字的,只是我们临时忽略连人都不能识别的数字吧。

             那么,我们该怎样開始呢!嘿嘿。我们的主角—神经网络登场啦!

    我想大家一定以前或多或少的听过一些关于神经网络的介绍。但我们在简介一下吧!

    首先。神经网络是机器学习中一个手段啦,机器学习嘛,了解一点的人知道,就是输入数据。训练下。得出一个网络图,然后输入数据就会给出输出了。像我们小时候,老师告诉我们这个字母是A,B,C…然后,我们渐渐的懂得了这些字母。当再给我们一些字母的时候,我们就会明确这些字母的含义。

            

    Perceptrons:

             什么是神经网络,让我们先来介绍一下什么是Perceptrons,是一种人工神经元(嗯哼,翻译的好挫有没有,见谅下哈,假设有更好的翻译请告诉我)。Perceptrons是1950s和1960s,由研究人员 Warren McCulloch 和 Walter Pitts提出,被Frank Rosenblatt发展。

    而今天,有很多其它的神经元被提出,比方sigmoid神经元(我们后面会有介绍),这些神经元在非常多模型中已经相当普遍了。

    总之就是非常火啦。不懂的话就会显得out了啦,所以要懂点了啦!

    而Perceptrons是一个比較基础的。所以我们从基础介绍起嘛。

             好了。废话太多了,进入正题,我想你应该大致学过点生物学,对于神经细胞的工作方式有一点了解,神经元之间传递信号的方式就是前面的神经元向后面的神经元释放一些信号。后面的神经元处理下,再传递给下一个,我说的好像太简单了,让我们看看我们的人工神经元的工作方式。Perceptrons是怎样工作的呢?

             Perceptrons可以处理一些二进制的输入。然后给你一个单一的二进制输出。

             还是用图片说话比較好。从图中看得比較清楚了吧,x1,x2和x3输入。然后得出一个输出。那么输出怎样得到呢?这个人Rosenblatt 提出了一个简单的规则去计算输出。

    他给每个输入都给一个权重,w1,w2,…,权重能够用来表示输入的重要性,(事实上直白点,就是,嗯哼。这个输入不错,给它定个0.8吧,诶哟,这个也不错,定个0.7吧。下个次点。定个0.1吧),这些值会对输出结果产生影响,权重越大,对结果的影响越大(女:“我和你妈掉进水里。你救哪个?”  男:“那得看你们的权重”  开个玩笑啦,嘿嘿)。那么输出是怎样得到的呢?能够这样得到。设定一个值threshhold。然后计算jwjxj假设结果比设定值大,输出1;否则输出0

    公式表达的应该挺清楚的了。接下来。让我们用一个不错的模型来看看。这个神经元怎么用。

           如果有一个露天演唱会,你事实上内心还是比較想去的,但是有一些因素你须要考率下,比方:1那天的天气怎么样? 2你的女朋友或者男朋友是否愿意陪你去? 3那个门票费用是多少?

           让我们分别用x1x2x3来进行表示,x1=1表示天气好,x1=0表示天气糟糕;x2=1,表示你的异性朋友(同性也能够的)愿意陪你去。x2=0表示不愿意;x3=1表示门票费用低,x3=0表示门票费用高。

         好了,定完输入的意义,以下就是你自己对各个因素的重视程度来设定了。

    比方你对天气非常看重,你能够设定w1=6,你对第二和第三个输入不太看重。那么w2=2w3=3,如上面说的,权重就是你对这些输入的重视程度。越大表示越重视。最后,我们须要设定一个threshhold,能够设定为5。但这个比較均衡设定。你也能够设定为3。表示你非常希望參加这个演唱会。终于的输出的意思就是1表示去。0表示不去。

    好了,我们用Perceptrons描写叙述了參加演唱会这个活动。

           看以下的一幅图:

    和上面我们描写叙述的是不是有一些不太一样,中间多了一些神经元,事实上,比較复杂的神经网络就是层次比較多,我们把最左边的叫做输入层,中间的叫做隐含层,最右边的叫做输出层。后面我们会见到很多其它的复杂的神经网络.

           刚刚上面的输出函数中有一个threshhold值,我们在这里做一个略微的改动,编程以下的。

    和公式(1)对照一下我们看到。就是把threshhold移到左边了,这里的b=-threshhold,你能够称为bias(不会翻译还是省省好了。大家记住英文,更原味点)。

             看到这里,你会不会认为上面的神经元有点死板诶,值还要自己设定,多麻烦啊,神经元应该自己能够设定啊。嗯哼,有这个想法就对了,神经网络就是应该自己更新。以下我们来看一看还有一个神经元,这个会自己更新的哦!

    Sigmoid neurons:

             假定我们须要一个可以自己进行学习的神经元,上面的显然不可以达到我们的要求嘛,那么我们该怎么办呢?比方我们的输入是一个扫描的图像矩阵,而且上面都是人写的数字呢?我们遇到这种情况该怎么办呢?

             看一下以下的图:

    改图想要表达的意思是。如果在各输入权重或者bias有一点改变,这些改变导致输出结果output改变了一点,那么我们可以利用这些信息对权重和bias进行改动。让网络变得更符合我们想要的。如果我们的神经网络模型误把“8”读成了“9”。对weight和bias进行改动,让它可以正确的读数字。

             但是假设输出仅仅是0和1的话,那么我们做的一点改变或许并不会对结果产生多大的影响。就是说比較难让结果从0跳变成1。即使我们改动了神经网络模型。让它可以正确的读“9”了,或许中间改变的weights和bias是巨大的,这种话,对于其他的数字。可能会遇上同样的问题,导致最后模型变来变去。并且每次变化都不小。或许你认为不麻烦是不是。但是聪明的你。请细致想想,假设做这些改变本身就须要消耗时间和资源,那么巨大的改变是不是相当消耗资源和时间的事。我们还是不要这样折腾电脑了吧,由于我们可以用更好的模型来进行表示。

    回到这个图,我们做一些改变吧,相同是应对一些输入,我们得到一个输出。可是这次我们的输出不再是0和1这么简单了,我们让输出介于0和1之间的随意值,我们引进一个函数。 σ(wx+b)这个引进是什么呢,我们把σ看成是一个sigmoid 函数。这个函数的定义例如以下:

    更确切的说,我们对于输入X1,X2…,,和w1,w2,…,和b,输出是:

    或许,你会说一句。我去。这个函数是干嘛的,sigmoid函数事实上基本的功能,在我看来,是一种将一个在- ∞ 至 + ∞之间的函数转换为(0,1)区间的函数。而且性质单调的,就是当z越大,则σ(z)越大,反之越小。

    比如,当z趋近于+∞时。σ(z)趋近于1;当z趋近于- ∞时,σ(z)趋近于0。若还是不清楚能够看下图σ(z)的形状。

    如今有了sigmoid函数。我们能够对w和b进行细微的变动。而这些小变动通常会导致output的变化(想想如今函数已经连续了)。用Δoutput来表示output的变化。用Δwj表示在weights的变化。Δb表示在bias的变化,依据微积分。有一个公式

    ∂output/∂wj 和 ∂output/∂b 是偏导数。假设对偏导数不是太了解。不用紧张,记住下面这里表达了,Δoutput是由Δwj和Δb变化导致的。事实上翻翻微积分的一些书,这里的东东都可以看懂的,由于微积分是非常多东西的基础嘛,还是要好好学滴。我们还是假定大家有对高数的了解,所以后面有关数学方面的东东就不再扯太多了。

             如今我们的输出已经是(0,1)区间内的一个实数了。不再是简单的0或1了。在原来的时候,我们推断一个数字图像是否是“9”,输出的是0表示不是“9”。“1”表示是“9”,如今能够设置一个值,比方0.5,当输出>0.5,推断是“9”;反之相反。讲了重要的sigmoid neuron了,以下就要開始设计神经网络了。

    神经网络的结构

             以下我们開始介绍神经网络。而且以数字识别举例。

    (准备好咯,比較好玩的东西来咯!

             先看以下的这幅图:

    上面我们介绍过,最左边的是输入层,里面是输入神经元。最右边是输出层,里面是输出神经元;中间的是隐含层。当然。我们能够有非常多中间隐含层。看下图:

    输入层和输出层的设计是比較直接的。比如,我们想要判定一个手写字符是否是“9”,我们就将改图作为输入,图片一般能够转换为灰度矩阵,用灰度矩阵作为输入处理更方便些。少点其他的推断。当然针对一些其他的推断,有时候还是用原图比較好。

    这些东西都须要详细情况详细分析。如果图片是64 by 64 的图片,能够有4,096=64×64个输入神经元。输出能够就是一个,就想前面说过的,输出少于0.5推断不是“9”,大于等于“0.5”推断是。

             中间层设计方式除了像上面比較直接的方式外。事实上还有非常多其他方法能够对中间层进行设计,一些启示式方法能够用来权衡中间层数和训练时间。这里不再细致详述。

             直至如今,我们讨论的神经网络,都是前一层的结果作为下一层的输入这种方式存在,这种网络我们称为前馈网络(feedforward neural networks),这种网络不会有环的存在。

    另一些网络,比方回归神经网络(recurrent neural networks),这种结构内部可能存在环,感兴趣的能够去差一些资料(资料链接)。

    一个简单是识别手写数字的神经网络

             如今我们进行一个还不错的课题,手写数字的识别。这是一个已经被研究得非常成熟的方向。识别率已经非常高的了。

    看上面的图,我们一般把手写数字的识别分成两部分,一部分是数字的切割,再一部分就是数字的识别了。关于第一部分,有非常多有效的方式能够用来切割。

    与其研究第一个问题。不如把重点放在更困难,更有意思的第二部分。

             以下可能是我们会用到的神经网络的结构图。

    一般我们的输入数据是28×28的像素图。所以我们用784=28×28 neurons作为输入层,每个输入是灰度矩阵值,介于(0,1)之间。越小颜色越淡,反之越深。

             第二层是隐含层。有15个神经元。这些值是能够自己设置试试设置多少精度最高的。

             最后一层是输出层。有10个神经元,每一个输出0或1,为什么不是4个,(2^4=16,所以若依照二进制编码。4个输出神经元就ok了),这个问题能够作为一个有意思的思考题。不了解的能够在评论里面留个言,比方邮箱。我能够发给你答案。

    当然最好自己先思考下哈!

             如今如果我们已经有了训练数据。用x表示输入。每个输入数据是一个28×28=784-维的向量。在向量中的每个值代表灰度值。我们用y=y(x)表示预期的输出。y是一个10维的向量,如果对于一个输入数据x。它相应的是一个6,那么我们的y=(0,0,0,0,0,0,1,0,0,0)T

             接下来看以下的一个函数:

    w表示神经网络中全部的权重,b表示全部的bias,a是神经网络中相应x的输出,     y(x)是预期的输出。所以输出a依赖于w。b。x。那么C(w,b)表示的是什么呢?就是神经网络的输出和相应数据估计输出的差的平方和。为什么要用平方和呢?事实上当然。这里的定义都是人定的。你要是认为不爽。用其它的衡量也是ok的,只是这里用平方和还是比較好滴。想想,如今会怎么样。C(w。b)越大,表示我们设计的神经网络输出和实际输出差距越大。C的值越小,则差距越小。

    “那么我们的目标是什么呢?”“没有误差(蛀牙!嘿嘿)”,仅仅要C(w,b)近于0,那么我们建立的神经网络结构就是一个优秀的模型。

             好了。如今问题就归结为怎样把C(w。b)变得小点。而这个就是Gradient Descent该做的事情了。

    Gradient Descent:

             接触过机器学习的人,对于GradientDescent一定不会陌生的吧。假设你认为对这个算法已经没有问题了。那么能够跳过这段了。以下的介绍主要參考这里LeftNotEasy的介绍文章)。只是请大家注意一下。里面的不论什么公式,仅仅是限于这个Gradient Descent内部介绍用的,后面我们使用Gradient Descent方法时。用的參数名字不一定同样,可是在后面我会标注一下。

    (主要是单独写一个关于Gradient介绍的内容比較麻烦,偷懒下,借鉴一下,并且这篇写得非常好)

    Gradient Descent 在神经网络中的运用:

             事实上我们使用GradientDescent的目的就是找到w和b。依据Gradient Descent方法,我们得出以下的递推规则。

    这里的η就是上面GradientDescent中的步长,依据这个规则我们不断更新w和b,终于趋向于使C最小。

    附加以下的图有利于空间想象一下。

    这样。我们就把Gradient Descent加进神经网络结构中。而且依据上面的推理规则,我们能够不断让结构中的w和b值更加准确。终于达到一个不错的效果。

    stochastic gradient descent:

             如今我们尽管能够进行递推了,只是。你会发现,有一个很大的问题没有解决。就是假设训练数据许多,我们对每一个训练数据都要进行一次Gradient Descent,显然会消耗大量的时间,学习的速度回很很慢。

             为了克服这个问题。能够用stochasticgradient descent方法。随机地从训练数据中挑选一部分数据,如m个,进行标记X1,X2,…Xm,用这一小撮来表示大数据。

    Cx表示表示对于某个训练数据X的C(w。b)。上面能够看到,用m个来表示n个。

    同一时候。我们能够对w和b的更新方式,进一步改进:

    当然。这里要不要m。还是你说了算。能够自己根据实际训练情况,确定最佳的步长。

    一般最佳的步长都是通过大量的測试得出来的一个根据。

             好了,大致的介绍内容就是这些了!

    实现:

             看了这么多,假设你想要动手实践一下,ok,鼓舞啊,数据能够在 MNIST下载,里面的数据都是收集到的专门用来训练的数据。

           当然,针对上面所说的。 Michael Nielsen 也有一个实现。在他的github上(链接),python实现。由于程序须要里面须要安装numpy,scikit-learn,scipy。三个python库,假设你是windows 64位,我在网上没有找到官方的scipy windows 64位的,只是在这里找到了http://blog.csdn.net/zhonghuan1992/article/details/32912557,当然,这里有非常多python的包,上面三个都有,尽管是非官方的,可是还是挺健康的。

    神经网络的初识
  • 相关阅读:
    TDengine 基本操作
    Spark 提交运行 保存结果 流程控制
    Redis 分布式锁
    Linux 基础命令
    HIVE 分桶模式
    EX: 这里是收集的面试题
    使用python批量创建 mysql 表
    Navicat写MySQL触发器,用来同步表
    NXOpen 创建体获取所有边、边端点信息,过虑竖边倒圆水平边倒角
    NXOpen遍历实体移除参数和改色
  • 原文地址:https://www.cnblogs.com/yangykaifa/p/7010518.html
Copyright © 2011-2022 走看看