手机如做网站,网页好看的网站设计,高端品牌企业管理系统,交友app搭建案例-图像分类 网络结构: 卷积BN激活池化 数据集介绍
CIFAR-10数据集5万张训练图像、1万张测试图像、10个类别、每个类别有6k个图像#xff0c;图像大小32323。下图列举了10个类#xff0c;每一类随机展示了10张图片#xff1a; 特征图计算
在卷积层和池化层结束后, 将特征…
案例-图像分类 网络结构: 卷积BN激活池化 数据集介绍
CIFAR-10数据集5万张训练图像、1万张测试图像、10个类别、每个类别有6k个图像图像大小32×32×3。下图列举了10个类每一类随机展示了10张图片 特征图计算
在卷积层和池化层结束后, 将特征图变形成一行n列数据, 计算特征图进行变化, 映射到全连接层时输入层特征为最后一层卷积层经池化后的特征图各维度相乘 具体流程-# Acc: 0.728
# 导包
import numpy as np
import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import DataLoader
from torchsummary import summary
from torchvision.datasets import CIFAR10
from torchvision.transforms import ToTensor, Compose # Compose: 数据增强(扩充数据集)
import time
import matplotlib.pyplot as plt
batch_size 16
# 创建数据集
def create_dataset():torch.manual_seed(21)train CIFAR10(rootdata,trainTrue,transformCompose([ToTensor()]))test CIFAR10(rootdata,trainFalse,transformCompose([ToTensor()]))return train, test
# 创建模型
class ImgCls(nn.Module):# 定义网络结构def __init__(self):super(ImgCls, self).__init__()# 定义网络层卷积层池化层self.conv1 nn.Conv2d(3, 16, stride1, kernel_size3)self.batch_norm_layer1 nn.BatchNorm2d(num_features16, eps1e-5, momentum0.1, affineTrue, track_running_statsTrue)self.pool1 nn.MaxPool2d(kernel_size2, stride2)
self.conv2 nn.Conv2d(16, 32, stride1, kernel_size3)self.batch_norm_layer2 nn.BatchNorm2d(num_features32, eps1e-5, momentum0.1, affineTrue, track_running_statsTrue)self.pool2 nn.MaxPool2d(kernel_size2, stride1)
self.conv3 nn.Conv2d(32, 64, stride1, kernel_size3)self.batch_norm_layer3 nn.BatchNorm2d(num_features64, eps1e-5, momentum0.1, affineTrue, track_running_statsTrue)self.pool3 nn.MaxPool2d(kernel_size2, stride1)
self.conv4 nn.Conv2d(64, 128, stride1, kernel_size2)self.batch_norm_layer4 nn.BatchNorm2d(num_features128, eps1e-5, momentum0.1, affineTrue, track_running_statsTrue)self.pool4 nn.MaxPool2d(kernel_size2, stride2)
self.conv5 nn.Conv2d(128, 256, stride1, kernel_size2)self.batch_norm_layer5 nn.BatchNorm2d(num_features256, eps1e-5, momentum0.1, affineTrue, track_running_statsTrue)self.pool5 nn.MaxPool2d(kernel_size2, stride1)
# 全连接层self.linear1 nn.Linear(1024, 2048)self.linear2 nn.Linear(2048, 1024)self.linear3 nn.Linear(1024, 512)self.linear4 nn.Linear(512, 256)self.linear5 nn.Linear(256, 128)self.out nn.Linear(128, 10)
# 定义前向传播def forward(self, x):# 第1层: 卷积BN激活池化x self.conv1(x)x self.batch_norm_layer1(x)x torch.rrelu(x)x self.pool1(x)
# 第2层: 卷积BN激活池化x self.conv2(x)x self.batch_norm_layer2(x)x torch.rrelu(x)x self.pool2(x)
# 第3层: 卷积BN激活池化x self.conv3(x)x self.batch_norm_layer3(x)x torch.rrelu(x)x self.pool3(x)
# 第4层: 卷积BN激活池化x self.conv4(x)x self.batch_norm_layer4(x)x torch.rrelu(x)x self.pool4(x)
# 第5层: 卷积BN激活池化x self.conv5(x)x self.batch_norm_layer5(x)x torch.rrelu(x)x self.pool5(x)
# 将特征图做成以为向量的形式相当于特征向量x x.reshape(x.size(0), -1) # 将3维特征图转化为1维向量(1, n)
# 全连接层x torch.rrelu(self.linear1(x))x torch.rrelu(self.linear2(x))x torch.rrelu(self.linear3(x))x torch.rrelu(self.linear4(x))x torch.rrelu(self.linear5(x))# 返回输出结果return self.out(x)
# 训练
def train(model, train_dataset, epochs):torch.manual_seed(21)loss nn.CrossEntropyLoss()opt optim.Adam(model.parameters(), lr1e-4)for epoch in range(epochs):dataloader DataLoader(train_dataset, shuffleTrue, batch_sizebatch_size)loss_total 0iter 0stat_time time.time()for x, y in dataloader:output model(x.to(device))loss_value loss(output, y.to(device))opt.zero_grad()loss_value.backward()opt.step()loss_total loss_value.item()iter 1print(fepoch:{epoch 1:4d}, loss:{loss_total / iter:6.4f}, time:{time.time() - stat_time:.2f}s)torch.save(model.state_dict(), model/img_cls_model.pth)
# 测试
def test(valid_dataset, model, batch_size):# 构建数据加载器dataloader DataLoader(valid_dataset, batch_sizebatch_size, shuffleFalse)
# 计算精度total_correct 0# 遍历每个batch的数据获取预测结果计算精度for x, y in dataloader:output model(x.to(device))y_pred torch.argmax(output, dim-1)total_correct (y_pred y.to(device)).sum()# 打印精度print(fAcc: {(total_correct.item() / len(valid_dataset))})
if __name__ __main__:batch_size 16device torch.device(cuda if torch.cuda.is_available() else cpu)# 获取数据集train_data, test_data create_dataset()
# # 查看数据集# print(f数据集类别: {train_data.class_to_idx})# print(f训练集: {train_data.data.shape})# print(f验证集: {test_data.data.shape})# print(f类别数量: {len(np.unique(train_data.targets))})# # 展示图像# plt.figure(figsize(8, 8))# plt.imshow(train_data.data[0])# plt.title(train_data.classes[train_data.targets[0]])# plt.show()
# 实例化模型model ImgCls().to(device)
# 查看网络结构summary(model, (3, 32, 32), devicecuda, batch_sizebatch_size)
# 模型训练train(model, train_data, epochs60)# 加载训练好的模型参数model.load_state_dict(torch.load(model/img_cls_model.pth))model.eval()# 模型评估test(test_data, model, batch_size16) # Acc: 0.728
调整网络结构
第一次调整: 训练50轮, Acc: 0.71 第二次调整: 训练30轮, Acc:0.7351 第三次调整: batch_size8, epoch50 Acc: 0.7644 # 导包
import numpy as np
import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import DataLoader
from torchsummary import summary
from torchvision.datasets import CIFAR10
from torchvision.transforms import ToTensor, Compose # Compose: 数据增强(扩充数据集)
import time
import matplotlib.pyplot as plt
batch_size 16
# 创建数据集
def create_dataset():torch.manual_seed(21)train CIFAR10(rootdata,trainTrue,transformCompose([ToTensor()]))test CIFAR10(rootdata,trainFalse,transformCompose([ToTensor()]))return train, test
# 创建模型
class ImgCls(nn.Module):# 定义网络结构def __init__(self):super(ImgCls, self).__init__()# 定义网络层卷积层池化层self.conv1 nn.Conv2d(3, 16, stride1, kernel_size3, padding1)self.batch_norm_layer1 nn.BatchNorm2d(num_features16, eps1e-5, momentum0.1, affineTrue, track_running_statsTrue)self.pool1 nn.MaxPool2d(kernel_size2, stride2)
self.conv2 nn.Conv2d(16, 32, stride1, kernel_size3, padding1)self.batch_norm_layer2 nn.BatchNorm2d(num_features32, eps1e-5, momentum0.1, affineTrue, track_running_statsTrue)self.pool2 nn.MaxPool2d(kernel_size2, stride2)
self.conv3 nn.Conv2d(32, 64, stride1, kernel_size3, padding1)self.batch_norm_layer3 nn.BatchNorm2d(num_features64, eps1e-5, momentum0.1, affineTrue, track_running_statsTrue)self.pool3 nn.MaxPool2d(kernel_size2, stride1)
self.conv4 nn.Conv2d(64, 128, stride1, kernel_size3, padding1)self.batch_norm_layer4 nn.BatchNorm2d(num_features128, eps1e-5, momentum0.1, affineTrue, track_running_statsTrue)self.pool4 nn.MaxPool2d(kernel_size2, stride1)
self.conv5 nn.Conv2d(128, 256, stride1, kernel_size3)self.batch_norm_layer5 nn.BatchNorm2d(num_features256, eps1e-5, momentum0.1, affineTrue, track_running_statsTrue)self.pool5 nn.MaxPool2d(kernel_size2, stride2)
# 全连接层self.linear1 nn.Linear(1024, 2048)self.linear2 nn.Linear(2048, 1024)self.linear3 nn.Linear(1024, 512)self.linear4 nn.Linear(512, 256)self.linear5 nn.Linear(256, 128)self.out nn.Linear(128, 10)
# 定义前向传播def forward(self, x):# 第1层: 卷积BN激活池化x self.conv1(x)x self.batch_norm_layer1(x)x torch.relu(x)x self.pool1(x)
# 第2层: 卷积BN激活池化x self.conv2(x)x self.batch_norm_layer2(x)x torch.relu(x)x self.pool2(x)
# 第3层: 卷积BN激活池化x self.conv3(x)x self.batch_norm_layer3(x)x torch.relu(x)x self.pool3(x)
# 第4层: 卷积BN激活池化x self.conv4(x)x self.batch_norm_layer4(x)x torch.relu(x)x self.pool4(x)
# 第5层: 卷积BN激活池化x self.conv5(x)x self.batch_norm_layer5(x)x torch.rrelu(x)x self.pool5(x)
# 将特征图做成以为向量的形式相当于特征向量x x.reshape(x.size(0), -1) # 将3维特征图转化为1维向量(1, n)
# 全连接层x torch.relu(self.linear1(x))x torch.relu(self.linear2(x))x torch.relu(self.linear3(x))x torch.relu(self.linear4(x))x torch.rrelu(self.linear5(x))# 返回输出结果return self.out(x)
# 训练
def train(model, train_dataset, epochs):torch.manual_seed(21)loss nn.CrossEntropyLoss()opt optim.Adam(model.parameters(), lr1e-4)for epoch in range(epochs):dataloader DataLoader(train_dataset, shuffleTrue, batch_sizebatch_size)loss_total 0iter 0stat_time time.time()for x, y in dataloader:output model(x.to(device))loss_value loss(output, y.to(device))opt.zero_grad()loss_value.backward()opt.step()loss_total loss_value.item()iter 1print(fepoch:{epoch 1:4d}, loss:{loss_total / iter:6.4f}, time:{time.time() - stat_time:.2f}s)torch.save(model.state_dict(), model/img_cls_model1.pth)
# 测试
def test(valid_dataset, model, batch_size):# 构建数据加载器dataloader DataLoader(valid_dataset, batch_sizebatch_size, shuffleFalse)
# 计算精度total_correct 0# 遍历每个batch的数据获取预测结果计算精度for x, y in dataloader:output model(x.to(device))y_pred torch.argmax(output, dim-1)total_correct (y_pred y.to(device)).sum()# 打印精度print(fAcc: {(total_correct.item() / len(valid_dataset))})
if __name__ __main__:batch_size 8device torch.device(cuda if torch.cuda.is_available() else cpu)# 获取数据集train_data, test_data create_dataset()
# # 查看数据集# print(f数据集类别: {train_data.class_to_idx})# print(f训练集: {train_data.data.shape})# print(f验证集: {test_data.data.shape})# print(f类别数量: {len(np.unique(train_data.targets))})# # 展示图像# plt.figure(figsize(8, 8))# plt.imshow(train_data.data[0])# plt.title(train_data.classes[train_data.targets[0]])# plt.show()
# 实例化模型model ImgCls().to(device)
# 查看网络结构summary(model, (3, 32, 32), devicecuda, batch_sizebatch_size)
# 模型训练train(model, train_data, epochs50)# 加载训练好的模型参数model.load_state_dict(torch.load(model/img_cls_model1.pth, weights_onlyTrue))model.eval()# 模型评估test(test_data, model, batch_size16) # Acc: 0.7644