深度学习CNN算法及算法应用--猫狗识别(二)


前言

本文介绍深度学习卷积神经网络(CNN)模型及其应用实战。本文主要介绍算法的应用–利用深度学习卷积神经网络构建猫狗识别模型。


一、构建数据集类

构建用于处理猫狗分类数据集的PyTorch数据集类。

1.导入模块

导入所需的Python模块和库,包括PyTorch的数据处理模块、操作系统路径处理模块、PIL库用于图像处理、以及PyTorch中的数据转换模块。
代码如下(示例):

import torch.utils.data
import os
import torch
import torch.utils.data as data
from PIL import Image
import torchvision.transforms as Trans

2.设置图片尺寸和转换

img_size 设置了图片的尺寸,tran 定义了图片转换的操作序列,包括调整大小、中心裁剪和转换为张量。
代码如下(示例):

img_size = 200
tran = Trans.Compose([
    Trans.Resize(img_size),
    Trans.CenterCrop([img_size, img_size]),
    Trans.ToTensor()
])

3.设数据集类 DogsVSCatsDataset:

init 方法:根据传入的 mode 和 dir 参数初始化数据集。如果是训练模式 (‘train’),则加载训练集数据;如果是测试模式 (‘test’),则加载测试集数据。每个模式下都会读取相应文件夹中的图像文件,并根据文件名判断是猫还是狗,将其存入 img_list 和 img_label 中。

getitem 方法:根据索引 item 返回数据集中的一个样本。在训练模式下,返回经过预定义转换 (tran) 处理后的图像及其对应的标签;在测试模式下,仅返回经过转换处理后的图像。

len 方法:返回整个数据集的大小,即样本数量。
代码如下(示例):

class DogsVSCatsDataset(data.Dataset):
    def __init__(self, mode, dir):
        # 初始化函数,定义了数据集的大小、图像列表、标签列表、转换方式和模式
    def __getitem__(self, item):
        # 获取数据函数,根据模式返回图像及其标签(训练模式)或仅返回图像(测试模式)
    def __len__(self):
        # 返回数据集大小
])

4.数据处理细节:

训练模式中,图像文件命名规则为 cat.* 或 dog.*,通过文件名切分来确定标签,cat 对应标签 1,dog 对应标签 0。

测试模式中,没有有意义的标签,因此用 2 来占位。

5.异常处理:

如果传入的 mode 不是 ‘train’ 或 ‘test’,则会打印 “没有这个mode” 提示信息。

全部代码如下:

import torch.utils.data
import os   #文件操作模块
import torch
import torch.utils.data as data   #用于继承一个父类(data.Dataset)里的函数
from PIL import Image
import torchvision.transforms as Trans #在定义图片转换的格式时,会用到相关的函数

img_size = 200 #设置图片尺寸

tran = Trans.Compose([Trans.Resize(img_size), Trans.CenterCrop([img_size, img_size]), Trans.ToTensor()]) #封装, 对后面读取的图片的格式转换

class DogsVSCatsDataset(data.Dataset):
    def __init__(self, mode, dir):
        self.data_size = 0 #数据集的大小
        self.img_list=[] #用于存图
        self.img_label =[]#标签
        self.trans=tran #转换的属性设置
        self.mode =mode #下面打开集的模式

        if self.mode =='train':
            dir += '/train/' #更新地址
            for file in os.listdir(dir): #遍历
                self.img_list.append(dir+file) #存图
                self.data_size += 1
                name = file.split(sep='.') #将 该文件名拆分,便于判断是cat还是dog
                label_x =0
                if name[0] =='cat':
                    label_x =1
                self.img_label.append(label_x)#设置入相对于的标签;cat:1; dog:0

        elif self.mode == 'test':
            dir +='/test/'
            for file in os.listdir(dir):#同理
                self.img_list.append(dir+file)
                self.data_size +=1
                self.img_label.append(2)#无意义的标签
        else:
            print("没有这个mode")

    def __getitem__(self,item):  #获取数据
        if self.mode =='train':
            img =Image.open(self.img_list[item])
            label_y = self.img_label[item]
            return self.trans(img), torch.LongTensor([label_y])  #返回该图片的地址和标签
        elif self.mode=='test':
            img =Image.open(self.img_list[item])
            return self.trans(img)
        else:
            print("None")
    def __len__(self):
        return self.data_size

二、定义构建卷积神经网络模型

定义了一个简单的卷积神经网络模型(Net),用于猫狗分类任务。

1.导入模块

导入了PyTorch所需的模块,包括张量操作、神经网络函数、神经网络模块以及数据处理模块。
代码如下(示例):

import torch
import torch.nn.functional as F
import torch.nn as nn
import torch.utils.data as data

