第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,将不会被激活。

Logo

汇聚原天河团队并行计算工程师、中科院计算所专家以及头部AI名企HPC专家,助力解决“卡脖子”问题

更多推荐