PyTorch的线性回归

「爱情、让人受尽委屈。」 2021-11-16 23:02 669阅读 0赞

PyTorch深度学习框架库之一,是来自Facebook的开源深度学习平台,提供研究原型到生产部署的无缝衔接。
本文旨在介绍PyTorch基础部分,帮助新手在4分钟内实现python PyTorch代码的初步编写。
coding前的准备
需要在电脑上安装Python包,导入一些科学计算包,如:numpy等,最最重要的,别忘记导入PyTorch,下文的运行结果均是在jupyter notebook上得到的,感兴趣的读者可以自行下载Anaconda,里面自带有jupyter notebook。(注:Anaconda支持python多个版本的虚拟编译环境,jupyter notebook是一个web形式的编译界面,将代码分割成一个个的cell,可以实时看到运行结果,使用起来非常方便!)
软件的配置和安装部分,网上有很多教程,这里不再赘述,纸上得来终觉浅,绝知此事要躬行。让我们直接进入Pytorch的世界,开始coding吧!
Tensors
Tensor张量类型,是神经网络框架中重要的基础数据类型,可以简单理解为一个包含单个数据类型元素的多维矩阵,tensor之间的通过运算进行连接,从而形成计算图。www.jianguoyuncom
下面的代码实例中创建了一个2*3的二维张量x,指定数据类型为浮点型(Float):

  1. import torch
  2. #Tensors
  3. x=torch.FloatTensor([[1,2,3],[4,5,6]])
  4. print(x.size(),"\n",x)

运行结果:
PyTorch包含许多关于tensors的数学运算。除此之外,它还提供了许多实用程序,如高效序列化Tensor和其他任意数据类型,以及其他有用的实用程序。
下面是Tensor的加法/减法的一个例子,其中torch.ones(sizes, out=None) → Tensor返回一个全为1 的张量,形状由可变参数sizes定义。在实例中,和变量x相加的是创建的两个相应位置值为1的23的张量,相当于x每一维度的值+2,代码和运行结果如下所示:

  1. #Add tensors
  2. x.add_(torch.ones([2,3])+torch.ones([2,3]))

运行结果:
同样的,PyTorch也支持减法操作,实例如下,在上面的运行结果基础上每一维度再减去2,x恢复到最初的值。

  1. #Subtract Tensor
  2. x.sub_(torch.ones([2,3])*2)

运行结果:
其他PyTorch运算读者可以查阅上文给出的中文链接。

  1. PyTorch and NumPy

用户可以轻松地在PyTorch和NumPy之间来回转换。
下面是将np.matrix转换为PyTorch并将维度更改为单个列的简单示例:

  1. #Numpy to torch tensors
  2. import numpy as np
  3. y=np.matrix([[2,2],[2,2],[2,2]])
  4. z=np.matrix([[2,2],[2,2],[2,2]],dtype="int16")
  5. x.short() @ torch.from_numpy(z)

运行结果:
其中@为张量乘法的重载运算符,x为23的张量,值为[[1,2,3],[4,5,6]],与转换成tensor的z相乘,z的大小是32,结果为22的张量。(与矩阵乘法类似,不明白运行结果的读者,可以看下矩阵的乘法运算)
除此外,PyTorch也支持张量结构的重构reshape,下面是将张量x重构成1
6的一维张量的实例,与numpy中的reshape功能类似。
#Reshape tensors(similar to np.reshape)
x.view(1,6)
运行结果:
CPU and GPUs
PyTorch允许变量使用 torch.cuda.device上下文管理器动态更改设备。以下是示例代码:

  1. #move variables and copies across computer devices
  2. x=torch.FloatTensor([[1,2,3],[4,5,6]])
  3. y=np.matrix([[2,2,2],[2,2,2]],dtype="float32")
  4. if(torch.cuda.is_available()):
  5. xx=x.cuda();
  6. y=torch.from_numpy(y).cuda()
  7. z=x+y
  8. print(z)
  9. print(x.cpu())

运行结果:
PyTorch Variables
变量只是一个包裹着Tensor的薄层,它支持几乎所有由Tensor定义的API,变量被巧妙地定义为自动编译包的一部分。它提供了实现任意标量值函数自动区分的类和函数。
以下是PyTorch变量用法的简单示例,将v1和v2相乘的结果赋值给v3,其中里面的参数requires_grad的属性默认为False,若一个节点requires_grad被设置为True,那么所有依赖它的节点的requires_grad都为True,主要用于梯度的计算。

  1. #Variable(part of autograd package)
  2. #Variable (graph nodes) are thin wrappers around tensors and have dependency knowle
  3. #Variable enable backpropagation of gradients and automatic differentiations
  4. #Variable are set a 'volatile' flad during infrencing
  5. from torch.autograd import Variable
  6. v1 = Variable(torch.tensor([1.,2.,3.]), requires_grad=False)
  7. v2 = Variable(torch.tensor([4.,5.,6.]), requires_grad=True)
  8. v3 = v1*v2
  9. v3.data.numpy()

