VGGNet是一种深度卷积神经网络,由牛津大学计算机视觉组的钻研团队开发。VGGNet的设计思维简略而无效,以深度重叠的卷积层为次要特点。
VGGNet的核心思想是通过多个小尺寸的卷积核和池化层来构建深度网络,具备比拟小的感触野。相比于其余网络结构,如AlexNet,VGGNet采纳了更深的网络结构,有更多的卷积层和池化层,从而进步了网络的表达能力。
VGGNet的根本组成单元是由间断的卷积层和池化层形成的块,通常有两到三个卷积层,前面追随一个池化层。整个网络由多个这样的块组成,最初是几个全连贯层和一个输入层。VGGNet的卷积核尺寸都是3x3,步长为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 torchimport torch.nn as nnimport torch.optim as optimimport torchvisionimport torchvision.transforms as transforms# Check if GPU is availabledevice = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")# Define a simplified VGG-like modelclass 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 datasettransform = 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 optimizernet = VGGNet().to(device) # Move the model to GPUcriterion = nn.CrossEntropyLoss()optimizer = optim.Adam(net.parameters(), lr=0.001)# Train the modelfor 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 modeltorch.save(net.state_dict(), 'mnist_vggnet.pth')
CPU版本:
import torchimport torch.nn as nnimport torch.optim as optimimport torchvisionimport torchvision.transforms as transforms# Define a simplified VGG-like modelclass 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 datasettransform = 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 optimizernet = VGGNet()criterion = nn.CrossEntropyLoss()optimizer = optim.Adam(net.parameters(), lr=0.001)# Train the modelfor 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 modeltorch.save(net.state_dict(), 'mnist_vggnet.pth')
其训练过程如下:
https://www.bilibili.com/video/BV1Fu4y1X76f/?spm_id_from=333....
通过训练可察看到如下区别
- 训练速度差别: GPU版本的训练代码在训练过程中会显著快于CPU版本。相比于CPU训练,应用A100训练的VGGNet工夫性能晋升了23倍,因为GPU在并行计算方面表现出色,特地实用于深度学习模型的训练。相比之下,CPU的通用计算能力较弱,解决图像数据的卷积运算等工作绝对较慢。
- 硬件加速成果: GPU版本的训练代码利用了GPU的并行计算能力,从而可能在更短的工夫内解决更多的计算工作。这种硬件加速成果在解决大规模数据集或简单模型时特地显著。