【动手深度学习】线性神经网络

这篇博客介绍了如何使用PyTorch从零开始实现线性回归模型。首先,通过生成数据集并绘制散点图展示数据分布。接着,定义了数据迭代器、模型参数、模型、损失函数以及优化算法(小批量随机梯度下降)。在训练过程中,逐步更新模型参数,最终得到较低的训练损失。此外,还展示了使用PyTorch内置的nn.Module和优化器简洁实现线性回归的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

线性回归从零开始实现

import random
import torch
from d2l import torch as d2l

# 生成数据集
def synthetic_data(w, b, num_examples):
    """y = Xw + b + noise"""
    X = torch.normal(0, 1, (num_examples, len(w)))
    y = torch.matmul(X, w) + b
    y += torch.normal(0, 0.01, y.shape)
    return X, y.reshape((-1, 1))

true_w = torch.tensor([2, -3.4])
true_b = 4.2
features, labels = synthetic_data(true_w, true_b, 1000)
print('features:', features[0], '\nlable:', labels[0])
"""
features: tensor([-0.4088, -0.5933]) 
lable: tensor([5.3928])
"""
# scatter the plot of features[:, 1]
d2l.set_figsize()
d2l.plt.scatter(features[:, 1].detach().numpy(), labels.detach().numpy(), 1)

在这里插入图片描述

# 读取数据集
def data_iter(batch_size, features, labels):
    num_examples = len(features)
    indices = list(range(num_examples))
    random.shuffle(indices)
    for i in range(0, num_examples, batch_size):
        batch_indices = torch.tensor(
            indices[i: min(i + batch_size, num_examples)])
        yield features[batch_indices], labels[batch_indices]
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)
b = torch.zeros(1, requires_grad=True)

# 定义模型
def linreg(X, w, b):
    return torch.matmul(X, w) + b

# 定义损失函数
def squared_loss(y_hat, y):
    """MSRE"""
    return (y_hat - y) ** 2/2

# 定义优化算法
def sgd(params, lr, batch_size):
    """小批量随机下降"""
    with torch.no_grad():
        for param in params:
            param -= lr * param.grad / batch_size
            param.grad.zero_()
# training
lr = 0.03
num_epochs = 5
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)
        l.sum().backward()
        sgd([w, b], lr, batch_size)
    with torch.no_grad():
        train_l = loss(net(features, w, b), labels)
        print(f'epoch {epoch + 1}, loss {float(train_l.mean()):f}')

"""
epoch 1, loss 0.029100
epoch 2, loss 0.000103
epoch 3, loss 0.000050
epoch 4, loss 0.000050
epoch 5, loss 0.000050
"""

线性回归的简洁实现

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

# 生成数据集
def synthetic_data(w, b, num_examples):
    """y = Xw + b + noise"""
    X = torch.normal(0, 1, (num_examples, len(w)))
    y = torch.matmul(X, w) + b
    y += torch.normal(0, 0.01, y.shape)
    return X, y.reshape((-1, 1))

true_w = torch.tensor([2, -3.4])
true_b = 4.2
features, labels = d2l.synthetic_data(true_w, true_b, 1000)

# 生成数据集
def load_array(data_arrays, batch_size, is_train=True):
    """构造PyTorch数据迭代器"""
    dataset = data.TensorDataset(*data_arrays)
    return data.DataLoader(dataset, batch_size, shuffle=is_train)

batch_size = 10
data_iter = load_array((features, labels), batch_size)
next(iter(data_iter))

在这里插入图片描述

# 定义模型
from torch import nn
"""在PyTorch中,全连接层在Linear类中定义"""
net = nn.Sequential(nn.Linear(2, 1))
"""
将两个参数传递到nn.Linear中。第一个指定输入特征形状,即2,
第二个指定输出特征形状,输出特征形状为单个标量,因此为1
"""

# 初始化模型参数
net[0].weight.data.normal_(0, 0.01)
net[0].bias.data.fill_(0)

# 定义损失函数
loss = nn.MSELoss()

# 定义优化算法
trainer = torch.optim.SGD(net.parameters(), lr=0.03)
# training
num_epochs = 5
for epoch in range(num_epochs):
    for X, y in data_iter:
        l = loss(net(X), y)
        trainer.zero_grad()
        l.backward()
        trainer.step()
    l = loss(net(features), labels)
    print(f'epoch {epoch + 1}, loss {l:f}')

"""
epoch 1, loss 0.000259
epoch 2, loss 0.000103
epoch 3, loss 0.000103
epoch 4, loss 0.000104
epoch 5, loss 0.000103
"""
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值