卷积神经网络可视化的探索

文章目录

卷积神经网络是利用图像空间结构的一种深度学习网络架构,图像在经过卷积层、激活层、池化层、全连接层等处理后得到输出。

本次想探索一下图像经过每一层都发生了什么变化,比如不同的卷积核(滤波器)都提取了图像的什么特征?越深层是否会对图像更抽象化?

带着这些问题,本文将使用FashionMNIST数据、简单的LeNet模型来探索CNN是如何处理图像的。

训练LeNet模型

首先来训练一个LeNet模型(换成其他卷积神经网络也可以),目的是为了利用训练好的模型参数获得输入图像的各层输出,以供可视化之用。

下载FashionMNIST数据

root:设置下载路径;

train:为True表示下载训练集,反之为测试集;

download:首次下载设为True,下载好后可以改为False。

python 复制代码
from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = "all"

from matplotlib import pyplot as plt
%matplotlib inline
from PIL import Image

import torch
from torch import nn
import torchvision
from torch.utils import data
from torchvision import transforms

#下载数据
def load_fashion_mnist(batch_size):
    trans = transforms.Compose([transforms.ToTensor()])
    train = torchvision.datasets.FashionMNIST(root="../data", train=True, transform=trans, download=False)
    test = torchvision.datasets.FashionMNIST(root="../data", train=False,transform=trans,download=False)
    
    return (data.DataLoader(train, batch_size, shuffle=True), data.DataLoader(test, batch_size, shuffle=False))

训练

简单地训练网络

python 复制代码
#批量大小
batch_size = 512
train_iter, test_iter = load_fashion_mnist(batch_size=batch_size)

#LeNet网络
net = nn.Sequential(
    nn.Conv2d(1, 6, kernel_size=5, padding=2), nn.ReLU(),
    nn.AvgPool2d(kernel_size=2, stride=2),
    nn.Conv2d(6, 16, kernel_size=5), nn.ReLU(),
    nn.AvgPool2d(kernel_size=2, stride=2),
    nn.Flatten(),
    nn.Linear(16 * 5 * 5, 120), nn.ReLU(),
    nn.Linear(120, 84), nn.ReLU(),
    nn.Linear(84, 10))

#参数初始化
def init_network(model, method='xavier'):
    for name, w in model.named_parameters():
        if 'weight' in name:
            if method == 'xavier':
                nn.init.xavier_normal_(w)
            elif method == 'kaiming':
                nn.init.kaiming_normal_(w)
            else:
                nn.init.normal_(w)
        elif 'bias' in name:
            nn.init.constant_(w, 0)
        else:
            pass    
init_network(net)

#损失函数
loss=nn.CrossEntropyLoss()

#优化算法
lr=0.05
updater=torch.optim.SGD(net.parameters(),lr=lr)

#训练
def train(net, train_iter, test_iter, loss, num_epochs, updater,device):
    net.to(device)
    for epoch in range(num_epochs):
        if isinstance(net, torch.nn.Module):
            net.train()
        for X, y in train_iter:
            X,y=X.to(device),y.to(device)         
            y_hat = net(X)        
            l = loss(y_hat, y)
            
            updater.zero_grad() 
            l.backward()                
            updater.step()
           
device = torch.device("mps" if torch.backends.mps.is_available else "cpu") #Mac使用mps
num_epochs = 20
train(net, train_iter, test_iter, loss, num_epochs, updater,device)

保存模型

python 复制代码
#保存模型参数
torch.save(net.state_dict(),'LeNet.params')

卷积神经网络可视化

本节将使用上文训练好的模型来可视化卷积神经网络不同层对图像的处理过程。

加载模型

python 复制代码
#LeNet网络结构
net = nn.Sequential(
    nn.Conv2d(1, 6, kernel_size=5, padding=2), nn.ReLU(),
    nn.AvgPool2d(kernel_size=2, stride=2),
    nn.Conv2d(6, 16, kernel_size=5), nn.ReLU(),
    nn.AvgPool2d(kernel_size=2, stride=2),
    nn.Flatten(),
    nn.Linear(16 * 5 * 5, 120), nn.ReLU(),
    nn.Linear(120, 84), nn.ReLU(),
    nn.Linear(84, 10))

