pytorch构建神经网络的每一个环节,线性回归为例

线性回归的间接实现

虽然线性回归很简单,但当我们使用pytorch的API去实现时,非常有利于理解其工作原理,便于以后的网络构建

必要包

import numpy as np
import torch
from torch.utils import data

生成数据的函数

# 定义一个函数,输入是w和b,输出是加上噪音后的这条线的散点
# synthetic_data 假数据
def synthetic_data(w, b, num_examples): #@save
    """⽣成y=Xw+b+噪声"""
    # 生成正态分布的散点矩阵,有num_examples行,每一行是一个样本
    X = torch.normal(0, 1, (num_examples, len(w)))
    # 生成y
    y = torch.matmul(X, w) + b
    # y加上噪音
    y += torch.normal(0, 0.01, y.shape)
    return X, y.reshape((-1, 1))

构造一个数据迭代器,每次要能去除batchsize的数据

data.TensorDataset
data.DataLoader
torch.utils.data.TensorDataset是一个数据集类,将张量(Tensor)数据和对应的标签组合成一个数据集,处理训练数据和标签之间的对应。TensorDataset的初始化参数是一系列的张量,每个张量代表一个特征或标签。它会将这些张量按照第一个维度进行对齐,即每个张量的第一个维度大小必须相同。这样,TensorDataset会将每个张量的第i个元素组合成一个样本,形成一个数据集。

torch.utils.data.DataLoader是一个数据加载器类,将数据集按照指定的批次大小进行加载和迭代。它可以方便地对数据进行批处理、随机打乱和并行加载等操作。DataLoader的初始化参数包括数据集、批次大小、是否打乱数据、是否使用多线程等。通过调用DataLoader的__iter__方法,可以获得一个可迭代的数据加载器对象,每次迭代会返回一个批次的数据和对应的标签。使用TensorDataset和DataLoader可以方便地将数据集加载到模型中进行训练。

首先,将数据和标签组合成TensorDataset对象,然后使用DataLoader对TensorDataset进行批处理和迭代,将数据输入到模型中进行训练。这样可以提高数据的处理效率和模型的训练速度。
def load_array(data_arrays, batch_size, is_train=True): #@save
    """构造⼀个PyTorch数据迭代器"""
    dataset = data.TensorDataset(*data_arrays) #传入一个元组tuple
    return data.DataLoader(dataset, batch_size, shuffle=is_train)

构造数据

true_w = torch.tensor([2, -3.4])
true_b = 4.2
features, labels = synthetic_data(true_w, true_b, 1000)
batch_size = 10
data_iter = load_array((features, labels), batch_size)
# 查看数据  next()迭代器下一个元素  iter()转换为可迭代对象
# next(iter(data_iter))

构造模型

这里使用pytorch中神经网络的模型,按我的经验,一般先定义一个网络net(或者称为模型model),然后定义优化器optim,把参数传到这个优化器里,设置学习率,再定义一个损失,通过损失计算梯度,通过优化器更新

from torch import nn # nn即neural network缩写
net = nn.Sequential(nn.Linear(2, 1)) # 输入特征维数为2,输入为1
net[0].weight.data.normal_(0, 0.01) # 权重
net[0].bias.data.fill_(0) # 偏置
tensor([0.])

设置损失和优化算法

loss = nn.MSELoss()
# 定义小批量随机梯度下降算法
trainer = torch.optim.SGD(net.parameters(), lr=0.03) 

训练

num_epochs = 3
# 注意每个epoch遍历一整个数据集
# 每个iter遍历一个batch
for epoch in range(num_epochs):
    for X, y in data_iter:
        # 计算损失
        l = loss(net(X) ,y)
        # 清除参数之前累积的梯度
        trainer.zero_grad()
        # 通过损失函数,对参数进行反向传播
        l.backward()
        # 使用反向传播的梯度,进行参数更新
        trainer.step()
    # 每个epoch的损失
    l = loss(net(features), labels)
    print(f'epoch {epoch + 1}, loss {l:f}')
epoch 1, loss 0.000286
epoch 2, loss 0.000097
epoch 3, loss 0.000097

比较误差

w = net[0].weight.data
print('w的估计误差: ', true_w - w.reshape(true_w.shape))
b = net[0].bias.data
print('b的估计误差: ', true_b - b)
w的估计误差:  tensor([-0.0003, -0.0004])
b的估计误差:  tensor([0.0004])
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

熊熊想读研究生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值