2.定义神经网络模型 Net

代码如下(示例):

class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.conv1 = torch.nn.Conv2d(3, 16, 3, padding=1)
        self.conv2 = torch.nn.Conv2d(16, 16, 3, padding=1)
        self.fc1 = torch.nn.Linear(50*50*16, 128)
        self.fc2 = torch.nn.Linear(128, 64)
        self.fc3 = torch.nn.Linear(64, 2)
    def forward(self, x):
        # 定义前向传播过程
        def forward(self, x):
    x = self.conv1(x)   # 第一层卷积
    x = F.relu(x)       # 激活函数 ReLU
    x = F.max_pool2d(x, 2)  # 池化层,大小为2x2的最大池化
    
    x = self.conv2(x)   # 第二层卷积
    x = F.relu(x)       # 激活函数 ReLU
    x = F.max_pool2d(x, 2)  # 池化层,大小为2x2的最大池化
    
    x = x.view(x.size(0), -1)  # 将特征图展平成一维向量
    
    x = F.relu(self.fc1(x))   # 第一个全连接层,并使用ReLU激活函数
    x = F.relu(self.fc2(x))   # 第二个全连接层,并使用ReLU激活函数
    x = self.fc3(x)           # 第三个全连接层,输出未经过激活函数
    
    return F.softmax(x, dim=1)  # 使用softmax函数进行分类,dim=1表示按行计算softmax

这个模型通过卷积层提取图像特征,通过池化层降低特征图的维度,然后通过全连接层进行分类。
使用ReLU作为激活函数,softmax函数作为最后的分类激活函数,输出每个类别的概率分布。

三、训练模型

构建简单的训练脚本,用于训练猫狗分类任务的神经网络模型

1.导入模块和类

代码如下(示例):

from getdata import DogsVSCatsDataset as DVCD
from torch.utils.data import DataLoader as DataLoader
from network import Net
import torch
from torch.autograd import Variable
import torch.nn as nn
  • from getdata import DogsVSCatsDataset as DVCD:导入了数据集类
  • DogsVSCatsDataset,该类用于加载和处理猫狗分类数据集。
  • from torch.utils.data import DataLoader as DataLoader:导入了数据加载器类DataLoader,用于批量加载数据。
  • from network import Net:导入了神经网络模型类 Net,该类在 network.py 文件中定义。
  • 其他导入的模块包括PyTorch核心模块、自动求导模块、神经网络模块等。

2.设置路径和参数:

代码如下(示例):

dataset_dir = 'C:/Users/86131/PycharmProjects/pythonProject/newnew/data/train'  # 数据集路径
model_dir = './model/'     # 网络参数保存位置
workers = 10                        # 线程数量
batch_size = 16                     # 一次训练所选取的样本数
lr = 0.001                         # 学习率
nepoch = 1                         # 训练的次数

数据集信息如下:
在这里插入图片描述

3.定义训练函数 train()

代码如下(示例):

def train():
    datafile = DVCD('train', dataset_dir)   # 实例化数据集对象
    dataloader = DataLoader(datafile, batch_size=batch_size, shuffle=True, num_workers=workers, drop_last=True)  # 创建数据加载器

    print('Dataset loaded! length of train set is {0}'.format(len(datafile)))

    model = Net()  # 实例化一个网络
    model = nn.DataParallel(model)  # 多GPU并行化
    model.train()  # 将模型设置为训练模式

    optimizer = torch.optim.Adam(model.parameters(), lr=lr)  # Adam优化器
    Lossfuc = torch.nn.CrossEntropyLoss()  # 交叉熵损失函数

    cnt = 0  # 记录训练图片数量
    for epoch in range(nepoch):  # 遍历每个epoch
        for img, label in dataloader:  # 遍历每个batch
            img, label = Variable(img), Variable(label)  # 将数据转为PyTorch的Variable类型
            out = model(img)  # 前向传播,计算输出
            loss = Lossfuc(out, label.squeeze())  # 计算损失
            loss.backward()  # 反向传播,计算梯度
            optimizer.step()  # 更新网络参数
            optimizer.zero_grad()  # 梯度清零
            cnt += 1

            print('Epoch:{0}, Frame:{1}, train_loss {2}'.format(epoch, cnt*batch_size, loss/batch_size))

    torch.save(model.state_dict(), '{0}/model.pth'.format(model_dir))  # 保存训练好的模型参数

四、应用模型

用于加载训练好的模型,并使用该模型对测试集中的随机一张图片进行分类和可视化展示

1.导入模块和类

代码如下(示例):

from getdata import DogsVSCatsDataset as DVCD
from network import Net
from torch.autograd import Variable
import numpy as np
import torch.nn.functional as F
import torch
import torch.nn as nn
import matplotlib.pyplot as plt
from PIL import Image
import os
os.environ["KMP_DUPLICATE_LIB_OK"] = "TRUE"  # 防止打印图片出错

