CNN——AlexNet

1.AlexNet概述

论文原文:ImageNet Classification with Deep Convolutional Neural Networks

        在LeNet提出后,卷积神经网络在计算机视觉和机器学习领域中很有名气。但卷积神经网络并没有主导这些领域。这是因为虽然LeNet在小数据集上取得了很好的效果,但是在更大、更真实的数据集上训练卷积神经网络的性能和可行性还有待研究。事实上,在上世纪90年代初到2012年之间的大部分时间里,神经网络往往被其他机器学习方法超越,如支持向量机(support vector machines)。

        虽然上世纪90年代就有了一些神经网络加速卡,但仅靠它们还不足以开发出有大量参数的深层多通道多层卷积神经网络。此外,当时的数据集仍然相对较小。除了这些障碍,训练神经网络的一些关键技巧仍然缺失,包括启发式参数初始化、随机梯度下降的变体、非挤压激活函数和有效的正则化技术。

        2012年,AlexNet横空出世。它首次证明了深度卷积神经网络学习到的特征可以超越手工设计的特征。它一举打破了计算机视觉研究的现状。 AlexNet使用了8层卷积神经网络,并以很大的优势赢得了2012年ImageNet图像识别挑战赛。

AlexNet和LeNet的设计理念非常相似,但也存在显著差异。

  1. AlexNet比相对较小的LeNet5要深得多。AlexNet由八层组成:五个卷积层、两个全连接隐藏层和一个全连接输出层。

  2. AlexNet使用ReLU而不是sigmoid作为其激活函数。ReLU 能够在保持计算速度的同时,有效地解决了梯度消失问题,从而使得训练更加高效

  3. 局部响应归一化(Local response nomalization,LRN)。后来发现没什么用。

  4. 在全连接层使用了dropout用于正则化

  5. 分布式训练。在当时GPU性能并不高,内存比较小,AlexNet在使用GPU进行训练时,可将卷积层和全连接层分别放到不同的GPU上进行并行计算,从而大大加快了训练速度。

        整个网络结构图如下,网络结构被切割为两部分,每个GPU单独计算一半的通道数,其中会互相通信两次。输入尺寸是227,224是论文中写错了。

        当然从现在的计算资源来看,AlexNet是一个非常简单的神经网络,已经不再需要分到2个GPU上并行计算了,于是网络结构可以简化如下

2.网络结构详解

1.输入层。227 × 227 × 3,三通道RGB图像

2.C1

  1. 卷积。96个11×11×3的卷积核,padding = 0,stride = 4。特征图尺寸为((227-11)/4)+1=55,得到输出55×55×96的特征图
  2. ReLU激活
  3. 最大池化。核大小为3×3,padding = 0,stride = 2,特征图尺寸为((55-3)/2)+1=27,得到输出27×27×96的特征图

3.C2

  1. 卷积。256个5×5×96的卷积核,padding = 2,stride = 1。特征图尺寸为((27-5+2×2)/1)+1=27,得到输出27×27×256的特征图
  2. ReLU激活
  3. 最大池化。核大小为3×3,padding = 0,stride = 2,特征图尺寸为((27-3)/2)+1=13,得到输出13×13×256的特征图

4.C3

  1. 卷积。384个3×3×256的卷积核,padding = 1,stride = 1。特征图尺寸为((13-3+2×1)/1)+1=13,得到输出13×13×384的特征图
  2. ReLU激活

5.C4

  1. 卷积。384个3×3×384的卷积核,padding = 1,stride = 1。特征图尺寸为((13-3+2×1)/1)+1=13,得到输出13×13×384的特征图
  2. ReLU激活

6.C5

  1. 卷积。256个3×3×384的卷积核,padding = 1,stride = 1。特征图尺寸为((13-3+2×1)/1)+1=13,得到输出13×13×256的特征图
  2. ReLU激活
  3. 最大池化。核大小为3×3,padding = 0,stride = 2,特征图尺寸为((13-3)/2)+1=6,得到输出6×6×256的特征图

7.全连接层FC6

  1. 全局平均池化然后展平。
  2. 全连接,6×6×256–>>1×1×4096,并使用Dropout,随机50%神经元弃用
  3. ReLU激活

8.全连接层FC7

  1. 全连接,1×1×4096–>>1×1×4096,并使用Dropout,随机50%神经元弃用
  2. ReLU激活

9.全连接层FC8

        全连接,1×1×4096–>>1×1×1000。1000是ImageNet1000个分类类别

3.AlexNet实现CIFAR-10分类

1.读取数据集

        CIFAR-10数据集是32*32尺寸的,但AlexNet网络结构是针对ImageNet大尺寸设计的,但ImageNet数据集作为简单实践的话又太大了。这里直接简单的将图片拉大,但实际上这并不是一个好的操作,这里只是简单实践,毕竟AlexNet现在并不常使用。

# 数据预处理
transform = transforms.Compose([transforms.Resize((224, 224)),  # AlexNet接受224x224的输入transforms.ToTensor(),transforms.Normalize((0.485, 0.456, 0.406), (0.229, 0.224, 0.225)),
])# 加载CIFAR-10数据集
train_dataset = datasets.CIFAR10(root='./dataset', train=True, download=True, transform=transform)
test_dataset = datasets.CIFAR10(root='./dataset', train=False, download=True, transform=transform)# 数据加载器
train_dataloader = DataLoader(train_dataset, batch_size=64, shuffle=True)
test_dataloader = DataLoader(test_dataset, batch_size=64, shuffle=False)

        这个归一化的数据来源于ImageNet数据集百万张统计得到,通常可以作为一般数据集的归一化标准。当然也可以针对自己数据集重新计算均值和标准差用于归一化。

2.搭建AlexNet

        dropout默认是0.5的概率,用于全连接之间

class AlexNet(nn.Module):def __init__(self, num_classes=1000):super(AlexNet, self).__init__()self.features = nn.Sequential(nn.Conv2d(3, 64, kernel_size=11, stride=4, padding=2),nn.ReLU(inplace=True),nn.MaxPool2d(kernel_size=3, stride=2),nn.Conv2d(64, 192, kernel_size=5, padding=2),nn.ReLU(inplace=True),nn.MaxPool2d(kernel_size=3, stride=2),nn.Conv2d(192, 384, kernel_size=3, padding=1),nn.ReLU(inplace=True),nn.Conv2d(384, 256, kernel_size=3, padding=1),nn.ReLU(inplace=True),nn.Conv2d(256, 256, kernel_size=3, padding=1),nn.ReLU(inplace=True),nn.MaxPool2d(kernel_size=3, stride=2),)self.classifier = nn.Sequential(nn.Dropout(),nn.Linear(256 * 6 * 6, 4096),nn.ReLU(inplace=True),nn.Dropout(),nn.Linear(4096, 4096),nn.ReLU(inplace=True),nn.Linear(4096, num_classes),)def forward(self, x):x = self.features(x)x = torch.flatten(x, 1)x = self.classifier(x)return x# 打印模型结构
model = AlexNet().to(device)
summary(model, (3, 227, 227))

3.使用GPU 

device = 'cuda' if torch.cuda.is_available() else 'cpu'

4.模型训练

