学习笔记来源于PyTorch官方教程中文版:PyTorch官方教程中文版 (pytorch123.com)
⭐用的Jupyter!可能存在输出和Pycharm不一样的
...这个教程怎么这么难
目录
1. 简介
1.1. Torch与PyTorch
(1)Torch是用小众语言Lua写的,PyTorch是它后来的Python版
1.2. 优势
(1)支持GPU
(2)灵活,支持动态神经网络
(3)底层代码易于理解
(4)命令式体验
(5)自定义扩展
1.3. 不足
(1)不支持快速傅里叶
(2)不支持沿维翻转张量
(3)不支持检查无穷与非数值张量
(4)社区不够强大
(5)在移动端,嵌入式部署以及高性能服务器端的部署其性能表现有待提升
2. 张量
2.1. 初始化张量
(1)torch.empty():构造一个n*m的矩阵并且不初始化(有点像刚刚去郊区围了一片地,里面都还是原始内存里的东西)
①代码
"""就只import这一次,后面略过了,默认有了"""
import torch
"""爱输几维输几维"""
x = torch.empty(5, 3) #如果想要限制格式的话就搁后面,如x = torch.empty(5,3,dtype=torch.long)
x
②结果展示
(2)torch.rand():构造一个随机初始化的矩阵(相当于还要再随机一次)
(3)torch.zeros():构造一个矩阵全为0
(4)torch.tensor():直接构造张量,把数据放进去(记得打中括号)
(5)变量名=变量名.new_ones():将原有的张量(普通变量是不行的,如果之前是int想改张量会报错)改为新的自设定的张量(这两个变量名相不相等完全看自己)
(6)变量名=torch.randn_like(变量名):创建一个和之前格式一样的变量
(7)变量名.size:输出维度信息
(8)加法
①x+y
②torch.add(x,y)
③torch.add(x, y, out=变量名)
④y.add_(x):把x加在y上
(9)变量名.view():把张量变成别的形状的视图
(10)变量名.item():获得value(注意只能是单个元素的tensor)
3. 自动微分
3.1. Tensor
(1)梯度:torch.tensor是torch包的核心类,若将.requires_grad设置为 True,则会开始跟踪针对 tensor 的所有操作。完成计算后,可以调用 .backward() 来自动计算所有梯度。该张量的梯度将累积到.grad 属性中(但是要注意一下给grad要float64的情况下,所以有时候报错,只需要在前面填一个dtype=float就好了)
①初始化代码示例
x = torch.ones(2, 2, requires_grad=True)
②调用代码示例
a = torch.randn(2, 2)
a.requires_grad_(True)
(2)变量名.detach:将变量与历史计算记录分离,即把变量常数化(不能求导了)
(3)with torch.no_grad(): 和detach应该是一样的,只是把代码块包装起来了
(4)张量名.grad_fn:张量的Function的引用
(5)张量名.backward():计算导数
①代码示例(张老师外援的代码,所以这里是pycharm格式)
"""创造一个二维x张量"""
x=torch.tensor([[1,2,3],[4,5,6]],dtype=float,requires_grad=True)
print(x)
"""创建两个都为x构造的函数(纯纯为了测试)"""
y=x*x
z=x*x*x
print(y)
print(z)
"""求导⭐y.backward后面的那个维度好像必须标出来不然会报错
这个1会*所有算出来的梯度 所以随机梯度反向传播也可以写
torch.randn()"""
y.backward(gradient=torch.tensor([[1,1,1],[1,1,1]]))
print(x.grad)
z.backward(gradient=torch.tensor([[1,1,1],[1,1,1]]))
print(x.grad) #测试会不会覆盖
print(y.grad) #测试y能不能打印出grad
②结果展示
首先torch里面张量的乘法都是单个元素乘!
⭐然后很神奇的是第二次x.grad是∂y/∂x和∂z/∂x的和,而不是简单的∂z/∂x覆盖∂y/∂x
以及,函数y和z不能求导,( ╯□╰ )
③代码优化(清空梯度,不然就要叠住了)
"""在第一次print(x.grad)之后就要清空"""
x.grad.zero_()
④优化后结果展示(正常了)
4. 神经网络
4.1. 示意图
(1)数字图片识别
4.2. 参数计算
(1)重更新方法
①w = w - lr*gradient(常用的)
②v=momentum*v-lr*gradient, w = w+v (引入momentum,一般把momentum设为0.9。如果上次的momentum(v)与这次的负梯度方向是相同的,那这次下降的幅度就会加大,从而加速收敛。来源:深度学习中momentum的作用_神经网络momentum_迷上微笑的博客-CSDN博客)
(2)池化的代码
①例子
"""用2*2的窗格池化(即这四个里面取最大的)"""
x = F.max_pool2d(F.relu(self.conv1(x)), (2, 2))
"""如果池化窗口是正方形可以只写一条边的长短"""
x = F.max_pool2d(F.relu(self.conv2(x)), 2)
(3)net.parameters():定义过前馈函数之后,反向传播被autograd自动定义。这个函数可以返回一个模型可训练的参数
(4)torch.optim:含有很多快捷方法的包
①代码
import torch.optim as optim
optimizer = optim.SGD(net.parameters(), lr=0.01)
optimizer.zero_grad() #注意这个的梯度清零和上面x的zero和grad是反着的
optimizer.step()
5. 图像分类器
5.1. torchvision
(1)将image转化为归一化的tensor
①代码示例
transform = transforms.Compose(
[transforms.ToTensor(),transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])