基于pytorch神经网络进行猫狗分类

本文介绍了如何使用Python和PyTorch库在Kaggle猫狗分类数据集上构建一个基础的神经网络模型BPNetwork,包括数据集的定义、模型结构、数据加载与预处理,以及训练过程中的损失函数和优化策略。
摘要由CSDN通过智能技术生成

一.第三方库及数据集的准备

import torch
from PIL import Image
import numpy as np
from matplotlib import pyplot as plt
from torch.utils.data import Dataset
import os
from torchvision import transforms

 数据集为kaggle上的猫狗分类数据集

二.数据集定义 (mydataset 类)

class mydataset(Dataset):
    def __init__(self, root_dir, label_dir):
        self.root__dir = root_dir
        self.label_dir = label_dir
        self.path = os.path.join(root_dir, label_dir)
        self.img_path = os.listdir(self.path)
        self.transform = transforms.Compose([
            transforms.Resize((224, 224)),
            transforms.ToTensor()
        ])

    def __getitem__(self, item):
        img_name = self.img_path[item]
        img_item_path= os.path.join(self.path, img_name)
        img = Image.open(img_item_path).convert('RGB')
        img = self.transform(img)

        if self.label_dir == "Cat":
            label = 0
        else:
            label = 1

        return img, label


    def __len__(self):
        iten = len(self.img_path)
        return iten

1.mydataset 类继承自 PyTorch 的 Dataset 类,用于加载图像数据并进行预处理。
2.init--  方法中接收两个参数:root-dir 是包含图像文件的根目录,label-dir是标签目录,即子文件夹的名称(例如"Cat" 和"Dog")。
3.--getitem--方法用于获取图像和对应的标签。它首先构建图像的完整路径,然后加载图像并getitem进行预处理!(调整大小和转换为张量)。最后,根据 label-dir 参数设置标签(0 表示猫,表示狗)
4.-len-方法返回数据集的长度

三.神经网络模型定义 (BPNetwork 类)

class BPNetwork(torch.nn.Module):

    def __init__(self):
        super(BPNetwork, self).__init__()
        self.linear1 = torch.nn.Linear(224 * 224 * 3, 128)
        self.relu1 = torch.nn.ReLU()
        self.linear2 = torch.nn.Linear(128, 64)
        self.relu2 = torch.nn.ReLU()
        self.linear3 = torch.nn.Linear(64, 2)
        self.softmax = torch.nn.LogSoftmax(dim=1)      #输出进行归一化处理

    def forward(self, x):
        x = x.view(x.shape[0], -1)
        x = self.linear1(x)
        x = self.relu1(x)
        x = self.linear2(x)
        x = self.relu2(x)
        x = self.linear3(x)
        x = self.softmax(x)
        return x

1.BPNetwork 类继承自 PyTorch 的 Module 类,用于定义神经网络模型。
2.在_init方法中定义了三个线性层(torch.nn.Linear ),两个激活函数(torch.m.Reu)。这个网络结构是一个简单的全连接层神经网络。
3.forward 方法定义了前向传播的过程。输入的图像数据首先被展平成一维张量,然后通过线性层和激活函数的组合进行前向传播,最终输出分类的 logjits。

四.数据加载和训练

root_dir = 'D:\Backup\Documents\WeChat Files\wxid_8rnhd895jesr22\FileStorage\File\2024-04\kagglecatsanddogs_5340.zip'
cat_label_dir = "Cat"
dog_label_dir = "Dog"

catdata = mydataset(root_dir, cat_label_dir)
dogdata = mydataset(root_dir, dog_label_dir)
traindataset = catdata + dogdata

trainloader = torch.utils.data.DataLoader(traindataset, batch_size=2, shuffle=True)

1.创建了两个数据集对象,分别对应猫和狗的图像数据集,并将它们合并成一个训练数据集traindataset 使用 DataLoader 创建了一个训练数据加载器 trainloader ,用于批量加载数据进行训练定义了损失函数 criterion 和优化器 optimizer ,分别用于计算损失和更新模型参数。使用循环进行模型训练,每个 epoch 遍历一次训练数据集,在每个 batch 上计算损失并进行反向传播优化模型参数。

epochs = 1
for i in range(epochs):
    running_loss = 0
    for images, labels in trainloader:
        output = model(images)
        loss = criterion(output, labels)
        loss.backward()
        optimizer.step()    # 使用优化器更新权重
        optimizer.zero_grad()   # 清除梯度,为下一次迭代做准备
        running_loss += loss.item()
    print("Epoch{}-Training loss:{}".format(i, running_loss / len(trainloader)))

examples = enumerate(trainloader)    #将数据进行打包
batch_idx, (imgs, labels) = next(examples)  #自动进行下一个
fig = plt.figure()
for i in range(2):
    t = torch.unsqueeze(imgs[i], dim=0)
    logps = model(t)  #将测试集进行训练,输出预测结果
    probad = list(logps.detach().numpy()[0])
    pred_lable = probad.index(max(probad))

    img = torch.squeeze(imgs[i])
    img = img.permute(1, 2, 0)
    img = img.numpy()

    plt.subplot(2, 1, i + 1)
    plt.tight_layout()
    if pred_lable == "0":
        a = "cat"
    else:
        a = "dog"

五.完整代码

import torch
from PIL import Image
import numpy as np
from matplotlib import pyplot as plt
from torch.utils.data import Dataset
import os
from torchvision import transforms


class mydataset(Dataset):
    def __init__(self, root_dir, label_dir):
        self.root__dir = root_dir
        self.label_dir = label_dir
        self.path = os.path.join(root_dir, label_dir)
        self.img_path = os.listdir(self.path)
        self.transform = transforms.Compose([
            transforms.Resize((224, 224)),
            transforms.ToTensor()
        ])

    def __getitem__(self, item):
        img_name = self.img_path[item]
        img_item_path= os.path.join(self.path, img_name)
        img = Image.open(img_item_path).convert('RGB')
        img = self.transform(img)

        if self.label_dir == "Cat":
            label = 0
        else:
            label = 1

        return img, label


    def __len__(self):
        iten = len(self.img_path)
        return iten


class BPNetwork(torch.nn.Module):

    def __init__(self):
        super(BPNetwork, self).__init__()
        self.linear1 = torch.nn.Linear(224 * 224 * 3, 128)
        self.relu1 = torch.nn.ReLU()
        self.linear2 = torch.nn.Linear(128, 64)
        self.relu2 = torch.nn.ReLU()
        self.linear3 = torch.nn.Linear(64, 2)
        self.softmax = torch.nn.LogSoftmax(dim=1)      #输出进行归一化处理

    def forward(self, x):
        x = x.view(x.shape[0], -1)
        x = self.linear1(x)
        x = self.relu1(x)
        x = self.linear2(x)
        x = self.relu2(x)
        x = self.linear3(x)
        x = self.softmax(x)
        return x

root_dir = 'D:\Backup\Documents\WeChat Files\wxid_8rnhd895jesr22\FileStorage\File\2024-04\kagglecatsanddogs_5340.zip'
cat_label_dir = "Cat"
dog_label_dir = "Dog"

catdata = mydataset(root_dir, cat_label_dir)
dogdata = mydataset(root_dir, dog_label_dir)
traindataset = catdata + dogdata

trainloader = torch.utils.data.DataLoader(traindataset, batch_size=2, shuffle=True)

model = BPNetwork()     #定义类对象

criterion = torch.nn.NLLLoss()  #定义损失函数的计算方式。这个损失函数常用于多分类问题中,
                                # 尤其是当输出是未归一化的 log-probabilities(即 logits)时。
optimizer = torch.optim.SGD(model.parameters(), lr=0.003, momentum=0.9)

epochs = 1
for i in range(epochs):
    running_loss = 0
    for images, labels in trainloader:
        output = model(images)
        loss = criterion(output, labels)
        loss.backward()
        optimizer.step()    # 使用优化器更新权重
        optimizer.zero_grad()   # 清除梯度,为下一次迭代做准备
        running_loss += loss.item()
    print("Epoch{}-Training loss:{}".format(i, running_loss / len(trainloader)))

examples = enumerate(trainloader)    #将数据进行打包
batch_idx, (imgs, labels) = next(examples)  #自动进行下一个
fig = plt.figure()
for i in range(2):
    t = torch.unsqueeze(imgs[i], dim=0)
    logps = model(t)  #将测试集进行训练,输出预测结果
    probad = list(logps.detach().numpy()[0])
    pred_lable = probad.index(max(probad))

    img = torch.squeeze(imgs[i])
    img = img.permute(1, 2, 0)
    img = img.numpy()

    plt.subplot(2, 1, i + 1)
    plt.tight_layout()
    if pred_lable == "0":
        a = "cat"
    else:
        a = "dog"

    plt.imshow(img, cmap='gray', interpolation='none')
    plt.title("预测值:{}".format(a))
    plt.xticks([])
    plt.yticks([])

plt.show()

六.总结

代码实现了一个基于 PyTorch 的猫狗图像分类器。通过自定义数据集类加载和预处理图像数据,构建了一个简单的多层感知器神经网络模型。使用随机梯度下降优化器和负对数似然损失函数进行模型训练,并在训练结束后对模型进行评估和预测。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值