zoukankan      html  css  js  c++  java
  • 深度学习笔记(一):logistic分类【转】

    本文转载自:https://blog.csdn.net/u014595019/article/details/52554582

    这个系列主要记录我在学习各个深度学习算法时候的笔记,因为之前已经学过大概的概念,所以这轮学习比较着重于公式推导和具体实现,而对概念上的描述不多,因此比较适合对此有一定基础的同学。

    在正式开始写深度学习的知识之前,会有两节传统神经网络的内容,因为深度学习中大量运用了以往神经网络的知识。搞懂传统的神经网络如何工作是很有必要的,有助于对之后的学习打下坚实的基础。


    1. logistic分类

    几乎所有的教材都是从logistic分类开始的,因为logistic分类实在太经典,而且是神经网络的基本组成部分,每个神经元(cell)都可以看做是进行了一次logistic分类。

    所谓logistic分类,顾名思义,逻辑分类,是一种二分类法,能将数据分成0和1两类。

    logistic分类的流程比较简单,主要有线性求和,sigmoid函数激活,计算误差,修正参数这4个步骤。前两部用于判断,后两步用于修正。本文分为3部分,前2部分讲普通logistic分类的流程,第三部分则稍作扩展。


    1.1 线性求和以及sigmoid函数

    第1,2步是用于根据输入来判断分类的,所以放在一起说。假设有一个n维的输入列向量 xx,也有一个n维的参数列向量hh, 还有一个偏置量b, 那么就可以线性求和得到z. 

     
    z=hTx+bz=hTx+b

    此时因为z的值域是[,+][−∞,+∞] ,是无法根据z来判断xx 到底是属于0还是1的。因此我们需要一个函数,来将z的值映射到[0,1]之间, 这就是激活函数。激活函数有很多种,这里的激活函数是sigmoid函数。 

     
    σ(x)=11+exσ(x)=σ(x)(1σ(x))σ(x)=11+e−xσ′(x)=σ(x)(1−σ(x))


    其形状为 

    这里写图片描述 
    图1 sigmoid函数


    可以看到x越大,σ(x)σ(x)越接近1,反之,则越接近0. 那么在判断的时候,我们首先对之前得到的z代入sigmoid函数 

     
    a=σ(z)=σ(hTx+b)a=σ(z)=σ(hTx+b)


    当 a 大于0.5的时候,我们判定x应属于1类,如果小于0.5,则属于0类。这样,就完成了判断的工作


    1.2 误差计算以及参数修正

    上面完成的判断过程中用到了参数向量h和偏置量b。 可以说,h和b的值直接关系到logistic判断的准确性。那么这两组参数是如何获得的呢?这就涉及到了参数的修正。在最开始的时候,h中的值是随机的,而b的值是0. 我们通过不断的训练来使得h和b能够尽可能的达到一个较优的值。

    那么如何训练呢?假设我们期望输入x的判定是y,而实际得到的判定值是a,那么我们定义一个损失函数C(a,y),通过修正h和b的值来使得C最小化,这是一个优化问题。在凸优化问题中,可以通过 

     
    Ch=0,Cb=0∂C∂h=0,∂C∂b=0


    来直接算得h和b的最优解。然而在某些情况下,例如数据规模很大,或者非凸优化问题中,则不能这么做,而是用迭代的方法来得到局部最优解。 

     
    h:=hηChb:=bηCbh:=h−η∂C∂hb:=b−η∂C∂b


    其中 ηη 表示学习率。在这里,我们把损失函数定为平方损失函数,即C=12(ay)2C=12(a−y)2 那么可以得到 

     
    Ch====Cah(ay)σ(z)h(ay)σx(ay)a(1a)x∂C∂h=C′∂a∂h=(a−y)∂σ(z)∂h=(a−y)σ′x=(a−y)a(1−a)x


     
    Cb=(ay)a(1a)∂C∂b=(a−y)a(1−a)

    这样,就能够得到每次迭代的参数更新公式为 

     
    h:=hη(ay)a(1a))xb:=bη(ay)a(1a))h:=h−η(a−y)a(1−a))xb:=b−η(a−y)a(1−a))

    1.3 将logistic扩展到多分类

    从之前可以看出,普通的logistic只能进行二分类,即只能够分为0或者1。那么如果这些样本属于多个类该怎么办呢?人们想了很多办法,例如一对多法,依次把某个类别的样本归为一类,其他剩余的样本归为另一类,这样k个类需要构建k个分类器。还有一对一法,在任意两类样本之间设计一个分类器,k个类需要k(k-1)/2个分类器。

    在这里,我们将输出由一个值更改为一个向量。例如有3个类,那么输出就是一个长度为3 的列向量,对应项的值为1,其他为0.即 

     
    ⎡⎣⎢⎢100⎤⎦⎥⎥⎡⎣⎢⎢010⎤⎦⎥⎥⎡⎣⎢⎢001⎤⎦⎥⎥[100][010][001]


    分别表示第0,1,2个类。 也可以看成是原来若干个logistic分类器组合在一起。对应的某个分类器只对该类输出1,其他情况都输出0.从这一点上来讲,这个做法有点类似于一对多法。此时,由于输出从一个数成为一个向量,之前的公式都要加以修改。首先,原来的y,a,z,b变成了列向量, 向量hh变成了矩阵W。这样,判断部分的公式变为 

     
    z=Wx+ba=σ(z)z=Wx+ba=σ(z)


    此时的σσ函数表示对向量中的每一个元素单独做运算。即 

     
    σ(x)=⎡⎣⎢⎢⎢⎢σ(x1)σ(x2)σ(xn)⎤⎦⎥⎥⎥⎥σ(x)=[σ(x1)σ(x2)⋮σ(xn)]


    得到的a向量中,其最大值所在的位置索引即为判断出的分类。 
    参数修正部分的公式也是类似的, 

     
    CW=(ay).×a.×(1a)×xTCb=(ay).×a.×(1a)∂C∂W=(a−y).×a.×(1−a)×xT∂C∂b=(a−y).×a.×(1−a)


    注意有些向量之间是进行点乘的。

  • 相关阅读:
    Spark 之 内存模型
    Python 之 windows上安装和pycharm 使用
    Kafka之 kafka消费->SparkStreaming|写入->Kafka|kafka消费->hbase
    SparkStreaming之 任务失败后,自动重启
    微信小程序常用赋值方法小结
    eclipse中xml文件Ctrl+左键不跳转解决办法
    SpringCloud简介以及相关组件
    spring怎么设置定时任务
    Http协议请求的不同类型
    Spring各个jar包作用
  • 原文地址:https://www.cnblogs.com/zzb-Dream-90Time/p/9634905.html
Copyright © 2011-2022 走看看