通过Pytorch代码可视化理解卷积神经网络

2024-06-21 08:32

本文主要是介绍通过Pytorch代码可视化理解卷积神经网络,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

本文代码地址:

https://github.com/AINewHorizon/visualising-cnns

机器在理解和识别图像中的特征和对象方面已经达到了99%的准确度。智能手机可以识别相机中的脸部;能够使用Google图像搜索特定照片; 从条形码或书籍扫描文本。所有这一切都归功于卷积神经网络(CNN),这是一种特殊类型的神经网络,也称为  convnet

如果你是一个深度学习[1]爱好者,你可能已经听说过卷积神经网络,也许你自己甚至开发了一些图像分类器。像Tensorflow和PyTorch这样的现代深度学习框架可以很容易地向机器训练图像,但是,仍然存在一些问题,如数据如何通过神经网络的人工层?计算机如何从中学习?如何更好地解释卷积神经网络。因此让我们通过每一层可视化图像,深入了解CNN。

卷积神经网络

卷积神经网络解释

什么是卷积神经网络?

卷积神经网络(CNN)是一种特殊类型的神经网络,在图像上工作得非常好。由Yan LeCun于1998年提出,卷积神经网络可以识别给定输入图像中存在的数字。

在开始使用卷积神经网络之前,了解神经网络的工作原理非常重要。神经网络模仿人类大脑如何解决复杂问题并在给定数据集中找到模式。在过去几年中,神经网络已经吞噬了许多机器学习和计算机视觉算法[2]

神经网络的基本模型由组织在不同层中的神经元组成。每个神经网络都有一个输入和一个输出层,根据问题的复杂性增加了许多隐藏层。一旦数据通过这些层,神经元就会学习并识别模式。神经网络的这种表示称为模型。一旦模型被训练,我们要求网络根据测试数据进行预测。如果您是神经网络的新手,那么关于Python深度学习的[3]这篇文章是一个很好的起点。

另一方面,CNN是一种特殊类型的神经网络,它在图像上工作得非常好。由Yan LeCun于1998年提出,卷积神经网络可以识别给定输入图像中存在的数字。使用CNN的其他应用包括语音识别,图像分割和文本处理。在卷积神经网络之前,多层感知器(MLP)被用于构建图像分类器。

图像分类是指从多波段光栅图像中提取信息类的任务。多层感知器需要更多时间和空间来查找图片中的信息,因为每个输入特征都需要与下一层中的每个神经元连接。CNN通过使用称为局部连接的概念来超越MLP,该概念涉及将每个神经元连接到仅输入音量的局部区域。这通过允许网络的不同部分专门处理诸如纹理或重复模式的高级特征来最小化参数的数量。迷茫?别担心。让我们比较一下如何通过多层感知器和卷积神经网络发送图像,以便更好地理解。

比较MLPS和CNNS

考虑到MNIST数据集,多层感知器的输入层的条目总数将为784,因为输入图像的大小为28x28 = 784。网络应该能够预测给定输入图像中的数字,这意味着输出可能属于以下任何类别,范围从0-9(1,2,3,4,5,6,7,8,9) )。在输出层,我们返回类别分数,比如说给定输入是一个数字为"3"的图像,那么在输出层中,相应的神经元"3"与其他神经元相比具有更高的类别分数。**我们需要包含多少个隐藏层以及每个隐藏层应该包含多少个神经元?**这是一个编码MLP的示例:

卷积神经网络pytorch可视化mlp

上面的代码片段使用名为Keras的框架实现(暂时忽略语法)。它告诉我们在第一个隐藏层中有512个神经元,它们连接到形状784的输入层。隐藏层后面是一个丢失层,它克服了过度拟合的问题**。**0.2表示在第一个隐藏层之后没有考虑神经元的可能性为20%。同样,我们添加了第二个隐藏层,其具有与第一个隐藏层(512)中相同数量的神经元,然后是另一个丢失层。最后,我们以包含10个类的输出层结束这组图层。具有最高值的该类将是模型预测的数量。

