机器学习练手项目-猫狗分类器
猫狗分类器是一个深度学习项目,旨在识别图像中的猫和狗。通过训练神经网络模型,该项目可以从输入的图像中准确地识别出是猫还是狗。这个项目可以应用于许多实际场景,如图像分类、动物识别等。
1. 准备数据集
首先,需要准备一个包含猫和狗图像的数据集。您可以从各种来源收集这些图像数据,例如网络上的图片库或自己的图片文件夹。确保每个类别的图像都放在单独的文件夹中,并将它们命名为相应的类别。
2. 数据预处理
在加载图像数据之前,需要进行一些预处理步骤。这包括调整图像大小、将图像转换为张量以及标准化图像数据。通过torchvision.transforms模块,我们可以方便地实现这些预处理步骤。
import torch import torchvision.transforms as transforms from torchvision.datasets import ImageFolder from torch.utils.data import DataLoader
3. 构建模型
将使用卷积神经网络(CNN)来构建我们的猫狗分类器。CNN是一种在图像识别任务中非常流行的深度学习模型。
import torch.nn as nn import torch.nn.functional as F class CNN(nn.Module): def __init__(self): super(CNN, self).__init__() # 定义卷积层、池化层和全连接层 self.conv1 = nn.Conv2d(3, 16, 3, padding=1) self.conv2 = nn.Conv2d(16, 32, 3, padding=1) self.conv3 = nn.Conv2d(32, 64, 3, padding=1) self.pool = nn.MaxPool2d(2, 2) self.fc1 = nn.Linear(64 * 8 * 8, 512) self.fc2 = nn.Linear(512, 2) def forward(self, x): # 前向传播函数 x = self.pool(F.relu(self.conv1(x))) x = self.pool(F.relu(self.conv2(x))) x = self.pool(F.relu(self.conv3(x))) x = x.view(-1, 64 * 8 * 8) # 将特征展平为一维向量 x = F.relu(self.fc1(x)) x = self.fc2(x) return x
4. 训练模型
将使用训练集来训练我们的模型,并使用测试集来评估模型的性能。
import torch.optim as optim # 实例化模型、定义损失函数和优化器 model = CNN() criterion = nn.CrossEntropyLoss() optimizer = optim.Adam(model.parameters(), lr=0.001) # 训练模型 num_epochs = 10 for epoch in range(num_epochs): running_loss = 0.0 for i, data in enumerate(train_loader, 0): inputs, labels = data optimizer.zero_grad() try: outputs = model(inputs) loss = criterion(outputs, labels) loss.backward() optimizer.step() running_loss += loss.item() if (i+1) % 100 == 0: print(f'Epoch [{epoch+1}/{num_epochs}], Iteration [{i+1}/{len(train_loader)}], Loss: {running_loss/100:.4f}') running_loss = 0.0 except Exception as e: print(f"Error processing batch {i}:", str(e)) continue print('Finished Training')
5. 评估模型
在训练完成后,需要评估模型在测试集上的性能。
model.eval() correct = 0 total = 0 with torch.no_grad(): for data in test_loader: images, labels = data outputs = model(images) _, predicted = torch.max(outputs.data, 1) total += labels.size(0) correct += (predicted == labels).sum().item() print(f'Accuracy of the network on the {total} test images: {100 * correct / total}%')
完整代码:
import os import torch import torchvision.transforms as transforms from torchvision.datasets import ImageFolder from torch.utils.data import DataLoader import torch.nn as nn import torch.optim as optim import torch.nn.functional as F import matplotlib.pyplot as plt from PIL import Image # 设置随机种子 torch.manual_seed(42) # 数据预处理,包括调整大小、转换为张量、以及标准化 transform = transforms.Compose([ transforms.Resize((64, 64)), # 将图像调整为 64x64 大小 transforms.ToTensor(), # 将图像转换为张量 transforms.Normalize(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5]) # 标准化图像数据 ]) # 加载训练数据集,使用ImageFolder自动加载图像数据,并应用上面定义的数据预处理 # root参数指定数据集根目录 train_dataset = ImageFolder(root='D:\\系统默认\\桌面\\python\\PetImages\\', transform=transform) # 计算训练集的大小 train_size = int(0.8 * len(train_dataset)) test_size = len(train_dataset) - train_size # 划分训练集和测试集 train_dataset, test_dataset = torch.utils.data.random_split(train_dataset, [train_size, test_size]) # 创建数据加载器,用于加载训练集和测试集的数据 train_loader = DataLoader(train_dataset, batch_size=32, shuffle=True) test_loader = DataLoader(test_dataset, batch_size=4, shuffle=False) # 定义卷积神经网络模型 class CNN(nn.Module): def __init__(self): super(CNN, self).__init__() # 定义卷积层 self.conv1 = nn.Conv2d(3, 16, 3, padding=1) self.conv2 = nn.Conv2d(16, 32, 3, padding=1) self.conv3 = nn.Conv2d(32, 64, 3, padding=1) # 定义池化层 self.pool = nn.MaxPool2d(2, 2) # 定义全连接层 self.fc1 = nn.Linear(64 * 8 * 8, 512) self.fc2 = nn.Linear(512, 2) def forward(self, x): # 前向传播函数,定义网络结构 x = self.pool(F.relu(self.conv1(x))) x = self.pool(F.relu(self.conv2(x))) x = self.pool(F.relu(self.conv3(x))) x = x.view(-1, 64 * 8 * 8) # 将特征展平为一维向量 x = F.relu(self.fc1(x)) x = self.fc2(x) return x # 实例化模型、定义损失函数和优化器 model = CNN() criterion = nn.CrossEntropyLoss() optimizer = optim.Adam(model.parameters(), lr=0.001) # 训练模型 num_epochs = 10 for epoch in range(num_epochs): running_loss = 0.0 for i, data in enumerate(train_loader, 0): inputs, labels = data optimizer.zero_grad() try: outputs = model(inputs) loss = criterion(outputs, labels) loss.backward() optimizer.step() running_loss += loss.item() if (i+1) % 100 == 0: print(f'Epoch [{epoch+1}/{num_epochs}], Iteration [{i+1}/{len(train_loader)}], Loss: {running_loss/100:.4f}') running_loss = 0.0 except Exception as e: print(f"Error processing batch {i}:", str(e)) continue print('Finished Training') # 保存模型 torch.save(model.state_dict(), 'cat_dog_model.pth') # 测试模型 model.eval() correct = 0 total = 0 with torch.no_grad(): for data in test_loader: images, labels = data outputs = model(images) _, predicted = torch.max(outputs.data, 1) total += labels.size(0) correct += (predicted == labels).sum().item() print(f'Accuracy of the network on the {total} test images: {100 * correct / total}%')
- 运行结果样子
想要获取数据集在这个地址里面:GitHub地址