Pytorch预训练Resnet18特征图可视化

原图

在百度图片上随便找的一张
Pytorch预训练Resnet18特征图可视化_第1张图片
在ImageNet预训练的resnet18分类结果(top5)
1 Egyptian_cat
2 tabby
3 tiger_cat
4 lynx
5 cougar

import torch
from torch import nn
from Generator import ResNet
from torchvision import models, transforms
# from tensorboardX import SummaryWriter
from PIL import Image
import json

model = ResNet()
model.load_state_dict(torch.load('resnet18.pth'))
model.eval()
image = Image.open('Cat01.jpg')

tf = transforms.Compose([transforms.Resize((224, 224)),
                         transforms.ToTensor(),
                         transforms.Normalize(mean=[0.485, 0.456, 0.406],
                                              std=[0.229, 0.224, 0.225])])
img = tf(image)
img = img.unsqueeze(0)

predict = nn.Softmax(dim=1)(model(img))  # [1, 1000]

value, index = torch.sort(predict, descending=True)

one = index[:, 0]
two = index[:, 1]
three = index[:, 2]
four = index[:, 3]
five = index[:, 4]

path = 'imagenet_class_index.json'
with open(path) as f:
    class_dict = json.load(f)
dic_imagenet = [class_dict[str(i)][1] for i in range(len(class_dict))]
print('1', dic_imagenet[one])
print('2', dic_imagenet[two])
print('3', dic_imagenet[three])
print('4', dic_imagenet[four])
print('5', dic_imagenet[five])

注:imagenet_class_index.json文件下载地址:https://pan.baidu.com/s/1B3Mi3p5Xp7eUmERVNVBhTA

ResNet18 网络结构

由于使用了BatchNorm,预测时注意把网络调到eval()阶段

ResNet(
  (conv1): Conv2d(3, 64, kernel_size=(7, 7), stride=(2, 2), padding=(3, 3), bias=False)
  (bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
  (relu): ReLU(inplace)
  (maxpool): MaxPool2d(kernel_size=3, stride=2, padding=1, dilation=1, ceil_mode=False)
  (layer1): Sequential(
    (0): BasicBlock(
      (conv1): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
      (bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (relu): ReLU(inplace)
      (conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
      (bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
    )
    (1): BasicBlock(
      (conv1): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
      (bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (relu): ReLU(inplace)
      (conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
      (bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
    )
  )
  (layer2): Sequential(
    (0): BasicBlock(
      (conv1): Conv2d(64, 128, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)
      (bn1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (relu): ReLU(inplace)
      (conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
      (bn2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (downsample): Sequential(
        (0): Conv2d(64, 128, kernel_size=(1, 1), stride=(2, 2), bias=False)
        (1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      )
    )
    (1): BasicBlock(
      (conv1): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
      (bn1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (relu): ReLU(inplace)
      (conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
      (bn2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
    )
  )
  (layer3): Sequential(
    (0): BasicBlock(
      (conv1): Conv2d(128, 256, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)
      (bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (relu): ReLU(inplace)
      (conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
      (bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (downsample): Sequential(
        (0): Conv2d(128, 256, kernel_size=(1, 1), stride=(2, 2), bias=False)
        (1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      )
    )
    (1): BasicBlock(
      (conv1): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
      (bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (relu): ReLU(inplace)
      (conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
      (bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
    )
  )
  (layer4): Sequential(
    (0): BasicBlock(
      (conv1): Conv2d(256, 512, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)
      (bn1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (relu): ReLU(inplace)
      (conv2): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
      (bn2): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (downsample): Sequential(
        (0): Conv2d(256, 512, kernel_size=(1, 1), stride=(2, 2), bias=False)
        (1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      )
    )
    (1): BasicBlock(
      (conv1): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
      (bn1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      (relu): ReLU(inplace)
      (conv2): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
      (bn2): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
    )
  )
  (avgpool): AdaptiveAvgPool2d(output_size=(1, 1))
  (fc): Linear(in_features=512, out_features=1000, bias=True)
)

提取各个卷积层输出特征图代码

import torch
from torch import nn
from torchvision import models, transforms
from torchvision.utils import make_grid
import numpy as np
from PIL import Image
import json

model = models.resnet18(pretrained=True)
# print(model)
model.eval()
image = Image.open('Cat01.jpg')
# transformation
tf = transforms.Compose([transforms.Resize((224, 224)),
                         transforms.ToTensor(),
                         transforms.Normalize(mean=[0.485, 0.456, 0.406],
                                              std=[0.229, 0.224, 0.225])])
img = tf(image)
img = img.unsqueeze(0)


def save_img(tensor, name):
    tensor = tensor.permute((1, 0, 2, 3))
    im = make_grid(tensor, normalize=True, scale_each=True, nrow=8, padding=2).permute((1, 2, 0))
    im = (im.data.numpy() * 255.).astype(np.uint8)
    Image.fromarray(im).save(name + '.jpg')


f1 = model.conv1(img)  # [1, 64, 112, 112]
save_img(f1,'conv1')

#提取出模型的前几层
new_model = nn.Sequential(*list(model.children())[:4])
f2 = new_model(img)  # [1, 64, 56, 56]
f2 = model.layer1[0](f2)
layer1_conv1 = model.layer1[1].conv1
layer1_bn = model.layer1[1].bn1
layer1_relu = model.layer1[1].relu
layer1_conv2 = model.layer1[1].conv2

f2 = layer1_conv1(f2)
save_img(f2, 'layer1_conv3')
f2 = layer1_conv2(layer1_relu(layer1_bn(f2)))
save_img(f2, 'layer1_conv4')
# new_model = nn.Sequential(*list(model.children())[:5])
# f3 = new_model(img)
# save_img(f3, 'layer1')
#
# # new_model = nn.Sequential(*list(model.children())[:6])
# # f4 = new_model(img)  # [1, 128, 28, 28]
# # save_img(f4, 'layer2')
#
# # new_model = nn.Sequential(*list(model.children())[:7])
# # print(new_model)
# # f5 = new_model(img)  # [1, 256, 14, 14]
# # print(f5.shape)
# # save_img(f5, 'layer3')
#
# # new_model = nn.Sequential(*list(model.children())[:8])
# # print(new_model)
# # f6 = new_model(img)  # [1, 256, 14, 14]
# # print(f6.shape)
# # save_img(f6, 'layer4')
#
# # new_model = nn.Sequential(*list(model.children())[:9])
# # print(new_model)
# # f7 = new_model(img)  # [1, 256, 14, 14]
# # save_img(f7, 'avgpool')

conv1输出特征图

Pytorch预训练Resnet18特征图可视化_第2张图片

layer1[0].conv1输出特征图

Pytorch预训练Resnet18特征图可视化_第3张图片

layer1[0].conv2输出特征图

Pytorch预训练Resnet18特征图可视化_第4张图片

经过layer1之后的特征图

Pytorch预训练Resnet18特征图可视化_第5张图片

经过layer2之后的特征图

Pytorch预训练Resnet18特征图可视化_第6张图片

经过layer2[0].conv1之后的特征图

Pytorch预训练Resnet18特征图可视化_第7张图片
Relu之后可视结果变黑,卷积之后可视结果又变亮了

经过layer3之后的特征图

Pytorch预训练Resnet18特征图可视化_第8张图片

经过layer4之后的特征图

Pytorch预训练Resnet18特征图可视化_第9张图片

你可能感兴趣的:(Pytorch预训练Resnet18特征图可视化)