CNNs: AlexNet补充

news2024/9/21 12:41:30

CNNs: AlexNet的补充

  • 导言
  • 对`AlexNet`模型进行调整
  • 模型不同层的表征
  • 其他探索
  • 总结

导言

上上篇和上一篇我们详细地讲述了AlexNet的网络结构和不同超参数对同一数据集的不同实验现象。

本节,我们就AlexNet的一些其他相关问题进行解剖,如修改AlexNet参数量调整和不同层的feature map表征的意义(当然,不同模型的不同层的feature map所表征的特征也有所不同,我们仅对模型做一个简单的探索)

AlexNet模型进行调整

本节,我们对AlexNet进行简单实验,将每一层的参数量减半(相当于Alex当初在一张显卡上的模型结构)。

相关代码如下:

import torch
import torch.nn as nn
from torchsummary import summary

class AlexNet(nn.Module):
    def __init__(self, class_num = 5):
        super(AlexNet, self).__init__()
        self.features = nn.Sequential(
            # input[3, 227, 227]  output[48, 55, 55]
            nn.Conv2d(3, 48, kernel_size=11, stride=4, padding=0),
            nn.ReLU(inplace=True),
            # output[48, 27, 27]
            nn.MaxPool2d(kernel_size=3, stride=2),

            # output[128, 27, 27]
            nn.Conv2d(48, 128, kernel_size=5, padding=2),
            nn.ReLU(inplace=True),
            # output[128, 13, 13]
            nn.MaxPool2d(kernel_size=3, stride=2),

            # output[192, 13, 13]
            nn.Conv2d(128, 192, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            # output[192, 13, 13]
            nn.Conv2d(192, 192, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            # output[128, 13, 13]
            nn.Conv2d(192, 128, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            # output[128, 6, 6]
            nn.MaxPool2d(kernel_size=3, stride=2),
        )

        self.classifier = nn.Sequential(
            nn.Linear(128 * 6 * 6, 2048),
            nn.ReLU(inplace=True),
            nn.Dropout(p=0.5),
            nn.Linear(2048, 2048),
            nn.ReLU(inplace=True),
            nn.Linear(2048, class_num),
        )
    
    def forward(self, x):
        x = self.features(x)
        x = torch.flatten(x, start_dim=1)
        x = self.classifier(x)
        return x

以下是基于调整过AlexNet模型参数batch size为8和16的实验结果。
在这里插入图片描述
以下是基于未调整过AlexNet模型参数batch size为8和16的实验结果。
在这里插入图片描述
由实验结果表明,调整过AlexNet模型并没有未调整过模型的效果好。当然,我们并不是想要表明调整模型参数的效果没有原模型的效果好,模型的调整也需要综合数据集、超参数等各种因素去进行优化。模型的调整也有可能会对不同实验带来更好的效果,如ZFNet(这一篇文献我们将在下一个CNNs系列进行讲解)。

模型不同层的表征

为了能够窥视AlexNet卷积层的feature map,我们将AlexNet网络的编写稍作修改,其改变后的模型如下。

import torch
import torch.nn as nn
from torchsummary import summary

class AlexNet(nn.Module):
    def __init__(self, class_num = 5):
        super(AlexNet, self).__init__()
        self.conv1 = nn.Sequential(
            # input[3, 224, 224]  output[96, 55, 55]
            nn.Conv2d(3, 96, kernel_size=11, stride=4, padding=0),
            nn.ReLU(inplace=True),
            # output[96, 27, 27]
            nn.MaxPool2d(kernel_size=3, stride=2)
        )

        self.conv2 = nn.Sequential(
            # output[256, 27, 27]
            nn.Conv2d(96, 256, kernel_size=5, padding=2),
            nn.ReLU(inplace=True),
            # output[256, 13, 13]
            nn.MaxPool2d(kernel_size=3, stride=2)
        )

        self.conv3 = nn.Sequential(
            # output[384, 13, 13]
            nn.Conv2d(256, 384, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            # output[384, 13, 13]
            nn.Conv2d(384, 384, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            # output[256, 13, 13]
            nn.Conv2d(384, 256, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            # output[256, 6, 6]
            nn.MaxPool2d(kernel_size=3, stride=2),
        )

        self.fc = nn.Sequential(
            nn.Linear(256 * 6 * 6, 2048),
            nn.ReLU(inplace=True),
            nn.Dropout(p=0.5),
            nn.Linear(2048, 2048),
            nn.ReLU(inplace=True),
            nn.Linear(2048, class_num),
        )
    
    def forward(self, x):
        x = self.conv1(x)
        x = self.conv2(x)
        x = self.conv3(x)
        output = self.fc(x.view(-1, 256 * 6 * 6))
        return output

基于以上代码的修改,我们将网络结构调整为三个卷积层。(当然,为了能够看到更加细节的feture map我们还可以进行拆分)

首先,我们使用上一篇的结论进行训练,并将模型保存至model目录中。

epoch <= 18, lr = 0.01
epoch > 18 ,lr = 0.003
epochs = 150
batch_size = 16

然后,我们将训练好的模型加载进来并且使用训练好的模型对图像进行预测。项目源码.

import sys
sys.path.append('.')

import cv2
import torch
import torchvision
import torchvision.transforms as transforms
import matplotlib.pyplot as plt
from PIL import Image
from utils_module import param_settings
from torchvision.models.feature_extraction import get_graph_node_names
from torchvision.models.feature_extraction import create_feature_extractor

transform = transforms.Compose(
    [transforms.Resize(256),
     transforms.CenterCrop(227),
     transforms.ToTensor(),
     transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])])

device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')
model_path = param_settings.SAVE_PATH
load_model = torch.load(model_path)

# nodes, _ = get_graph_node_names(load_model)
# print(nodes)

feature_extractor = create_feature_extractor(load_model, return_nodes={"conv1":"output1","conv2":"output2","conv3":"output3","fc":"output4"})

test_img_path = 'G:/learning/05dataset/pokeman/test/4.jpg'

img = Image.open(test_img_path)
img = transform(img)

#转换维度
img = img.unsqueeze(0).to(device)

out = feature_extractor(img) 
size = len(out["output1"][0])
for i in range(0, size):
    plt.imshow(out["output1"][0].cpu()[i,:,:].detach().numpy())

size = len(out["output2"][0])
for i in range(0, size):
    plt.imshow(out["output2"][0].cpu()[i,:,:].detach().numpy())

size = len(out["output3"][0])
for i in range(0, size):
    plt.imshow(out["output3"][0].cpu()[i,:,:].detach().numpy())
# 这里没有分通道可视化
plt.imshow(out["output1"][0].cpu().transpose(0, 1).sum(1).detach().numpy())
plt.imshow(out["output2"][0].cpu().transpose(0, 1).sum(1).detach().numpy())
plt.imshow(out["output3"][0].cpu().transpose(0, 1).sum(1).detach().numpy())
plt.show()
nodes, _ = get_graph_node_names(load_model)
print(nodes)

可以使用get_graph_node_names获取网络结构,并使用create_feature_extractor进行提取对应结构的特征图。
我们使用的测试图片如图所示:
在这里插入图片描述
卷积网络1的输出特征图如图所示,输出feature mapshape为[96, 27, 27]:
在这里插入图片描述
卷积网络2的输出特征图如图所示,输出feature mapshape为[256, 13, 13]:
在这里插入图片描述
由实验结果表明,卷积网络2所表征的意义十分抽象,已经和原图像中物体相差较远。

卷积网络2的输出特征图如图所示,输出feature mapshape为[256, 6, 6]:
在这里插入图片描述
以上是对不同的卷积网络不同通道进行的抽样,可以看到,基本上从第二个卷积网络生成的feature map会越来越抽象,很难表示feature与原图中物体的关系。

下面是将三个卷积网络的生成的feature map没有拆分通道的图像:
在这里插入图片描述

其他探索

本节,我们验证了文献AlexNet中的一个结论:如果两幅图像产生的特征激活向量具有很小的欧几里得分离,我们可以说神经网络的更高层次认为它们是相似的。(If two images produce feature activation vectors with a small Euclidean separation, we can say that the higher levels of the neural network consider them to be similar)
在这里插入图片描述
上图是第一列中的五个ILSVRC-2010测试图像。剩余的列示出了在最后一个隐藏层中产生特征向量的六个训练图像,其具有与测试图像的特征向量的最小欧几里得距离。其原理与以图搜图的功能类似。

我们复现了这部分的实验,源码地址。
以下是部分实验结果展示,图中共有三行11张图像,第一行第一张图片是我们在网上随机找到的宝可梦图像,第二行和第三行是训练集中图像与测试图像的特征向量的最小欧几里得距离的前十张图像。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

总结

至此,我们对AlexNet探究就结束了。当然,我们对AlexNet的探索仅仅是管中窥豹,下一篇CNNs系列的文章ZFNet将跟随文章对AlexNet做进一步的探索,以及对修改后的模型做进一步的探索!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/494727.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

JVM内存模型基础

大家好&#xff0c;我是易安&#xff01; 我们知道运行一个Java应用程序&#xff0c;我们必须要先安装JDK或者JRE包。这是因为Java应用在编译后会变成字节码&#xff0c;然后通过字节码运行在JVM中&#xff0c;而JVM是JRE的核心组成部分。 JVM不仅承担了Java字节码的分析&#…

JavaWeb ( 五 ) Servlet

2.3.Servlet Servlet&#xff08;Server Applet&#xff09;是Java Servlet的简称。 是在服务器端执行的 , 用于响应客户端请求的Java类。HttpServlet 是使用java语言对http通信的实现。 2.3.1.Servlet声明 在 web.xml 中声明Servlet的请求url及对应的类路径 , 3.0版本后可以…

APSIM模型

随着数字农业和智慧农业的发展&#xff0c;基于过程的农业生产系统模型在模拟作物对气候变化的响应与适应、农田管理优化、作物品种和株型筛选、农田固碳和温室气体排放等领域扮演着越来越重要的作用。APSIM (Agricultural Production Systems sIMulator)模型是世界知名的作物生…

趣谈西工大电子实习物联网智慧交通系统

学习简介&#xff1a; 物联网智慧交通系统是电子实习中相当有趣的一个环节&#xff0c;可以在一定程度上弥补没有被分配到智能小车的遗憾。在这个模块当中&#xff0c;你将在老师的带领下以完成两个小任务为驱动&#xff0c;让自身能力在八个学时当中充分锻炼。 下面这两张图…

微信小程序商城搭建--后端+前端+小程序端

介绍&#xff1a; 前端技术&#xff1a;React、AntdesignPro、umi、JavaScript、ES6、TypeScript、 小程序 后端技术&#xff1a;Springboot、Mybatis、Spring、Mysql 软件架构&#xff1a; 后端采用Springboot搭配前端React进行开发&#xff0c;完成用户管理、轮播图管理、…

[MySQL / Mariadb] 数据库学习-Linux中安装MySQL,YUM方式

[Mariadb] 数据库学习笔记 在Linux中安装MySQL&#xff0c;YUM方式mariadb 介绍安装启服务初始配置修改密码 密码策略,默认策略是1show variables; 查所有变量show variables like "%变量%"; 查特定的变量参数临时&#xff1a;永久&#xff1a; MySQL基本操作连接SQL…

使用@PropertySource加载配置文件

1.PropertySource和PropertySources注解 1.1.PropertySource注解概述 PropertySource注解是Spring 3.1开始引入的配置类注解。通过**PropertySource注解可以将properties配置文件中的key/value存储到Spring的Environment中&#xff0c;Environment接口提供了方法去读取配置文…

ModStartCMS v6.3.0 电脑端在线充值,前端库升级

ModStart 是一个基于 Laravel 模块化极速开发框架。模块市场拥有丰富的功能应用&#xff0c;支持后台一键快速安装&#xff0c;让开发者能快的实现业务功能开发。 系统完全开源&#xff0c;基于 Apache 2.0 开源协议&#xff0c;免费且不限制商业使用。 功能特性 丰富的模块市…

AMA 回顾|关于访问水晶铸造的一些调整建议

这是社区系列 AMA 的第一期。下周&#xff0c;我们将举行一场新的 AMA&#xff0c;讨论重新启动游戏的相关内容。 感谢大家在百忙之中参与这次活动。相信社区的每一位成员都在蓝精灵协会这个项目中投资了一些东西&#xff0c;比如时间、精力或者是金钱。蓝精灵协会团队在过去的…

docker打包流程

docker打包流程 1、使用docker前置准备&#xff1a; 电脑下载docker桌面版&#xff0c;以及开启虚拟机步骤&#xff1a;https://blog.csdn.net/qq_34905631/article/details/126573826下载docker桌面版 &#xff1a;https://docs.docker.com/desktop/install/windows-install…

swagger-codegen智能生成Python-unittest测试用例

简介&#xff1a;Swagger Codegen是一个开源项目&#xff0c;用于从OpenAPI规范&#xff08;以前称为Swagger规范&#xff09;文件生成服务器存根、客户端库和API文档。它支持多种编程语言和框架&#xff0c;包括Python、Java、Ruby、Go等。 历史攻略&#xff1a; sanic&…

快速打造高效代驾服务:代驾系统源码分享

要想快速打造高效代驾服务&#xff0c;选择一款优秀的代驾系统是非常重要的。本文介绍的代驾系统源码是基于PHP语言和MySQL数据库开发的&#xff0c;可以轻松地在Linux或Windows系统中部署。 首先&#xff0c;需要确保服务器环境符合系统的要求&#xff0c;包括PHP版本、MySQL版…

三范式(详解+例子)

第一范式&#xff08;1NF&#xff09;&#xff1a;每一列都是不可分割的原子数据项&#xff08;什么意思&#xff0c;每一项都不可分割&#xff0c;像下面的表格就能分割&#xff0c;所以它连第一范式都算不上&#xff09; 分割后的样子 &#xff08;它就是第一范式了&#xff…

crm项目bug小结

项目主要内容分析&#xff1a; 第一天完成了系统用户登录、退出、密码修改、全局异常、非法请求与记住我等系统基本功能。 项目的目录结构如图&#xff1a; 1 登录思路&#xff1a; ** * 1.参数校验 * 用户名 非空 * 密码 非空 * 2.根据用户名 查询用户记录 * 3.校验用户存…

搞懂 API ,API 中 URI 设计规范分享

API&#xff08;Application Programming Interface&#xff09;是现代软件开发中的一项关键技术&#xff0c;它为不同应用程序间提供了数据和功能交互的标准化方式。而 URI&#xff08;Uniform Resource Identifier&#xff09;作为 API 中的重要部分&#xff0c;其规范和良好…

BigCode开放性能超越Copilot的代码生成模型Starcoder

BigCode释出高效能程式码生成模型StarCoderBase&#xff0c;与为Python调校的StarCoder&#xff0c;效能超越GitHub Copilot初期版本所用的OpenAI code-cushman-001模型&#xff1a; BigCode昨晚发布了基于源代码和自然语言文本训练的编程语言生成模型StarCoder。其训练数据包…

JavaSE基础(五)—— 方法(定义、调用、重载)、return关键字

目录 一、方法定义、调用 1. 方法完整的定义形式、调用 2. 方法的其他定义形式、调用 二、方法使用的常见问题 三、方法案例 1. 定义方法的技巧、计算 1- n的和返回 2. 数组求最值案例改方法形式 四、方法调用的内存图 五、方法的参数传递机制 基本类型和引用类型的参…

携带信息的Ajax GET请求

前端页面代码&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>ajax get请求</title><script type"text/javascript">window.onload function () {document.getEle…

Spring管理数据库事务

Spring编程式事务和声明式事务的验证 1、工程目录pom.xml 2、在resources目录创建配置文件applicationContext_1.xmlapplicationContext_2.xmlapplicationContext_3.xmljdbc.properties 3、创建数据表accountaccount 4、创建dao类5、创建service类6、创建测试类7、实验结果图1 …

基于python的点云处理库总结

想对于PCL&#xff0c;python处理点云的库还是比较多的&#xff0c;下面对此进行简单的总结&#xff1a; 一、Open3D A Modern Library for 3D Data Processing&#xff0c;Intel出品&#xff0c;MIT协议。 Open3D是一个支持3D数据处理软件快速开发的开源库。Open3D使用C和P…