这是在定义所有层之后多层网络的样子。这种多层感知器的一个缺点是连接完整(完全连接)以供网络学习,这需要更多的时间和空间。MLP只接受向量作为输入。

卷积神经网络pytorch可视化图像分类器

卷积不使用全连接层,而是稀疏连接的层,即它们接受矩阵作为输入,这是优于MLP的优势。输入功能连接到本地编码节点。在MLP中,每个节点都有责任了解整个画面。在CNN中,我们将图像分解为区域(像素的小局部区域)。每个隐藏节点必须向输出层报告,其中输出层将接收的数据组合以查找模式。下图显示了各层如何在本地连接。

卷积神经网络pytorch可视化cnn

在我们了解CNN如何在图片中查找信息之前,我们需要了解如何提取这些功能。卷积神经网络使用不同的层,每层保存图像中的特征。例如,考虑一张狗的照片。每当网络需要对狗进行分类时,它应该识别所有特征 - 眼睛,耳朵,舌头,腿等 - 并且使用滤波器和内核在网络的本地层中分解和识别这些特征。

计算机如何理解图像?

与通过用眼睛拍摄快照来理解图像的人类不同,计算机使用0到255之间的一组像素值来理解图像。计算机查看这些像素值并理解它们。乍一看,它不知道对象或颜色,它只是识别像素值,这是计算机的所有图像。

在分析像素值之后,计算机慢慢开始了解图像是灰度还是彩色。它知道差异,因为灰度图像只有一个通道,因为每个像素代表一种颜色的强度。零表示黑色,255表示白色,黑色和白色的其他变化,即灰色位于两者之间。另一方面,彩色图像有三个通道 - 红色,绿色和蓝色。这些代表三种颜色(3D矩阵)的强度,当值同时变化时,它会产生一组颜色!在计算出颜色属性后,计算机会识别图像中对象的曲线和轮廓。

可以在卷积神经网络中使用PyTorch来加载数据集并对图像应用滤波器来探索该过程。以下是代码段。

# Load the libraries
import torch
import numpy as npfrom torchvision import datasets
import torchvision.transforms as transforms# Set the parameters
num_workers = 0
batch_size = 20# Converting the Images to tensors using Transforms
transform = transforms.ToTensor()train_data = datasets.MNIST(root='data', train=True,download=True, transform=transform)
test_data = datasets.MNIST(root='data', train=False,download=True, transform=transform)# Loading the Data
train_loader = torch.utils.data.DataLoader(train_data, batch_size=batch_size,num_workers=num_workers)
test_loader = torch.utils.data.DataLoader(test_data, batch_size=batch_size,num_workers=num_workers)import matplotlib.pyplot as plt
%matplotlib inlinedataiter = iter(train_loader)
images, labels = dataiter.next()
images = images.numpy()# Peeking into dataset
fig = plt.figure(figsize=(25, 4))
for image in np.arange(20):ax = fig.add_subplot(2, 20/2, image+1, xticks=[], yticks=[])ax.imshow(np.squeeze(images[image]), cmap='gray')ax.set_title(str(labels[image].item()))
卷积神经网络pytorch可视化输入数据

现在让我们看看如何将单个图像输入神经网络。

img = np.squeeze(images[7])fig = plt.figure(figsize = (12,12))
ax = fig.add_subplot(111)
ax.imshow(img, cmap='gray')
width, height = img.shape
thresh = img.max()/2.5
for x in range(width):for y in range(height):val = round(img[x][y],2) if img[x][y] !=0 else 0ax.annotate(str(val), xy=(y,x),color='white' if img[x][y]<thresh else 'black')
单张图片像素可视化

这就是将数字"3"分解为像素的方式。在一组手写数字中,随机选择"3",其中示出了像素值。在这里,ToTensor()将实际像素值(0-255)标准化,并将它们限制在0到1之间。为什么?因为,它使得后面部分的计算更容易,无论是解释图像还是找到它们中存在的常见模式。

