Pytorch 任意层特征图可视化
程序员文章站
2022-04-30 22:49:50
...
1. 思路: 输入一张随机像素图片,然后不断调整输入图片中各个像素点的像素值,使得选定可视化的特征图表现出最大的**度,图片越能引起特征图的兴奋,即说明图片和该特征图能识别的特征越相近
2. 代码:
import torch
import cv2
import numpy as np
import torch.optim
import torchvision
from PIL import Image
feature_result = None
def feature_hoook(layer, data_input, data_output):
global feature_result
feature_result = data_output # 这里如果使用list来添加data_output会使得list中的元素从计算图中脱离, 导致没办法进行backward
vgg16 = torchvision.models.vgg16(pretrained=True).eval()
vgg16.features[5].register_forward_hook(feature_hoook) # 选择第五层的feature map可视化
sz = 56
img = np.uint8(np.random.uniform(0, 250, (sz, sz, 3))) / 255 # 随机初始化图片
for i in range(20):
img = torch.tensor(img.transpose((2, 0, 1))).unsqueeze(0).to(torch.float32)
img.requires_grad = True # 问题: https://blog.csdn.net/nkhgl/article/details/100047276
optim = torch.optim.Adam([img], lr=0.1, weight_decay=1e-6) # 优化器对图像进行优化, 修改图像的像素值, 这里参数需要是Tensors,使用列表代替
for n in range(20):
optim.zero_grad()
vgg16(img)
loss = -1 * feature_result[0, 5].mean() # 选择网络第五层的第五个feature map进行可视化
loss.backward()
optim.step()
print(f'epoch:{i}, level:{n}, loss: {loss.item()}, img-mean:{img[0].mean()}')
img = img.data.numpy()[0].transpose(1, 2, 0)
sz = int(1.2 * sz)
img = cv2.resize(img, (sz, sz))
cv2.imshow('ans', img)
cv2.waitKey(0)
效果: