神经网络可视化:卷积核可视化

文章目录

  • 前言
      • 一般过程:
  • 一、代码示例
  • 二、卷积核和输入图片相乘可视化
  • 总结


前言

卷积核可视化是一种用于理解卷积神经网络 (CNN) 中卷积层的工作原理和特征提取能力的方法。通过可视化卷积核,我们可以观察卷积层学习到的特征模式,帮助我们理解网络如何对输入进行处理。

本文给出了一个具体的pytorch实现的例子。
本文还给了一个用权重核和直接卷积图像的例子。

一般过程:

导入必要的库和模型:首先,你需要导入相关的库,如 PyTorch、NumPy 和 Matplotlib,并加载已经训练好的 CNN 模型。

获取卷积层权重:从模型中获取卷积层的权重。这些权重通常存储在模型的卷积层参数中。

可视化卷积核:对于每个卷积层,获取对应的权重,并以图像形式展示。可以使用 Matplotlib 或其他图像处理库来显示卷积核。

可选:对于多通道的卷积核,你可以将每个通道的权重分别可视化,以更好地理解卷积核的组成。


一、代码示例

以resnet50为例进行第一层可视化

import os
import numpy as np
import torch
from PIL import Image
import matplotlib.pyplot as plt
from torchvision import models
from torchvision import transforms


def visualize_conv_filters():
    # 设置GPU设备
    torch.cuda.set_device(0) # 没有GPU可以删除

    model = models.resnet50(pretrained=True)
    model = model.cuda()  # 将模型移动到GPU上 # 没有GPU可以删除

    # 获取第一个卷积层的权重
    conv1_weights = model.conv1.weight.data.cpu().numpy()
    # 调整权重形状,从 [out_channels, in_channels, kernel_size, kernel_size] 变为 [out_channels, kernel_size, kernel_size, in_channels]
    conv1_weights = np.transpose(conv1_weights, (0, 2, 3, 1))

    # 可视化卷积核
    fig, axes = plt.subplots(nrows=8, ncols=8, figsize=(12, 12))
    for i, ax in enumerate(axes.flat):
        ax.imshow(conv1_weights[i])
        ax.axis('off')

    plt.show()


if __name__ == '__main__':
    visualize_conv_filters()

获得图像:
神经网络可视化:卷积核可视化_第1张图片


二、卷积核和输入图片相乘可视化

把卷积核(作为权重)和图片进行卷积操作

import os
import numpy as np
import torch
from PIL import Image
import matplotlib.pyplot as plt
from torchvision import models
from torchvision import transforms

def visualize_conv_filters(model_conv, img_file):
    # 设置GPU设备
    # torch.cuda.set_device(gpu_number)

    # model = models.resnet50(pretrained=True)
    # model = model.cuda()  # 将模型移动到GPU2上

    # 获取第一个卷积层的权重
    conv1_weights = model_conv.weight.data.cpu().numpy()
    # 调整权重形状,从 [out_channels, in_channels, kernel_size, kernel_size] 变为 [out_channels, kernel_size, kernel_size, in_channels]
    conv1_weights = np.transpose(conv1_weights, (0, 2, 3, 1))

    # 读入图像
    image = Image.open(img_file)
    image = transforms.ToTensor()(image)
    image = image.unsqueeze(0)  # 添加批次维度并将图像移动到GPU上

    # 对每个卷积核进行卷积操作并绘制图像
    fig, axes = plt.subplots(nrows=8, ncols=4, figsize=(12, 6),dpi=100)

    al_list = range(conv1_weights.shape[0])

    for i, ax in zip(al_list, axes.flat):
        conv1_weight = conv1_weights[i]
        conv1_weight = torch.from_numpy(conv1_weight).permute(2, 0, 1).cuda()  # 将当前卷积核移动到GPU上

        # 对图像的每个通道进行卷积操作
        output_channels = []
        for channel in range(conv1_weight.size(0)):
            conv1_weight_ = torch.unsqueeze(conv1_weight, 0)
            ## 重点代码,卷积操作
            output_channel = torch.nn.functional.conv2d(image[:,channel:channel+1,:,:],
                                                        conv1_weight_[:,channel:channel+1,:,:],
                                                        stride=(1, 1), padding=0)
            output_channels.append(output_channel)

        # 合并卷积后的通道
        output = torch.cat(output_channels, dim=1)

        # 转换为NumPy数组并绘制图像
        output = output.squeeze(0).cpu().detach().numpy()  # 移除批次维度,并将结果移动到CPU上
        output = np.transpose(output, (1, 2, 0))  # 调整形状为 [height, width, channels]
        ax.imshow(output)
        ax.axis('off')
        # input('>>')

    if not os.path.exists('./img/'):
        os.mkdir('./img/')
    plt.savefig('./img/abc.png')

if __name__ == '__main__':
    model = models.resnet50(pretrained=True)
    torch.cuda.set_device(0)
    img_file = 'img_1.png'
    visualize_conv_filters(model.conv1, img_file)
    

原图:
神经网络可视化:卷积核可视化_第2张图片
乘以卷积核之后的可视化结果:
神经网络可视化:卷积核可视化_第3张图片


总结

以上就是今天要讲的内容,本文仅仅简单介绍了卷积核可视化的计算

你可能感兴趣的:(神经网络,人工智能,深度学习)