极限速成pytorch
最近在准备搞搞这个自己的毕业设计,复现两篇论文什么的,于是要重新捡起好久不写的pytorch,于是决定简单写一个速成教程。首先,我得讲一下我的速成思想:对比学习+调整,还有速成不等于质量差,仅仅代表高效。
焚电子高香,敲电子木鱼
炼赛博丹药,成赛博神仙
数据操作
这里我们以numpy
作为原本的模板,只指出差异,不处理相同部分,减少学习成本
很好,我们通过看文档发现貌似没什么不一样的,只是把原来的np
改为torch
。
下面不解释的罗列:
1 2 3 4 5 6 7 import torchtorch.arrange(n) torch.shape torch.reshape(Size) torch.zeros(Size) torch.ones(Size) torch.randn(Size)
同样的,torch
中也有numpy
中类似的初始化方法,其使用方式与numpy
一致:
1 2 3 import numpy as npnp.array() torch.tensor()
两者具有完全一致的基本运算、广播机制、索引和切片,所以这块直接可以不学。
转换语法:
1 2 X.numpy() torch.tensor(ndarray)
pandas
转换为tensor
格式
1 2 3 a = pd.read_csv("you.csv" ) my_array = np.array(a) my_tensor = torch.tensor(my_array)
线性代数
其实各种运算和numpy还是基本一样的,除了两个特定的乘法:
1 2 3 4 torch.mv(A,x) torch.mm(A,B)
然后我们研究一点一点不一样的东西,也是会对写网络有帮助的,不同于我们在使用numpy
手搓时,pytorch
是以批为单位进网络训练,所以对轴的操作非常频繁,我以前理解轴,表示非常难记住,然后我查资料发现:轴实际上就是Shape这个list的下标 。
自动微分
y1s1,这应该是pytorch
中最重要的功能了,自动微分提供了一个很大的便利,那就是不在需要人手去写backward
函数,我们也不去纠结什么计算图什么玩意,我们直接上例子:
1 2 3 4 5 6 7 8 9 10 11 12 from torch.autograd import Variablex=Variable(torch.ones(2 ,2 ),requires_grad=True ) y=x+2 y.grad_fn z=y*y*3 out=z.mean() out.backward() x.grad
原理什么的我们不去细究,甚至连参数列表我们也不去细究,就先了解到这儿,知道他很神奇就够了(毕竟一时半会儿也不用)
神经网络
看到这儿除了对自动微分可能有点懵,肯定觉得,pytorch
就这?其实pytorch
是出了名的接口简单,but重头戏才刚开始。这里呢,我么使用我们的传统艺能,拟合sin曲线,来走一个全部的流程,然后就能理解如何操作了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 import torchimport matplotlib.pyplot as pltimport numpy as npimport torch.nn as nnimport torch.nn.functional as Fimport torch.optim as optimfrom torch.autograd import Variablex = torch.linspace(0 , 1 , 100 ) y = torch.sin(2 * np.pi * x) np.random.seed(20 ) y_noisy = y + 0.05 * torch.randn(size=x.shape) plt.figure() plt.plot(x, y, label='True function' , color='g' ) plt.scatter(x, y_noisy, edgecolor='b' , s=20 , label='Noisy samples' ) plt.legend() plt.tight_layout() plt.show()
image-20240221223054399
1 2 3 4 5 6 7 8 9 10 11 12 13 14 class Net (nn.Module): def __init__ (self ): super (Net,self).__init__() self.fc=nn.Linear(100 ,5 ) def forward (self,x ): output=F.tanh(x) output=self.fc(output) output= output[0 ]+output[1 ]*x+output[2 ]*x**2 +output[3 ]*x**3 +output[4 ]*x**4 return output net=Net() criterion = nn.MSELoss() optimizer = optim.SGD(net.parameters(), lr=0.001 , momentum=0.9 )
1 2 3 4 5 6 7 8 9 for i in range (30000 ): y_pred=net(x) loss=criterion(y_pred,y) if i % 2000 == 1999 : print ("epoch:{},mse:{}" .format (i+1 ,loss.item())) optimizer.zero_grad() loss.backward() optimizer.step()
epoch:2000,mse:0.10116397589445114
epoch:4000,mse:0.05751330405473709
epoch:6000,mse:0.034589387476444244
epoch:8000,mse:0.02254333905875683
epoch:10000,mse:0.016206299886107445
epoch:12000,mse:0.012865572236478329
epoch:14000,mse:0.011097476817667484
epoch:16000,mse:0.010154816322028637
epoch:18000,mse:0.009645464830100536
epoch:20000,mse:0.009363631717860699
epoch:22000,mse:0.009201298467814922
epoch:24000,mse:0.0091018071398139
epoch:26000,mse:0.009035366587340832
epoch:28000,mse:0.008986384607851505
epoch:30000,mse:0.008946665562689304
1 2 3 4 5 6 7 8 9 x_test=torch.linspace(0 , 1 , 100 ) y_pred=net(x_test) plt.figure() plt.plot(x_test.detach().numpy(), y_pred.detach().numpy(), label='Regressor' , color='#FFA628' ) plt.plot(x, y, label='True function' , color='g' ) plt.scatter(x, y_noisy, edgecolor='b' , s=20 , label='Noisy samples' ) plt.legend() plt.tight_layout() plt.show()
再要加强的话,就要去学习一些dataloarder等一些包,目前来说就足够了
参考资料
zh-v2.d2l.ai/d2l-zh-pytorch.pdf
PyTorch的自动微分(autograd)_pytorch
自动微分-CSDN博客