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

文章目录

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

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

带着这些问题,本文将使用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和池化处理后,基本上已经面目全非:

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

相关推荐
fantasy_arch3 小时前
深度学习--softmax回归
人工智能·深度学习·回归
Blossom.1183 小时前
量子计算与经典计算的融合与未来
人工智能·深度学习·机器学习·计算机视觉·量子计算
大刘讲IT3 小时前
制造业数字化转型:流程改造先行还是系统固化数据?基于以MTO和MTS的投资回报分析
运维·经验分享·生活·产品经理·数据可视化
硅谷秋水3 小时前
MoLe-VLA:通过混合层实现的动态跳层视觉-语言-动作模型实现高效机器人操作
人工智能·深度学习·机器学习·计算机视觉·语言模型·机器人
2301_764441333 小时前
基于神经网络的肾脏疾病预测模型
人工智能·深度学习·神经网络
HABuo4 小时前
【YOLOv8】YOLOv8改进系列(12)----替换主干网络之StarNet
人工智能·深度学习·yolo·目标检测·计算机视觉
Dovis(誓平步青云)5 小时前
深挖 DeepSeek 隐藏玩法·智能炼金术2.0版本
人工智能·深度学习·机器学习·数据挖掘·服务发现·智慧城市
赵钰老师5 小时前
【Deepseek、ChatGPT】智能气候前沿:AI Agent结合机器学习与深度学习在全球气候变化驱动因素预测中的应用
人工智能·python·深度学习·机器学习·数据分析
Start_Present7 小时前
Pytorch 第十三回:神经网络编码器——自动编解码器
pytorch·python·深度学习·神经网络
Y1nhl9 小时前
搜广推校招面经六十四
人工智能·深度学习·leetcode·广告算法·推荐算法·搜索算法