第3章 - 神经网络基础实训操作手册
1. 神经网络架构介绍
目标:理解神经网络的基本组成部分以及其工作原理。
内容:
a. 什么是神经网络?
神经网络是一种模拟人类大脑神经元工作原理的算法模型,由层层的节点(也称为“神经元”或“单元”)组成。每个节点都会接收输入,对其进行加权处理并通过一个激活函数,然后产生输出。
- b. 主要组件
- 输入层:接收原始数据作为输入。
- 隐藏层:在输入层和输出层之间的层。可以有多个隐藏层。
- 输出层:产生最终的预测结果。
- 权重和偏置:网络的参数,通过学习从数据中调整。
- 激活函数:引入非线性,使得神经网络可以拟合复杂的函数。
2. 使用nn.Module定义网络
目标:学会使用PyTorch的nn.Module
类来定义神经网络模型。
内容:
a. 定义神经网络
使用nn.Module
,你可以轻松地定义一个神经网络,其中每个层都是一个属性。
实操:
import torch.nn as nn
class SimpleNN(nn.Module):
def __init__(self):
super(SimpleNN, self).__init__()
self.fc1 = nn.Linear(10, 5)
self.fc2 = nn.Linear(5, 1)
def forward(self, x):
x = torch.relu(self.fc1(x))
x = self.fc2(x)
return x
model = SimpleNN()
print(model)
- 注意点:始终确保定义了
forward
方法,以指定数据在网络中的传播方式。
3. 损失函数和优化器介绍
目标:理解损失函数的重要性以及如何选择和使用优化器。
内容:
a. 损失函数
损失函数(或代价函数)测量模型预测的输出与真实值之间的差异。目标是最小化这个差异。
b. 优化器
优化器负责更新网络的权重和偏置,以最小化损失函数。
实操:
import torch.optim as optim
criterion = nn.MSELoss()
optimizer = optim.SGD(model.parameters(), lr=0.01)
- 注意点:选择与问题匹配的损失函数(例如,分类问题通常使用交叉熵损失)。对于优化器,SGD是最常见的,但根据情况,也可能考虑使用Adam、RMSprop等。
4. 实现基础的前馈神经网络
目标:使用PyTorch构建、训练并评估一个简单的前馈神经网络。
操作步骤:
# 1. 生成模拟数据
x_train = torch.randn(100, 10)
y_train = torch.sum(x_train, dim=1)
# 2. 使用上面定义的SimpleNN模型
model = SimpleNN()
# 3. 定义损失函数和优化器
criterion = nn.MSELoss()
optimizer = optim.SGD(model.parameters(), lr=0.01)
# 4. 训练模型
epochs = 100
for epoch in range(epochs):
model.train()
optimizer.zero_grad()
outputs = model(x_train)
loss = criterion(outputs, y_train)
loss.backward()
optimizer.step()
if (epoch+1) % 10 == 0:
print(f'Epoch [{epoch+1}/{epochs}], Loss: {loss.item():.4f}')
- 注意点:每次前向传播之后,都要使用
optimizer.zero_grad()
来清除旧的梯度。确保损失计算正确,并经常检查模型输出以确保一切正常。
实战项目:手写数字识别
项目描述:在这个实战项目中,学生将使用PyTorch构建一个神经网络模型来识别手写数字(0-9)。我们将使用著名的MNIST数据集,它包含了大量的28x28像素的手写数字图片。
1. 数据加载与预处理
我们首先需要加载MNIST数据集,并对其进行适当的预处理。
import torch
from torchvision import datasets, transforms
# 定义数据转换: 转换为张量并进行标准化
transform = transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.5,), (0.5,))
])
# 下载并加载训练数据
train_dataset = datasets.MNIST(root='./data', train=True, download=True, transform=transform)
train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=32, shuffle=True)
注意点:transforms.Normalize((0.5,), (0.5,))
将图片的像素值从[0,1]范围转换到[-1,1]范围。
2. 定义神经网络模型
我们将构建一个简单的两层全连接网络。
import torch.nn as nn
class MNISTNet(nn.Module):
def __init__(self):
super(MNISTNet, self).__init__()
self.fc1 = nn.Linear(28*28, 500)
self.fc2 = nn.Linear(500, 10) # 10个类别的输出
def forward(self, x):
x = x.view(-1, 28*28)
x = torch.relu(self.fc1(x))
x = self.fc2(x)
return x
model = MNISTNet()
print(model)
3. 定义损失函数和优化器
import torch.optim as optim
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(model.parameters(), lr=0.01)
4. 训练模型
epochs = 5
for epoch in range(epochs):
for batch_idx, (data, target) in enumerate(train_loader):
optimizer.zero_grad()
output = model(data)
loss = criterion(output, target)
loss.backward()
optimizer.step()
if batch_idx % 100 == 0:
print(f"Epoch {epoch+1}/{epochs}, Batch {batch_idx}/{len(train_loader)}, Loss: {loss.item():.4f}")
5. 评估模型
在训练结束后,我们可以使用模型在一些样本上进行预测,并评估其准确性。
# 使用部分测试数据
test_dataset = datasets.MNIST(root='./data', train=False, transform=transform)
test_loader = torch.utils.data.DataLoader(test_dataset, batch_size=1000, shuffle=True)
# 评估模型
model.eval()
correct = 0
with torch.no_grad():
for data, target in test_loader:
output = model(data)
pred = output.argmax(dim=1)
correct += pred.eq(target).sum().item()
print(f"Accuracy: {correct / len(test_loader.dataset):.4f}")
注意点:在评估模型时,使用model.eval()
确保模型在评估模式下运行,这样某些特定的层,如Dropout,将不会被激活。