ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

<从零开始pytorch>:01-torch的基本使用方法和线性回归模型

2021-04-04 14:58:41  阅读:240  来源: 互联网

标签:loss 01 True torch epoch requires pytorch grad


  • 记录pytorch的学习过程 – 备注多,方便查阅
  1. torch的基本使用方法
  2. 实现一个线性回归模型并测试
import torch
torch.__version__
'1.8.0+cpu'

1.torch基本的使用方法`

1.1创建一个矩阵0矩阵

x = torch.empty(5,3)
x
tensor([[0., 0., 0.],
        [0., 0., 0.],
        [0., 0., 0.],
        [0., 0., 0.],
        [0., 0., 0.]])

1.2创建一个随机值

x = torch.randn(5,3)
x
tensor([[ 0.9290,  0.8528, -0.4443],
        [ 1.0932, -0.7507, -0.2703],
        [ 0.2908, -1.6405, -0.6977],
        [ 0.0574,  0.1044,  0.0233],
        [ 0.0722,  0.1150,  0.3934]])

1.3构建一个全0矩阵

x = torch.zeros(5,3)
x
tensor([[0., 0., 0.],
        [0., 0., 0.],
        [0., 0., 0.],
        [0., 0., 0.],
        [0., 0., 0.]])

1.4直接输入数据

x = torch.tensor([5.5,3])
x
tensor([5.5000, 3.0000])

1.5 view操作可以改变矩阵的维度

x = torch.randn(4,4)
y = x.view(16)
z = x.view(-1,8)
x.shape,y.shape,z.shape
(torch.Size([4, 4]), torch.Size([16]), torch.Size([2, 8]))

1.6 Pytorch的自动求导机制

1.6.1 需要求导的,可以手动定义

# 方法1 
x = torch.randn(3,4,requires_grad=True)
x
tensor([[-0.9228,  0.5714, -0.6876,  1.9532],
        [-0.3574, -0.3873, -1.8445, -1.2344],
        [-0.7455, -0.2275, -2.0875, -0.5985]], requires_grad=True)
# 方法2
x = torch.randn(3,4)
x.requires_grad=True
x
tensor([[-0.7503, -1.0792, -0.7416, -1.4556],
        [ 1.4662,  0.0910, -0.3608, -0.0494],
        [ 0.7349,  0.0184,  1.0263,  2.2171]], requires_grad=True)
b = torch.randn(3,4,requires_grad=True)
b
tensor([[-1.5929,  1.3165, -0.2407,  1.1987],
        [ 1.7689,  0.7053, -0.0073, -1.4798],
        [ 1.0369,  0.7267,  1.0260, -0.8435]], requires_grad=True)

1.6.2 对可求导的参数进行运算后得到的参数,也是可求导的

t = x + b
t
tensor([[-2.3433,  0.2373, -0.9824, -0.2569],
        [ 3.2351,  0.7963, -0.3681, -1.5292],
        [ 1.7718,  0.7452,  2.0523,  1.3736]], grad_fn=<AddBackward0>)
y = t.sum()
y
tensor(4.7316, grad_fn=<SumBackward0>)
x.requires_grad,b.requires_grad,t.requires_grad,y.requires_grad
(True, True, True, True)

1.6.3在最后一步调用一下这个反向传播,然后就可以求各个数的梯度了

y.backward()

1.6.4 b的梯度

b.grad
tensor([[1., 1., 1., 1.],
        [1., 1., 1., 1.],
        [1., 1., 1., 1.]])

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aQN0CLmY-1617518437305)(attachment:image.png)]

1.6.5 梯度计算的流程

随机生成一组数进行测试

x = torch.rand(1)
b = torch.rand(1,requires_grad=True)
w = torch.rand(1,requires_grad=True)
y = w * x
z = y + b

查看下是否需要进行求导

x.requires_grad,w.requires_grad,b.requires_grad,y.requires_grad,z.requires_grad
(False, True, True, True, True)

查看各参数是否是叶子节点

x.is_leaf,w.is_leaf,y.is_leaf,b.is_leaf,z.is_leaf
(True, True, False, True, False)

反向传播

z.backward(retain_graph=True) # 梯度是会累加的,retain_graph=True将之前的清空
w.grad
tensor([0.5243])
b.grad
tensor([1.])

2. 动手写一个线性回归

  • y = 2x+1

2.1 准备数据

import numpy as np
x_values = [i for i in range(11)]
x_train = np.array(x_values,dtype=np.float32) # 将数据以ndarray的方式读入
x_train = x_train.reshape(-1,1) # 将其转换为矩阵的格式,防止格式上的错误
x_train.shape,x_train
((11, 1),
 array([[ 0.],
        [ 1.],
        [ 2.],
        [ 3.],
        [ 4.],
        [ 5.],
        [ 6.],
        [ 7.],
        [ 8.],
        [ 9.],
        [10.]], dtype=float32))
y_values = [2 * x + 1 for x in x_values]
y_train = np.array(y_values,dtype=np.float32)
y_train = y_train.reshape(-1,1)
y_train
array([[ 1.],
       [ 3.],
       [ 5.],
       [ 7.],
       [ 9.],
       [11.],
       [13.],
       [15.],
       [17.],
       [19.],
       [21.]], dtype=float32)
import torch.nn as nn

2.2 定义一个线性回归模型

  • 线性回归其实就是一个不加激活函数的全连接层
class LinearRegressionModel(nn.Module):
    # __init__()函数中写的就是要用到的哪些层,是继承自nn.Model里面的
    def __init__(self,input_dim,output_dim):
        super(LinearRegressionModel,self).__init__()
        self.liner = nn.Linear(input_dim,output_dim) # input_dim这里就是每次数据有几个特征
    def forward(self,x):
        out = self.liner(x)
        return out
input_dim = 1
output_dim = 1

model = LinearRegressionModel(input_dim,output_dim)
model
LinearRegressionModel(
  (liner): Linear(in_features=1, out_features=1, bias=True)
)

2.3 指定好参数和损失函数

epochs = 1000
learning_rate = 0.01 
optimizer = torch.optim.SGD(model.parameters(),lr=learning_rate) # 传入需要更新的参数和学习率
criterion = nn.MSELoss()

2.4 训练模型

for epoch in range(epochs):
    epoch += 1
    
    # 将ndarray格式的数据转成tensor格式
    inputs = torch.from_numpy(x_train)
    labels = torch.from_numpy(y_train)
    
    # 每一次迭代时,梯度要清零,否则会叠加
    optimizer.zero_grad()
    
    # 前向传播
    outputs = model(inputs)
    
    # 计算损失
    loss = criterion(outputs,labels)
    
    # 反向传播 -- 会计算梯度,但是参数没有更新
    loss.backward()

    # 更新参数的权重
    optimizer.step() # 这个就是参数的更新
    
    if epoch % 50 == 0:
        print('epoch {},loss {}'.format(epoch,loss))
      
epoch 50,loss 0.24966569244861603
epoch 100,loss 0.14240005612373352
epoch 150,loss 0.0812196210026741
epoch 200,loss 0.04632469266653061
epoch 250,loss 0.026421738788485527
epoch 300,loss 0.015069996938109398
epoch 350,loss 0.008595331571996212
epoch 400,loss 0.004902484826743603
epoch 450,loss 0.0027961786836385727
epoch 500,loss 0.0015948202926665545
epoch 550,loss 0.0009096470312215388
epoch 600,loss 0.0005188201903365552
epoch 650,loss 0.0002959173871204257
epoch 700,loss 0.0001687801122898236
epoch 750,loss 9.626944665797055e-05
epoch 800,loss 5.4907563026063144e-05
epoch 850,loss 3.131549237878062e-05
epoch 900,loss 1.786198299669195e-05
epoch 950,loss 1.0188020496570971e-05
epoch 1000,loss 5.812353720102692e-06

2.5 用数据测试模型的结果

predicted = model(torch.from_numpy(x_train).requires_grad_()).data.numpy()
predicted
array([[ 0.9955155],
       [ 2.9961615],
       [ 4.996807 ],
       [ 6.997453 ],
       [ 8.998099 ],
       [10.998745 ],
       [12.999392 ],
       [15.000037 ],
       [17.000683 ],
       [19.00133  ],
       [21.001974 ]], dtype=float32)
predicted = model(torch.tensor([1.,4,6]).reshape(-1,1)) # 是按照列进行传数据!
predicted
tensor([[ 2.9962],
        [ 8.9981],
        [12.9994]], grad_fn=<AddmmBackward>)

2.6 模型的保存与存取

torch.save(model.state_dict(),'linerModel.pkl')
model.load_state_dict(torch.load('linerModel.pkl'))
<All keys matched successfully>

标签:loss,01,True,torch,epoch,requires,pytorch,grad
来源: https://blog.csdn.net/DDxuexi/article/details/115428560

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有