def train(model, lr, epochs, train_dataloader, device, save_path):# 将模型放入GPUmodel = model.to(device)# 使用交叉熵损失函数loss_fn = nn.CrossEntropyLoss().to(device)# SGDoptimizer = torch.optim.SGD(model.parameters(), lr=lr, weight_decay=5e-4, momentum=0.9)# 记录训练与验证数据train_losses = []train_accuracies = []# 开始迭代   for epoch in range(epochs):   # 切换训练模式model.train()  # 记录变量train_loss = 0.0correct_train = 0total_train = 0# 读取训练数据并使用 tqdm 显示进度条for i, (inputs, targets) in tqdm(enumerate(train_dataloader), total=len(train_dataloader), desc=f"Epoch {epoch+1}/{epochs}", unit='batch'):# 训练数据移入GPUinputs = inputs.to(device)targets = targets.to(device)# 模型预测outputs = model(inputs)# 计算损失loss = loss_fn(outputs, targets)# 梯度清零optimizer.zero_grad()# 反向传播loss.backward()# 使用优化器优化参数optimizer.step()# 记录损失train_loss += loss.item()# 计算训练正确个数_, predicted = torch.max(outputs, 1)total_train += targets.size(0)correct_train += (predicted == targets).sum().item()# 计算训练正确率并记录train_loss /= len(train_dataloader)train_accuracy = correct_train / total_traintrain_losses.append(train_loss)train_accuracies.append(train_accuracy)# 输出训练信息print(f"Epoch [{epoch + 1}/{epochs}] - Train Loss: {train_loss:.4f}, Train Acc: {train_accuracy:.4f}")# 绘制损失和正确率曲线plt.figure(figsize=(10, 5))plt.subplot(1, 2, 1)plt.plot(range(epochs), train_losses, label='Training Loss')plt.xlabel('Epoch')plt.ylabel('Loss')plt.legend()plt.subplot(1, 2, 2)plt.plot(range(epochs), train_accuracies, label='Accuracy')plt.xlabel('Epoch')plt.ylabel('Accuracy')plt.legend()plt.tight_layout()plt.show()torch.save(model.state_dict(), save_path)
model = AlexNet(num_classes=10) # 十分类
lr = 0.01 
epochs = 10
save_path = './modelWeight/AlexNet_CIFAR10'
train(model,lr,epochs,train_dataloader,device,save_path)

        这里只训练了10个epoch,也没有使用验证集调参,仅仅是简单实践而已。可以看到损失还在不断降低,还没收敛。

5.模型测试

def test(model, test_dataloader, device, model_path):# 将模型设置为评估模式model.eval()# 将模型移动到指定设备上model.to(device)# 从给定路径加载模型的状态字典model.load_state_dict(torch.load(model_path))correct_test = 0total_test = 0# 不计算梯度with torch.no_grad():# 遍历测试数据加载器for inputs, targets in test_dataloader:  # 将输入数据和标签移动到指定设备上inputs = inputs.to(device)targets = targets.to(device)# 模型进行推理outputs = model(inputs)# 获取预测结果中的最大值_, predicted = torch.max(outputs, 1)total_test += targets.size(0)# 统计预测正确的数量correct_test += (predicted == targets).sum().item()# 计算并打印测试数据的准确率test_accuracy = correct_test / total_testprint(f"Accuracy on Test: {test_accuracy:.4f}")return test_accuracy
model_path = './modelWeight/AlexNet_CIFAR10'
test(model, test_dataloader, device, save_path)

6.使用Pytorch自带的AlexNet

        Pytorch有官方实现的AlexNet以及它在ImageNet上预训练好的权重,如果数据集的分类类别都在ImageNet中存在,而且想快速训练,可以使用预训练好的权重。地址:alexnet — Torchvision main documentation (pytorch.org)

        此外还需要修改最后一层全连接层的输出数目

from torchvision import models
# 初始化预训练的AlexNet模型
modelPre = models.alexnet(weights=models.AlexNet_Weights.DEFAULT)
num_ftrs = modelPre.classifier[6].in_features
modelPre.classifier[6] = nn.Linear(num_ftrs, 10)  # CIFAR-10有10个类别
modelPre = modelPre.to(device)
summary(modelPre, (3, 227, 227))

        .DEFAULT就是使用默认最新最好的预训练权重,直接指定weights=models.AlexNet_Weights.IMAGENET1K_V1也是一样的,因为AlexNet在pytroch中只有一个权重,其他模型会有多个版本权重可以在官方文档中看。

        如果只想使用他的模型而不使用预训练权重,直接不设定这个参数就可以了。

        可以看到除了多了个全局平均池化,其他都和我们自己写的是一样的。因为AlexNet出来的时候并没有全局平均池化这个操作,不过现在在过度卷积和全连接都是这么做的。

