线性回归pytorch代码实现

线性回归

%matplotlib inline
import random
import torch
import matplotlib.pyplot as plt
from d2l import torch as d2l

生成数据集

我们使⽤线性模型参数w = [2, −3.4]⊤、b = 4.2 和噪声项ϵ⽣成数据集及其标签

def synthetic_data(w,b,num_examples):
    x = torch.normal(0,1,(num_examples,len(w)))#生成一个均值为0,方差为1,有n个样本,大小为w列的长度
        #torch.normal(means, std, out=None)
        #·means (Tensor) – 均值
        #·std (Tensor) – 标准差
        #· out (Tensor) – 可选的输出张量
        
        
    y = torch.matmul(x,w)+b
        #torch.mul(a, b)是矩阵a和b对应位相乘,a和b的维度必须相等,比如a的维度是(1, 2),b的维度是(1, 2),返回的仍是(1, 2)的矩阵;
        #torch.mm(a, b)是矩阵a和b矩阵相乘,比如a的维度是(1, 2),b的维度是(2, 3),返回的就是(1, 3)的矩阵。
        #torch.matmul()没有强制规定维度和大小,可以用利用广播机制进行不同维度的相乘操作
        

    y +=torch.normal(0,0.01,y.shape)#均值为0,方差为1,形状大小与y相同
    return   x,y.reshape((-1,1))#将x和y作为一个列向量来进行返回


true_w = torch.tensor([2,-3.4])
true_b=4.2
features ,labels = synthetic_data(true_w,true_b,1000)
    #d2l.synthetic_data用来生成人工合成数据
# x
# y

features中的每⼀⾏都包含⼀个⼆维数据样本,labels中的每⼀⾏都包含⼀维标签值(⼀个标量)

print(features.shape)
print(labels.shape)
plt.plot(features[:, 0], features[:, 1], '.')

数据可视化

d2l.set_figsize()
d2l.plt.scatter(features[:,1].detach().numpy(),
                labels.detach().numpy(),1);
#detach函数将torch内部数据传给numpy,由numpy来输出

features可视化
构造函数读取数据

#构造生成读取数据的数据集,该函数接收批量⼤小、特征矩阵和标签向量作为输⼊,⽣成⼤小为batch_size的小批量
def data_iter(batch_size,features,labels):
    num_examples = len(features)
#     print(num_examples)
    indices = list(range(num_examples))#生成每个样本的index,转化成list
    random.shuffle(indices)#shuffle() 方法将序列的所有元素随机排序。
    #随机顺序来访问样本
    
    for i in range(0,num_examples,batch_size):#从0开始访问,一直到num_examples,间隔为batch_size
        batch_indices = torch.tensor(
            indices[i:min(i+batch_size,num_examples)]
            #从0开始进行拿取数据,如果数据批量拿取时不足,就会取一个最小值
        )

        yield features[batch_indices],labels[batch_indices]#每一次产生随机顺序的特征和标号
            #return:在程序函数中返回某个值,返回之后函数不在继续执行,彻底结束。
            #yield: 带有yield的函数是一个迭代器,函数返回某个值时,会停留在某个位置,返回函数值后,会在前面停留的位置继续执行,直到程序结束

batch_size = 10

#查看读取的数据信息
for x,y in data_iter(batch_size,features,labels):
    print(x,'\n',y)
    break

数据参数初始化

w = torch.normal(0, 0.01, size=(2,1), requires_grad=True)
#需要进行梯度计算,参数需要设置 requires_grad=True
b = torch.zeros(1,requires_grad=True)

定义模型

def linreg(x,w,b):
    """线性回归模型"""
    return torch.matmul(x,w)+b

定义损失函数

def squared_loss(y_hat , y):
    """均方损失"""
    return (y_hat - y.reshape(y_hat.shape))**2/2
#防止y_hat 和 y 不能相减,所以把y的reshape成y_hat的reshape

定义优化算法

def sgd(params , lr , batch_size):#params是给定的list,其中包括w和b,lr是学习率
    """小梯度随机梯度下降"""
    with torch.no_grad():
        for param in params:
            param -= lr * param.grad /batch_size
            param.grad.zero_()

训练模型

lr = 0.03
num_epochs = 10 #扫描数据次数
net = linreg#所采用的模型
loss = squared_loss#均方损失函数

for epoch in range(num_epochs):
    for x, y in data_iter(batch_size, features, labels):
        
        l = loss(net(x, w, b), y) # X和y的⼩批量损失
        #将参数x , w , b ,放入net模型当中来进行预测,将预测的y~ 与真实的y做损失
        # 因为l形状是(batch_size,1),⽽不是⼀个标量。l中的所有元素被加到⼀起,
        # 并以此计算关于[w,b]的梯度
        
        l.sum().backward()
        #对损失先进行求和,之后再来计算梯度
        
        sgd([w, b], lr, batch_size) # 使⽤参数的梯度更新参数
        
    with torch.no_grad():
        train_l = loss(net(features, w, b), labels)
        #net(features, w, b)预测的参数与labels做损失
        print(f'epoch {epoch + 1}, loss {float(train_l.mean()):f}')   
        #输出训练的损失
        

查看误差率

print(f'w的估计误差: {true_w - w.reshape(true_w.shape)}')
print(f'b的估计误差: {true_b - b}')
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
下面是使用PyTorch进行二元一次线性回归代码示例: ```python import torch import torch.nn as nn import torch.optim as optim # 定义数据 x1 = torch.tensor([1, 2, 3, 4, 5], dtype=torch.float32) x2 = torch.tensor([2, 4, 6, 8, 10], dtype=torch.float32) y = torch.tensor([3, 5, 7, 9, 11], dtype=torch.float32) # 定义模型 class LinearRegression(nn.Module): def __init__(self): super(LinearRegression, self).__init__() self.linear = nn.Linear(2, 1) # 输入特征维度为2,输出特征维度为1 def forward(self, x): out = self.linear(x) return out model = LinearRegression() # 定义损失函数和优化器 criterion = nn.MSELoss() optimizer = optim.SGD(model.parameters(), lr=0.01) # 训练模型 num_epochs = 1000 for epoch in range(num_epochs): inputs = torch.stack([x1, x2], dim=1) # 将两个自变量堆叠在一起 outputs = model(inputs) loss = criterion(outputs.squeeze(), y) # 计算损失 optimizer.zero_grad() loss.backward() optimizer.step() if (epoch+1) % 100 == 0: print('Epoch [{}/{}], Loss: {:.4f}'.format(epoch+1, num_epochs, loss.item())) # 打印模型参数 print("模型参数:") for name, param in model.named_parameters(): if param.requires_grad: print(name, param.data) # 使用模型进行预测 test_input = torch.tensor([[6, 12]], dtype=torch.float32) predicted = model(test_input) print("预测结果:", predicted.item()) ``` 在这个示例中,我们首先定义了输入变量x1和x2,以及对应的目标变量y。然后,我们定义了一个继承自nn.Module的线性回归模型,并在模型的forward方法中定义了模型的计算流程。接着,我们定义了损失函数和优化器。在训练过程中,我们使用最小均方误差作为损失函数,并使用随机梯度下降(SGD)作为优化器。最后,我们通过迭代训练模型,并输出训练过程中的损失值。最后,我们使用训练好的模型进行预测,并输出预测结果。 请注意,这只是一个简单的示例代码,实际应用中可能需要根据具体情况进行修改和调整。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值