pytorch 对特征进行mean_PyTorch 提取神经网络中间层特征进行可视化

实现步骤:处理单张图片作为网络输入

根据给定的layer层,获取该层的输出结果 features

考虑到 feature 的形状为 (batch_size, filter_number, H, W), 提取其中的第一个过滤器得到的结果

以一张图片作为输入的情况下,我们得到的feature即为(H, W)大小的tensor

将tensor 转为numpy, 然后归一化到 [0, 1], 最后乘255,使得范围为[0, 255]

代码说明:使用了在ImageNet预先训练好的VGG16作为示例

打印模型结构可以看到每一层对应的ID编号是什么

通常选择conv后面的特征进行可视化

整个的实现放在类 FeatureVisualization中实现

对于归一化[0, 1]的方法,使用了sigmoid方法

数字5意思是,选择ID编号为5的层。myClass=FeatureVisualization('./input_images/home.jpg',5)

代码如下:

import cv2

import numpy as np

import torch

from torch.autograd import Variable

from torchvision import models

def preprocess_image(cv2im, resize_im=True):

"""

Processes image for CNNs

Args:

PIL_img (PIL_img): Image to process

resize_im (bool): Resize to 224 or not

returns:

im_as_var (Pytorch variable): Variable that contains processed float tensor

"""

# mean and std list for channels (Imagenet)

mean = [0.485, 0.456, 0.406]

std = [0.229, 0.224, 0.225]

# Resize image

if resize_im:

cv2im = cv2.resize(cv2im, (224, 224))

im_as_arr = np.float32(cv2im)

im_as_arr = np.ascontiguousarray(im_as_arr[..., ::-1])

im_as_arr = im_as_arr.transpose(2, 0, 1)  # Convert array to D,W,H

# Normalize the channels

for channel, _ in enumerate(im_as_arr):

im_as_arr[channel] /= 255

im_as_arr[channel] -= mean[channel]

im_as_arr[channel] /= std[channel]

# Convert to float tensor

im_as_ten = torch.from_numpy(im_as_arr).float()

# Add one more channel to the beginning. Tensor shape = 1,3,224,224

im_as_ten.unsqueeze_(0)

# Convert to Pytorch variable

im_as_var = Variable(im_as_ten, requires_grad=True)

return im_as_var

class FeatureVisualization():

def __init__(self,img_path,selected_layer):

self.img_path=img_path

self.selected_layer=selected_layer

self.pretrained_model = models.vgg16(pretrained=True).features

def process_image(self):

img=cv2.imread(self.img_path)

img=preprocess_image(img)

return img

def get_feature(self):

# input = Variable(torch.randn(1, 3, 224, 224))

input=self.process_image()

print(input.shape)

x=input

for index,layer in enumerate(self.pretrained_model):

x=layer(x)

if (index == self.selected_layer):

return x

def get_single_feature(self):

features=self.get_feature()

print(features.shape)

feature=features[:,0,:,:]

print(feature.shape)

feature=feature.view(feature.shape[1],feature.shape[2])

print(feature.shape)

return feature

def save_feature_to_img(self):

#to numpy

feature=self.get_single_feature()

feature=feature.data.numpy()

#use sigmod to [0,1]

feature= 1.0/(1+np.exp(-1*feature))

# to [0,255]

feature=np.round(feature*255)

print(feature[0])

cv2.imwrite('./img.jpg',feature)

if __name__=='__main__':

# get class

myClass=FeatureVisualization('./input_images/home.jpg',5)

print (myClass.pretrained_model)

myClass.save_feature_to_img()

结果如下:

输入图片:

(5): Conv2d(64, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) 的结果:

(12): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))的结果

你可能感兴趣的:(pytorch,对特征进行mean)