赞
踩
一步步带你敲卷积网络识别猫狗图片算法,步骤详细思路清晰。本文章利用 模块化模型解决猫狗图片识别问题。
文章还会对训练好的模型进行测试使用,延伸利用图像的函数做训练过程数据的可视化,分享数据训练的情况。
首先先构建Alex Net网络模型,我把网络模型写在一个独立的文件上,模块化,我后期可以替换模型来训练数据集。
Alex Net :
这是Alex Net模型的结构图,没有复杂的结构,就是CONV卷积层和Max pool最大池化的堆叠,最后连到全连接层并做Softmax的分类,网络输出的是1000,但是我们做的是猫狗的分类只需要2个答案,所以1000的输出在做一层线性转换为2输出即可。
tips:每次卷积后要做Rule激活
网络模型结构细分步骤(依次往下走): |
---|
Conv(输入:3,输出:96,卷积核:11*11,步数:4) |
Max pool(卷积核:3*3,步数:2) |
Relu |
Conv(输入:96,输出:256,卷积核:5*5,padding:2) |
Max pool(卷积核:3*3,步数:2) |
Relu |
Conv(输入:256,输出:384,卷积核:3*3,padding:1) |
Relu |
Conv(输入:384,输出:384,卷积核:3*3,padding:1) |
Relu |
Conv(输入:384,输出:256,卷积核:3*3,padding:1) |
Max pool(卷积核:3*3,步数:2) |
Relu |
Linear(输入:4096,输出:4096) |
Linear(输入:4096,输出:2048) |
Linear(输入:2048,输出:1000) |
Linear(输入:1000,输出:2) |
第一层Linear的输入是通过卷积后的数据变形成一维的数据得到的,可以先不填让系统报错得到:
这里把网络模型另外写出了一个文件net.py:
import torch import torch.nn.functional as f '''Alex net ''' class MyAlexNet(torch.nn.Module): def __init__(self): '''定义子类和参数''' super(MyAlexNet, self).__init__() self.conv1 = torch.nn.Conv2d(3,96,kernel_size=11,stride=4) self.mp = torch.nn.MaxPool2d(kernel_size=3,stride=2) self.conv2 = torch.nn.Conv2d(96,256,kernel_size=5,padding=2) self.conv3 = torch.nn.Conv2d(256,384,kernel_size=3,padding=1) self.conv4 = torch.nn.Conv2d(384,384,kernel_size=3,padding=1) self.conv5 = torch.nn.Conv2d(384,256,kernel_size=3) self.Linear1 = torch.nn.Linear(1,4096) self.Linear2 = torch.nn.Linear(4096,2048) self.Linear3 = torch.nn.Linear(2048,1000) self.Linear4 = torch.nn.Linear(1000,2) def forward(self,x): '''网络构建''' batch_size =x.size(0)#x.Size([1, 3, 224, 224]) x = f.relu(self.mp(self.conv1(x))) x = f.relu(self.mp(self.conv2(x))) x = f.relu(self.conv3(x)) x = f.relu(self.conv4(x)) x = f.relu(self.conv5(x)) x = self.mp(x) x = x.view(batch_size,-1)#(数据维度,数据长度)-1是指让电脑自动运算数据得到 x = self.Linear1(x) x = f.dropout(x, p=0.5) # 防止过拟合,有50%的数据随机失效 x = self.Linear2(x) x = f.dropout(x,p=0.5) x = self.Linear3(x) x = f.dropout(x, p=0.5) x = self.Linear4(x) return x model = MyAlexNet()
数据集链接: https://pan.baidu.com/s/1CTPq-ttZXX_MJsXaRz3vDg
提取码: cofr
拿到的数据集是只有两个Cat和Dog文件,文件需要做些预处理:
1.建立train训练的数据集和val验证的数据集并存入数据
2.载入数据,并利用transform图像预处理包,对图像进行预处理:大小统一设置为224*224、数据类型转换为Pytorch可处理的tensor形式。读取图像数据,将可视化的图像处理为数字信息用于计算。
建立train和val数据文件,train存入80%数据val存入20%,我们直接用python的os模块来分块,代码主要功能分为三步,第一步检测是否,没有就生成,第二步创建train和val文件夹,第三步把区分好的数据传入train和val文件中。
流程图:
建立和划分数据的代码split_data.py:
import os from shutil import copy import random def mkfile(file): if not os.path.exists(file): os.makedirs(file)#如果没有file文件就创建一个 # 获取data文件夹下所有文件夹名(即需要分类的类名) file_path = '/Users/aixuexi_pro/PycharmProjects/pytorch/torch/Alex net 猫狗识别/data_name' flower_class = [cla for cla in os.listdir(file_path)] # 创建 训练集train 文件夹,并由类名在其目录下创建5个子目录 mkfile('data/train') for cla in flower_class: mkfile('data/train/' + cla) # 创建 验证集val 文件夹,并由类名在其目录下创建子目录 mkfile('data/val') for cla in flower_class: mkfile('data/val/' + cla) # 划分比例,训练集 : 验证集 = 8 : 2 split_rate = 0.2 # 遍历所有类别的全部图像并按比例分成训练集和验证集 for cla in flower_class: cla_path = file_path + '/' + cla + '/' # 某一类别的子目录 images = os.listdir(cla_path) # iamges 列表存储了该目录下所有图像的名称 num = len(images) eval_index = random.sample(images, k=int(num * split_rate)) # 从images列表中随机抽取 k 个图像名称 for index, image in enumerate(images): '''保存图像进文件中''' # eval_index 中保存验证集val的图像名称 if image in eval_index: image_path = cla_path + image new_path = 'data/val/' + cla copy(image_path, new_path) # 将选中的图像复制到新路径 # 其余的图像保存在训练集train中 else: image_path = cla_path + image new_path = 'data/train/' + cla copy(image_path
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。