pytorch卷积神经网络中间特征层可视化

前言

在我们使用神经网络的过程中,经常会好奇中间的网络到底学到了些什么,所以常常想用可视化的方法来输出这些特征层,所以惊天带大家用一个简易的网络来输出这些特征层。

搭建网络

from torch import nn
import torch
from torch.nn import functional as F
import cv2
from matplotlib import pyplot as plt
class Net(nn.Module):
    def __init__(self):
        super().__init__()
        self.conv1=nn.Conv2d(3,6,5)
        self.pool1=nn.MaxPool2d(4,4)
        self.conv2=nn.Conv2d(6,16,5)
        self.pool2=nn.MaxPool2d(4,4)

    def forward(self,x):
        output=[]     #保存特征层的列表,在最后的时候返回
        x=self.conv1(x)
        output.append(x)   #加入output中
        x=F.relu(x)
        output.append(x)
        x=self.pool1(x)
        output.append(x)
        x=self.conv2(x)
        output.append(x)
        x=F.relu(x)
        output.append(x)
        x=self.pool2(x)
        return x,output

net=Net()   #实例化网络,当然也可以选择导入预训练的权重,这里就不导入了

导入图像,并进行前向传播

path="dog.png"   #图像路径
img=cv2.imread(path)  #读取图片
img=cv2.cvtColor(img, cv2.COLOR_BGR2RGB)  #opencv读取的图片默认是bgr需要转换成rgb
img=torch.tensor(img,dtype=torch.float32) #opencv采用的是numpy,所以需要转成tensor
# img=torch.unsqueeze(img,0)
# img=torch.permute(img,(0,3,1,2))
img=torch.permute(img,(2,0,1))  #[348,348,3] --->[3,348,348]
print(img.shape)
_,output=net(img)  #前向传播,并返回特征层

打印特征层

for layer in output:
    fig = plt.figure()  # 定义画布
    # layer=torch.squeeze(layer)
    #print(layer.shape)
    layer = layer.detach().numpy() #将tensor转成numpy
    print(layer.shape)
    plt.subplots_adjust(wspace=0.05, hspace=0)  # 无缝布局,间距可改
    for i in range(layer.shape[0]):      #画出每一个通道的特征
        # plt.tight_layout() #紧密布局
        ax = fig.add_subplot(2, layer.shape[0]//2, i + 1, xticks=[], yticks=[])  
        plt.imshow(layer[i,:,:],cmap="gray")   #使用灰度图
    plt.show()

效果展示

卷积层输出
pytorch卷积神经网络中间特征层可视化_第1张图片
Relu之后
pytorch卷积神经网络中间特征层可视化_第2张图片
池化之后
pytorch卷积神经网络中间特征层可视化_第3张图片

完整源代码

from torch import nn
import torch
from torch.nn import functional as F
import cv2
from matplotlib import pyplot as plt
class Net(nn.Module):
    def __init__(self):
        super().__init__()
        self.conv1=nn.Conv2d(3,6,5)
        self.pool1=nn.MaxPool2d(4,4)
        self.conv2=nn.Conv2d(6,16,5)
        self.pool2=nn.MaxPool2d(4,4)

    def forward(self,x):
        output=[]     #保存特征层的列表,在最后的时候返回
        x=self.conv1(x)
        output.append(x)   #加入output中
        x=F.relu(x)
        output.append(x)
        x=self.pool1(x)
        output.append(x)
        x=self.conv2(x)
        output.append(x)
        x=F.relu(x)
        output.append(x)
        x=self.pool2(x)
        return x,output

net=Net()   #实例化网络,当然也可以选择导入预训练的权重,这里就不导入了

path="dog.png"
img=cv2.imread(path)
img=cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
img=torch.tensor(img,dtype=torch.float32)
# img=torch.unsqueeze(img,0)
# img=torch.permute(img,(0,3,1,2))
img=torch.permute(img,(2,0,1))
print(img.shape)
_,output=net(img)
# print(output)
for layer in output:
    fig = plt.figure()  # 定义画布
    # layer=torch.squeeze(layer)
    #print(layer.shape)
    layer = layer.detach().numpy()
    print(layer.shape)
    plt.subplots_adjust(wspace=0.05, hspace=0)  # 无缝布局,间距可改
    for i in range(layer.shape[0]):
        # plt.tight_layout() #紧密布局
        ax = fig.add_subplot(2, layer.shape[0]//2, i + 1, xticks=[], yticks=[])  # 2行4列,坐标为空
        plt.imshow(layer[i,:,:],cmap="gray")
    plt.show()

你可能感兴趣的:(深度学习,pytorch,cnn,python)