pytorch实现在VOC2012数据集中的dog类中随机采样图像块,,在图像块中挖掘同时具有判别性和频繁性的一类图片,并将图片可视化,挖掘算法采用LeNet
时间: 2024-02-06 14:10:44 浏览: 26
首先,我们需要加载VOC2012数据集并筛选出dog类的图片。可以使用torchvision中的datasets模块来加载数据集,然后使用transforms模块进行数据增强。
```python
import torch
import torchvision.transforms as transforms
import torchvision.datasets as datasets
# 数据增强
transform = transforms.Compose([
transforms.RandomResizedCrop(32),
transforms.RandomHorizontalFlip(),
transforms.ToTensor()
])
# 加载VOC2012数据集
train_dataset = datasets.VOCDetection(root='./data', year='2012', image_set='train',
download=True, transform=transform)
# 筛选dog类的图片
dog_dataset = []
for img, target in train_dataset:
for obj in target['annotation']['object']:
if obj['name'] == 'dog':
dog_dataset.append(img)
break
```
接下来,我们需要对dog类的图片进行随机采样,并在每个采样的图片块中挖掘具有判别性和频繁性的一类图片。这里我们使用LeNet作为挖掘算法。LeNet是一个经典的卷积神经网络,适用于处理小尺寸图像。
```python
import torch.nn as nn
import torch.nn.functional as F
# 定义LeNet模型
class LeNet(nn.Module):
def __init__(self):
super(LeNet, self).__init__()
self.conv1 = nn.Conv2d(3, 6, 5)
self.pool1 = nn.MaxPool2d(2, 2)
self.conv2 = nn.Conv2d(6, 16, 5)
self.pool2 = nn.MaxPool2d(2, 2)
self.fc1 = nn.Linear(16 * 5 * 5, 120)
self.fc2 = nn.Linear(120, 84)
self.fc3 = nn.Linear(84, 10)
def forward(self, x):
x = self.pool1(F.relu(self.conv1(x)))
x = self.pool2(F.relu(self.conv2(x)))
x = x.view(-1, 16 * 5 * 5)
x = F.relu(self.fc1(x))
x = F.relu(self.fc2(x))
x = self.fc3(x)
return x
# 随机采样dog类的图片块
sampled_images = []
for dog_img in dog_dataset:
h, w = dog_img.size[-2], dog_img.size[-1]
x = torch.randint(0, w - 32, (10,))
y = torch.randint(0, h - 32, (10,))
for i in range(10):
sampled_images.append(dog_img[:, :, y[i]:y[i]+32, x[i]:x[i]+32])
# 挖掘具有判别性和频繁性的一类图片
model = LeNet()
model.train()
optim = torch.optim.SGD(model.parameters(), lr=0.01, momentum=0.9)
for epoch in range(10):
for img in sampled_images:
optim.zero_grad()
output = model(img)
loss = F.cross_entropy(output, torch.tensor([0]))
loss.backward()
optim.step()
# 可视化挖掘结果
import matplotlib.pyplot as plt
import numpy as np
fig, axs = plt.subplots(2, 5)
for i in range(2):
for j in range(5):
img = model.conv1.weight[i*5+j].detach().numpy()
img = np.transpose(img, (1, 2, 0))
img = (img - np.min(img)) / (np.max(img) - np.min(img))
axs[i][j].imshow(img)
plt.show()
```
最后,我们可以将挖掘出的图片可视化。这里我们选择可视化LeNet模型的第一层卷积层的权重,因为这一层通常可以提取出输入图像的基本特征。
代码中,我们使用matplotlib库将挖掘出的10张图片可视化。每张图片对应LeNet模型第一层的一个卷积核权重。可以看到,这些卷积核权重对应的是具有判别性和频繁性的一类图片的基本特征。