目录

1 CIFAR10数据集下载

2 实操

3 附完整代码


1 CIFAR10数据集下载

直接使用代码下载

train_data = torchvision.datasets.CIFAR10(root='../dataset_transforms', train=True, transform=transform, download=True)
test_data = torchvision.datasets.CIFAR10(root='../dataset_transforms', train=False, transform=transform, download=True)

下载之后的文件目录:

2 实操

ps: 以下代码全部写在一个 .py  文件中

(1)数据预处理操作:

# 1.预处理
transform = torchvision.transforms.Compose([
    torchvision.transforms.ToTensor()
])

(2)加载数据集

# 2. 加载数据集
train_data = torchvision.datasets.CIFAR10(root='../dataset_transforms', train=True, transform=transform, download=True)
test_data = torchvision.datasets.CIFAR10(root='../dataset_transforms', train=False, transform=transform, download=True)

print(len(train_data))
print(len(test_data))

train_loader = torch.utils.data.DataLoader(train_data, batch_size=64, shuffle=True)
test_loader = torch.utils.data.DataLoader(test_data, batch_size=64, shuffle=True)

(3) 构建神经网络模型

# 3.定义模型
class Model(nn.Module):
    def __init__(self):
        super(Model, self).__init__()
        self.conv1 = nn.Conv2d(3, 64, 5, 1, 2)
        self.batchNorm1 = nn.BatchNorm2d(64)
        self.relu1 = nn.ReLU()
        self.maxpool1 = nn.MaxPool2d(2)

        self.conv2 = nn.Conv2d(64, 64, 5, 1, 2)
        self.batchNorm2 = nn.BatchNorm2d(64)
        self.relu2 = nn.ReLU()
        self.maxpool2 = nn.MaxPool2d(2)

        self.conv3 = nn.Conv2d(64, 128, 5, 1, 2)
        self.batchNorm3 = nn.BatchNorm2d(128)
        self.relu3 = nn.ReLU()
        self.maxpool3 = nn.MaxPool2d(2)

        self.conv4 = nn.Conv2d(128, 128, 5, 1, 2)
        self.batchNorm4 = nn.BatchNorm2d(128)
        self.relu4 = nn.ReLU()
        self.maxpool4 = nn.MaxPool2d(2)

        self.flatten = nn.Flatten()
        self.linear1 = nn.Linear(128 * 2 * 2, 128)
        self.relu5 = nn.ReLU()
        self.dropout = nn.Dropout(0.5)  # 添加Dropout层,丢弃率为0.5
        self.linear2 = nn.Linear(128, 10)

    def forward(self, x):
        x = self.conv1(x)
        x = self.batchNorm1(x)
        x = self.relu1(x)
        x = self.maxpool1(x)

        x = self.conv2(x)
        x = self.batchNorm2(x)
        x = self.relu2(x)
        x = self.maxpool2(x)

        x = self.conv3(x)
        x = self.batchNorm3(x)
        x = self.relu3(x)
        x = self.maxpool3(x)

        x = self.conv4(x)
        x = self.batchNorm4(x)
        x = self.relu4(x)
        x = self.maxpool4(x)

        x = self.flatten(x)
        x = self.linear1(x)
        x = self.relu5(x)
        x = self.dropout(x)
        x = self.linear2(x)

        return x


model = Model()

loss = nn.CrossEntropyLoss()  # 损失函数使用交叉熵损失函数
# 优化器: 使用随机梯度下降
optimizer = torch.optim.SGD(model.parameters(), lr=0.14)  # lr:学习率
scheduler = StepLR(optimizer, step_size=10, gamma=0.5)  # 学习率调度器,每10个epoch将学习率减半

# 将模型放在 GPU 上跑
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model = model.to(device)

writer = SummaryWriter("../nn_classify_image_logs")  # 创建 SummaryWriter 对象,用于记录训练过程中的数据

(4) 训练模型

# 4.训练模型
def train():
    epochs = 10
    total_train_num = 0
    model.train()
    for epoch in range(epochs):
        for data in train_loader:
            imgs, targets = data
            imgs = imgs.to(device)
            targets = targets.to(device)
            model_predict = model(imgs)
            _, predicted = torch.max(model_predict, 1)
            loss_result = loss(model_predict, targets)

            # 优化模型
            optimizer.zero_grad()
            loss_result.backward()
            optimizer.step()

            total_train_num += 1
            if total_train_num % 100 == 0:
                print("Epoch: {}, Loss: {}".format(epoch + 1, loss_result.item()))
                writer.add_scalar("train_loss", loss_result.item(), total_train_num)  # 记录训练损失
                torch.save(model.state_dict(), './model/model.pth')  # 保存模型参数
                torch.save(optimizer.state_dict(), './model/optimizer.pth')  # 保存优化器参数
                print("模型参数已保存")
                print("优化器参数已保存")
                print("训练完成")
            # 计算预测正确的数量
            # total_train_correct += (predicted == targets).sum().item()
            # total_train_loss += loss_result.item()

        # print("Total train loss: {}".format(total_train_loss))


