# coding=utf-8
# %matplotlib inline,只用于jupyter中
# 数据处理阶段
import random
import torch
# 现在构造人工数据集
def synthetic_data(w, b, num_examples):
"""生成y=wx+b+噪声"""
x = torch.normal(0, 1, (num_examples, len(w))) # torch.normal是PyTorch中的一个函数,用于生成服从正态分布的随机数
y = torch.matmul(x, w) + b # torch.matmul(x, w)是PyTorch中的一个函数,用于计算两个张量(矩阵)的矩阵乘法
y += torch.normal(0, 0.01, y.shape) # 添加噪声
return x, y.reshape((-1, 1)) # 让Y恢复到张量形式
true_w = torch.tensor([2, -3.4])
true_b = 4.2
features, labels = synthetic_data(true_w, true_b, 1000)
def data_iter(beatch_size, features, labels):
num_examples = len(features)
indices = list(range(num_examples))
random.shuffle(indices)
for i in range(0, num_examples, beatch_size):
batch_indices = torch.tensor(
indices[i:min(i + beatch_size, num_examples)]
) # 从索引i开始,取连续beatch_size个样本的索引值。
# 如果i+beatch_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):
return (y_hat - y.reshape(y_hat.shape)) ** 2 / 2
# 这段代码中的y.reshape(y_hat.shape)是为了确保y的形状与y_hat相同,以便进行逐元素的相减操作
# 定义优化算法,随机梯度下降算法
def sgd(params, lr, batch_size):
with torch.no_grad():
for param in params:
param -= lr * param.grad / batch_size
#param.grad.data.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)
l.sum().backward()
sgd([w,b],lr,batch_size)
with torch.no_grad():
w.grad.data.zero_()
b.grad.data.zero_()
train_l = loss(net(features, w, b), labels)
print('epoch %d, loss %f' % (epoch + 1, train_l.mean().item()))
动手学习深度学习-线性回归的从零开始实现
于 2023-10-10 19:17:58 首次发布