文章目录
一、导数、偏微分、梯度
-
导数代表某一自变量附近的函数值变化率
-
梯度指示了函数变化率最大的方向,是向量
-
使用梯度下降算法求解使函数值取尽可能小时的自变量值,算法性能依赖于:①学习率α;②求解梯度时的起始位置
二、深度学习的学习过程(各权值、误差值的求解过程)
① 一般的学习趋势梯度逐渐减小,学习的值逐渐稳定,不同的学习率使得学习过程不一样。应该选择适当的学习率。
② 采用不同的梯度算法得到的学习过程
-
存在全局最优解的情况
-
存在局部最优解的情况
-
实际场景中的局部最优解的情况,很难最终定位在最优解上
-
鞍点
三、影响深度学习学习过程的因素
-
初始化参数
-
学习率
① 设置大了会振荡,可能不会收敛
② 设置小了会学习的很慢
-
动量(如何逃离局部最小值)
综合之前的梯度值以“逃离”局部值区域
-
其他
四、常见函数的梯度
五、激活函数
- 设置后置函数f,主要起到设置阈值的作用
5.1 跳变激活函数
- 采用跳变的处理方式。
缺点:在z=0处不可导
5.2 sigmoid/Logistic激活函数
sigmoid/Logistic激活函数,使处处可导。
适用于:输出为概率预测值、输出值值域在(0,1)之间的等
缺点:由于函数斜率均小于1,在多层结构的神经网络中,反向传播会有梯度弥散问题
-
sigmoid求导
-
pytorch中实现sigmoid
torch.sigmoid(torch) or F.sigmoid(torch)
注:from torch.nn import functional as F
5.3 tanh激活函数
-
广泛应用于RNN的结构中
-
主要特征与sigmoid一致,相当于sigmoid向下平移了0.5
-
tanh求导
-
pytorch中实现tanh
torch.tanh(torch)
5.4 Relu(Rectified Linear Unit)激活函数
- 斜率固定,主要解决梯度弥散\爆炸问题
- pytorch中实现relu
torch.relu(torch) or F.relu(torch)
六、Loss函数
- Loss用于表示深度学习学习的函数值与实际值之间的 “相似” 关系,loss越小学习的函数越准确
6.1 均方差MSE ∑ ( y − y ‾ ) 2 \sum(y - \overline y)^2 ∑(y−y)2
-
MSE求导
-
pytorch实现MSE梯度求解
① F.mse_loss(pred,label)
设置MSE loss函数
a) pred:预测值
b) label:标签真实值
② torch.autograd.grad(loss,[param1,…])
自动求导数,函数返回参数的导数
a) y:loss的函数值
b) param1…:表示梯度下降求解的参数变量
③ w.requires_grad_()
设置tensor需要更新
④ mse.backward()
自动求导数,模拟反向传播,所有的梯度信息,均赋给参数的grad成员变量中,该函数无返回值
6.2 softmax
适用于多分类情况的概率输出层,可以探知预测为不同类别的概率值大小
- softmax求导的公式
七、感知机
7.1 梯度推导过程 — 单层感知机(激活层使用跳变函数)
-
方向传播的对应参数的梯度值
-
pytorch的实现
7.2 梯度推导过程 — 多层感知机(伪全连接层)
- pytorch实现
八、链式法则
- 多层间的链式变量求导
- pytorch实现
九、MLP(Multi-Layer Perceptron 全连接层结构)反向传播
存在:输入层、隐藏层、输出层的结构
- 推导公式总结
十、实战pytorch API使用
-
目标求自变量梯度的函数为:
-
已知的最小值位置:
-
利用pytorch实战求解
# -*- coding: UTF-8 -*-
'''
@version: 1.0
@PackageName: pytorch_learning - pytorch_grad_demo.py
@author: yonghao
@Description: 使用pytorch API解决问题的练习
@since 2021/02/21 23:01
'''
import torch
import torch.nn.functional as F
# 定义求最小值位置的函数
def himmelblau_function(x):
return (x[0] ** 2 + x[1] - 11) ** 2 + (x[0] + x[1] ** 2 - 7) ** 2
# 定义求解过程
def run():
# 学习率
learning_rate = 1e-3
# 初始位置
x_inital, y_inital = 4., 0.
x = torch.tensor([x_inital, y_inital], requires_grad=True)
# 定制梯度下降学习公式
optimizer = torch.optim.Adam([x], lr=learning_rate)
for step in range(20000):
pred = himmelblau_function(x)
optimizer.zero_grad()
pred.backward()
optimizer.step()
if step % 2000 == 0:
print('step {}: x = {} , f(x) = {}'.format(step, x.tolist(), pred.item()))
if __name__ == '__main__':
run()