欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

使用Pytorch实现简单的线性回归

程序员文章站 2022-03-03 14:06:42
...
import torch

import numpy as np


#生成数据
num_inputs=2
num_examples = 1000
true_w = [2,-3.4]
true_b = 4.2
features = torch.tensor(np.random.normal(0,1,(num_examples,num_inputs)),dtype=torch.float)

#labels=X*w+b

labels = true_w[0]*features[:,0] + true_w[1]*features[:,1] + true_b
labels += torch.tensor(np.random.normal(0,0.01,size=labels.size()),dtype=torch.float)

#读取数据
import torch.utils.data as Data

batch_size = 10

#将训练数据的特征和标签组合,将数据特征和 数据标签合并成一行如:x1,x2,x3,y
dataset = Data.TensorDataset(features,labels)

#随机读取小批量数据
data_iter = Data.DataLoader(dataset,batch_size,shuffle=True)

for X,y in data_iter:
    # print(X,y)
    break

import torch.nn as nn

class LinearNet(nn.Module):
    def __init__(self,n_feature):
        super(LinearNet,self).__init__()
        self.linear = nn.Linear(n_feature,1)

    #forward 定义前向传播
    def forward(self, x):
        y = self.linear(x)
        return y

net = LinearNet(num_inputs)
print(net)

#如果可以使用多个网络形成多个层可以使用Sequential 把单个的网络按照一定的顺序插入到Sequential序列中进行
#使用nn.Sequential来组合网络层,Sequential是一个有序的容器,网络层按照转入的顺序加入到计算图中
#写法1
net = nn.Sequential(
    nn.Linear(num_inputs,1)
    #其他层
)
#写法二
net = nn.Sequential()
net.add_module('linear',nn.Linear(num_inputs,1))
#net.add_module...
#写法三
from collections import OrderedDict
net = nn.Sequential(OrderedDict([('linear',nn.Linear(num_inputs,1))
                                 #......
                                 ]))
print(net)
print(net[0])

#获取训练模型的可学习的参数
#通过net.parameters()查看模型所有可学习的参数,返回一个生成器
for param in net.parameters():
    print(param)

#初始化模型参数

from torch.nn import init
init.normal_(net[0].weight,mean=0,std=0.01)
init.constant_(net[0].bias,val=0) #也可以直接的修改bias的data:net[0].bias.data.dill_(0)

#使用modal中提供的损失函数
#定义损失函数
loss=nn.MSELoss()

#进行优化训练
#实现一个学习率为0.03的小批量随机梯度下降SGD
import torch.optim as optim
optimizer = optim.SGD(net.parameters(),lr=0.03)
print(optimizer)

#为不同的子网络设置不同的学习率
# optimizer = optim.SGD([
#     #如果对某个参数不指定学习率,就使用最外层的默认学习率
#     {'params':net.subnet1.parameters()},
#     {'params':net.subnet2.parameters(),'lr':0.01}
#     ],lr=0.03)

#调整学习率
for param_group in optimizer.param_groups:
    param_group['lr']*=0.1

#训练模型
num_epochs = 3
for epoch in range(1,num_epochs+1):
    for X,y in data_iter:
        output = net(X)
        l = loss(output,y.view(-1,1))
        optimizer.zero_grad()   # 梯度清零,等价于net.zero_grad()
        l.backward()
        optimizer.step()
    print('epoch %d,loss:%f'%(epoch,l.item()))

dense = net[0]
print(true_w,dense.weight)
print(true_b,dense.bias)