1.利用Pytorch深度学习框架,根据yolov3的主干网络darknet53模型(参考下图),进行猫狗数据集的模型训练和模型推理,按下面要求完成相应代码。(76分) ①读入猫狗数据集(cat2dog),并进行必要的预处理 ②划分数据为训练集和测试集(比例自拟) ③在训练集中随机选取9张图片进行3行3列图像显示 ④构建卷积单元类封装ConvUnit,由卷积、BN、Relu激活组成 ⑤参见附图,构建yolov3的主干网络类封装DarkNet53 ⑥进行前向传播 ⑦打印输出整体模型维度结构 ⑧正确合理使用损失函数和优化器 ⑨训练集数据进行模型训练,自拟合适的超参数 ⑩模型训练完毕后,打印输出训练集准确率 ⑪打印输出测试集准确率
时间: 2024-02-19 20:02:33 浏览: 80
由于本题需要完整的代码实现,且涉及到多个部分的内容,无法在此进行完整的展示和讲解。以下是一份可能的实现代码,仅供参考:
```
import torch
from torch.utils.data import DataLoader, Dataset
from torchvision import transforms
from torchvision.datasets import ImageFolder
from torchvision.models import Darknet
# 定义数据预处理
transform = transforms.Compose([
transforms.Resize((256, 256)),
transforms.CenterCrop((224, 224)),
transforms.ToTensor(),
transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
])
# 定义数据集
class CatDogDataset(Dataset):
def __init__(self, root_dir, transform=None):
self.dataset = ImageFolder(root_dir, transform=transform)
def __len__(self):
return len(self.dataset)
def __getitem__(self, index):
return self.dataset[index]
# 读入数据集
train_dataset = CatDogDataset('cat2dog/train', transform=transform)
test_dataset = CatDogDataset('cat2dog/test', transform=transform)
# 划分训练集和测试集
train_loader = DataLoader(train_dataset, batch_size=32, shuffle=True)
test_loader = DataLoader(test_dataset, batch_size=32, shuffle=True)
# 显示部分训练集图片
import matplotlib.pyplot as plt
import numpy as np
images, _ = iter(train_loader).next()
fig, axs = plt.subplots(3, 3, figsize=(10, 10))
for i in range(3):
for j in range(3):
axs[i][j].imshow(np.transpose(images[i*3+j], (1, 2, 0)))
axs[i][j].axis('off')
plt.show()
# 构建卷积单元类
class ConvUnit(torch.nn.Module):
def __init__(self, in_channels, out_channels, kernel_size, stride=1, padding=0):
super(ConvUnit, self).__init__()
self.conv = torch.nn.Conv2d(in_channels, out_channels, kernel_size, stride, padding)
self.bn = torch.nn.BatchNorm2d(out_channels)
self.relu = torch.nn.ReLU(inplace=True)
def forward(self, x):
x = self.conv(x)
x = self.bn(x)
x = self.relu(x)
return x
# 构建DarkNet53主干网络
class DarkNet53(torch.nn.Module):
def __init__(self):
super(DarkNet53, self).__init__()
self.conv1 = ConvUnit(3, 32, 3, padding=1)
self.conv2 = ConvUnit(32, 64, 3, stride=2, padding=1)
self.residual1 = self._make_residual(64, 32, 64)
self.conv3 = ConvUnit(64, 128, 3, stride=2, padding=1)
self.residual2 = self._make_residual(128, 64, 128)
self.conv4 = ConvUnit(128, 256, 3, stride=2, padding=1)
self.residual3 = self._make_residual(256, 128, 256)
self.conv5 = ConvUnit(256, 512, 3, stride=2, padding=1)
self.residual4 = self._make_residual(512, 256, 512)
self.conv6 = ConvUnit(512, 1024, 3, stride=2, padding=1)
self.residual5 = self._make_residual(1024, 512, 1024)
def _make_residual(self, in_channels, mid_channels, out_channels):
return torch.nn.Sequential(
ConvUnit(in_channels, mid_channels, 1),
ConvUnit(mid_channels, out_channels, 3, padding=1),
torch.nn.Identity() if in_channels == out_channels else ConvUnit(in_channels, out_channels, 1)
)
def forward(self, x):
x = self.conv1(x)
x = self.conv2(x)
x = self.residual1(x)
x = self.conv3(x)
x = self.residual2(x)
x = self.conv4(x)
x = self.residual3(x)
x = self.conv5(x)
x = self.residual4(x)
x = self.conv6(x)
x = self.residual5(x)
return x
# 创建DarkNet53模型实例
model = Darknet(num_classes=2, init_weights=True)
# 进行前向传播
inputs, _ = iter(train_loader).next()
outputs = model(inputs)
# 打印模型维度结构
print(outputs.shape)
# 定义损失函数和优化器
criterion = torch.nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)
# 训练模型
num_epochs = 10
for epoch in range(num_epochs):
train_loss = 0.0
train_total = 0
train_correct = 0
for i, (inputs, labels) in enumerate(train_loader):
optimizer.zero_grad()
outputs = model(inputs)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
train_loss += loss.item() * inputs.size(0)
train_total += inputs.size(0)
_, predicted = torch.max(outputs.data, 1)
train_correct += (predicted == labels).sum().item()
train_accuracy = train_correct / train_total
print(f'Epoch {epoch+1}/{num_epochs}, Train Loss: {train_loss/train_total:.4f}, Train Accuracy: {train_accuracy:.4f}')
# 计算训练集准确率
train_total = 0
train_correct = 0
for inputs, labels in train_loader:
outputs = model(inputs)
_, predicted = torch.max(outputs.data, 1)
train_total += labels.size(0)
train_correct += (predicted == labels).sum().item()
train_accuracy = train_correct / train_total
print(f'Train Accuracy: {train_accuracy:.4f}')
# 计算测试集准确率
test_total = 0
test_correct = 0
for inputs, labels in test_loader:
outputs = model(inputs)
_, predicted = torch.max(outputs.data, 1)
test_total += labels.size(0)
test_correct += (predicted == labels).sum().item()
test_accuracy = test_correct / test_total
print(f'Test Accuracy: {test_accuracy:.4f}')
```
请注意,本题中的代码实现仅供参考,实际实现中可能存在错误或需要做出适当修改。如有疑问,建议参考PyTorch官方文档或相关教程进行学习。
阅读全文