赞
踩
使用PyTorch搭建基本神经网络的分步指南。
微信搜索关注《Python学研大本营》,加入读者群,分享更多精彩
PyTorch是一个强大的深度学习框架,本文将详细介绍使用PyTorch搭建一个基本神经网络所涉及的步骤,并希望能够帮助你提高技能和加深知识。接下来就开始我们的PyTorch之旅吧!
使用PyTorch搭建神经网络的第一步是导入必要的库和模块。在这个代码片段中,我们导入了PyTorch的torch
库,以及其他几个模块,例如nn
(用于定义神经网络层)、optim
(用于定义优化算法),以及datasets
和transforms
(用于加载和处理数据)。
- import torch
- import torch.nn as nn
- import torch.optim as optim
- import torch.nn.functional as F
- from torch.utils.data import DataLoader
- import torchvision.datasets as datasets
- import torchvision.transforms as transforms
一旦我们导入了必要的库和模块,我们就可以定义我们的神经网络模型。在这个例子中,我们使用PyTorch提供的nn.Module
类定义了一个全连接的神经网络(也被称为前馈神经网络)。我们定义了两个线性层(nn.Linear
),其中有50个(你可以使用不同数量的单元)隐藏单元和一个ReLU
激活函数(F.relu
),然后是最后一个线性层,其输出大小等于我们要预测的类别数量。
- class NeuralNetwork(nn.Module):
- def __init__(self, input_size, num_classes):
- super(NeuralNetwork, self).__init__()
- self.fc1 = nn.Linear(in_features=input_size, out_features=50)
- self.fc2 = nn.Linear(in_features=50, out_features=num_classes)
-
- def forward(self, x):
- return self.fc2(F.relu(self.fc1(x)))
检查模型的输出形状以确保它符合期望是一个不可或缺的步骤。在这个例子中,我们创建了一个神经网络模型的实例,并传入一个大小为(64, 784)
的随机输入张量来检查模型的输出形状。我们使用.shape
属性输出张量的形状。
- model = NeuralNetwork(784, 10)
- x = torch.rand(64,784)
- print(model(x).shape) # Output : torch.Size([64, 10])
如果我们可以使用GPU,我们应该使用它来加快我们的计算速度。在这段代码中,如果GPU可用,我们将设备设置为cuda
,否则为cpu
。这对于确保我们的模型和数据在正确的设备上进行处理是很重要的。
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
在训练我们的神经网络之前,我们需要定义一些超参数,例如学习率、批量大小和轮数。在这个例子中,我们定义了一个学习率0.001
,一个批量大小64
,并训练了10
个epochs
。
- input_size = 784
- num_classes = 10
- learning_rate = 0.001
- batch_size = 64
- num_epochs = 10
为了训练我们的神经网络,我们需要加载和预处理我们的训练和测试数据。在这个例子中,我们使用MNIST数据集(包含手写数字图像)和PyTorch提供的DataLoader
类来加载数据。我们还应用ToTensor
变换来将图像转换为PyTorch的张量。
- train_data = datasets.MNIST(root = "dataset/",
- train=True,
- transform=transforms.ToTensor(),
- download=True
- )
-
- train_loader = DataLoader(dataset=train_data,
- batch_size=batch_size,
- shuffle=True
- )
-
- test_data = datasets.MNIST(root = "dataset/",
- train=False,
- transform=transforms.ToTensor(),
- download=True
- )
-
- test_loader = DataLoader(dataset=test_data,
- batch_size=batch_size,
- shuffle=True
- )

