卷积神经网络实现猫狗分类

一.环境配置以及数据加载

import torch
import torch.nn as nn
import torch.optim as optim
import torchvision.transforms as transforms
from torchvision.datasets import ImageFolder
from torch.utils.data import DataLoader
import matplotlib.pyplot as plt

使用pytorch来进行卷积处理

transform = transforms.Compose([
    transforms.Resize((64, 64)),
    transforms.ToTensor(),
    transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))
])

train_dataset = ImageFolder(root='train2/', transform=transform)
train_loader = DataLoader(train_dataset, batch_size=16, shuffle=True)  # 修改批次大小

传入数据集,将图像数据进行转换和标准化,首先将图像调整为64*64大小,根据gpu和cpu来选择图像的处理,将图像转换为张量(tensor)的格式,使用normalize函数对图像进行标准化处理,格式为均值和标准差的形式。 

二.cnn模型的创建

class CNN(nn.Module):
    def __init__(self):
        super(CNN, self).__init__()
        self.conv1 = nn.Conv2d(3, 32, kernel_size=3, padding=1)
        self.conv2 = nn.Conv2d(64, 128, kernel_size=3, padding=1)
        self.conv3 = nn.Conv2d(64, 128, kernel_size=3, padding=1)
        self.pool = nn.MaxPool2d(2, 2)
        self.fc1 = nn.Linear(128 * 8 * 8, 512)  # 修改全连接层的输入大小
        self.fc2 = nn.Linear(512, 2)  # 2 classes: cat and dog

    def forward(self, x):
        x = self.pool(torch.relu(self.conv1(x)))
        x = self.pool(torch.relu(self.conv2(x)))
        x = self.pool(torch.relu(self.conv3(x)))
        x = x.view(-1, 128 * 8 * 8)  # 修改视图大小
        x = torch.relu(self.fc1(x))
        x = self.fc2(x)
        return x

 在这段代码中,我们首先定义了三个卷积核,由于图像是rgb三个通道的输入,所以我们第一个卷积核的输入通道为3,输出为32,以此类推,第二个卷积核输入32,输出64,卷积核大小为3*3。

通过堆叠多个卷积层,可以逐渐扩大特征图的通道数,从而增加网络的非线性能力和表达能力。这种逐渐加深和加宽网络的设计可以更好地拟合复杂的数据分布,提高模型的泛化能力和准确性。因此,堆叠卷积层是设计深度卷积神经网络的重要手段之一。、

池化层

定义了一个最大池化层(nn.MaxPool2d)。在这个例子中,参数2, 2表示池化核大小为2x2,步幅为2。最大池化层的作用是对输入特征图进行下采样,通过保留每个池化窗口中的最大值来减少特征图的尺寸,同时保留主要特征。

我们将三个卷积核通过relu函数处理,使用池化层一一提取特征,进行下采样,得到一个128*8*8的特征。

全连接层

我们通过三次卷积叠加以及一次池化层下采样,得到了输入的特征,创建两个链接层,将第一个连接层的数据进行relu激活函数的处理最后通过激活函数输出

三.训练模型

for epoch in range(10):  # 可以调整 epoch 数量
    running_loss = 0.0
    correct = 0
    total = 0
    for inputs, labels in train_loader:
        optimizer.zero_grad()
        outputs = model(inputs)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()
        running_loss += loss.item()

使用了一个for循环来迭代训练模型的次数,每次迭代称为一个epoch。在每个epoch中,我们都会将运行损失(running_loss)初始化为0,正确预测数量(correct)和总样本数量(total)初始化为0。然后我们遍历训练数据加载器(train_loader)中的输入和标签对。对于每个输入,我们将优化器(optimizer)的梯度归零,将输入传递给模型(model),计算模型的输出,计算损失(loss),然后通过反向传播(loss.backward())更新模型的参数(optimizer.step())。最后,我们将每个样本的损失值加到运行损失中。

计算准确率

        _, predicted = torch.max(outputs, 1)
        total += labels.size(0)
        correct += (predicted == labels).sum().item()

    epoch_loss = running_loss / len(train_loader)
    epoch_accuracy = 100 * correct / total
    loss_history.append(epoch_loss)
    accuracy_history.append(epoch_accuracy)

在这段代码中,我们使用torch.max函数来获取模型输出outputs在第一个维度上的最大值以及对应的索引,即预测值predicted。然后,我们将标签的数量labels.size(0)加到total中,用于统计总样本数量。接着,我们将预测值与真实标签labels进行比较,如果预测值与真实标签相等,则计算出的结果为True,否则为False。将这些结果求和并转换为Python的整数类型(item()方法),然后累加到正确预测数量correct中。这段代码的目的是用于计算模型在每个epoch中的准确率。

四.源代码