lr = 0.01 
epochs = 10
save_path = './modelWeight/AlexNetPreTrain_CIFAR10'
train(modelPre,lr,epochs,train_dataloader,device,save_path)

        可以看到收敛更快 

lr = 0.01 
epochs = 10
save_path = './modelWeight/AlexNetPreTrain_CIFAR10'
train(modelPre,lr,epochs,train_dataloader,device,save_path)

 

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

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

相关文章

C#: Label、TextBox 鼠标停留时显示提示信息

说明:记录在 Label、TextBox 控件上 鼠标停留时显示提示信息的方法。 1.效果图 2.具体实现步骤 1. 在Form 窗口中先创建 Label 并取名:KEY_label ,或 TextBox 取名:KEY_textBox 在 Form1 函数中添加初始化代码,如下&…

ssm基于web的素材网的设计与实现+vue论文

基于web的素材网站的设计与实现 摘要 当下,正处于信息化的时代,许多行业顺应时代的变化,结合使用计算机技术向数字化、信息化建设迈进。传统的素材信息管理模式,采用人工登记的方式保存相关数据,这种以人力为主的管理…

C#中使用 async await TaskCompletionSource<T>实现异步逻辑同步写

Task、async 和 await 是 C# 中用于处理异步编程的关键概念。它们一起构成了异步编程的基础。 Task Task 是表示异步操作的抽象,它属于 System.Threading.Tasks 命名空间。Task 可以表示已经完成的任务、正在运行的任务或者尚未开始的任务。通过 Task,…

你的第一个C/S程序

目录 socket服务端代码客户端代码执行结果 socket socket基础知识 服务端代码 import socket import threading import timeMSG_LENGTH 64 DISCONNECTED !CONNECTION CLOSED connections 0#定义服务器地址 server_ip socket.gethostbyname(socket.gethostname()) server…

【设计模式之美】面向对象分析方法论与实现(二):需求到接口实现的方法论

文章目录 一. 进行面向对象设计1. 划分职责>需要有哪些类2. 定义类及其属性和方法3. 定义类与类之间的交互关系4. 将类组装起来并提供执行入口 二. 如何进行面向对象编程?1. 接口实现2. 辩证思考与灵活应用 【设计模式之美】面向对象分析方法论与实现&#xff08…

教育场景数字化中音视频小程序的发展