一旦我们定义了我们的模型并加载了数据,我们就可以使用.to()
方法在正确的设备(如步骤4中定义的)上初始化我们的神经网络模型。
model = NeuralNetwork(input_size=input_size, num_classes=num_classes).to(device)
为了训练我们的神经网络,我们需要定义一个损失函数和一个优化算法。在这个例子中,我们使用CrossEntropyLoss
损失函数和PyTorch提供的Adam
优化器。我们还使用model.parameters()
方法将模型参数传递给优化器。
- criterion = nn.CrossEntropyLoss()
- optimizer = optim.Adam(params= model.parameters(), lr=learning_rate)
现在已经定义了我们的模型,加载了数据,并初始化了必要的组件,可以通过分批迭代训练数据来训练我们的神经网络,并使用反向传播更新模型参数。在这段代码中,我们在训练数据上循环了指定数量的epochs
,这是对整个训练数据集的完整遍历。在每个历时中,我们使用train_loader
数据加载器对象分批迭代数据。对于每个批次,我们将数据和标签移到设备上(GPU或CPU),并将数据重塑为形状扁平的张量(batch_size
,input_size
)。然后我们通过神经网络传递数据,并使用交叉熵损失函数计算损失。我们将优化器的梯度设置为零,使用反向传播计算梯度,并使用优化器的阶跃函数更新参数。这个过程重复进行,直到我们在训练数据集中的所有批次上进行了指定次数的迭代。
- for epoch in range(num_epochs):
- for batch_idx, (data, labels) in enumerate(train_loader):
- data = data.to(device=device)
- labels = labels.to(device=device)
-
- data = data.reshape(data.shape[0], -1)
-
- scores = model(data)
- loss = criterion(scores, labels)
-
- optimizer.zero_grad()
- loss.backward()
-
- optimizer.step()
训练完模型后,可以在测试数据上评估其性能。我们使用训练好的模型来预测测试数据的标签,并将其与地面真实标签进行比较。然后,我们用正确预测的数量除以预测的总数来计算模型的准确性。
- num_correct = 0
- num_samples = 0
- model.eval()
-
- with torch.no_grad():
- for data, labels in test_loader:
- data = data.to(device=device)
- labels = labels.to(device=device)
-
- data = data.reshape(data.shape[0],-1)
-
- scores = model(data)
-
- _, predictions = torch.max(scores, dim=1)
- num_correct += (predictions == labels).sum()
- num_samples += predictions.size(0)
-
- print(f'Got {num_correct} / {num_samples} with accuracy {float(num_correct) / float(num_samples)*100:.2f}')
-
- model.train()

Output : Got 9712 / 10000 with accuracy 97.12
注:在PyTorch中,模型有两种模式:训练模式和评估模式。model.eval()
方法将模型设置为评估模式,它将关闭某些层或模块,如dropout
和batch normalization
。这很重要,因为在评估期间,我们不希望这些层改变我们模型的输出。
另一方面,model.train()
将模型设置为训练模式,从而启用那些在评估期间被关闭的层或模块。这很重要,因为我们需要这些层在训练过程中学习并更新它们的参数。
在给定的代码中,我们首先将模型设置为评估模式,然后在测试数据上测试模型。这确保了评估是在没有任何噪音或像dropout
这样的层所应用的正则化的情况下进行的。一旦评估完成,我们在继续训练循环之前将模型设置为训练模式。这可以确保在训练过程中应用必要的正则化。
接下来让我们在test_loader
上可视化一些随机图像。
- import matplotlib.pyplot as plt
-
- # 测试并绘制10张随机图像
- model.eval()
- with torch.no_grad():
- fig, axs = plt.subplots(2, 5, figsize=(12, 6))
- axs = axs.flatten()
-
- for i, (data, labels) in enumerate(test_loader):
- if i >= 10: # Break after 10 images
- break
-
- data = data.to(device=device)
- labels = labels.to(device=device)
-
- data = data.reshape(data.shape[0], -1)
-
- scores = model(data)
-
- _, predictions = torch.max(scores, dim=1)
-
- # 绘制图像和预测结果
- img = data.cpu().numpy().reshape(-1, 28, 28)
- axs[i].imshow(img[0], cmap='gray')
- axs[i].set_title(f"Label: {labels[0]} - Prediction: {predictions[0]}")
-
-
- plt.tight_layout()
- plt.show()
-
- model.train()