运行结果:

  1. #Variables remember what created them
  2. v3.grad_fn

运行结果:
Back Propagation
反向传播算法用于计算相对于输入权重和偏差的损失梯度,以在下一次优化迭代中更新权重并最终减少损失,PyTorch在分层定义对于变量的反向方法以执行反向传播方面非常智能。
以下是一个简单的反向传播计算方法,以sin(x)为例计算差分:

  1. #Backpropagation with example of sin(x)
  2. x=Variable(torch.Tensor(np.array([0.,1.,1.5,2.])*np.pi),requires_grad=True)
  3. y=torch.sin(x)
  4. x.grad
  5. y.backward(torch.Tensor([1.,1.,1.,1]))
  6. #Check gradient is indeed cox(x)
  7. if( (x.grad.data.int().numpy()==torch.cos(x).data.int().numpy()).all() ):
  8. print ("d(sin(x)/dx=cos(x))")

运行结果:

  1. SLR: Simple Linear Regression

现在我们了解了基础知识,可以开始运用PyTorch 解决简单的机器学习问题——简单线性回归。我们将通过4个简单步骤完成:
第一步:
在步骤1中,我们创建一个由方程y = wx + b产生的人工数据集,并注入随机误差。请参阅以下示例:
#Simple Liner Regression

  1. # Fit a line to the data. Y =w.x+b
  2. #Deterministic behavior
  3. np.random.seed(0)
  4. torch.manual_seed(0)
  5. #Step 1:Dataset
  6. w=2;b=3
  7. x=np.linspace(0,10,100)
  8. y=w*x+b+np.random.randn(100)*2
  9. xx=x.reshape(-1,1)
  10. yy=y.reshape(-1,1)

第二步:
在第2步中,我们使用forward函数定义一个简单的类LinearRegressionModel,使用torch.nn.Linear定义构造函数以对输入数据进行线性转换:

  1. #Step 2:Model
  2. class LinearRegressionModel(torch.nn.Module):
  3. def __init__(self,in_dimn,out_dimn):
  4. super(LinearRegressionModel,self).__init__()
  5. self.model=torch.nn.Linear(in_dimn,out_dimn)
  6. def forward(self,x):
  7. y_pred=self.model(x);
  8. return y_pred;
  9. model=LinearRegressionModel(in_dimn=1, out_dimn=1)

第三步:
下一步:使用 MSELoss 作为代价函数,SGD作为优化器来训练模型。

  1. #Step 3: Training
  2. cost=torch.nn.MSELoss()
  3. optimizer=torch.optim.SGD(model.parameters(),lr=0.01,momentum=0.9)
  4. inputs=Variable(torch.from_numpy(x.astype("float32")))
  5. outputs=Variable(torch.from_numpy(y.astype("float32")))
  6. for epoch in range(100):
  7. #3.1 forward pass:
  8. y_pred=model(inputs)
  9. #3.2 compute loss
  10. loss=cost(y_pred,outputs)
  11. #3.3 backward pass
  12. optimizer.zero_grad();
  13. loss.backward()
  14. optimizer.step()
  15. if((epoch+1)%10==0):
  16. print("epoch{},loss{}".format(epoch+1,loss.data))

第四步:
现在训练已经完成,让我们直观地检查我们的模型:

  1. #Step 4:Display model and confirm
  2. import matplotlib.pyplot as plt
  3. plt.figure(figsize=(4,4))
  4. plt.title("Model and Dataset")
  5. plt.xlabel("X");plt.ylabel("Y")
  6. plt.grid()
  7. plt.plot(x,y,"ro",label="DataSet",marker="x",markersize=4)
  8. plt.plot(x,model.model.weight.item()*x+model.model.bias.item(),label="Regression Model")
  9. plt.legend();plt.show()

运行结果:
现在你已经完成了PyTorch的第一个线性回归例子的编程了,对于后续希望百尺竿头,更进一步的读者来说,可以参考PyTorch的官方文档链接,完成大部分的编码应用。

发表评论

表情:
评论列表 (有 0 条评论,669人围观)

还没有评论,来说两句吧...

相关阅读

    相关 pytorch-线性回归

    线性回归 主要内容包括: 1. 线性回归的基本要素 2. 线性回归模型从零开始的实现 3. 线性回归模型使用pytorch的简洁实现 线性回归的基本要素