PyTorch 训练简单的线性模型
什么是线性回归?
以下是一个简单的线性回归模型的例子,基于一个虚构的数据集,描述了学习时间与考试成绩的关系。
假设我们有以下数据:
| 学习时间(小时) | 考试成绩(分数) |
|---|---|
| 1 | 50 |
| 2 | 60 |
| 3 | 70 |
| 4 | 80 |
| 5 | 90 |
我们可以使用这个数据集来建立一个线性回归模型,模型的形式如下:
其中:
- 是考试成绩
- 是学习时间
- 是截距项
- 是学习时间的系数
为了简化,我们可以手工计算,或者使用统计软件(如R、Python的scikit-learn库、SPSS等)来拟合这些数据。假设我们使用某个软件得到以下估计结果:
那么,我们的回归模型为:
这意味着,每增加一个小时的学习,考试成绩预期会增加10分。而如果一个学生没有学习(即学习时间为0小时),那么他的预期考试成绩是40分。
使用这个模型,如果一个学生学习了6小时,我们可以预测他的考试成绩为:
所以,预测分数是100分。
请注意,真实的回归分析通常涉及更复杂的数据处理、模型检查和诊断过程。这只是一个简化的示例,目的是展示基本的概念和计算。
使用 PyTorch 训练线性模型
下面是针对上述数据的代码:
import torch
import torch.nn as nn
import torch.optim as optim
# 1. 准备数据
# 输入数据: 学习时间
X_data = [1, 2, 3, 4, 5]
# 输出数据: 考试成绩
Y_data = [50, 60, 70, 80, 90]
# 转换为 PyTorch tensors
X = torch.tensor(X_data, dtype=torch.float32).view(-1, 1) # 将数据变为列矩阵
Y = torch.tensor(Y_data, dtype=torch.float32).view(-1, 1)
# 2. 定义模型
# 使用 PyTorch 的 nn.Module 定义一个简单的线性模型
class LinearRegression(nn.Module):
def __init__(self):
super(LinearRegression, self).__init__()
# 定义一个线性层,输入和输出的特征维度 都是1
self.linear = nn.Linear(1, 1)
def forward(self, x):
return self.linear(x)
model = LinearRegression()
# 3. 定义损失函数和优化器
# 使用均方误差作为损失函数
criterion = nn.MSELoss()
# 使用随机梯度下降作为优化器
optimizer = optim.SGD(model.parameters(), lr=0.01)
# 4. 训练模型
epochs = 1000
for epoch in range(epochs):
# 前向传播
outputs = model(X)
# 计算损失
loss = criterion(outputs, Y)
# 清零之前的梯度
optimizer.zero_grad()
# 反向传播
loss.backward()
# 更新参数
optimizer.step()
if (epoch+1) % 100 == 0:
print(f'Epoch [{epoch+1}/{epochs}], Loss: {loss.item():.4f}')
# 5. 查看训练后的参数
print(f'Estimated model: Y = {model.linear.bias.item():.4f} + {model.linear.weight.item():.4f}X')
代码解释:
- 我们首先为输入(学习时间)和输出(考试成绩)准备数据,并将它们转化为PyTorch张量。
- 使用 PyTorch 的
nn.Module定义了一个简单的线性回归模型。 - 选择了均方误差作为损失函数,并使用随机梯度下降进行优化。
- 对模型进行了1000轮的训练,每100轮输出一次当前的损失。
- 最后,打印出训练后的线性模型参数。
请注意,这个简单的模型和数据可能不需要1000轮训练,但这里只是为了展示基本的训练过程。在实际的应用中,你可能需要根据你的数据和模型调整各种参数,例如学习率和迭代次数。
nn.Linear 是什么?
当 我们在PyTorch中提到 nn.Linear,我们实际上是在讨论一个全连接层(也被称为线性层或密集层)。在神经网络中,这种层是最基本的构建块之一。
nn.Linear 的主要作用是为输入数据应用线性变换。具体来说,它执行以下操作:
其中:
- 是输入数据。
- 是该层的权重。
- 是该层的偏置。
- 是输出。
参数:
in_features: 输入特征的大小(即输入数据的维度)。out_features: 输出特征的大小(即输出数据的维度)。bias: 一个布尔值,表示是否应该为该层添加偏置。默认为True。
属性:
weight: 层的权重,大小为(out_features, in_features)。bias: 层的偏置,大小为(out_features)。
示例:
考虑我们有5个输入特征,希望将它们转换为3个输出特征。我们可以如下定义一个线性层:
import torch.nn as nn
linear_layer = nn.Linear(in_features=5, out_features=3)
此后,如果我们有一个输入数据的批次,大小为 (batch_size, 5),我们可以将其传递给 linear_layer 来获得一个大小为 (batch_size, 3) 的输出:
import torch
input_data = torch.rand(10, 5) # A batch of 10 samples, each with 5 features
output_data = linear_layer(input_data)
在内部,nn.Linear 自动为权重和偏置进行初始化,但你也可以使用 PyTorch 的其他工具和技术进一步自定义这些初始化。