2.设置环境变量

设置环境变量,防止在某些系统上使用matplotlib时出现问题。

代码如下(示例):

os.environ["KMP_DUPLICATE_LIB_OK"] = "TRUE"  # 防止打印图片出错

3.定义路径和常量

代码如下(示例):

data_dir = '.../newnew/data/test'  # 测试集路径
model_file = './model/model.pth'  # 模型文件路径
N = 10  # 随机选择测试图片的数量

测试集如下:
在这里插入图片描述

4.加载模型

代码如下(示例):

model = Net()  # 实例化一个网络模型
model = nn.DataParallel(model)  # 多GPU并行化
model.load_state_dict(torch.load(model_file))  # 加载模型参数
model.eval()  # 将模型设置为评估模式
datafile = DVCD('test', data_dir)  # 实例化测试数据集对象

5.随机测试

代码如下(示例):

index = np.random.randint(0, datafile.data_size, 1)[0]  # 随机选择一个索引
img = datafile.__getitem__(index)  # 获取对应索引的图片及其标签

6.处理测试图片并进行预测

代码如下(示例):

img = img.unsqueeze(0)  # 在第0维增加一个维度,变成(batch_size, channels, height, width)
img = Variable(img)  # 将数据转为PyTorch的Variable类型
out = model(img)  # 输入模型,进行前向传播,得到输出
out = F.softmax(out, dim=1)  # 对输出进行softmax处理,得到分类概率

7.输出预测结果

代码如下(示例):

print(out.data)
if out[0, 0] > out[0, 1]:
    print("the picture is a cat")
else:
    print("the picture is a dog")

8.可视化展示测试图片

代码如下(示例):

img = Image.open(datafile.img_list[index])  # 打开对应索引的原始图像
plt.figure('image')  # 创建一个新的图像窗口
plt.imshow(img)  # 显示图片
plt.show()  # 显示图像窗口

运行结果
在这里插入图片描述
在这里插入图片描述


总结

代码展示了一个简单的卷积神经网络结构,包括卷积层、池化层和全连接层,并使用PyTorch进行训练和预测。这些组件和操作是构建深度学习图像分类模型的基础,通过逐步调整网络结构和超参数,可以优化模型性能和准确率。

  • 48
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是一个简单的 CNN 深度学习算法识别猫狗图片的代码示例。这里使用 Python 和 Keras 框架实现。 ```python # 导入必要的库 import numpy as np from keras.models import Sequential from keras.layers import Conv2D, MaxPooling2D, Dropout, Flatten, Dense from keras.preprocessing.image import ImageDataGenerator # 定义模型 model = Sequential() model.add(Conv2D(32, (3, 3), activation='relu', input_shape=(150, 150, 3))) model.add(MaxPooling2D((2, 2))) model.add(Conv2D(64, (3, 3), activation='relu')) model.add(MaxPooling2D((2, 2))) model.add(Conv2D(128, (3, 3), activation='relu')) model.add(MaxPooling2D((2, 2))) model.add(Conv2D(128, (3, 3), activation='relu')) model.add(MaxPooling2D((2, 2))) model.add(Flatten()) model.add(Dense(512, activation='relu')) model.add(Dense(1, activation='sigmoid')) # 编译模型 model.compile(loss='binary_crossentropy', optimizer='rmsprop', metrics=['accuracy']) # 数据增强 train_datagen = ImageDataGenerator(rescale=1./255, rotation_range=40, width_shift_range=0.2, height_shift_range=0.2, shear_range=0.2, zoom_range=0.2, horizontal_flip=True) test_datagen = ImageDataGenerator(rescale=1./255) # 加载数据 train_generator = train_datagen.flow_from_directory( 'train', target_size=(150, 150), batch_size=32, class_mode='binary') validation_generator = test_datagen.flow_from_directory( 'validation', target_size=(150, 150), batch_size=32, class_mode='binary') # 训练模型 model.fit_generator( train_generator, steps_per_epoch=2000, epochs=50, validation_data=validation_generator, validation_steps=800) # 保存模型 model.save('cat_dog_classifier.h5') ``` 在这个示例中,我们使用了一个包含四个卷积层和两个全连接层的 CNN 模型,并使用 RMSprop 优化器和元交叉熵损失函数进行编译。我们还使用 Keras 的 ImageDataGenerator 类来进行数据增强,以改善模型的泛化能力。 注意,这个示例的数据集应该是包含两个子目录 train 和 validation,分别包含狗和猫的图像数据。你需要将数据集准备好并放到正确的目录中,然后运行这个代码来训练模型。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值