import torch
import torch.nn as nn
import torch.optim as optim
import torchvision.transforms as transforms
from torchvision.datasets import ImageFolder
from torch.utils.data import DataLoader
import matplotlib.pyplot as plt


# 定义 CNN 模型
class CNN(nn.Module):
    def __init__(self):
        super(CNN, self).__init__()
        self.conv1 = nn.Conv2d(3, 32, kernel_size=3, padding=1)
        self.conv2 = nn.Conv2d(32, 64, kernel_size=3, padding=1)
        self.conv3 = nn.Conv2d(64, 128, kernel_size=3, padding=1)
        self.pool = nn.MaxPool2d(2, 2)
        self.fc1 = nn.Linear(128 * 8 * 8, 512)  # 修改全连接层的输入大小
        self.fc2 = nn.Linear(512, 2)  # 2 classes: cat and dog

    def forward(self, x):
        x = self.pool(torch.relu(self.conv1(x)))
        x = self.pool(torch.relu(self.conv2(x)))
        x = self.pool(torch.relu(self.conv3(x)))
        x = x.view(-1, 128 * 8 * 8)  # 修改视图大小
        x = torch.relu(self.fc1(x))
        x = self.fc2(x)
        return x


# 数据预处理和加载
transform = transforms.Compose([
    transforms.Resize((64, 64)),
    transforms.ToTensor(),
    transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))
])

train_dataset = ImageFolder(root='train2/', transform=transform)
train_loader = DataLoader(train_dataset, batch_size=16, shuffle=True)  # 修改批次大小

# 实例化模型、损失函数和优化器
model = CNN()
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)

# 训练过程中的损失和准确率可视化
loss_history = []
accuracy_history = []

for epoch in range(10):  # 可以调整 epoch 数量
    running_loss = 0.0
    correct = 0
    total = 0
    for inputs, labels in train_loader:
        optimizer.zero_grad()
        outputs = model(inputs)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()
        running_loss += loss.item()

        # 计算训练集上的准确率
        _, predicted = torch.max(outputs, 1)
        total += labels.size(0)
        correct += (predicted == labels).sum().item()

    epoch_loss = running_loss / len(train_loader)
    epoch_accuracy = 100 * correct / total
    loss_history.append(epoch_loss)
    accuracy_history.append(epoch_accuracy)

    print(f"Epoch {epoch + 1}, Loss: {epoch_loss}, Accuracy: {epoch_accuracy}%")

# 可视化损失和准确率
plt.figure(figsize=(10, 5))

plt.subplot(1, 2, 1)
plt.plot(loss_history, label='Training Loss')
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.title('Training Loss')
plt.legend()

plt.subplot(1, 2, 2)
plt.plot(accuracy_history, label='Training Accuracy')
plt.xlabel('Epoch')
plt.ylabel('Accuracy (%)')
plt.title('Training Accuracy')
plt.legend()

plt.show()

# 保存模型
torch.save(model.state_dict(), 'cat_dog_classifier.pth')

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,以下是使用卷积神经网络实现分类任务的代码示例: ```python import tensorflow as tf from tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten, Dense from tensorflow.keras.models import Sequential from tensorflow.keras.preprocessing.image import ImageDataGenerator # 设置训练集和测试集的路径 train_dir = 'path/to/training/dataset' test_dir = 'path/to/testing/dataset' # 设置图像的大小和批次大小 img_height, img_width = 150, 150 batch_size = 32 # 创建数据生成器 train_datagen = ImageDataGenerator(rescale=1./255) test_datagen = ImageDataGenerator(rescale=1./255) train_generator = train_datagen.flow_from_directory( train_dir, target_size=(img_height, img_width), batch_size=batch_size, class_mode='binary') test_generator = test_datagen.flow_from_directory( test_dir, target_size=(img_height, img_width), batch_size=batch_size, class_mode='binary') # 构建卷积神经网络模型 model = Sequential([ Conv2D(32, (3,3), activation='relu', input_shape=(img_height, img_width, 3)), MaxPooling2D((2,2)), Conv2D(64, (3,3), activation='relu'), MaxPooling2D((2,2)), Conv2D(128, (3,3), activation='relu'), MaxPooling2D((2,2)), Conv2D(128, (3,3), activation='relu'), MaxPooling2D((2,2)), Flatten(), Dense(512, activation='relu'), Dense(1, activation='sigmoid') ]) # 编译模型 model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy']) # 训练模型 model.fit(train_generator, epochs=10, validation_data=test_generator) # 评估模型 test_loss, test_acc = model.evaluate(test_generator) print('Test accuracy:', test_acc) ``` 需要注意的是,这是一个简单的示例代码,实际应用中可能需要更加复杂的网络结构和更多的训练参数来提高模型的性能。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值