详解用PyTorch搭建一个图像分类神经网络

您所在的位置:网站首页 使用pytorch实现图像分类数据集 详解用PyTorch搭建一个图像分类神经网络

详解用PyTorch搭建一个图像分类神经网络

2024-07-15 07:36| 来源: 网络整理| 查看: 265

前言

今天是大年初二,业余时间总结一下在PyTorch框架下,用自组织数据集,自己亲手搭建一个图像分类神经网络的详细步骤.

在这里插入图片描述

环境 本地编辑器 win 10 + PyCharm本地环境 Anaconda + Python3 + PyTorch训练环境 腾讯云高性能服务器 (斜眼笑~ 勿酸)测试环境 本地 数据集准备

经典的范例是猫狗图像分类,这次不出意外,我们以 Kaggle 上的 Dog vs. Cat 数据集作为本次神经网络训练所需要的数据.

数据集下载地址:https://www.kaggle.com/c/dogs-vs-cats/data

之后放到项目根目录中,命名为train,下分两个文件夹 Cat / Dog.

在这里插入图片描述

引入依赖包 from torchvision.datasets import ImageFolder # 图形数据组织工具 from torchvision import transforms # 图形变换工具 import torch.nn as nn # pytorch网络核心依赖 import torch.nn.functional as F # pytorch函数工具箱 import torch.optim as optim # pytorch优化工具箱 import os # os文件系统工具包 import torch # torch核心以依赖 图形变换函数和图形数据加载 # 定义图像变换 tfs = transforms.Compose([ transforms.Resize((256, 256)), # 规定图形大小 transforms.ToTensor(), # 转化为张量数据 transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]) # 数据归中 ]) # 加载图像数据集,并在加载的时候对图像施加变换 train_data = ImageFolder('./train', tfs) # print(train_data.class_to_idx) # {'Cat': 0, 'Dog': 1} # print(train_data.classes) # ['Cat', 'Dog'] 定义神经网络 class Net(nn.Module): # init定义网络中的结构 def __init__(self): super(Net, self).__init__() # 3输入,16输出,卷积核(7, 7),膨胀系数为2 self.conv1 = nn.Conv2d(3, 16, kernel_size=7, dilation=2) self.conv2 = nn.Conv2d(16, 32, kernel_size=5) # dropout self.conv2_drop = nn.Dropout2d() # 全连接层 self.fc1 = nn.Linear(55696*2, 1000) self.fc2 = nn.Linear(1000, 50) self.fc3 = nn.Linear(50, 2) # forward定义数据在网络中的流向 def forward(self, x): # 卷积之后做一个最大池化,然后RELU激活 x = F.relu(F.max_pool2d(self.conv1(x), 2)) x = F.relu(F.max_pool2d(self.conv2_drop(self.conv2(x)), 2)) # 整形 x = x.view(-1, 55696*2) x = F.relu(self.fc1(x)) x = F.dropout(x) x = F.relu(self.fc2(x)) x = F.dropout(x) x = self.fc3(x) return F.log_softmax(x, dim=1) 一个epoch的训练过程 def train_epoch(epoch, model, device, data_loader, optimizer): # model进入训练模式 model.train() pid = os.getpid() # 加载训练数据,(data, target)二元组表示 “训练数据-训练标签” for batch_idx, (data, target) in enumerate(data_loader): # 优化器梯度清 0 optimizer.zero_grad() # 输出特征预测值 output = model(data.to(device)) # 计算损失 loss = F.nll_loss(output, target.to(device)) # 计算梯度 loss.backward() # 更新梯度 optimizer.step() # 每十个批次打印一下信息 if batch_idx % 10 == 0: print('{}\tTrain Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format( pid, epoch, batch_idx * len(data), len(data_loader.dataset), 100. * batch_idx / len(data_loader), loss.item())) 整体训练函数 def train(args, model, device, dataloader_kwargs): # 指定随机值,让每次网络的初始值虽然是随机但却是固定的 torch.manual_seed(args['seed']) # 训练数据加载器 (suffle指定随机打乱数据) train_loader = torch.utils.data.DataLoader(train_data, batch_size=args['batch_size'], shuffle=True, **dataloader_kwargs) # 优化器 optimizer = optim.SGD(model.parameters(), lr=args['lr'], momentum=args['momentum']) # 迭代训练 for epoch in range(1, args['epochs'] + 1): train_epoch(args['epochs'], model, device, train_loader, optimizer) 主函数调用 # 定义参数 # batch_size:每次训练的样本量 # epochs:训练轮次 # lr:学习率 # momentum:动量 # seed: # log_interval: args = { 'batch_size': 32, 'test_batch_size': 1000, 'epochs': 10, 'lr': 0.01, 'momentum': 0.9, 'seed': 1, 'log_interval': 10 } # 用cuda use_cuda = True if torch.cuda.is_available() else False if __name__ == '__main__': # 指定训练设备 device = torch.device("cpu" if use_cuda else "cpu") dataloader_kwargs = {'pin_memory': True} if use_cuda else {} # 将模型送达设备 model = Net().to(device) # 训练 train(args, model, device, dataloader_kwargs) 服务器训练结果

已经从服务器下载到本地了 在这里插入图片描述

模型测试

先上结果:0.8813643104300544,看来还可以接受.

测试所用的数据集是:https://www.kaggle.com/tongpython/cat-and-dog

def test(model, device): # 加载测试数据集 test_data = ImageFolder(r'./test', tfs) test_loader = torch.utils.data.DataLoader(test_data, batch_size=64, shuffle=True) lenn = len(test_data) # 测试过程不记录权重 with torch.no_grad(): acc = 0 for item in test_loader: img, tag = item outputs = model(img.to(device)) # [1] 维度是预测的类别 predict_y = torch.max(outputs, dim=1)[1] # 统计正确分类的个数 acc += torch.eq(predict_y, tag.to(device)).sum().item() acc /= lenn print(acc)

主函数改为测试函数

device = torch.device("cpu" if use_cuda else "cpu") model = Net().to(device) # 加载模型参数 model.load_state_dict(torch.load('./model.pth', map_location=device), strict=False) # 测试 test(model, device) 模型预测 def predict(model, img): with torch.no_grad(): out = model(img) _, pre = torch.max(out.data, 1) return pre.item()

主函数改为:

device = torch.device("cpu" if use_cuda else "cpu") model = Net().to(device) model.load_state_dict(torch.load('./model.pth', map_location=device), strict=False) print(predict(model, tfs(Image.open(r'xxx.jpg')).unsqueeze(0))) 参考和推荐阅读资料 深度学习:深入浅出地理解神经网络 https://zhuanlan.zhihu.com/p/61492295BP神经网络算法推导及代码实现笔记 https://zhuanlan.zhihu.com/p/38006693Pytorch 模型构建、训练、测试及预测 https://blog.csdn.net/andyL_05/article/details/103363603深度学习中Dropout原理解析 https://blog.csdn.net/program_developer/article/details/80737724常用激活函数总结 https://zhuanlan.zhihu.com/p/74393124从 SGD 到 Adam —— 6大常见优化算法总结 https://zhuanlan.zhihu.com/p/64113429


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3