线性回归是机器学习中最基础的算法之一,它通过寻找输入特征与输出目标之间的线性关系来进行预测。这个简单的模型包含了深度学习中的许多核心概念,是理解更复杂神经网络的基础。
线性回归模型的基本形式可以表示为:
y = w₁x₁ + w₂x₂ + ... + wₙxₙ + b
其中:
我们的目标是找到一组w和b,使得模型预测的y值与真实值之间的误差最小。这个过程称为"拟合"或"训练"模型。
注意:虽然线性回归看似简单,但它包含了参数初始化、前向传播、损失计算、反向传播和参数更新等深度学习中的核心概念。
PyTorch是一个流行的深度学习框架,它提供了自动微分功能,可以大大简化梯度计算的过程。下面我们逐步解析如何使用PyTorch实现一个完整的线性回归模型。
首先需要生成一些模拟数据来训练我们的模型:
python复制import torch
import matplotlib.pyplot as plt
import random
def create_data(w, b, data_num):
# 生成特征矩阵X,形状为(data_num, len(w))
x = torch.normal(0, 1, (data_num, len(w)))
# 计算目标值y = Xw + b
y = torch.matmul(x, w) + b
# 添加噪声使数据更真实
noise = torch.normal(0, 0.01, y.shape)
y += noise
return x, y
这段代码的关键点:
在实际训练中,我们通常不会一次性使用所有数据,而是将其分成小批量(batch):
python复制def data_provider(data, label, batchsize):
length = len(label)
indices = list(range(length))
random.shuffle(indices) # 随机打乱数据
for i in range(0, length, batchsize):
batch_indices = indices[i:i+batchsize]
yield data[batch_indices], label[batch_indices]
这个数据加载器实现了:
线性回归模型非常简单,就是一个矩阵乘法加偏置:
python复制def fun(x, w, b):
return torch.matmul(x, w) + b
虽然只有一行代码,但它实现了模型的前向传播过程。
我们使用平均绝对误差(MAE)作为损失函数:
python复制def maeLoss(pre_y, y):
return torch.sum(abs(pre_y - y)) / len(y)
MAE的优点是对异常值不敏感,计算简单。在深度学习中,MSE(均方误差)也很常用,但对异常值更敏感。
这里实现了最简单的随机梯度下降(SGD)优化器:
python复制def sgd(paras, lr):
with torch.no_grad(): # 不计算梯度
for para in paras:
para -= para.grad * lr # 参数更新
para.grad.zero_() # 梯度清零
关键点:
python复制# 生成500个样本数据
num = 500
true_w = torch.tensor([8.1, 2, 2, 4])
true_b = torch.tensor(1.1)
X, Y = create_data(true_w, true_b, num)
# 初始化模型参数
w_0 = torch.normal(0, 0.01, true_w.shape, requires_grad=True)
b_0 = torch.tensor(0.01, requires_grad=True)
参数初始化注意事项:
python复制lr = 0.05 # 学习率
epochs = 50 # 训练轮数
batchsize = 16 # 批量大小
for epoch in range(epochs):
data_loss = 0
for batch_x, batch_y in data_provider(X, Y, batchsize):
pred_y = fun(batch_x, w_0, b_0) # 前向传播
loss = maeLoss(pred_y, batch_y) # 计算损失
loss.backward() # 反向传播
sgd([w_0, b_0], lr) # 参数更新
data_loss += loss.item()
print(f"epoch {epoch:03d}: loss: {data_loss:.6f}")
训练过程解析:
训练完成后,我们可以比较学习到的参数与真实参数:
python复制print("真实的函数值是", true_w, true_b)
print("训练得到的参数值是", w_0, b_0)
# 可视化结果
idx = 2 # 选择第3个特征可视化
plt.plot(X[:,idx].detach().numpy(),
X[:,idx].detach().numpy()*w_0[idx].detach().numpy()+b_0.detach().numpy())
plt.scatter(X[:,idx], Y, 1)
plt.show()
评估要点:
损失不下降:
损失震荡:
过拟合:
学习率选择:
批量大小:
初始化策略:
虽然线性回归是一个简单模型,但它体现了深度学习的核心思想:
理解线性回归的这些方面,为学习更复杂的神经网络模型打下了坚实基础。在实际项目中,线性回归仍然有广泛应用,特别是在特征工程做得好、数据关系基本线性的场景下。