使用 Python 代码实现 ResNet 猫咪 12 分类模型并生成 CSV 文件和可视化结果
本教程将指导您使用 Python 代码构建一个 ResNet 神经网络模型,用于对 12 种不同品种的猫进行分类。您将学习如何加载数据集、预处理数据、训练模型、评估性能以及生成可视化结果,最终将预测结果保存到 CSV 文件中。
数据集:
/kaggle/input/cat111/cat_12_train/cat_12_train(包含 2115 张猫的图片)/kaggle/input/cat111/cat_12_test/cat_12_test(包含 240 张猫的图片)/kaggle/input/cat111/train_list.txt(训练集图片路径和标签文本文件,格式为cat_12_train/8GOkTtqw7E6IHZx4olYnhzvXLCiRsUfM.jpg 0)
模型训练:
- 训练集 80% 用于训练,验证集 20% 用于评估模型性能。
- 使用 ResNet 模型进行训练。
可视化:
- 可视化训练过程中的损失函数和准确率曲线。
- 可视化模型对测试集的预测结果。
最终结果:
- 生成一个 CSV 文件,包含测试集图片路径和对应的预测标签。
建议:
由于该任务比较复杂,建议您先学习一些基础的深度学习知识和 Python 编程,例如 Python 基础语法、NumPy、Pandas、Matplotlib、PyTorch 等。以下是一些 Python 代码示例,供您参考:
1. 导入所需库和数据:
import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import Dataset, DataLoader
import torchvision.transforms as transforms
from PIL import Image
import pandas as pd
import matplotlib.pyplot as plt
# 读取训练集图片路径和标签
train_list = pd.read_csv('/kaggle/input/cat111/train_list.txt', sep='\t', header=None)
train_list.columns = ['image_path', 'label']
# 定义数据预处理
transform_train = transforms.Compose([
transforms.Resize(256), # 调整图片大小
transforms.CenterCrop(224), # 中心裁剪
transforms.RandomHorizontalFlip(), # 随机水平翻转
transforms.ToTensor(), # 转为张量
transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) # 标准化
])
# 自定义数据集类
class CatDataset(Dataset):
def __init__(self, data, transform=None):
self.data = data
self.transform = transform
def __len__(self):
return len(self.data)
def __getitem__(self, index):
# 读取图片和标签
image_path = self.data.loc[index, 'image_path']
label = self.data.loc[index, 'label']
image = Image.open(image_path).convert('RGB')
# 数据预处理
if self.transform:
image = self.transform(image)
return image, label
# 划分训练集和验证集
train_set = train_list.sample(frac=0.8, random_state=42)
val_set = train_list.drop(train_set.index)
# 创建数据集实例
train_data = CatDataset(train_set, transform=transform_train)
val_data = CatDataset(val_set, transform=transform_train)
# 创建数据加载器
train_loader = DataLoader(train_data, batch_size=32, shuffle=True)
val_loader = DataLoader(val_data, batch_size=32, shuffle=False)
2. 定义模型:
# 定义ResNet模型
class ResNet(nn.Module):
def __init__(self, num_classes=12):
super(ResNet, self).__init__()
self.resnet = torch.hub.load('pytorch/vision:v0.6.0', 'resnet18', pretrained=True)
self.resnet.fc = nn.Linear(in_features=512, out_features=num_classes, bias=True)
def forward(self, x):
x = self.resnet(x)
return x
# 创建模型实例
model = ResNet()
3. 定义损失函数和优化器:
# 定义损失函数和优化器
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)
4. 训练模型:
# 训练模型
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
model.to(device)
num_epochs = 10
train_losses = []
train_accs = []
val_losses = []
val_accs = []
for epoch in range(num_epochs):
train_loss = 0.0
train_acc = 0.0
val_loss = 0.0
val_acc = 0.0
# 训练集
model.train()
for inputs, labels in train_loader:
inputs, labels = inputs.to(device), labels.to(device)
optimizer.zero_grad()
outputs = model(inputs)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
train_loss += loss.item() * inputs.size(0)
_, preds = torch.max(outputs, 1)
train_acc += torch.sum(preds == labels.data)
train_loss = train_loss / len(train_data)
train_acc = train_acc / len(train_data)
train_losses.append(train_loss)
train_accs.append(train_acc)
# 验证集
model.eval()
with torch.no_grad():
for inputs, labels in val_loader:
inputs, labels = inputs.to(device), labels.to(device)
outputs = model(inputs)
loss = criterion(outputs, labels)
val_loss += loss.item() * inputs.size(0)
_, preds = torch.max(outputs, 1)
val_acc += torch.sum(preds == labels.data)
val_loss = val_loss / len(val_data)
val_acc = val_acc / len(val_data)
val_losses.append(val_loss)
val_accs.append(val_acc)
print('Epoch [{}/{}], Train Loss: {:.4f}, Train Acc: {:.4f}, Val Loss: {:.4f}, Val Acc: {:.4f}'\n .format(epoch+1, num_epochs, train_loss, train_acc, val_loss, val_acc))
5. 可视化训练过程:
# 绘制训练过程曲线
plt.plot(train_losses, label='Train Loss')
plt.plot(val_losses, label='Val Loss')
plt.legend()
plt.show()
plt.plot(train_accs, label='Train Acc')
plt.plot(val_accs, label='Val Acc')
plt.legend()
plt.show()
6. 测试集预测和结果可视化:
# 读取测试集图片路径
test_list = pd.read_csv('/kaggle/input/cat111/test_list.txt', sep='\t', header=None)
test_list.columns = ['image_path']
# 定义数据预处理
transform_test = transforms.Compose([
transforms.Resize(256),
transforms.CenterCrop(224),
transforms.ToTensor(),
transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
])
# 创建数据集实例
test_data = CatDataset(test_list, transform=transform_test)
# 创建数据加载器
test_loader = DataLoader(test_data, batch_size=32, shuffle=False)
# 测试集预测
model.eval()
preds = []
with torch.no_grad():
for inputs, _ in test_loader:
inputs = inputs.to(device)
outputs = model(inputs)
_, batch_preds = torch.max(outputs, 1)
preds += batch_preds.tolist()
# 保存预测结果到csv文件
test_list['label'] = preds
test_list.to_csv('test_preds.csv', index=False)
# 随机选取一张图片进行可视化
image_path = test_list.sample()['image_path'].values[0]
image = Image.open(image_path).convert('RGB')
image = transform_test(image)
image = image.unsqueeze(0) # 加上batch维度
image = image.to(device)
model.eval()
with torch.no_grad():
output = model(image)
_, pred = torch.max(output, 1)
pred = pred.item()
plt.imshow(Image.open(image_path))
plt.title('Predicted Label: {}'.format(pred))
plt.axis('off')
plt.show()
原文地址: https://www.cveoy.top/t/topic/oEKe 著作权归作者所有。请勿转载和采集!