构建滤波器

在卷积神经网络中,过滤图像中的像素信息。为什么我们需要一个滤波器?就像孩子一样,计算机需要经历理解图像的学习过程。值得庆幸的是,这不需要多年的时间!计算机通过从头学习,然后继续前进到整体来实现这一目标。因此,网络必须首先知道图像中的所有原始部分,如边缘,轮廓和其他低级特征。一旦检测到这些,计算机就可以处理更复杂的功能。简而言之,必须首先提取低级功能,然后提取中级功能,然后是高级功能。滤波器提供了一种提取信息的方法。

可以使用特定滤波器提取低级特征,该滤波器也是一组像素值,类似于图像。可以理解为连接CNN中的层的权重。这些权重或滤波器与输入相乘以得到中间图像,其描绘了计算机对图像的部分理解。之后,这些副产品将与多个滤波器相乘以扩展视图。这个过程以及功能的检测一直持续到计算机理解它所看到的内容为止。

根据您的需要,您可以使用许多滤波器。您可能想要模糊,锐化,变暗,进行边缘检测等 - 所有都是滤波器。

让我们看一些代码片段来理解滤波器的功能。

输入图像代码段
输入狗的图像

定义一个滤波器
对输入图像狗进行滤波

这是应用滤镜后图像的外观。在这种情况下,我们使用了Sobel滤波器。

完整的CNNS

到目前为止,我们已经看到滤波器如何用于从图像中提取特征,但是为了完成整个卷积神经网络,我们需要理解我们用来设计它的层。CNN中使用的层称为:

  1. 卷积层

  2. 池化层

  3. 全连接层

使用这三个层,卷积图像分类器如下所示:

卷积神经网络

现在让我们看看每个层的作用:

卷积层 - 卷积层(CONV)使用滤波器执行卷积操作,同时扫描输入图像的尺寸。其超参数包括滤波器大小,可以是2x2,3x3,4x4,5x5(但不仅限于这些)和步幅(S)。生成的输出(O)称为  要素图或激活图,并具有使用输入图层和滤波器计算的所有要素。下图描绘了应用卷积时特征贴图的生成:

卷积运算

池化层 - 该池化层(POOL)用于所述特征采样和一个卷积层之后典型地施加。两种类型的池化操作称为最大和平均池,其中分别采用要素的最大值和平均值。下面,描述了池化操作的工作:

最大池化操作
平均池化操作

**全连接层 - **全连接层(FC)在平坦的输入上操作,其中每个输入连接到所有神经元。这些通常在网络末端用于将隐藏层连接到输出层,这有助于优化课程分数。

全连接层

在PYTORCH中可视化CNNS

现在我们已经更好地了解CNN如何运作,现在让我们使用Facebook的PyTorch  框架实现一个CNN。

步骤1:  加载应通过网络发送的输入图像。我们将使用Numpy和OpenCV。

import cv2
import matplotlib.pyplot as plt
%matplotlib inline
img_path = 'dog.jpg'
bgr_img = cv2.imread(img_path)
gray_img = cv2.cvtColor(bgr_img, cv2.COLOR_BGR2GRAY)# Normalise
gray_img = gray_img.astype("float32")/255
plt.imshow(gray_img, cmap='gray')
plt.show()
可视化滤波器

第2步: 可视化滤波器以更好地了解我们将使用哪些滤波器。

import numpy as np
filter_vals = np.array([[-1, -1, 1, 1],[-1, -1, 1, 1],[-1, -1, 1, 1],[-1, -1, 1, 1]
])print('Filter shape: ', filter_vals.shape)# Defining the Filtersfilter_1 = filter_vals
filter_2 = -filter_1
filter_3 = filter_1.T
filter_4 = -filter_3
filters = np.array([filter_1, filter_2, filter_3, filter_4])# Check the Filters
fig = plt.figure(figsize=(10, 5))
for i in range(4):ax = fig.add_subplot(1, 4, i+1, xticks=[], yticks=[])ax.imshow(filters[i], cmap='gray')ax.set_title('Filter %s' % str(i+1))width, height = filters[i].shapefor x in range(width):for y in range(height):ax.annotate(str(filters[i][x][y]), xy=(y,x),color='white' if filters[i][x][y]<0 else 'black')
定义CNN

