vgg16网络模型的实现
这里只讲怎么实现
 百度搜到vgg16的网络模型图,用pytorch框架进行实现
 
 图是这样,用pytorch实现就行,pyotrch不太熟悉的话可以去看小土堆的视频
 命名mode.py 也可以使用其他名字,在后面的train.py里面改一下也行
import torch
import torch.nn as nn
class VGG16(nn.Module):
    def __init__(self):
        super(VGG16, self).__init__()
        self.layer1 = nn.Sequential(
            nn.Conv2d(3, 64, 3, 1, 1),
            nn.BatchNorm2d(64),
            nn.ReLU(),
            nn.Conv2d(64, 64, 3, 1, 1),
            nn.BatchNorm2d(64),
            nn.ReLU(),
            nn.MaxPool2d(2, 2)
        )
        self.layer2 = nn.Sequential(
            nn.Conv2d(64, 128, 3, 1, 1),
            nn.BatchNorm2d(128),
            nn.ReLU(),
            nn.Conv2d(128, 128, 3, 1, 1),
            nn.BatchNorm2d(128),
            nn.ReLU(),
            nn.MaxPool2d(2, 2)
        )
        self.layer3 = nn.Sequential(
            nn.Conv2d(128, 256, 3, 1, 1),
            nn.BatchNorm2d(256),
            nn.ReLU(),
            nn.Conv2d(256, 256, 3, 1, 1),
            nn.BatchNorm2d(256),
            nn.ReLU(),
            nn.Conv2d(256, 256, 3, 1, 1),
            nn.BatchNorm2d(256),
            nn.ReLU(),
            nn.MaxPool2d(2, 2)
        )
        self.layer4 = nn.Sequential(
            nn.Conv2d(256, 512, 3, 1, 1),
            nn.BatchNorm2d(512),
            nn.ReLU(),
            nn.Conv2d(512, 512, 3, 1, 1),
            nn.BatchNorm2d(512),
            nn.ReLU(),
            nn.Conv2d(512, 512, 3, 1, 1),
            nn.BatchNorm2d(512),
            nn.ReLU(),
            nn.MaxPool2d(2, 2)
        )
        self.layer5 = nn.Sequential(
            nn.Conv2d(512, 512, 3, 1, 1),
            nn.BatchNorm2d(512),
            nn.ReLU(),
            nn.Conv2d(512, 512, 3, 1, 1),
            nn.BatchNorm2d(512),
            nn.ReLU(),
            nn.Conv2d(512, 512, 3, 1, 1),
            nn.BatchNorm2d(512),
            nn.ReLU(),
            nn.MaxPool2d(2, 2)
        )
        self.fc1 = nn.Sequential(
            nn.Flatten(),
            nn.Linear(512, 512),
            nn.ReLU(),
            nn.Dropout()
        )
        self.fc2 = nn.Sequential(
            nn.Linear(512, 256),
            nn.ReLU(),
            nn.Dropout()
        )
        self.fc3 = nn.Linear(256, 10)
    def forward(self, x):
        x = self.layer1(x)
        x = self.layer2(x)
        x = self.layer3(x)
        x = self.layer4(x)
        x = self.layer5(x)
        x = self.fc1(x)
        x = self.fc2(x)
        x = self.fc3(x)
        return x
if __name__ == '__main__':
    VGG16 = VGG16()
    input = torch.ones((64, 3, 32, 32))
    output = VGG16(input)
    print(output.shape)
训练文件的编写
具体的都在注释里,需要注意的是 命名train.py
- 模型文件与训练文件在同一文件夹下
- batch_size以及epoch和学习率lr根据自己的需要进行更改,同时更改生成的模型文件名以及日志名(在代码里)要不会乱套
- 数据集设置的是假如没有会自动下载,因此不用担心下载数据集
- 本人的实验环境 ubuntu 18.04 显卡:2080ti window下的可以尝试应该没问题
import torchvision
from torch import optim
from torch.utils.data import DataLoader
import torch.nn as nn
from model import *
import matplotlib.pyplot as plt
import time
from torch.utils.tensorboard import SummaryWriter
device = torch.device("cuda:0")
train_data = torchvision.datasets.CIFAR10(root="data", train=True, transform=torchvision.transforms.ToTensor(),
                                          download=True)
test_data = torchvision.datasets.CIFAR10(root="data", train=False, transform=torchvision.transforms.ToTensor(),
                                         download=True)
