用心努力
- 引言
- 神经网络基础
一、引言
1、ML与DL的区别
a) 什么是ML呢?
给定一组数据集,ML等效于寻找一个函数,这个函数可以实现预测识别功能。比如,给定一个波形,识别出“你好”,给定一个手写字体图片识别出“2”,给定星期四多云预测出星期六下雨等等。
模型:假设函数的集合(f1,f2,…) ⇒ 训练:挑选最优函数f* ⇒ 预测:测试集
b) 什么是DL呢?
是寻找一个更复杂的函数,这个函数是由多个函数累积起来的,它的学习过程是一个端对端训练,每一个函数会自主的学习。DL通常所指神经网络类模型。DL尝试找出(多层)特征,并给出结果。
举例,机器学习应用于语音识别:
波形 ⇒ DFT ⇒ 频谱图 ⇒ 滤波 ⇒ log ⇒ DCT(离散余弦变换)⇒ GMM ⇒ Hello
除GMM之外,所有的处理函数都是既定的模型,需要手动出算出结果,只有GMM是从数据中学习。
而深度学习应用于语音识别:
波形 ⇒ f1 ⇒ f2 ⇒ f3 ⇒ f4 ⇒ f5⇒ Hello
所有的处理函数都是从数据中学习的模型,不需要太多的领域知识。机器学习和深度学习应用于图像处理也是这样的区别。
小结:
- 机器学习
- 特征工程:手动的,需要专业知识的
- 模型算法:在特征工程的基础上求解最优参数
- 深度学习
- 特征工程:自发的,模型自主学习得到
- 模型算法:在特征工程的基础上求解最优参数
2、神经网络
a) 单个神经元是怎样的呢?
可以看出,单个神经元模型很简单,就是将一个线性模型,丢到一个sigmoid函数(可供选择)里,得到的模型。
b) 神经网络是怎样的呢?
可以看出,神经网络模型是由许多的单个神经元组成,得到一个预测值至少需要一个神经元,那么要得到一个预测值组成的向量,至少需要该向量维度大小个数的神经元。因此,
神经元是一个复杂的函数 f:RN⇒RM
c) 神经网络中神经元越多,层数越深越好?
不是的,具体采用多少神经元,层数设置多深是深度学习的难点,一般工程上都从经验值出发调试。
3、DL的发展背景
a) DL的历史
1969: Perceptron has limitation
1980s: Multi-layer perceptron
1986: Backpropagation
1989: 1 hidden layer is “good enough”, why deep?
2006: RBM initialization (breakthrough)
2009: GPU
2010: breakthrough in Speech Recognition (Dahl et al., 2010)
2012: breakthrough in ImageNet (Krizhevsky et al. 2012)
2015: “superhuman” results in Image and Speech Recognition
b) 为什么DL能在2010后有重大突破呢?
- 大数据
- GPU
c) 为什么速度特别重要呢?
- 训练时间
- 数据量大
- 训练时间过长不利于工程化
- 预测时间
- 用户没有那么多时间成本等待结果
d) 普遍性定理
任意一个连续函数 f:RN⇒RM,都可以由一个只有一层hidden layer的神经网络来取代。
e) 肥的复杂还是深的复杂
当然是深的复杂了,因为肥的只是在同一层线性增长O(2d),而深的是叠加增长的O(d2)。
e) 怎样运用DL
学习算法可以看作,输入(各种专业领域获取的数据)X到所需结果Y的映射: f:X⇒Y
- Input domain:词汇,语句,声音信号,点击率等等
- 要考虑连续性, temporal, 重要性分布
- Output domain:词性,树结构,概率分布等等
二、神经网络基础
像机器学习的训练过程就涉及到3个问题,
- 模型是怎样的?
- 怎么评估一个好的模型
- 怎么挑选最优模型
那这个基础的讲解大纲也按照这几个问题引出。
1、模型是怎样的?
a) 输入输出
一个分类任务的目标函数可以表示为:一个N维向量到M维向量的映射。
f(x)=yf:RN⇒RM
其中x可以是像素,词语等等,y可以是分类类别,词性等等。
b) 神经网络模型
单个神经元
之前已经学习过了,模型也给出了,由线性模型和一个激励函数组成,并且要注意,一般偏值b也是看作一个特征的。这里思考一个问题,为什么需要偏值b?
输出向量x不能改变,假如增大偏值b,那么线性模型的输出z会增大,通过激励函数后的输出会增大,那么划分为+的概率增大,这就赋予了类别的prior,
y=hw,b(x)=σ(wTx+b)
通过控制w,b来控制y,以0.5为临界值,判别图片是否为2。但是单个神经元只能用作二分类。
输出层
单个神经元只能用作二分类,那要辨别0~9怎么办,那就用10个神经元咯,每个神经元只要能辨别,是i或不是i就行咯。那得到了10个y值有好几个都大于0.5怎么办,取最大值咯。
但是呢,输出层每个单元都是独立的,没有权重共享,学习效率很低。感知机只能判断与、或、非的等线性判断,不能判断异或等非线性的。
隐藏层
由异或门电路得到启发,增加layer的层数,能完成非线性的判断,得到隐藏层,为什么叫隐藏层呢,因为只有x和y是给定的,隐藏层的输入z是要模型自己学习的过程中求出来的。
多层神经网络具有更好的表达能力,能够逼近更多更复杂的函数。
DNN
DNN就是Deep Neural Networks,深层神经网络,至少有两层隐藏层。
符号定义
- ali : 表示第l层第i个神经元输出值
- al : 表示第l层输出值
- wli :表示第l-1层第j个神经元与第l层第i个神经元之间的联系
- Wl=⎧⎩⎨⎪⎪wl11wl21...wl12wl22............⎫⎭⎬⎪⎪ :表示第l-1层与第l层之间的所有联系,维度应当是Nl−1×Nl
- bli : 表示第l层第i个神经元从第l-1层获得的偏值
- bl=⎧⎩⎨⎪⎪bl1bl2...⎫⎭⎬⎪⎪ :表示第l层所有从第l-1层获得的所有偏值
- zli :表示第l层第i个神经元激活函数的输入值
- Zl :表示第l层激活函数的所有输入值
激活函数
线性的激活函数很少用,效果不好,一般都是用非线性的。
最常用的非线性激活函数:
- sigmoid
- tanh
- relu:rectified linear unit
为什么偏爱用非线性的呢??
- 假如没有非线性的激活函数,DNN就只能等效于一种线性变换
W1(W2∗x)=(W1W2)∗x=Wx - 激活函数隔离了直接的线性变换,使得模型能够模拟更复杂的映射
c) 损失函数与目标函数
模型架构搭好,那么如何判别这个模型的好坏呢??
模型的函数=模型的参数
神经网络的模型:
y=f(x)=σ(WL...σ(W2σ(W1x+b)))
不同的W,b对应着不同的模型,重新定义模型为f(x,θ)
θ=W1,b1,W2,b2,...WL,bL
那评判模型的好坏就等价为对模型参数的度量。
模型参数的度量
那么定义一个函数来度量模型参数:
- 损失函数( loss/cost/error function)
- 用损失函数来评估模型参数,损失函数值越大,模型参数越差劲
- 最好的模型参数:θ∗=argminθC(θ)
- 目标函数(objective/reward function O(θ))
- 用目标函数来评估模型参数,目标函数值越大,模型参数越好
- 最好的模型参数:θ∗=argmaxθC(θ)
d) 找到最好的模型
提出问题
如何解决最优化问题
- Brute force?枚举所有的θ
- 计算C(θ)的导数?
都不可行!
梯度下降法
假设θ只有一个变量。从θ0开始迭代:
θ1←θ0−η∂C(θ0)∂θ
…
θi+1←θi−η∂C(θi)∂θ
这其中的η呢,是学习效率。偏导的结果会告诉我们θ是往左边走还是右边走,最后找到一个比较好的θ。
假设θ有两个变量了{θ1,θ2}。也是从θ0开始迭代,都是一样的。再多的变量也是一样的。
这其中的η呢,是学习效率。偏导的结果会告诉我们θ是往左边走还是右边走,最后找到一个比较好的θ。
推导过程markdown太难写了,手动推了一下。
gradient descent
但是随着参数的增加,要算的梯度特别多,那怎么解决高效计算的问题呢?利用反向传播。原本理论上的算法是要计算所有样本的squareloss平均值对θ的偏导,样本和参数量大的话,这样的学习速度简直太低了,这是传统的gradient descent。
SGD
那么可以这样想,所有样本的squareloss平均值的期望其实同单个样本squareloss的期望是一样的,那么直接利用单个样本squareloss对θ的偏导做梯度下降。那么就衍生了一个名词epoch,每次只针对一个样本进行求偏导迭代,总共针对k个样本迭代k次,这就代表一个epoch,一个epoch要浏览完所有的数据,一次训练会包含好几次epoch,也就是重复看好几遍数据,就像检查作业似的,与学习速率折衷的情况下是有好处的,这是stochastic gradient descent(SGD)。
Mini-Batch SGD
那么上述两个折衷下,就有mini-batch SGD,也就是针对一定量的样本(不是一个也不是所有)的squareloss求偏导对参数进行迭代。
- 样本总数K
- batchsize为B
- 一个epoch包含K/B次迭代
三者性能比较
Training speed: mini-batch > SGD > Gradient Descent
mini-batch 快过SGD的原因:M×M的速度快过M×V
局部最优
神经网络的算法不能保证一定能得到全局最优!
那么怎么操作会更好呢?随机的从不同点出发进行Mini-Batch SGD得到不同的模型,最终取lossfunction最小的模型
learningrate
learningrate要很小心的去调试,太小速度慢,太大就直接跨过了极小值。
调参总结
- 每个epoch迭代前都对训练样本进行shuffle
- 因为模型可能会记住之前的sample顺序使得学习进度降低
- batchsize要固定
- 因此实施同样大小的矩阵相乘速度会更快
- batchsize越大learningrate最好要小