第3步: 定义CNN。该CNN具有卷积层和最大池化层,并且使用上述滤波器初始化权重:

import torch
import torch.nn as nn
import torch.nn.functional as Fclass Net(nn.Module):def __init__(self, weight):super(Net, self).__init__()# initializes the weights of the convolutional layer to be the weights of the 4 defined filtersk_height, k_width = weight.shape[2:]# assumes there are 4 grayscale filtersself.conv = nn.Conv2d(1, 4, kernel_size=(k_height, k_width), bias=False)# initializes the weights of the convolutional layerself.conv.weight = torch.nn.Parameter(weight)# define a pooling layerself.pool = nn.MaxPool2d(2, 2)def forward(self, x):# calculates the output of a convolutional layer# pre- and post-activationconv_x = self.conv(x)activated_x = F.relu(conv_x)# applies pooling layerpooled_x = self.pool(activated_x)# returns all layersreturn conv_x, activated_x, pooled_x# instantiate the model and set the weights
weight = torch.from_numpy(filters).unsqueeze(1).type(torch.FloatTensor)
model = Net(weight)# print out the layer in the network
print(model)
Net(
(conv): Conv2d(1, 4, kernel_size=(4, 4), stride=(1, 1), bias=False)
(pool): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
)

第4步:  可视化滤波器。以下是对所用滤波器的快速浏览。

def viz_layer(layer, n_filters= 4):fig = plt.figure(figsize=(20, 20))for i in range(n_filters):ax = fig.add_subplot(1, n_filters, i+1)ax.imshow(np.squeeze(layer[0,i].data.numpy()), cmap='gray')ax.set_title('Output %s' % str(i+1))fig = plt.figure(figsize=(12, 6))
fig.subplots_adjust(left=0, right=1.5, bottom=0.8, top=1, hspace=0.05, wspace=0.05)
for i in range(4):ax = fig.add_subplot(1, 4, i+1, xticks=[], yticks=[])ax.imshow(filters[i], cmap='gray')ax.set_title('Filter %s' % str(i+1))gray_img_tensor = torch.from_numpy(gray_img).unsqueeze(0).unsqueeze(1)

滤波器:

滤波器

第5步:  跨层过滤输出。在CONV和POOL层输出的图像如下所示。

viz_layer(activated_layer)
viz_layer(pooled_layer)

Conv Layers

卷积层

池化层

池化层

本文代码地址:https://github.com/AINewHorizon/visualising-cnns

请长按或扫描二维码关注本公众号

喜欢的话,请给我个在看吧

参考资料

[1]

深度学习: https://builtin.com/artificial-intelligence/deep-learning

[2]

机器学习和计算机视觉算法: https://builtin.com/data-science/tour-top-10-algorithms-machine-learning-newbies

[3]

Python深度学习的: https://builtin.com/data-science/deep-learning-python

这篇关于通过Pytorch代码可视化理解卷积神经网络的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1080718

相关文章

可视化实训复习篇章

前言: 今天,我们来学习seaborn库可视化,当然,这个建立在Matplotlib的基础上,话不多说,进入今天的正题吧!当然,这个是《python数据分析与应用》书中,大家有需求的可以参考这本书。 知识点: Matplotlib中有两套接口分别是pyplot和pyylab,即绘图时候主要导入的是Matplotlib库下的两个子模块(两个py文件)matplotlib.pyplot和matp

uniapp接入微信小程序原生代码配置方案(优化版)