train_dataloader = DataLoader(train_data, batch_size=128)
test_dataloader = DataLoader(test_data, batch_size=128)
file = open('logs_epoch50_bt128_lr0.015.txt', 'w')
# 查看测试集,训练集的大小
train_data_size = len(train_data)
test_data_size = len(test_data)
print("训练数据集的长度为:{}".format(train_data_size))
file.write("训练数据集的长度为:{}".format(train_data_size) + '\n')
print("测试数据集的长度为:{}".format(test_data_size))
file.write("测试数据集的长度为:{}".format(test_data_size) + '\n')
# 创建网络模型
vgg16 = VGG16()
vgg16 = vgg16.to(device)
# 损失函数
loss_fn = nn.CrossEntropyLoss()
loss_fn = loss_fn.to(device)
# 优化器
learning_rate = 0.015  # 设置学习速率
optimizer = torch.optim.SGD(vgg16.parameters(), lr=learning_rate)
# 设置训练网络的参数
# 记录训练的次数
total_train_step = 0
# 记录测试的次数
total_test_step = 0
# 训练的轮数
epoch = 50
# 添加tensorboard画图可视化
writer = SummaryWriter("logs_train")
for i in range(epoch):
    print("--------第{}轮训练开始---------".format(i + 1))
    file.write("--------第{}轮训练开始---------".format(i + 1) + '\n')
    for data in train_dataloader:
        imgs, targets = data
        imgs = imgs.to(device)
        targets = targets.to(device)
        outputs = vgg16(imgs)
        loss = loss_fn(outputs, targets)
        # 梯度调0
        optimizer.zero_grad()
        # 反向传播 梯度
        loss.backward()
        # 调优
        optimizer.step()
        # 记录训练次数
        total_train_step = total_train_step + 1
        # 每100打印loss
        if total_train_step % 100 ==0:
            print("训练次数:{},Loss:{}".format(total_train_step, 
                                           loss.item()))
            file.write("训练次数:{},Loss:{}".format(total_train_step, 
                                           loss.item()) + '\n')
            writer.add_scalar("train_loss", loss.item(), total_train_step)
    # 测试,没梯度没有调优代码
    total_test_loss = 0
    total_accuracy = 0
    with torch.no_grad():
        for data in test_dataloader:
            imgs, targets = data
            imgs = imgs.to(device)
            targets = targets.to(device)
            outputs = vgg16(imgs)
            loss = loss_fn(outputs, targets)
            total_test_loss = total_test_loss + loss.item()
            # 计算整体测试集上的正确率
            accuracy = (outputs.argmax(1) == targets).sum()
            total_accuracy = total_accuracy + accuracy
    print("整体测试集上的loss:".format(total_test_loss))
    file.write("整体测试集上的loss:".format(total_test_loss) + '\n')
    # 使用/进行的tensor整数除法不再支持,可以使用true_divide代替
    print("整体测试集上的正确率:{}".format(total_accuracy.true_divide(test_data_size)))
    file.write("整体测试集上的正确率:{}".format(total_accuracy.true_divide(test_data_size)) + '\n')
    writer.add_scalar("test_loss", total_test_loss, total_test_step)
    total_test_step = total_test_step + 1
    # 可视化正确率
    writer.add_scalar("test_accuracy", total_accuracy.true_divide(test_data_size), total_test_step)
    # 保存每一轮的模型 这是第一种保存方式非官方推荐
    torch.save(vgg16, "epoch50_bt128_lr0.015/vgg16_{}.pth".format(i+1))
    print("模型已保存")
writer.close()
训练日志如下(具体大家自行训练)
训练数据集的长度为:50000
 测试数据集的长度为:10000
 --------第1轮训练开始---------
 训练次数:100,Loss:1.8452614545822144
 训练次数:200,Loss:1.3886604309082031
 训练次数:300,Loss:1.4469469785690308
 整体测试集上的loss:
 整体测试集上的正确率:0.5472999811172485
 --------第2轮训练开始---------
 训练次数:400,Loss:1.108359694480896
 训练次数:500,Loss:1.1589107513427734
 训练次数:600,Loss:1.156502604484558
 训练次数:700,Loss:0.886533796787262
 整体测试集上的loss:
 整体测试集上的正确率:0.6538000106811523
 --------第3轮训练开始---------
 训练次数:800,Loss:0.884425163269043
 训练次数:900,Loss:0.8080787062644958
 训练次数:1000,Loss:0.7888829112052917
 训练次数:1100,Loss:0.6955403089523315
 整体测试集上的loss:
 整体测试集上的正确率:0.7030999660491943




![2022年 大学生工程训练比赛[物料搬运]](https://img-blog.csdnimg.cn/6bf79a143bca48338c8da0d5f58c3cb7.jpeg)