教育场景数字化逐步成为刚需 2018年以来,国家对在线教育行业的监管收紧,以及受益于 5G 技术的发展,教育科技逐步走向成熟化和规范化。 教育行业的本质是人与人(老师与学生、老师与家长,以及更多角色直接的沟通与互动…

【数据结构和算法】小行星碰撞

其他系列文章导航 Java基础合集数据结构与算法合集 设计模式合集 多线程合集 分布式合集 ES合集 文章目录 其他系列文章导航 文章目录 前言 一、题目描述 二、题解 2.1 什么情况会用到栈 2.2 方法一:模拟 栈 三、代码 3.1 方法一:模拟 栈 四…

【LLM+RS】LLM在推荐系统的实践应用(华为诺亚)

note LLM用于推荐主要还是解决推荐系统加入open domain 的知识。可以基于具体推荐场景数据做SFT。学习华为诺亚-技术分享-LLM在推荐系统的实践应用。 文章目录 note一、背景和问题二、推荐系统中哪里使用LLM1. 特征工程2. 特征编码3. 打分排序 三、推荐系统中如何使用LLM四、挑…

共享WiFi贴项目加盟可以解决商家哪些痛点?

近年来,共享WiFi贴项目在共享商业领域引起了广泛关注。作为一种便捷的网络分享工具,共享WiFi贴不仅受到很多人的青睐,更能够为商家带来诸多实际利益。那么,共享WiFi贴项目加盟究竟可以解决商家哪些痛点呢? 共享WiFi贴为…

【C#】知识点实践序列之Lock的锁定代码块

大家好,我是全栈小5,欢迎来到《小5讲堂之知识点实践序列》文章。 2024年第1篇文章,此篇文章是C#知识点实践序列之Lock知识点,博主能力有限,理解水平有限,若有不对之处望指正! 本篇验证Lock锁定代…

Navicat(数据库可视化软件)安装教程以及连接MYSQL

Navicat安装教程以及连接MYSQL Navicat(数据库可视化软件)安装流程安装MySQLnavicat连接mysql数据库 Navicat(数据库可视化软件) Navicat 是一款专门为 MySQL 设计的可视化数据库 GUI 管理工具,我们可以在自己的计算机…

深入浅出Python日志打印

0.引言 在编程过程中,日志记录是一项非常重要的任务,无论是用于调试代码、记录系统运行状态,还是跟踪可能出现的问题,日志都能发挥重要作用。然而,许多开发者习惯使用简单的print语句来记录信息,这种方法虽…

ensp vlan连接(详细)

1.将需要的设备放置好 2.将设备连接起来 3.启动所有设备 4.备注好每台PC机的信息 5.配置好每台PC机 6.配置交换机1 进入配置视图,关闭信息提示 重命名设备 批量创建VLAN 开始配置接口 更改接口类型为ACCESS 将接口划分到对应的VLANN 配置下一个接口,步…

编译 nccl-tests 项目

1,编译 下载源代码 git clone --recursive https://github.com/NVIDIA/nccl-tests.git 编译源代码 cd nccl-tests/ make -j 2,运行 cd ./build/ ./all_reduce_perf --help ./all_reduce_perf -b 8 -e 256M -f 2 -g 4 效果图: 3&#…

说说产品经理能力模型

产品经理的能力模型应该是什么样的,可能100个产品人会有100种看法,每个人的认知都是不一样的,今天和大家分享下我对产品经理能力模型的总结。 前段时间,一个30多岁做前端开发的朋友跟我说想转行做产品,让我帮忙指导下…

关于Python里xlwings库对Excel表格的操作(三十)

这篇小笔记主要记录如何【如何使用“Chart类”、“Api类"和“Axes函数”为新图表设置标题文本内容、字体、字号、粗细、正斜、颜色、坐标轴主要网格线】。前面的小笔记已整理成目录,可点链接去目录寻找所需更方便。 【目录部分内容如下】【点击此处可进入目录】…

Maple 各版本安装指南

Maple 下载链接 https://pan.baidu.com/s/11hKo1XxZGa0xv3Ivj6fbEA?pwd0531 1.鼠标右击【Maple 2023】压缩包(win11及以上系统需先点击“显示更多选项”)【解压到 Maple 2023】。 2.打开解压后的文件夹,鼠标右击【Setup】选择【以管理员身…

计算机毕业设计------SSM的公寓房屋出租系统

项目介绍 该项目分为前后台,分为普通用户与管理员两种角色。 前台主要功能包括: 普通用户的注册、登录,房屋列表展示,租房,我的订单、用户中心等功能模块; 后台主要功能包括: 系统设置:菜单管…

航空业数字化展翅高飞,开源网安专业服务保驾护航

​某知名航空公司是中国首批民营航空公司之一,运营国内外航线200多条,也是国内民航最高客座率的航空公司之一。在数字化发展中,该航空公司以数据驱动决策,通过精细化管理、数字创新和模式优化等方式,实现了精准营销和个…

day58算法训练|单调栈part01

参考:代码随想录 单调栈的使用情况: 通常是一维数组,要寻找任一个元素的右边或者左边第一个比自己大或者小的元素的位置,此时我们就要想到可以用单调栈了。时间复杂度为O(n)。 单调栈的本质是空间换时间,因为在遍历…