深度学习入门...小鱼书
数据是学习的核心
概念梳理:
1.感知机:
感知机是二分类的线性分类模型,感知机的目的是求出将输入数据划分为两类的分离超平面。
他需要合适的,符合预期的权重才能够正常工作。
感知机是构成神经网络的最小构成单位。可以理解为神经元的仿生结构。
2.神经网络:
历史:
1958年,计算科学家Rosenblatt提出了由两层神经元组成的神经网络。他给它起了一个名字--“感知器”(Perceptron)(有的文献翻译成“感知机”,下文统一用“感知器”来指代)。
感知器是当时首个可以学习的人工神经网络。Rosenblatt现场演示了其学习识别简单图像的过程,在当时的社会引起了轰动。
人们认为已经发现了智能的奥秘,许多学者和科研机构纷纷投入到神经网络的研究中。美国军方大力资助了神经网络的研究,并认为神经网络比“原子弹工程”更重要。这段时间直到1969年才结束,这个时期可以看作神经网络的第一次高潮。
模拟人类神经元的工作机理。由输入,输出和计算功能组成,分别照应了人类神经元中树突,轴突,细胞核的功能。输入接受信号由计算做出反应并将反应信号输出。--摘抄
在形式上,神经网络是节点与连接构成的网络,每个连接上存在一个“权重”,将输入的信号计算加权后输出给下一个神经元便完成了一次神经传递。
神经网络可分为单层神经网络(即为感知机),和多层神经网络,层数=输入层+隐藏层+输出层-1在意义上感知机层数与实际与权重有关,也有些人会层数=输入层+隐藏层+输出层与层的数目有关,本书使用的是前者。感知机没有隐藏层,只有单次权重。
3.权重:权重是神经网络中最重要的东西。权重的合适程度直接决定了神经网络是否是优良的。训练一个神经网络就是使其权重达到最佳的过程。
在权重作用的过程时,即节点与节点间传输信号的过程中偏值也起了一定的作用,偏值会改变神经元被启动的难易程度。
神经元能否被启动取决于传入的信号是否达到峰值,偏值影响峰值大小。
4.计算:计算在神经元中进行,神经元具备存储和计算的功能。将输入(x)与输出(y)挂钩的函数(f(x))我们称之为激活函数,激活函数代表的神经元中枢细胞体对输入的数据进行反应的过程。
正常神经的反应过程是:输入的信号传至细胞体,细胞体对信号进行判断后输出新的信号并输出。
5.激活函数:
激活函数旨在帮助神经网络学习数据中的复杂模式。在神经元中,输入的input经过一系列加权求和后作用 的另一个函数。
----摘抄[深度学习笔记:如何理解激活函数?(附常用激活函数) - 知乎 (zhihu.com)]
激活函数可以适用在复杂环境中,人类神经元的传递过程是复杂的,倘若只用权重来改变输入和输出,那么无论电脑神经网络在形式上(隐藏层数目多少)有多么复杂,其最后的结果仍会是线性相加的结果,其复杂度难以达到人类神经网络的复杂程度。
插入片段:文本内容记录:
回归问题和分类问题。
不管是分类,还是回归,其本质是一样的,都是对输入做出预测,并且都是监督学习。说白了,就是根据特征,分析输入的内容,判断它的类别(分类),或者预测其值(回归)。
两者的含义近似对立,分类问题即将事物归类,就像把人按照性别分为男女,按照身高规定大于1.7米为高否则为低,其结果是离散的。而回归问题则是根据已有数据进行预测
两者都可以用来判断:对于身高,分类问题的判断会根据标准给出这个人是否可以被分到高的一组,其输出的结果只能为是或否。而回归问题则是根据视觉感受判断这个人的身高,其输出的结果可以是连续的一串数字。
两者都可以用于预测:在天气预报中,预测天气,只能在晴,雨,阴,雪中选择,此为分类问题。而在预测气温时,通常给出的是一个区间,此为回归问题。
结果的离散和连续为结果特征的差别,其本质区别在于损失函数的形式不同
6.损失函数:
当大学生在宿舍中攀比谁的电脑性能更好时,如果我们只是说电脑的价格,电脑的硬件,不太清晰的人是无法听懂的,也不明白其中的价值,但如果使用类似某大师的跑分程序,我们可以获得直观的电脑评分,通过电脑的评分我们能够轻松选看出谁的电脑的性能更高。
损失函数在这里就起到了一个跑分的作用,不过损失函数的结果表明的是神经网络的恶劣程度,即损失函数的结果越大,神经网络的准确性越差。
损失函数表明的是神经网络返回预测值与真实值的差异程度。预测值与真实值之间的差异值被称为损失值。
损失函数的工作原理:损失函数利用于训练神经网络的过程中。测试数据(批)被送入神经网络并且返回预测值,损失函数利用预测值和真实值求出损失值,之后神经网络根据损失函数的结果反向传播更新各个参数,使得后来的损失值减小,使得神经网络向真实靠拢,达到学习的效果。
将神经网络的准确率具象化为损失函数的结果,通过损失函数计算神经网络调整前后的结果来判定对神经网络的调整是否是进步的。同时,将神经网络进步这个抽象问题转化为损失函数缩小这个具体的数学问题,同时函数的性质也为如何提高神经网络的准确率提供了依据。
作为函数,损失函数可以通过求某一点的导数(具体来说是梯度)来了解该点的走势,然后以这个导数为指引,逐渐更新参数。
one-hot表示
y = [0, 0, 1, 0, 0, 0, 0, 0, 0, 0]
t = [0.1, 0.05, 0.6, 0.0, 0.05, 0.1, 0.0, 0.1, 0.0, 0.0]
# t是用one-hot表示的真实值,y是用softmax函数生成的预测值(概率值)。
# one-hot表示中只有正确选项标记为1错误选项标记为0
# 在10个数中,只有“2”数字是正确的(从0开始数)其概率是0.6也就是说该神经网络在
# <此次>测试中有0.6概率正确。
梯度法:
为了了解梯度,我们先了解导数以及导数在程序中的实现。
导数表明可以表明函数图形中某个点的变化趋势,包括变化方向(增大还是减小),导数大于0,则此处的函数值随着自变量的增大有增大的趋势;变化速率,导数的绝对值越大,则表明该点函数值的变化快。
如果要在程序中利用导数,了解导数的图形含义是必要的,因为程序中求导的方法就是利用的图形意义。
导数的图形意义:导数的值等于函数图像中以该点为切点的切线的斜率。
如果是直线,该点的切线斜率也就是直线斜率,曲线的斜率我们会利用微分的方法求得
f(x+Δx) - f(x)
k = lim ---------------# 将x+Δx 和x两个函数点连线,当Δx趋向于0时,该
Δx->0 Δx 连线近似趋向于点x处的切线。
上式为导数的图形理解
但是在深度学习中,我们一般使用下式
f(x+Δx) - f(x-Δx)
k = lim ---------------
Δx->0 2*Δx
导数的程序实现:
def numerical_diff(f, x):
h = 0.0001
return (f(x+h) - f(x-h)) / 2h
在上面的解读中,我们提出要求h无限趋近于0,但是因为在程序中存在舍入误差的缘故(是指因省略小数的精细部分的数值(比如,小数点第8位以后的数值)而造成最终的计算结果上的误差)
即 h = 1e-50
print(h)
>>>0.0
因为h数字极小导致最后结果变为0.0使得导数的结果与正确值相差甚远。
同时,因为h并不能像理想的那羊无限接近于0,所以如果最后➗h的结果的误差也会变大,为了缩小误差,取x前后各一个h的距离的两个点所连成的直线的斜率近似表示为x处的切线的斜率。这种算法也成为中心差分。
批mini-batch(小批量处理):
批是一种处理数据的方式,用通过样本近似代替整体的方法缩小计算量。
批大小的选择必须合适,过小的数据量难题代表整体,过大的数据量又无法显著达到减小计算量的目的。
减小计算量的益处:
1.当有1000个测试数据时,如果直接把1000个数据投入神经网络中计算,可能会对计算机的配置提出更高的需求,其次即便配置过关,其运行速度也不一定能达到理想状态。但如果将1000个数据分成10组,每次只投入100个数据,其对电脑的配置要求更低,同时,通过矩阵的并行性来缩短计算的时间,也可以使用多线程的方法来缩短计算时间(同时进行多个批次的处理,占用不同的进程,所以时间线上不冲突)。(当然,如果你只有10个小数据,那么再分成10个1份明显有些画蛇添足,所以要考虑每批的大小,和数据总量的大小问题)
2.如果数据的量级过大,比如上百万,上千万甚至是上亿的程度,我们也可以用分批的方法,随机选择一部分数据作为样本数据,用这部分样本数据作为测试数据进行操作。即将测试数据分批,但是只选取其中几批进行操作。
常用激活函数:
恒等函数:将输入的值原封不动的输出
阶跃函数:
# 类比人类神经元,可以理解为只有当传入神经元的信号强度高于阙值才会使细胞体做出相应的反应。
而在阶跃函数中,阶跃代表这里输出的结果是具有跳跃性的,于分类问题性质类似。
--f(x) = 0 x <= 0
--f(x) = 1 x > 0
Sigmoid(Logistic)函数:
# f(x) = 1/1+exp(-x)
# exp(-x)表达的是e的-x次(e**-x)
# 不难看出这个激活函数的返回值介于(0:1)之间
缺点:将输出的结果定于0到1之间,实现了神经元输出结果的归一化。
这个梯度平滑,且函数可微分,前者能够避免了输出值的大幅度变化并利于后续神经网络的学习,后者是梯度下降法的基础。
不足:
其函数图形呈现”s“形,两端趋向于水平,即两端的导数结果极小,此处在神经网络学习过程中,权重可能出现不更新的结果,同时与之相连的神经元的更新速度也会被减慢。
计算成本高,因为此处使用了exp。
不以0为中心。
Tanh(双曲正切函数):
f(x) = 2/(1+exp(-2*x)) - 1
Tanh(x) = 2*Sigmoid(2x) -1
这个函数与sigmoid函数的一些区别
首先,该函数的输出结果介于(-1,1)之间,并以0为中心。
但依然保留了Sigmoid函数两端的导数偏向0的问题(梯度消失问题)
Softmax函数:
>>> a = np.array([0.3, 2.9, 4.0])
>>>
>>> exp_a = np.exp(a) # 指数函数
>>> print(exp_a)
[ 1.34985881 18.17414537 54.59815003]
>>>
>>> sum_exp_a = np.sum(exp_a) # 指数函数的和
>>> print(sum_exp_a)
>>> 74.1221542102
>>> y = exp_a / sum_exp_a
>>> print(y)
"""
e**ak
yk = -------- 分母代表所有输入数据经此括号内运算后求和
sum(e**ai)
将上一层的原始数据进行处理,返回一个介于0.1之间的数字,通常用来标识概率问题。
softmax处理数据的意义:
softmax将数据的原始输出转化为概率分布只能作为softmax的特征,而不能作为softmax的意义,意义应该表明其益处,也就是说,softmax的意义应该包括但不仅限于转化为概率分布所带来的便利性。防止有人将只看到softmax的概率归一化处理而忽略其他优点。
包括后续对交叉熵损失函数使用的遍历以及求导的裨益,视觉上的直观性。
"""
REUL函数:
-----f(x) = 0 x <= 0
-----f(x) = x x > 0
# 当 x 大于0时x不变,小于等于0变为0
优点:
一定程度上避免了Tanh和Sigmoid函数中梯度消失的问题。
计算速度更快。
被认为具有生物学合理性(Biological Plausibility),比如单侧抑制、宽兴奋边界(即兴奋程度可以非常高)
不足:
当输入为负数时失效
不已0为中心
【Dead ReLU问题】ReLU神经元在训练时比较容易“死亡”。在训练时,如果参数在一次不恰当的更新后,第一个隐藏层中的某个ReLU 神经元在所有的训练数据上都不能被激活,那么这个神经元自身参数的梯度永远都会是0,在以后的训练过程中永远不能被激活。这种现象称为死亡ReLU问题,并且也有可能会发生在其他隐藏层。
恒等函数:
f(x) = x
即为恒等。
细节:
softmax与sigmoid函数类似,其返回的结果都是介于0~1之间。其中softmax函数各项结果之和为1,因为这个特性,softmax又被称之为概率函数。在"softmax"这个单词中,“soft”意思是软的,“max”代表最大值。
softmax适合用于解决二分类问题。二分类是一种特殊的分类问题,其结果只有对错,好坏两种分类。在二分类问题中,softmax可以将概率转化为两种结果的概率。
当激活函数使用softmax函数时,损失函数常常使用交叉熵函数:
交叉熵函数常用于评估概率分布之间的差异,与softmax得出概率的性质相适应。
在神经网络输出的值非常大的时候,直接使用这些数值进行计算容易造成的数值溢出的结果,通过softmax归一化处理可以有效避免这种情况。
常用的损失函数:
--->y为预测值
--->t为真实值
--->k为总数
均方误差损失函数(MSE):
res = 0
for i in range(k):
res += (y-t)**2
return res/k
"""
形式与方差类似,不同的是y为预测值,t为真实值。
"""
交叉熵误差损失函数:
E = -t1 * ln( y1 ) - t2 * ln( y2 ) - …… - tk * ln ( yk )
神经网络的学习随机梯度下降法(SGD):
关于数据对于神经网络学习的重要性:
神经网络的特征就是可以从数据中学习,数据是神经网络学习的基础。
从数据中寻找答案、从数据中发现模式、根据数据讲故事……这些机器学习所做的事情,如果没有数据的话,就无从谈起。因此,数据是机器学习的核心。这种数据驱动的方法,也可以说脱离了过往以人为中心的方法。--《深度学习》
学习意味着神经网络可以根据已有数据对网络中的权重进行调整。
在第三章中,神经网络的学习体现在神经网络的函数的值从当前位置沿着梯度方向前进一定的距离的过程,这里我们用二维状态下的球过坡来描述这个问题。
其中学习率(lr-->learning rate)决定前进的速度。
step_num表示前进移动的次数
为了方便接下里的理解,我们引入一个现实问题:这里有一个小球放在斜坡上,受到重力和摩擦力影响,小球会在斜坡底部往复运动且其运动的高度会不断降低,假如时间无限延长下去,小球总会有停下的时刻。
我们将现实问题映射在神经网络的学习中:斜率的绝对值代表滚动的速度,斜率的正负代表滚动的方向,由learning rate(下文写作lr) 和 setp-num(sn代替),这里的时间是分段的lr代表每一段的时间有多少,而sn代表时间段数的多少,速度的大小只会在时间节点的开始发生变化,并且是瞬时变化,即每一段lr会存在一个不变的速度。因为时间的定义问题产生了一些与上文引述的现实问题不同的现象。比如:
1.在这里小球的运动状态会存在这样的几种情况。若lr的数值很小,如果sn也很小那么会出现小球还没怎么动,距离谷底仍然有较打距离时结束,学习的结果不佳。如果要通过增大sn的数值来提高学习的最终效果,以下面这个例子来介绍
# 一个简单的f(x) = x**2 的例子来介绍
a1 = 3
for i in range(sn):
a1 -= lr * (a1 * 2)
print(a1 , i)
# 不难知道,这个函数的谷底是当x = 0时,那么x = 0就是我们的目标了
# 条件1:如果lr = 0.02 , sn = 100,最后的结果大约是0.05
# 2:但如果设置lr为0.01 sn = 100 最后的结果是0.397 # 这里的结果省略了小数
# 如果lr = 0.01想到达到和条件1一样的效果需要200次数
# 如果lr = 0.005,则需要400次
# lr = 0.0025需要800次
# 这个简单的函数中,不完全统计可以推测lr每少一半,sn要提高一倍。
2.学习率过大,小球每一步的跨度过大,导致本该在谷底附近减速的小球没有减速而穿过谷底后又再次上升。此时,如果小球能够停在谷底附近,那么接下来小球仍会被约束在谷底附近且靠近谷底,但是另一种情况如果小球攀升的高度过大,这意味着小球从右坡向下走的速度仍会较大,如果在这段lr中小球再次经过了谷底并且超过了起始位置,这意味着小球很有可能会不断偏离谷底,而无法达到学习的目的。
为了让小球最后停止的位置接近于谷底,从理论上讲,如果时间可以无限延长,那么学习率越小越好,但事实上却存在一个时间上的取舍问题。如果只是减小学习率,会减慢学习的效率,同时,如果学习提前停止了,那么学习的效果差-->需要提高学习次数,但是学习次数的提高同样伴随着学习时间的提高(计算成本与时间-->学习成本)。
同时,学习效果过强同样面临着过拟合的结果,特别是在训练数据中,如果损失函数结果过低,导致神经网络在特别适应训练数据的情况下排斥后来的测试数据,使得其对数据处理的泛化能力降低。在真实世界的数据还包括噪声和许多不确定性因素,过拟合的表现可能会导致神经网络对这些不确定因素的处理能力下降。
当然,神经网络中损失函数结果过低也不意味着一定会出现过拟合现象,这取决于算法的复杂度,训练策略和训练数据的特征。
误差反向传播:
反向传播算法是梯度下降算法在神经网络中的实现方式,由于深度学习网络是按层深入,层层嵌套,对深度学习网络目标函数计算梯度的时候,需要使用反向传播的方式由深到浅倒着计算以及更新参数。
随机梯度性下降法中:我们要求的是损失函数的结果对权重的微分,但是在多层神经网络中,权重的数量并不唯一,而我们需要的是损失函数结果对所有权重的微分,我们知道,神经网络以层划分,层与层之间是相互关联,这种情况下合理利用链式法则的特性大有裨益。
链式法则的应用:在神经网络的学习中,我们将神经网络看作是一个复合函数,其中每一层看作复合函数中的一个单独函数,利用下述导函数的特性可以关联每一权重对损失函数结果的影响。
# 导函数的特性:
# 对于f(x)而言
# f(x)对x的导数等于df(x)/dx,*此处的df(x) and dX都可以看作是一个独立的数值*
# 假如此时还有一个变量名为y.记f(x)的导数为z
df(x) df(x) dy df(x) dy
z = --------- = -----------*------ = ------- * -------
dx dx dy dy dx
也就是最终f(x)对x求导的结果变为了f(x)对y求导的结果乘以y对x的求导结果反过来也是如此的
当f(x)为最终的损失函数,y、x……代表每一层输出的结果,相邻结果的导数为权重。
如此,从输出层开始反向递归每一层的梯度并储存起来,再根据梯度下降等优化算法来更新模型的权重。
标签:函数,导数,结果,学习,神经网络,softmax,深度 From: https://www.cnblogs.com/zonghongqi/p/18075948