线性回归的第一课
基本思路
-
生成数据集
1.1 假设一个w, b
1.2 设置数据集的大小
1.3 随机化数据点,也就是数据集和标签(feature, label)torch.manual_seed 随机数种子, 使每次生成的随机数据集相同
np.random.seed 用法同于torch.manual_seed -
编写需要运用到的函数
2.1 mini_batch分割数据集
2.2 定义模型
2.3 定义损失函数
2.4 使用梯度下降法来更新w, bnp.random.shuffle 随机打乱数据
index_select(轴, 需要查找的元素) 按照索引查找元素
torch.mm 矩阵相乘(注意两个向量的维度) -
训练模型
3.1 初始化参数(w, b, 包括一些超参数)
3.2 调用已经写好的函数, 按照分批数据集、构建模型、计算损失、反向传播、更新参数的顺序进行训练模型
3.3 用假设的w, b 和已经训练好的w, b进行对比, 来评测模型的性能
import numpy as np
import torch
# 生成数据集
torch.manual_seed(2)
true_w = [2, -3.4]
true_b = 2.6
input_shape = 2
element_shape = 1000
feature= torch.randn((element_shape, input_shape), dtype=torch.float32)
label = true_w[0] * feature[:, 0] + true_w[1] * feature[:, 1] + true_b
np.random.seed(2)
label += torch.tensor(np.random.normal(0, .001, size=label.shape), dtype=torch.float32)
label = label.reshape(-1, 1)
print(feature.shape)
print(label.shape)
def mini_batch_data(batch, feature, label):
"""
batch: 每个批次大小
feature: 数据集
label: 标签
return: iter
"""
idxs = list(range(len(label)))
np.random.shuffle(idxs)
for i in range(0, len(label), batch):
index = torch.LongTensor(idxs[i: min(i + batch, len(label))])
yield feature.index_select(0, index), label.index_select(0, index)
# 设置每个批次为64
mini_batch = 64
# for x, y in mini_batch_data(mini_batch, feature, label):
# print(x.shape, y.shape)
# break
def model_nn(x, w, b):
"""
x: 数据集
w: 权重
b: 偏置
return: 线性模型
"""
return torch.mm(x, w) + b
def mse_loss(y, y_hat):
"""
y: label真实值
y_hat: 模型预测值
return: MSELoss
"""
return (y_hat - y) ** 2 / 2
def optim(para, alpha, batch):
"""
para: 参数
alpha: 学习率
batch: 批次大小
"""
for i in para:
# 在没有梯度的情况下操作参数
i.data -= i.grad * alpha / batch
# 初始化参数
w = torch.tensor(np.random.normal(0, 0.001, (input_shape, 1)), dtype=torch.float32)
b = torch.zeros(1, dtype=torch.float32)
# 让w, b在计算中保留梯度
w.requires_grad_(requires_grad=True)
b.requires_grad_(requires_grad=True)
# 初始化超参数
lr = 0.01
epochs = 150
for epoch in range(epochs):
# 批次加载数据集
for x, y in mini_batch_data(mini_batch, feature, label):
# 模型
net = model_nn(x, w, b)
# 损失
loss = mse_loss(y, net).sum()
# 反向传播
loss.backward()
# 梯度下降
optim([w, b], lr, mini_batch)
# 清零梯度
w.grad.data.zero_()
w.grad.data.zero_()
test = model_nn(feature, w, b)
loss = mse_loss(label, test).mean()
if epoch % 10 == 0:
print(f"loss: {loss}")
print(w, true_w)
print()
print(b, true_b)
"""
output:
tensor([[ 1.9820],
[-3.4100]], requires_grad=True) [2, -3.4]
tensor([2.1723], requires_grad=True) 2.6
"""
注意: 建好数据集最好加上数据类型, 我就在这个问题上纠结了半天