前言
这篇是个人学习龙曲良老师的pytorch课程的笔记,疑惑地方自己加的内容
一、pytorch引入
1. 自动求导
在深度学习中,我们通常需要训练一个模型来最小化损失函数。这个过程可以通过梯度下降等优化算法来实现。梯度是函数在某一点上的变化率,可以告诉我们如何调整模型的参数以使损失函数最小化。自动求导是一种计算梯度的技术,它允许我们在定义模型时不需要手动推导梯度计算公式。PyTorch 提供了自动求导的功能,使得梯度的计算变得非常简单和高效。
PyTorch是动态图,即计算图的搭建和运算是同时的,随时可以输出结果。在pytorch的计算图里只有两种元素:数据(tensor)和 运算(operation)。
运算包括了:加减乘除、开方、幂指对、三角函数等可求导运算。
数据可分为:叶子节点(leaf node)和非叶子节点;叶子节点是用户创建的节点,不依赖其它节点;它们表现出来的区别在于反向传播结束之后,非叶子节点的梯度会被释放掉,只保留叶子节点的梯度,这样就节省了内存。如果想要保留非叶子节点的梯度,可以使用retain_grad()方法。
torch.tensor 具有如下属性:
- 查看 是否可以求导
requires_grad
- 查看 运算名称
grad_fn
- 查看 是否为叶子节点
is_leaf
- 查看 导数值
grad
针对requires_grad属性,自己定义的叶子节点默认为False,而非叶子节点默认为True,神经网络中的权重默认为True。判断哪些节点是True/False的一个原则就是从你需要求导的叶子节点到loss节点之间是一条可求导的通路。当我们想要对某个Tensor变量求梯度时,需要先指定requires_grad属性为True,指定方式主要有两种:
x = torch.tensor(1.).requires_grad_() # 第一种
x = torch.tensor(1., requires_grad=True) # 第二种
梯度计算
自动求导的核心是反向传播算法(Backpropagation)。反向传播算法是一种高效地计算梯度的方法,它使用链式法则计算每个可导操作的梯度,然后利用这些梯度更新参数。一旦我们创建了可导张量,PyTorch 将会自动追踪所有涉及这些张量的操作,并构建一个计算图。计算图是一个有向无环图,表示了计算过程中张量之间的依赖关系。
import torch
x=torch.tensor(1.,requires_grad=True)
b=torch.tensor(2.,requires_grad=True)
w=torch.tensor(3.,requires_grad=True)
z=w*x+b
z.backward() #反向传播
print(x.grad) #x导数值
print(w.grad) #w导数值
print(b.grad) #b导数值
下面再举一个两阶导数的例子:
import torch
x = torch.tensor(2.).requires_grad_()
y = torch.tensor(3.).requires_grad_()
z = x * x * y
z.backward(create_graph=True) # x.grad = 12
print(x.grad)
x.grad.data.zero_() #PyTorch使用backward()时默认会累加梯度,需要手动把前一次的梯度清零
x.grad.backward() #对x一次求导后为2xy,然后再次反向传播
print(x.grad)
2. 常用网络层
后续详写
二、简单回归问题
1. 梯度下降(gradient descent)
1.1 预测函数
设计一个算法尽可能能够拟合这些数据,帮助我们算出参数w,y=wx就是预测函数
1.2 损失函数(loss function)/代价函数(cost function)
均方误差一般用于回归问题 下面的实战就很显然
对于一个点,误差e1=y1-wx1
使用最小平方误差(Ordinary Least Squares, OLS),即将误差平方
左图w增大,右图点往右走
2. 学习率
每一次更新参数利用多少误差, 就需要通过一个参数来控制, 这个参数就是学习率,也称为步长。
选择最优学习率是很重要的,因为它决定了我们是否可以迅速收敛到全局最小值。
小的学习率需要多次更新才能达到最低点,并且需要花费很多时间,且很容易仅收敛到局部极小值
学习率过大会导致剧烈的更新,可能总是在全局最小值附近,但是从未收敛到全局最小值
最佳学习率迅速达到最低点
新的w=旧的w-斜率*学习率
3. 回归问题实战
这里
三、分类问题引入
1. mnist数据集引入
这里的意思是,图片是28×28的,有点小,但是存放9×9个数字足够了,每个数字有7000个这样的图片,6000用来训练,1000用来测试
2. 矩阵维度
3. 计算loss
one-hot编码方式很适合这种分类问题,因为没有上面那种1<2<3的情况,只需要计算预测值和真实值的差距(欧氏距离)即可。
线性模型很难结局非线性的问题,所以我们这里引入一个比较简单的relu函数,后面详解
然后通过公式计算欧氏距离,找到概率最大的值和索引即可。
4. 手写数字识别实战
这里