自学深度学习Pytorch——day02

5.梯度、激活函数、损失函数

5.1 什么是梯度

梯度:所有的偏微分的向量
在这里插入图片描述

梯度的性质:
1.梯度的长度可以反映函数变化的趋势
2.梯度的方向可以表示函数增长的方向

梯度与优化问题:
在这里插入图片描述
鞍点:
一个点,对于一个维度取极大值,对于另一个维度取极小值

影响优化性能的因素:
初始状态、学习率、动量(逃出局部极小值的方法)

5.2 常见函数的梯度

一维函数的梯度即导数:
在这里插入图片描述
f(x) = [y - (x * w + b) ] 2
在这里插入图片描述

5.3 激活函数及其梯度

最早的激活函数:
在这里插入图片描述
sigmoid激活函数:
在这里插入图片描述
sigmoid的求导:
在这里插入图片描述
Tanh激活函数:
在这里插入图片描述
ReLU激活函数:
在这里插入图片描述

5.4 Loss及其梯度

MSE(均方误差)

在这里插入图片描述
L2-norm与MSE的区别在于:L2-norm有开根号,MSE没有开根号

MSE的求导:
在这里插入图片描述
MSE求梯度的示例:
两种方法:
1.torch.autograd.grad(自动求梯度)
2.loss.backward(反向传播,求出所有参数梯度,并主动访问)

 #方法1
 import torch
from torch.nn import functional as F

x = torch.ones(1)
w = torch.full([1],2.0)
mse = F.mse_loss(torch.ones(1),x*w)
print(mse)#输出结果:tensor(1.)

w.requires_grad_()
mse = F.mse_loss(torch.ones(1),x*w)
print(torch.autograd.grad(mse,[w]))#输出结果:(tensor([2.]),)

#方法2
w.requires_grad_()
mse = F.mse_loss(torch.ones(1),x*w)
mse.backward()
print(w.grad)#输出结果:tensor([2.])

5.5 softmax回归

在这里插入图片描述
线性回归的输出输入到softmax回归中,softmax的所有概率输出值相加和为1。

softmax的导数:
在这里插入图片描述
实现softmax的操作和求导示例:

import torch
from torch.nn import functional as F

a = torch.rand(3)
print(a.requires_grad_())#输出结果:tensor([0.2317, 0.3873, 0.8968], requires_grad=True)

p = F.softmax(a,dim=0)
print(torch.autograd.grad(p[1],[a],retain_graph=True))#输出结果:(tensor([-0.0691,  0.2034, -0.1343]),)
print(torch.autograd.grad(p[2],[a]))#输出结果:(tensor([-0.1150, -0.1343,  0.2493]),)

5.6 感知机的梯度推导

简单的单层感知机模型:
在这里插入图片描述
损失函数E与模型表示:
在这里插入图片描述
经过推导可得,损失函数关于某参数wj0的导数:
在这里插入图片描述
单层感知机模型求导示例:

import torch
from torch.nn import functional as F
x = torch.randn(1,10)
w = torch.randn(1,10,requires_grad=True)

o = torch.sigmoid(x@w.t())
loss = F.mse_loss(torch.ones(1,1),o)
loss.backward()
print(w.grad)#输出结果:tensor([[-0.0329, -0.3117,  0.0493, -0.2312, -0.2009,  0.4507,  0.1286,  0.1634,-0.2982,  0.0854]])