uniapp项目需要把微信小程序原生语法的功能代码嵌套过来,无需把原生代码转换为uniapp,可以配置拷贝的方式集成过来 1、拷贝代码包到src目录 2、vue.config.js中配置原生代码包直接拷贝到编译目录中 3、pages.json中配置分包目录,原生入口组件的路径 4、manifest.json中配置分包,使用原生组件 5、需要把原生代码包里的页面修改成组件的方

公共筛选组件(二次封装antd)支持代码提示

如果项目是基于antd组件库为基础搭建,可使用此公共筛选组件 使用到的库 npm i antdnpm i lodash-esnpm i @types/lodash-es -D /components/CommonSearch index.tsx import React from 'react';import { Button, Card, Form } from 'antd'

17.用300行代码手写初体验Spring V1.0版本

1.1.课程目标 1、了解看源码最有效的方式,先猜测后验证,不要一开始就去调试代码。 2、浓缩就是精华,用 300行最简洁的代码 提炼Spring的基本设计思想。 3、掌握Spring框架的基本脉络。 1.2.内容定位 1、 具有1年以上的SpringMVC使用经验。 2、 希望深入了解Spring源码的人群,对 Spring有一个整体的宏观感受。 3、 全程手写实现SpringM

YOLOv8改进 | SPPF | 具有多尺度带孔卷积层的ASPP【CVPR2018】

💡💡💡本专栏所有程序均经过测试,可成功执行💡💡💡 专栏目录 :《YOLOv8改进有效涨点》专栏介绍 & 专栏目录 | 目前已有40+篇内容,内含各种Head检测头、损失函数Loss、Backbone、Neck、NMS等创新点改进——点击即可跳转 Atrous Spatial Pyramid Pooling (ASPP) 是一种在深度学习框架中用于语义分割的网络结构,它旨

Windows/macOS/Linux 安装 Redis 和 Redis Desktop Manager 可视化工具

本文所有安装都在macOS High Sierra 10.13.4进行,Windows安装相对容易些,Linux安装与macOS类似,文中会做区分讲解 1. Redis安装 1.下载Redis https://redis.io/download 把下载的源码更名为redis-4.0.9-source,我喜欢跟maven、Tomcat放在一起,就放到/Users/zhan/Documents

代码随想录算法训练营:12/60

非科班学习算法day12 | LeetCode150:逆波兰表达式 ,Leetcode239: 滑动窗口最大值  目录 介绍 一、基础概念补充: 1.c++字符串转为数字 1. std::stoi, std::stol, std::stoll, std::stoul, std::stoull(最常用) 2. std::stringstream 3. std::atoi, std

回调的简单理解

之前一直不太明白回调的用法,现在简单的理解下 就按这张slidingmenu来说,主界面为Activity界面,而旁边的菜单为fragment界面。1.现在通过主界面的slidingmenu按钮来点开旁边的菜单功能并且选中”区县“选项(到这里就可以理解为A类调用B类里面的c方法)。2.通过触发“区县”的选项使得主界面跳转到“区县”相关的新闻列表界面中(到这里就可以理解为B类调用A类中的d方法

记录AS混淆代码模板

开启混淆得先在build.gradle文件中把 minifyEnabled false改成true,以及shrinkResources true//去除无用的resource文件 这些是写在proguard-rules.pro文件内的 指定代码的压缩级别 -optimizationpasses 5 包明不混合大小写 -dontusemixedcaseclassnames 不去忽略非公共

人工智能机器学习算法总结神经网络算法(前向及反向传播)

1.定义,意义和优缺点 定义: 神经网络算法是一种模仿人类大脑神经元之间连接方式的机器学习算法。通过多层神经元的组合和激活函数的非线性转换,神经网络能够学习数据的特征和模式,实现对复杂数据的建模和预测。(我们可以借助人类的神经元模型来更好的帮助我们理解该算法的本质,不过这里需要说明的是,虽然名字是神经网络,并且结构等等也是借鉴了神经网络,但其原型以及算法本质上还和生物层面的神经网络运行原理存在