输出(你的可能是不同的,因为他们是随机选择的)。
如下所示是完整的代码,请查收:
- # 导入
- import torch
- import torch.nn as nn
- import torch.optim as optim
- import torch.nn.functional as F
- from torch.utils.data import DataLoader
- import torchvision.datasets as datasets
- import torchvision.transforms as transforms
-
- # 创建FCN
- class NeuralNetwork(nn.Module):
- def __init__(self, input_size, num_classes):
- super(NeuralNetwork, self).__init__()
- self.fc1 = nn.Linear(in_features=input_size, out_features=50)
- self.fc2 = nn.Linear(in_features=50, out_features=num_classes)
-
- def forward(self, x):
- return self.fc2(F.relu(self.fc1(x)))
-
- # 检查它的形状是否正确
- model = NeuralNetwork(784, 10)
- x = torch.rand(64,784)
- print(model(x).shape)
-
- # 设置设备
- device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
- print(device)
-
- # 设置超参数
- input_size = 784
- num_classes = 10
- learning_rate = 0.001
- batch_size = 64
- num_epochs = 1
-
- # 加载数据
- train_data = datasets.MNIST(root = "dataset/", train=True, transform=transforms.ToTensor(), download=True)
- train_loader = DataLoader(dataset=train_data, batch_size=batch_size, shuffle=True)
-
- test_data = datasets.MNIST(root = "dataset/", train=False, transform=transforms.ToTensor(), download=True)
- test_loader = DataLoader(dataset=test_data, batch_size=batch_size, shuffle=True)
-
- # 初始化网络
- model = NeuralNetwork(input_size=input_size, num_classes=num_classes).to(device)
-
- # 损失和优化器
- criterion = nn.CrossEntropyLoss()
- optimizer = optim.Adam(params= model.parameters(), lr=learning_rate)
-
- # 训练
- for epoch in range(num_epochs):
- for batch_idx, (data, labels) in enumerate(train_loader):
- data = data.to(device=device)
- labels = labels.to(device=device)
-
- data = data.reshape(data.shape[0], -1)
-
- scores = model(data)
- loss = criterion(scores, labels)
-
- optimizer.zero_grad()
- loss.backward()
-
- optimizer.step()
-
- # 测试
- num_correct = 0
- num_samples = 0
- model.eval()
-
- with torch.no_grad():
- for data, labels in test_loader:
- data = data.to(device=device)
- labels = labels.to(device=device)
-
- data = data.reshape(data.shape[0],-1)
-
- scores = model(data)
-
- _, predictions = torch.max(scores, dim=1)
- num_correct += (predictions == labels).sum()
- num_samples += predictions.size(0)
-
- print(f'Got {num_correct} / {num_samples} with accuracy {float(num_correct) / float(num_samples)*100:.2f}')
-
- model.train()
-
- import matplotlib.pyplot as plt
-
- # 测试并绘制10张随机图像
- model.eval()
- with torch.no_grad():
- fig, axs = plt.subplots(2, 5, figsize=(12, 6))
- axs = axs.flatten()
-
- for i, (data, labels) in enumerate(test_loader):
- if i >= 10: # Break after 10 images
- break
-
- data = data.to(device=device)
- labels = labels.to(device=device)
-
- data = data.reshape(data.shape[0], -1)
-
- scores = model(data)
-
- _, predictions = torch.max(scores, dim=1)
-
- # 绘制图像和预测结果
- img = data.cpu().numpy().reshape(-1, 28, 28)
- axs[i].imshow(img[0], cmap='gray')
- axs[i].set_title(f"Label: {labels[0]} - Prediction: {predictions[0]}")
-
-
- plt.tight_layout()
- plt.show()
-
- model.train()

在本教程中,我们已经了解了如何使用PyTorch建立一个用于图像分类的简单神经网络。我们首先加载了MNIST数据集,进而定义了神经网络的架构。然后,我们使用训练数据对模型进行了训练,并评估了它在测试数据上的表现。我们还讨论了一些重要的概念,例如设备放置、前向和后向传递、损失函数和优化算法。本教程为那些对深度学习和PyTorch感兴趣的人提供了一个良好的起点。
本书针对深度学习及开源框架——PyTorch,采用简明的语言进行知识的讲解,注重实战。全书分为4篇,共19章。深度学习基础篇(第1章~第6章)包括PyTorch简介与安装、机器学习基础与线性回归、张量与数据类型、分类问题与多层感知器、多层感知器模型与模型训练、梯度下降法、反向传播算法与内置优化器。计算机视觉篇(第7章~第14章)包括计算机视觉与卷积神经网络、卷积入门实例、图像读取与模型保存、多分类问题与卷积模型的优化、迁移学习与数据增强、经典网络模型与特征提取、图像定位基础、图像语义分割。自然语言处理和序列篇(第15章~第17章)包括文本分类与词嵌入、循环神经网络与一维卷积神经网络、序列预测实例。生成对抗网络和目标检测篇(第18章~第19章)包括生成对抗网络、目标检测。
本书适合人工智能行业的软件工程师、对人工智能感兴趣的学生学习,同时也可作为深度学习的培训教程。
精彩回顾
《使用TensorFlow和Keras创建猫狗图片深度学习分类器》
《使用Python和OpenPlayground轻松探索大语言模型》
微信搜索关注《Python学研大本营》,加入读者群
访问【IT今日热榜】,发现每日技术热点
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。