多输出感知机模型:
在这里插入图片描述
多输出感知机导数推导过程:
在这里插入图片描述
多输出感知机模型求导示例:`

import torch
from torch.nn import functional as F

x = torch.randn(1,10)
w = torch.randn(2,10,requires_grad=True)

o = torch.sigmoid(x@w.t())

loss = F.mse_loss(torch.ones(1,2),o)
print(loss)#输出loss

loss.backward()
print(w.grad)#输出所有权重对应的梯度

5.7 链式法则

其它的导数运算法则:
在这里插入图片描述
链式法则:
在这里插入图片描述
感知机中的链式法则:
在这里插入图片描述

5.8 反向传播算法

反向传播推导过程:
在这里插入图片描述

优化问题实战

Himmelblau函数:
在这里插入图片描述
在这里插入图片描述
目标:使函数值收敛于极小值点

代码示例:

import numpy as np
from matplotlib import pyplot as plt
def himmelblau(x):
    return (x[0]**2 + x[1] - 11) ** 2 + (x[0] + x[1] ** 2 -7) ** 2
x = np.arange(-6,6,0.1)
y = np.arange(-6,6,0.1)
print("x,y shape:",x.shape,y.shape)#输出结果:x,y shape: (120,) (120,)
X,Y = np.meshgrid(x,y)
print("X,Y shape:",X.shape,Y.shape)#输出结果:X,Y shape: (120, 120) (120, 120)
Z = himmelblau([X,Y])

from mpl_toolkits.mplot3d import Axes3D
fig = plt.figure('himmelblau')
ax = fig.add_axes(Axes3D(fig))
ax.plot_surface(X,Y,Z)
ax.view_init(60,-30)
ax.set_xlabel('x')
ax.set_ylabel('y')
plt.show()

import torch
x = torch.tensor([0.,0.],requires_grad=True)
optimizer = torch.optim.Adam([x],lr=1e-3)
for step in range(20000):
    pred = himmelblau(x)
    
    optimizer.zero_grad()
    pred.backward()
    optimizer.step()
    
    if step % 2000 == 0:
        print("step {}: x = {},f(x) = {}".
             format(step,x.tolist(),pred.item()))

打印出的Himmelblau函数图像:
在这里插入图片描述
迭代过程:
step 0: x = [0.0009999999310821295, 0.0009999999310821295],f(x) = 170.0
step 2000: x = [2.3331806659698486, 1.9540694952011108],f(x) = 13.730916023254395
step 4000: x = [2.9820079803466797, 2.0270984172821045],f(x) = 0.014858869835734367
step 6000: x = [2.999983549118042, 2.0000221729278564],f(x) = 1.1074007488787174e-08
step 8000: x = [2.9999938011169434, 2.0000083446502686],f(x) = 1.5572823031106964e-09
step 10000: x = [2.999997854232788, 2.000002861022949],f(x) = 1.8189894035458565e-10
step 12000: x = [2.9999992847442627, 2.0000009536743164],f(x) = 1.6370904631912708e-11
step 14000: x = [2.999999761581421, 2.000000238418579],f(x) = 1.8189894035458565e-12
step 16000: x = [3.0, 2.0],f(x) = 0.0
step 18000: x = [3.0, 2.0],f(x) = 0.0

6. 分类问题

6.1 逻辑回归

逻辑回归:线性回归输入到logistic function当中,获得[0,1]的值,解决分类问题。

回归问题和分类问题目标和方法
1.回归问题的目标:得到预测值=真实值
方法:使得损失函数最小化
2.分类问题的目标:预测准确率达到100%
方法:使得概率值损失(散度)最小化

6.2 交叉熵

交叉熵:用于计算逻辑回归的损失
熵:消除不确定所需的信息量的度量
在这里插入图片描述

6.3 全连接层

通过线性回归不断堆叠,逐层减少输出神经元个数,直到神经元个数等于标签数。
上一层的输出与下一层的输入之间可以插入激活函数。

应用nn.Module搭建全连接层的步骤:
1.继承nn.Module
2.初始化层
3.执行前向传播

代码示例:

class MLP(nn.Module):
	def __init__(self):
		super(MLP,self).__init__()
		self.model = nn.Sequential(
			nn.Linear(784,200),
			nn.ReLU(inplace=True),
			nn.Linear(200,200),
			nn.ReLU(inplace=True),
			nn.Linear(200,10),
			nn.ReLU(inplace=True),
		)
		
	def forward(self,x):
		x = self.model(x)
		return x

6.4 激活函数与GPU加速

sigmoid和tanh激活函数的缺点:会出现梯度消失问题
ReLU激活函数:有效缓解了梯度消失的问题
LeakyReLU激活函数:在ReLU的基础上,在负区间范围内y = a * x(a很小)

更换设备(示例):

device = torch.device('cuda:0')
net = MLP().to(device)

6.5 测试效果

在这里插入图片描述
评价模型测试性能的指标:准确率、loss
准确率的代码示例:

correct = torch.eq(pred_label,label)
print(correct.sum().float().item() / 4.)

什么时候做测试合适:通常训练了一次或多次epoch之后测试一次

7.深度学习常见问题

7.1 过拟合和欠拟合

y = w * x + b + eps
样本过少容易受到eps的影响,造成模型模拟的能力受到影响。

欠拟合:训练出的模型的复杂度小于真实模型的复杂度
欠拟合表现在:训练的准确率较低,损失较大;测试更是如此
解决方法:增加模型的复杂度

过拟合:训练出的模型复杂度大于真实模型的复杂度
过拟合表现在:训练的准确率较高,损失较小;但测试上表现相反
解决方法:降低模型的复杂度

过拟合现象:
在这里插入图片描述

7.2 交叉验证

通过训练集与验证集的划分,从而检测判断是否存在过拟合现象。
通过多个验证集的划分,得到测试效果最好的参数。
在这里插入图片描述
K折交叉验证:
在这里插入图片描述

7.3 正则化

正则化作用:减轻过拟合

奥卡姆剃刀定理:优先选择更简单的模型

减轻过拟合的方法:
1.增大数据集。2.降低模型复杂度。3.Dropout。4.数据增强。5.提前终止训练。

常见的正则化:L1-正则化与L2-正则化
在这里插入图片描述
正则化之后的效果:
在这里插入图片描述

7.4 动量与学习率衰减

引入动量的目的:缓解模型收敛于局部最优,而非全局最优的问题。

没有引入动量的情况:
在这里插入图片描述
引入动量的情况:
在这里插入图片描述

学习率会带来的影响:
在这里插入图片描述
学习率衰减方法:一开始可以使用较大的学习率,接近收敛时使用较小的学习率,经过几轮逐渐减小学习率大小。

7.5 提前终止和丢弃法

提前终止:在测试效果增加与降低的交界时,终止训练过程,将当前的参数作为训练出的模型参数。

提前终止示意图:
在这里插入图片描述

丢弃法:随机丢弃神经网络层中的神经单元,也就是将参数w设为0。

丢弃法示意图:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值