# train()

训练时的可视化图像:

(5) 测试模型

# 5.测试模型
def test():
    model.load_state_dict(torch.load('./model/model.pth'))
    model.eval()
    total_test_num = 0
    total_test_correct = 0
    total_test_loss = 0
    with torch.no_grad():
        for imgs, targets in test_loader:
            imgs = imgs.to(device)
            targets = targets.to(device)
            model_predict = model(imgs)
            _, predicted = torch.max(model_predict, 1)
            loss_result = loss(model_predict, targets)
            total_test_num += imgs.size(0)
            total_test_correct += (predicted == targets).sum().item()
            total_test_loss += loss_result.item()

            if total_test_num % 100 == 0:
                print("Test_Nums: {}, Loss: {}".format(total_test_num, loss_result.item()))
                writer.add_scalar("Test Loss", loss_result.item(), total_test_num)
                print("Test Accuracy: {}".format(total_test_correct / total_test_num))  # 该批次预测的准确度
                writer.add_scalar("Test Accuracy", total_test_correct / total_test_num, total_test_num)

        print("Test Total Accuracy: {}".format(total_test_correct / total_test_num))  # 总预测的准确度
        print("Test Total Loss: {}".format(total_test_loss / len(test_loader)))


# test()

测试时的可视化图像:


整体的测试精确度才71%左右,较低:

(6)测试自己的图片

# 6.测试自己的图片
def test_my_image():
    model.load_state_dict(torch.load('./model/model.pth'))
    model.eval()  # 设置为评估模式
    # 定义图像预处理
    transform_image = torchvision.transforms.Compose([
        torchvision.transforms.Resize((32, 32)),  # 调整图像大小为 28x28
        torchvision.transforms.ToTensor(),  # 转换为张量并归一化到 [0, 1]
    ])

    # 加载自己的图片
    img = Image.open('./test_images/deer.png')
    img = img.convert('RGB')
    img = transform_image(img)

    img = img.unsqueeze(0)  # 形状变为 [1, 1, 28, 28]
    img = img.to(device)

    class_names = ["airplane", "automobile", "bird", "cat", "deer", "dog", "frog", "horse", "ship", "truck"]
    with torch.no_grad():
        model_predict = model(img)
        _, predicted = torch.max(model_predict, 1)
        print("预测结果为:", class_names[predicted.item()])  # 输出预测结果
        print("真实结果为:deer")  # 输出真实结果


# test_my_image()

总结:该模型预测的准确度仍需改进,欢迎指正,交流学习!

3 附完整代码

import torch
import torchvision
from PIL import Image
from torch import nn
from torch.optim.lr_scheduler import StepLR
from torch.utils.tensorboard import SummaryWriter

# 1.预处理
transform = torchvision.transforms.Compose([
    torchvision.transforms.ToTensor()
])

# 2. 加载数据集
train_data = torchvision.datasets.CIFAR10(root='../dataset_transforms', train=True, transform=transform, download=True)
test_data = torchvision.datasets.CIFAR10(root='../dataset_transforms', train=False, transform=transform, download=True)

print(len(train_data))
print(len(test_data))

train_loader = torch.utils.data.DataLoader(train_data, batch_size=64, shuffle=True)
test_loader = torch.utils.data.DataLoader(test_data, batch_size=64, shuffle=True)


# 3.定义模型
class Model(nn.Module):
    def __init__(self):
        super(Model, self).__init__()
        self.conv1 = nn.Conv2d(3, 64, 5, 1, 2)
        self.batchNorm1 = nn.BatchNorm2d(64)
        self.relu1 = nn.ReLU()
        self.maxpool1 = nn.MaxPool2d(2)

        self.conv2 = nn.Conv2d(64, 64, 5, 1, 2)
        self.batchNorm2 = nn.BatchNorm2d(64)
        self.relu2 = nn.ReLU()
        self.maxpool2 = nn.MaxPool2d(2)

        self.conv3 = nn.Conv2d(64, 128, 5, 1, 2)
        self.batchNorm3 = nn.BatchNorm2d(128)
        self.relu3 = nn.ReLU()
        self.maxpool3 = nn.MaxPool2d(2)

        self.conv4 = nn.Conv2d(128, 128, 5, 1, 2)
        self.batchNorm4 = nn.BatchNorm2d(128)
        self.relu4 = nn.ReLU()
        self.maxpool4 = nn.MaxPool2d(2)

        self.flatten = nn.Flatten()
        self.linear1 = nn.Linear(128 * 2 * 2, 128)
        self.relu5 = nn.ReLU()
        self.dropout = nn.Dropout(0.5)  # 添加Dropout层,丢弃率为0.5
        self.linear2 = nn.Linear(128, 10)

    def forward(self, x):
        x = self.conv1(x)
        x = self.batchNorm1(x)
        x = self.relu1(x)
        x = self.maxpool1(x)

        x = self.conv2(x)
        x = self.batchNorm2(x)
        x = self.relu2(x)
        x = self.maxpool2(x)

        x = self.conv3(x)
        x = self.batchNorm3(x)
        x = self.relu3(x)
        x = self.maxpool3(x)

        x = self.conv4(x)
        x = self.batchNorm4(x)
        x = self.relu4(x)
        x = self.maxpool4(x)

        x = self.flatten(x)
        x = self.linear1(x)
        x = self.relu5(x)
        x = self.dropout(x)
        x = self.linear2(x)

        return x


