线性回归的第一课
基本思路
- 
生成数据集 
 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
"""
注意: 建好数据集最好加上数据类型, 我就在这个问题上纠结了半天
来源:CSDN
作者:Crazy - ?
链接:https://blog.csdn.net/weixin_46310125/article/details/104267545