【课程笔记】神经网络的结构与学习


1. 多层感知机
a. 能够进行复杂的表示
b. 权重设定的工作需要人工来执行 → 解决方法,利用神经网络自动地从数据中学习到合适的权重参数
2. 前馈神经网络
a. 神经元之间的连接只能单向连接,不能反馈(连成一个回环)
b. 层与层之间是全连接
3. 激活函数
a. sigmoid函数:阶跃函数的平滑版本,定义域上处处可导 → 为神经网络的学习提供了数学上的便利
i. 缺点,在x很大时,导数趋近于0。这在神经网络的训练时是不希望看到的(w←w-eta(dL/dw),梯度下降法),如果梯度变到0,意味着w一直固定在这里,训练不动了。
ii. 深度神经网络的训练:涉及到大量梯度的连乘。而对于大量梯度的连乘来说,很可能出现中间有很小的梯度导数,导致网络训练不动了。这也是以前深度神经网络训练不出来的原因之一。
b. ReLU函数(Rectified Linear Unit):缺点,有一个点不可导;优点,>0时导数恒为1
i. 非线性激活函数,大量使用
ii. 断点问题,Tensorflow或者Pytorch都处理好了。早期还有人考虑不同的激活函数,现在基本上没有人考虑这方面的问题了。
c. 输出层的非线性激活函数,一般不用ReLU函数
i. 回归函数:identity函数,恒等函数y=sigma(x)=x
ii. 分类问题:softmax函数,y=sigma(x)=exp(ak)/sum_i(exp(ai));取值范围,0<y<1,sum(yi)=1;意味着输出了离散的概率分布【←概率化的输出的解释,不意味着得到了数据的分布!!!】
4. 符号约定:
a. 输入:x1,x2,…
b. 层:
i. 净输入a:a^(1)_(2),上标是层级,下标是层级下的索引号
ii. 权重w:w^(1)_(12),下标前一个表示输入,后一个表示输出作用于的神经元
iii. 非线性输出z:z^(2)_(1)=h(a^(2)_1),净输入经过非线性激活函数激活之后,得到了非线性输出
c. 输出层:
非线性激活函数需要根据需求来设计
1. 神经网络的学习
a. 向量nabla(y)所指示的方向,是函数增长最快的方向;反之,往nabla(y)的反方向走,则是函数减小最快的方向
i. 注意,nabla(y)不一定是归一化的!!!
b. w' ← w-lambda·(dL/dw),其中d表示partial(偏导数)
i. L:损失函数,定义为预测值和真实值的某种差距,L(y,t),其中y表示预测量,t表示真实量
ii. -(dL/dw),负梯度方向在w轴上的投影系数
iii. lambda,步长
2. 理解学习概念的三个角度:数据驱动的学习;基于数值微分的神经网络学习;基于反向传播的神经网络学习(BP,神经网络中最重要的算法)
a. 数据驱动的学习:网络架构非常成熟(模型到处都是,model zoo);数据是制约瓶颈(找不到足够能够把网络训练出来的合适的数据)
i. 数据→人想到的算法→答案
ii. 数据→人想到的特征量(SIFT、HOG等)→机器学习(SVM,KNN等)→答案 (2012年以前的范式)
iii. 数据→神经网络(深度学习)→答案 (2012年以后,不再去区分哪个部分是特征提取器,哪个部分是分类器;也被称为端到端机器学习end-to-end machine learning)
b. 基于数值微分的神经网络学习:(划分mini-batch→计算梯度→更新参数→重复)
i. 沿着网络的方向,以负梯度方向更新网络
ii. 初始的参数分布:
1) 一种方式:随机猜出来的 → 很可能导致较大的Loss → 利用梯度更新参数分布
iii. 神经网络的学习中所用的指标称为损失函数,L=L(y,t)
1) 损失函数可以使用任意函数,但一般用均方误差和交叉熵误差等等
a) 均方误差:回归问题(输出是一个实数,有大小之分)常用!!
b) 交叉熵误差:E=-sum(tk·logyk)
i) 由于t是独热向量(正确的是1,不对的都是0),因此最小化交叉熵损失函数,等价于极大似然
ii) 分类问题(输出是一个标签,没有大小之分)常用!!
2) 通常不使用识别的精度作为损失函数:(相对于参数的变化)不敏感,有跳跃
3) Mini-batch学习
a) 如果以全部数据为对象求损失函数的和,耗时长甚至算不了
b) 受到计算电视节目收视率的启发,取mini-batch进行计算
c) 分批次进行训练、更新参数。batch的规模取决于显卡(显存的大小决定了一个batch有多大)
d) 一个epoch:把所有的batch过了一遍
i) 不同的epoch,batch的划分通常会不一样
iv. 计算梯度的方法:前项差分,后向差分,中心差分
c. 基于反向传播的神经网络学习:可以用反向传播方法对神经网络进行学习,也可以用数值微分方法进行学习。但是反向传播方法效率高很多
i. 符号约定:连接权,偏置(激活阈值)→净输入,非线性输出
ii. BP算法:
1) 前向计算:Forward Calculation,输入样本x,沿着网络一直计算到输出y(预测值)
2) (获得损失函数)
3) 反向传播:Back Propagation
a) 如何算损失函数J相对于模型参数的导数?【两层网络示例】
i) J对w的导数:链式法则(复合函数求导)
One. 先考虑输出层对应的w:w变化,首先影响的是输出层节点的净输入beta;输出层节点的净输入beta变化,影响的是输出层非线性输出y^hat;输出层非线性输出y^hat变化,导致损失函数J变化
First. dJ/dy^hat:根据J的表达式,可以给出来(用当前已有的值即可,可以不需要数值的微分)
Second. dy^hat/dbeta:根据激励函数的表达式,可以给出来(用当前已有的值即可,可以不需要数值的微分)
Third. dbeta/domega:根据线性求和函数(仿射变换)的表达式,可以给出来(用当前已有的值即可,可以不需要数值的微分)
Two. 再考虑隐藏层-输入层的权重v:v变化,首先影响的是隐藏层的净输入alpha;alpha变化,影响的是隐藏层非线性输出b;b变化,影响的是输出层每一个节点的净输入beta;beta变化,y^hat变化,导致导致J变化
First. 注意,dJ/db=sum(dJ/dbeta·dbeta/db),这里有sum的原因在于,不止一个变量跟b有函数关系
Three. 再考虑激活阈值的更新量:很简单,可以直接写出来
First. 可以直接从J对权重的导数,给出J相对于激活阈值的导数
Second. 原因在于,theta也可以认为是和-1相乘的连接权,它更新的公式应该和权重更新的公式结构一样,只不过需要把输入取成-1
ii) 注意,在推导BP算法的时候,是基于一个样本输入的推导。
One. 实际过程中,往往是算一个batch对应的一个损失值(推导时不这么做,是为了避免角标复杂)
b) 缺点:链式法则公式的乘子数扩张速度特别大,网络深了之后,上述求导的分析方法非人力可为
i) 怎么解决?采用计算图
One. 计算图解题的一般流程:构建计算图;在计算图上,从左向右进行计算(类似于正向传播)
First. 正向传播:从左向右进行计算;反向传播:从右向左进行计算
Second. 计算图的好处:屏蔽一些很复杂的计算,只需要计算输出的结果就可以了;在各个计算节点上,只有一些简单的计算
1. 消耗:中间计算的结果需要保存下来:“快”的实质——用空间换时间
Third. 如何用计算图求导数?(示例)