关于深度学习:炼丹侠如何用GPU服务器实现VGGNet训练

VGGNet是一种深度卷积神经网络,由牛津大学计算机视觉组的钻研团队开发。VGGNet的设计思维简略而无效,以深度重叠的卷积层为次要特点。

VGGNet的核心思想是通过多个小尺寸的卷积核和池化层来构建深度网络,具备比拟小的感触野。相比于其余网络结构,如AlexNet,VGGNet采纳了更深的网络结构,有更多的卷积层和池化层,从而进步了网络的表达能力。

VGGNet的根本组成单元是由间断的卷积层和池化层形成的块,通常有两到三个卷积层,前面追随一个池化层。整个网络由多个这样的块组成,最初是几个全连贯层和一个输入层。VGGNet的卷积核尺寸都是3×3,步长为1,并且在每个卷积层后都应用了ReLU激活函数进行非线性映射。

VGGNet的一个重要奉献是证实了减少网络深度能够进步性能,同时还提出了一种通用的网络结构设计准则。VGGNet在2014年的ImageNet图像识别挑战赛中获得了很好的问题,成为了过后最具影响力的深度学习模型之一。其简略而无效的设计思维对起初的深度卷积神经网络的倒退产生了重要影响。

本次选取经典的VGGNet对MNIST数据集进行训练操作,失去一个可用的模型文件,本次训练应用的服务器为炼丹侠平台A100服务器,其中GPU型号为A100 80GB,CPU应用了AMD EPYC 7542 32-Core Processor,训练分为了GPU训练测试和CPU训练测试。

上面是GPU版本和CPU版本VGGNet训练MNIST数据集的残缺代码。

GPU版本:

import torch
import torch.nn as nn
import torch.optim as optim
import torchvision
import torchvision.transforms as transforms

# Check if GPU is available
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")

# Define a simplified VGG-like model
class VGGNet(nn.Module):
    def __init__(self):
        super(VGGNet, self).__init__()
        self.features = nn.Sequential(
            nn.Conv2d(1, 32, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            nn.Conv2d(32, 32, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=2, stride=2),
            nn.Conv2d(32, 64, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            nn.Conv2d(64, 64, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=2, stride=2)
        )
        self.classifier = nn.Sequential(
            nn.Linear(64 * 7 * 7, 128),
            nn.ReLU(inplace=True),
            nn.Dropout(),
            nn.Linear(128, 10)
        )
    
    def forward(self, x):
        x = self.features(x)
        x = x.view(x.size(0), -1)
        x = self.classifier(x)
        return x

# Load and preprocess MNIST dataset
transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.5,), (0.5,))])
trainset = torchvision.datasets.MNIST(root='./data', train=True, download=True, transform=transform)
trainloader = torch.utils.data.DataLoader(trainset, batch_size=128, shuffle=True)

# Create the network, loss function, and optimizer
net = VGGNet().to(device)  # Move the model to GPU
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(net.parameters(), lr=0.001)

# Train the model
for epoch in range(10):
    running_loss = 0.0
    for i, data in enumerate(trainloader, 0):
        inputs, labels = data
        inputs, labels = inputs.to(device), labels.to(device)  # Move inputs and labels to GPU
        optimizer.zero_grad()
        outputs = net(inputs)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()
        running_loss += loss.item()
    print(f"Epoch {epoch+1}, Loss: {running_loss / len(trainloader)}")

print("Finished Training")

# Save the trained model
torch.save(net.state_dict(), 'mnist_vggnet.pth')

CPU版本:

import torch
import torch.nn as nn
import torch.optim as optim
import torchvision
import torchvision.transforms as transforms

# Define a simplified VGG-like model
class VGGNet(nn.Module):
    def __init__(self):
        super(VGGNet, self).__init__()
        self.features = nn.Sequential(
            nn.Conv2d(1, 32, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            nn.Conv2d(32, 32, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=2, stride=2),
            nn.Conv2d(32, 64, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            nn.Conv2d(64, 64, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=2, stride=2)
        )
        self.classifier = nn.Sequential(
            nn.Linear(64 * 7 * 7, 128),
            nn.ReLU(inplace=True),
            nn.Dropout(),
            nn.Linear(128, 10)
        )
    
    def forward(self, x):
        x = self.features(x)
        x = x.view(x.size(0), -1)
        x = self.classifier(x)
        return x

# Load and preprocess MNIST dataset
transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.5,), (0.5,))])
trainset = torchvision.datasets.MNIST(root='./data', train=True, download=True, transform=transform)
trainloader = torch.utils.data.DataLoader(trainset, batch_size=128, shuffle=True)

# Create the network, loss function, and optimizer
net = VGGNet()
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(net.parameters(), lr=0.001)

# Train the model
for epoch in range(10):
    running_loss = 0.0
    for i, data in enumerate(trainloader, 0):
        inputs, labels = data
        optimizer.zero_grad()
        outputs = net(inputs)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()
        running_loss += loss.item()
    print(f"Epoch {epoch+1}, Loss: {running_loss / len(trainloader)}")

print("Finished Training")

# Save the trained model
torch.save(net.state_dict(), 'mnist_vggnet.pth')

其训练过程如下:
https://www.bilibili.com/video/BV1Fu4y1X76f/?spm_id_from=333….

通过训练可察看到如下区别

  1. 训练速度差别: GPU版本的训练代码在训练过程中会显著快于CPU版本。相比于CPU训练,应用A100训练的VGGNet工夫性能晋升了23倍,因为GPU在并行计算方面表现出色,特地实用于深度学习模型的训练。相比之下,CPU的通用计算能力较弱,解决图像数据的卷积运算等工作绝对较慢。
  2. 硬件加速成果: GPU版本的训练代码利用了GPU的并行计算能力,从而可能在更短的工夫内解决更多的计算工作。这种硬件加速成果在解决大规模数据集或简单模型时特地显著。

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理