PyTorch | 提取神經(jīng)網(wǎng)絡(luò)中間層特征進行可視化
一 写在前面
未经允许,不得转载,谢谢。
这篇博客主要记录了如何提取特定层的特征,然后对它进行可视化。
二 主要的实现思路:
处理单张图片作为网络输入。
根据给定的layer层,获取该层的输出结果
features
。考虑到
features
的形状为:[batch_size, filter_nums, H, W] 提取其中的第一个过滤器得到的结果feature
。以一张图片作为输入的情况下,我们得到的
feature
即为[H,W]大小的tensor。将tensor转为numpy,然后归一化到[0,1],最后乘255,使得范围为[0,255]
得到灰度图像并保存。
三 具体实现过程
了解实现流程之后整个代码没有什么难度,对其中的关键点进行简单说明一下:
模型我用了在ImageNet预先训练好的vgg16作为示例。
打印模型结构可以看到每一层对应的id是什么。
通常选择
conv
后面的特征进行可视化。整个的实现放在类
FeatureVisualization
中实现。对于归一化到[0,1]的部分我用了sigmod方法。
需要特别交代的差不多就是这些,直接上代码了:
import cv2import numpy as npimport torchfrom torch.autograd import Variablefrom torchvision import modelsdef 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_varclass 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()
四 结果展示
输入图片:
home.jpg
conv2的结果
conv2
conv5的结果
conv5
五 写在最后:彩蛋哈哈哈
上面的程序完成了对神经网络特征层的输出特征值进行可视化的过程。
在github上找到了同样用pytorch对CNN网络进行可视化的代码,目前作者已经实现了对梯度、过滤器的可视化等等,还是非常具有学习和参考价值的
对于本文实现的可视化方法有什么问题的欢迎简信交流~~~
作者:与阳光共进早餐
链接:https://www.jianshu.com/p/2fe73baa09b8
共同學(xué)習(xí),寫下你的評論
評論加載中...
作者其他優(yōu)質(zhì)文章