#加载模型参数
net.load_state_dict(torch.load('LeNet.params'))
net.eval()

一个测试图像

python 复制代码
#批量大小
batch_size = 1
train_iter, test_iter = load_fashion_mnist(batch_size=batch_size)
python 复制代码
#随机选择一个图像
for x,y in train_iter:
    _=plt.imshow(x.squeeze(0).permute(1,2,0).numpy())
    break

看上去我们抽到了一件T恤。

不同层对图像处理的可视化

python 复制代码
#计算到给定层的输出
def cnn_net(X,net,l=1):
    for i,layer in enumerate(net[0:l]):
        X=layer(X)  
        if i==l-1:
            print('第%s层:%-10s 输出形状:%s'%(i+1, layer.__class__.__name__, X.shape))        
    return X
  
#可视化
def cnn_visual(imgs,nrows,ncols,scale):
    figsize = (ncols * scale, nrows * scale)
    fig,axes = plt.subplots(nrows=nrows, ncols=ncols,figsize=figsize)
    axes = axes.flatten()

    for i, (ax, img) in enumerate(zip(axes, imgs.squeeze(0))):   
        _ = ax.imshow(img.detach().numpy())
        ax.axes.get_xaxis().set_visible(False)
        ax.axes.get_yaxis().set_visible(False)
    return axes
  
for l in [1,2,3,4,5,6]:
    imgs=cnn_net(x.clone(),net,l=l)
    nrows=2
    ncols=int(imgs.shape[1]/nrows)
    axes=cnn_visual(imgs,nrows,ncols,2)

第一个卷积层的处理

我们先来看看第一个卷积层中不同卷积核分别从图像中提取了什么信息,第一个卷积层有6个输出通道,因此查看每个通道输出的图像。

从下图可以看出,第一个卷积层提取到了不同轮廓层次信息。

经过ReLU处理后:

再经平均池化处理后,变化不大:

第二个卷积层的处理

第二个卷积层有16个输出通道,随着层次加深,感受野扩大,通道的融合后,从下图看已经比较抽象了,但隐隐约约还能看出点端倪:

再经ReLU和池化处理后,基本上已经面目全非:

以上就是对卷积神经网络可视化的初步探索,感兴趣的读者可以在不同卷积神经网络和图像上多做尝试。
另附一个卷积神经网络可视化网站

相关推荐
牧歌悠悠7 小时前
【深度学习】Unet的基础介绍
人工智能·深度学习·u-net
Archie_IT8 小时前
DeepSeek R1/V3满血版——在线体验与API调用
人工智能·深度学习·ai·自然语言处理
大数据追光猿8 小时前
Python应用算法之贪心算法理解和实践
大数据·开发语言·人工智能·python·深度学习·算法·贪心算法
Watermelo61711 小时前
从DeepSeek大爆发看AI革命困局:大模型如何突破算力囚笼与信任危机?
人工智能·深度学习·神经网络·机器学习·ai·语言模型·自然语言处理
Donvink11 小时前
【DeepSeek-R1背后的技术】系列九:MLA(Multi-Head Latent Attention,多头潜在注意力)
人工智能·深度学习·语言模型·transformer
计算机软件程序设计11 小时前
深度学习在图像识别中的应用-以花卉分类系统为例
人工智能·深度学习·分类
終不似少年遊*14 小时前
词向量与词嵌入
人工智能·深度学习·nlp·机器翻译·词嵌入
B站计算机毕业设计超人16 小时前
计算机毕业设计Python+DeepSeek-R1高考推荐系统 高考分数线预测 大数据毕设(源码+LW文档+PPT+讲解)
大数据·python·机器学习·网络爬虫·课程设计·数据可视化·推荐算法
夏莉莉iy17 小时前
[MDM 2024]Spatial-Temporal Large Language Model for Traffic Prediction
人工智能·笔记·深度学习·机器学习·语言模型·自然语言处理·transformer
pchmi17 小时前
CNN常用卷积核
深度学习·神经网络·机器学习·cnn·c#