model = Model()

loss = nn.CrossEntropyLoss()  # 损失函数使用交叉熵损失函数
# 优化器: 使用随机梯度下降
optimizer = torch.optim.SGD(model.parameters(), lr=0.14)  # lr:学习率
scheduler = StepLR(optimizer, step_size=10, gamma=0.5)  # 学习率调度器,每10个epoch将学习率减半

# 将模型放在 GPU 上跑
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model = model.to(device)

writer = SummaryWriter("../nn_classify_image_logs")  # 创建 SummaryWriter 对象,用于记录训练过程中的数据


# 4.训练模型
def train():
    epochs = 10
    total_train_num = 0
    model.train()
    for epoch in range(epochs):
        for data in train_loader:
            imgs, targets = data
            imgs = imgs.to(device)
            targets = targets.to(device)
            model_predict = model(imgs)
            _, predicted = torch.max(model_predict, 1)
            loss_result = loss(model_predict, targets)

            # 优化模型
            optimizer.zero_grad()
            loss_result.backward()
            optimizer.step()

            total_train_num += 1
            if total_train_num % 100 == 0:
                print("Epoch: {}, Loss: {}".format(epoch + 1, loss_result.item()))
                writer.add_scalar("train_loss", loss_result.item(), total_train_num)  # 记录训练损失
                torch.save(model.state_dict(), './model/model.pth')  # 保存模型参数
                torch.save(optimizer.state_dict(), './model/optimizer.pth')  # 保存优化器参数
                print("模型参数已保存")
                print("优化器参数已保存")
                print("训练完成")
            # 计算预测正确的数量
            # total_train_correct += (predicted == targets).sum().item()
            # total_train_loss += loss_result.item()

        # print("Total train loss: {}".format(total_train_loss))


# train()

# 5.测试模型
def test():
    model.load_state_dict(torch.load('./model/model.pth'))
    model.eval()
    total_test_num = 0
    total_test_correct = 0
    total_test_loss = 0
    with torch.no_grad():
        for imgs, targets in test_loader:
            imgs = imgs.to(device)
            targets = targets.to(device)
            model_predict = model(imgs)
            _, predicted = torch.max(model_predict, 1)
            loss_result = loss(model_predict, targets)
            total_test_num += imgs.size(0)
            total_test_correct += (predicted == targets).sum().item()
            total_test_loss += loss_result.item()

            if total_test_num % 100 == 0:
                print("Test_Nums: {}, Loss: {}".format(total_test_num, loss_result.item()))
                writer.add_scalar("Test Loss", loss_result.item(), total_test_num)
                print("Test Accuracy: {}".format(total_test_correct / total_test_num))  # 该批次预测的准确度
                writer.add_scalar("Test Accuracy", total_test_correct / total_test_num, total_test_num)

        print("Test Total Accuracy: {}".format(total_test_correct / total_test_num))  # 总预测的准确度
        print("Test Total Loss: {}".format(total_test_loss / len(test_loader)))


test()

# 6.测试自己的图片
def test_my_image():
    model.load_state_dict(torch.load('./model/model.pth'))
    model.eval()  # 设置为评估模式
    # 定义图像预处理
    transform_image = torchvision.transforms.Compose([
        torchvision.transforms.Resize((32, 32)),  # 调整图像大小为 28x28
        torchvision.transforms.ToTensor(),  # 转换为张量并归一化到 [0, 1]
    ])

    # 加载自己的图片
    img = Image.open('./test_images/deer.png')
    img = img.convert('RGB')
    img = transform_image(img)

    img = img.unsqueeze(0)  # 形状变为 [1, 1, 28, 28]
    img = img.to(device)

    class_names = ["airplane", "automobile", "bird", "cat", "deer", "dog", "frog", "horse", "ship", "truck"]
    with torch.no_grad():
        model_predict = model(img)
        _, predicted = torch.max(model_predict, 1)
        print("预测结果为:", class_names[predicted.item()])  # 输出预测结果
        print("真实结果为:deer")  # 输出真实结果


# test_my_image()

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