1.利用Pytorch深度学习框架,根据yolov3的主干网络darknet53模型(参考下图),进行猫狗数据集的模型训练和模型推理,按下面要求完成相应代码。(76分) ①读入猫狗数据集(data_zoo),并进行必要的预处理 ②划分数据为训练集和测试集(比例自拟) ③在训练集中随机选取9张图片进行3行3列图像显示 ④构建卷积单元类封装ConvCell,由卷积、BN、Relu激活组成 ⑤参见附图,构建yolov3的主干网络类封装DarkNet53 ⑥进行前向传播 ⑦打印输出整体模型维度结构 ⑧正确合理使用损失函数和优化器 ⑨训练集数据进行模型训练,自拟合适的超参数 ⑩模型训练完毕后,打印输出训练集准确率 ⑪打印输出测试集准确率代码
时间: 2024-02-15 09:03:57 浏览: 75
基于深度学习CNN网络+pytorch框架实现遥感图像滑坡识别源码+数据集+训练好的模型.zip
为了满足您的需求,我将提供一个大致的代码框架,你可以参考这个框架进行具体的实现:
```python
import torch
import torch.nn as nn
import torch.optim as optim
import torchvision
import torchvision.transforms as transforms
import numpy as np
import matplotlib.pyplot as plt
# 读入猫狗数据集
transform = transforms.Compose([
transforms.Resize((224, 224)),
transforms.RandomHorizontalFlip(),
transforms.ToTensor(),
transforms.Normalize(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5])
])
trainset = torchvision.datasets.ImageFolder(root='data_zoo', transform=transform)
trainloader = torch.utils.data.DataLoader(trainset, batch_size=32, shuffle=True, num_workers=2)
# 划分数据为训练集和测试集
trainset, testset = torch.utils.data.random_split(trainset, [8000, 2000])
trainloader = torch.utils.data.DataLoader(trainset, batch_size=32, shuffle=True, num_workers=2)
testloader = torch.utils.data.DataLoader(testset, batch_size=32, shuffle=False, num_workers=2)
# 随机选取9张图片进行3行3列图像显示
def imshow(img):
img = img / 2 + 0.5 # unnormalize
npimg = img.numpy()
plt.imshow(np.transpose(npimg, (1, 2, 0)))
plt.show()
dataiter = iter(trainloader)
images, labels = dataiter.next()
imshow(torchvision.utils.make_grid(images[:9]))
# 构建卷积单元类封装ConvCell,由卷积、BN、Relu激活组成
class ConvCell(nn.Module):
def __init__(self, in_channels, out_channels, kernel_size, stride, padding):
super(ConvCell, self).__init__()
self.conv = nn.Conv2d(in_channels, out_channels, kernel_size, stride, padding)
self.bn = nn.BatchNorm2d(out_channels)
self.relu = nn.ReLU(inplace=True)
def forward(self, x):
x = self.conv(x)
x = self.bn(x)
x = self.relu(x)
return x
# 构建yolov3的主干网络类封装DarkNet53
class DarkNet53(nn.Module):
def __init__(self):
super(DarkNet53, self).__init__()
self.conv1 = ConvCell(3, 32, kernel_size=3, stride=1, padding=1)
self.conv2 = ConvCell(32, 64, kernel_size=3, stride=2, padding=1)
self.res1 = nn.Sequential(
ConvCell(64, 32, kernel_size=1, stride=1, padding=0),
ConvCell(32, 64, kernel_size=3, stride=1, padding=1)
)
self.conv3 = ConvCell(64, 128, kernel_size=3, stride=2, padding=1)
self.res2 = nn.Sequential(
ConvCell(128, 64, kernel_size=1, stride=1, padding=0),
ConvCell(64, 128, kernel_size=3, stride=1, padding=1)
)
self.conv4 = ConvCell(128, 256, kernel_size=3, stride=2, padding=1)
self.res3 = nn.Sequential(
ConvCell(256, 128, kernel_size=1, stride=1, padding=0),
ConvCell(128, 256, kernel_size=3, stride=1, padding=1)
)
self.conv5 = ConvCell(256, 512, kernel_size=3, stride=2, padding=1)
self.res4 = nn.Sequential(
ConvCell(512, 256, kernel_size=1, stride=1, padding=0),
ConvCell(256, 512, kernel_size=3, stride=1, padding=1)
)
self.conv6 = ConvCell(512, 1024, kernel_size=3, stride=2, padding=1)
self.res5 = nn.Sequential(
ConvCell(1024, 512, kernel_size=1, stride=1, padding=0),
ConvCell(512, 1024, kernel_size=3, stride=1, padding=1)
)
def forward(self, x):
x = self.conv1(x)
x = self.conv2(x)
x = self.res1(x) + x
x = self.conv3(x)
x = self.res2(x) + x
x = self.conv4(x)
x = self.res3(x) + x
x = self.conv5(x)
x = self.res4(x) + x
x = self.conv6(x)
x = self.res5(x) + x
return x
# 进行前向传播
net = DarkNet53()
inputs = torch.randn(1, 3, 224, 224)
outputs = net(inputs)
print(outputs.shape)
# 打印输出整体模型维度结构
print(net)
# 正确合理使用损失函数和优化器
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(net.parameters(), lr=0.001)
# 训练集数据进行模型训练,自拟合适的超参数
for epoch in range(10):
running_loss = 0.0
for i, data in enumerate(trainloader, 0):
inputs, labels = data[0], data[1]
optimizer.zero_grad()
outputs = net(inputs)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
running_loss += loss.item()
if i % 100 == 99:
print('[%d, %5d] loss: %.3f' %
(epoch + 1, i + 1, running_loss / 100))
running_loss = 0.0
# 模型训练完毕后,打印输出训练集准确率
correct = 0
total = 0
with torch.no_grad():
for data in trainloader:
images, labels = data
outputs = net(images)
_, predicted = torch.max(outputs.data, 1)
total += labels.size(0)
correct += (predicted == labels).sum().item()
print('Accuracy of the network on the %d train images: %d %%' % (len(trainset), 100 * correct / total))
# 打印输出测试集准确率
correct = 0
total = 0
with torch.no_grad():
for data in testloader:
images, labels = data
outputs = net(images)
_, predicted = torch.max(outputs.data, 1)
total += labels.size(0)
correct += (predicted == labels).sum().item()
print('Accuracy of the network on the %d test images: %d %%' % (len(testset), 100 * correct / total))
```
需要注意的是,由于猫狗数据集的大小和具体内容未知,因此具体代码实现可能会有所差异,但是按照上述步骤进行实现应该可以满足您的需求。
阅读全文