深度学习---从入门到放弃(七)CNN进阶,迁移学习

article/2025/9/29 22:03:48

深度学习—从入门到放弃(七)CNN进阶,迁移学习

引入

图像是高维的。即image_length* image_width*image_channels是一个很大的数字,而上一教程里所提到的CNN的权值共享便是一种解决图像和其他领域高维问题的方法。
在这里插入图片描述
从上图中可以看出现代卷积神经网络主要被用于各类图像识别和捕捉,而这些应用也归功于我们之后要讲到的Large-scale CNNs以及迁移学习了。

在CNN网络结构的演化上,出现过许多优秀的CNN网络,本文的目的就是带大家了解现代卷积神经网络的发展历程,本文主要关注以下四种网络:LeNet,AlexNet,VGG-Net,ResNets。

1.有关卷积神经网络的回顾

在这里插入图片描述
卷积可以被简单的理解为在过滤器(filter)的基础上对于我们图像的卷积运算,即通过一个滑动的filter,计算filter与滑动窗口内像素矩阵的点积,从而生成一个带有某一种空间特征的输出项,而在这之中的权值共享可以大大减少模型参数的个数,从而降低计算负担。
在这里插入图片描述
上图是模拟一个大小为 H ∗ W H*W HW且有in个channel的图像的卷积过程,可以发现通过卷积生成了out个filter并且输出大小也发生了改变(a new H ∗ W ∗ o u t H*W*out HWout “image”)

2.CNN 经典网络结构

2.1 AlexNet

AlexNet 可以说标志着当前深度学习时代的开始。它融合了当今成功 DL 的许多定义特征:深度网络、GPU 驱动的并行化和编码特定任务先验的构建块。
在这里插入图片描述
AlexNet加入了 (1)非线性激活函数:ReLU;利用ReLU进行训练时训练速度明显优于tanh(2)防止过拟合的方法:随机Dropout,Data augmentation。同时,使用多个GPU,LRN归一化层。

2.2 VGG

在这里插入图片描述
VGG-Net使用更多的层,通常有16-19层,而AlexNet只有8层。同时,VGG-Net的所有 convolutional layer 使用同样大小的 convolutional filter,大小为 3 x 3。

2.3 残差网络 (ResNets)

ResNet

在这里插入图片描述
ResNet提出了一种减轻网络训练负担的残差学习框架,这种网络比以前使用过的网络本质上层次更深。

ResNet 有两个特别有趣的特性。首先,它使用跳过连接来避免梯度消失问题。其次,ResNet 中的每个块(层的集合)都可以被视为学习残差函数。

在数学上,神经网络可以被认为是将输入(如狗的图像)映射到输出(如标签“狗”)的一系列操作。在数学上,从输入到输出的映射称为函数。神经网络是表达该功能的灵活方式。

如果你要从网络学习的函数中减去将图像映射到类标签的真实函数,则会留下残差或“残差函数”。ResNets 尝试学习原始函数,然后是残差函数,然后是残差的残差,依此类推,使用它们的残差块并将它们添加到前面层的输出中。

ResNeXt

在这里插入图片描述
ResNeXt通过添加路径的方式可以做到进一步节省参数。

2.4 MobileNet

在这里插入图片描述
另一种降低大型模型计算成本的方法是使用深度可分离卷积。深度可分离卷积是使MobileNets高效的关键组件。它可以进一步降低计算复杂度,减少参数。

  • 它的核心思想是将一个完整的卷积运算分解为两步进行,分别为Depthwise Convolution(逐深度卷积)与Pointwise Convolution(逐点1*1卷积)。

3.迁移学习

在实践中训练大图像模型的最常见方式是通过迁移学习。首先在像 ImageNet 这样的大型分类数据集上预训练网络,然后使用该网络的权重作为初始化(“微调”)。

3.1 加载数据

import zipfile, io# original link: https://github.com/ben-heil/cis_522_data.git
url = 'https://osf.io/u4njm/download'fname = 'small_pokemon_dataset'if not os.path.exists(fname+'zip'):print("Data is being downloaded...")r = requests.get(url, stream=True)z = zipfile.ZipFile(io.BytesIO(r.content))z.extractall()print("The download has been completed.")
else:print("Data has already been downloaded.")

在这里插入图片描述
在这里我们引入一个具有9个宝可梦类别的图像数据集。

3.2 微调 ResNet

在计算机视觉中,采用在大型数据集(通常是 ImageNet)上训练的大型模型,替换分类层并对整个网络进行微调以执行不同的任务是很常见的。

在这里,我们将使用预训练的 ResNet 模型对 Pokemon 的类型进行分类。

resnet = torchvision.models.resnet18(pretrained=True)
num_ftrs = resnet.fc.in_features
# 将全连接层中类别标签个数改为9
resnet.fc = nn.Linear(num_ftrs, num_classes)
resnet.to(DEVICE)
#对于网络中是所有权值进行微调
optimizer = torch.optim.Adam(resnet.parameters(), lr=1e-4)#优化器为Adam
loss_fn = nn.CrossEntropyLoss()#交叉熵损失为目标函数

下面的示例代码则为进行迁移训练后的模型效果评估

pretrained_accs = []
for epoch in range(10):# Train loopfor batch in pokemon_train_loader:images, labels = batchimages = images.to(DEVICE)labels = labels.to(DEVICE)#梯度下降optimizer.zero_grad()output = resnet(images)loss = loss_fn(output, labels)loss.backward()optimizer.step()#训练效果评估with torch.no_grad():loss_sum = 0total_correct = 0total = len(pokemon_test_set)for batch in pokemon_test_loader:images, labels = batchimages = images.to(DEVICE)labels = labels.to(DEVICE)output = resnet(images)loss = loss_fn(output, labels)loss_sum += loss.item()predictions = torch.argmax(output, dim=1)num_correct = torch.sum(predictions == labels)total_correct += num_correct# Plot accuracypretrained_accs.append(total_correct / total)plt.plot(pretrained_accs)plt.xlabel('epoch')plt.ylabel('accuracy')plt.title('Pokemon prediction accuracy')IPython.display.clear_output(wait=True)IPython.display.display(plt.gcf())plt.close()

在这里插入图片描述

3.3 仅训练分类层

利用迁移学习的另一种可能方法是采用预先训练的模型并替换最后一层,即分类层(有时也称为“linear readout”)。我们没有像以前那样对整个模型进行微调,而是只训练分类层。

resnet = torchvision.models.resnet18(pretrained=True)
for param in resnet.parameters():param.requires_grad = False#锁定了网络中其他权值的梯度下降
num_ftrs = resnet.fc.in_features
# 将全连接层中类别标签个数改为9
resnet.fc = nn.Linear(num_ftrs, num_classes)
resnet.to(DEVICE)
optimizer = torch.optim.Adam(resnet.fc.parameters(), lr=1e-2)#这里只对分类层权值进行梯度下降
loss_fn = nn.CrossEntropyLoss()#交叉熵损失为目标函数

在这里插入图片描述

3.4 从头开始训练 ResNet

我们还可以从头开始训练ResNet,即:随机初始化权重并专门在 Pokemon 数据集上训练整个网络。

resnet = torchvision.models.resnet18(pretrained=False)#在Pokemon数据集上训练整个网络
num_ftrs = resnet.fc.in_features
# 将全连接层中类别标签个数改为9
resnet.fc = nn.Linear(num_ftrs, num_classes)
resnet.to(DEVICE)
optimizer = torch.optim.Adam(resnet.parameters(), lr=1e-4)loss_fn = nn.CrossEntropyLoss()

在这里插入图片描述

3.5 三种训练方式的比较

在这里插入图片描述

  • Pretrained ResNet vs Trained from Scratch(从头开始训练)的 ResNet:
  1. 预训练数据和目标数据越接近,Pretrained ResNet训练效果越好
  2. 预训练数据越多,Pretrained ResNet预训练效果越好
  3. Pretrained ResNet可能会导致学习到无用的特征
  • fine-tuning(微调整个网络)vs linear Readout(只训练分类层):
    1.因为只训练了一层,所以linear Readout训练过程更快/计算成本更低
    2.更多的权值调整可能意味着fine-tuning更好的训练效果

欢迎大家关注公众号奇趣多多一起交流!
在这里插入图片描述
深度学习—从入门到放弃(一)pytorch基础
深度学习—从入门到放弃(二)简单线性神经网络
深度学习—从入门到放弃(三)多层感知器MLP
深度学习—从入门到放弃(四)优化器
深度学习—从入门到放弃(五)正则化
深度学习—从入门到放弃(六)CNN入门


http://chatgpt.dhexx.cn/article/9mWv3SSO.shtml

相关文章

【傻瓜攻略】深度学习之从入门到放弃

从研究生进来之后,一直到现在已经进行了一年关于DP的学习,写篇文章总结一下我蹒跚的学习过程。总结来说是一个从入门学习到几乎想要放弃的过程。顺带列举下面几个坑,希望能帮助一下同样在这条路上行走的旅人们。 1、overfitting这个东西 很…

android异步编程,使用RxAndroid处理异步任务

欢迎Follow我的GitHub, 关注我的简书. 其余参考Android目录. Demo Android Rx是响应式编程的意思, 本质是观察者模式, 是以观察者(Observer)和订阅者(Subscriber)为基础的异步响应方式. 在Android编程时, 经常会使用后台线程, 那么就可以使用这种方式. 目前的异步编程方式都会导…

RxAndroid 入门笔记

参考链接: http://gank.io/post/560e15be2dca930e00da1083#toc_10 https://mcxiaoke.gitbooks.io/rxdocs/content/Observables.html http://blog.chengyunfeng.com/?p948 http://www.apkbus.com/blog-705730-62567.html 要了解RxAndroid,必须先要了解RxJava,应…

【Rxandroid】Rxandroid源码解读

目录 1.AndroidSchedulers类的源码 2.RxAndroidPlugins类的源码 3.RxAndroidSechedulersHook类的源码 4.LooperScheduler类的源码 5.HandlerScheduler类的源码 6.BuildConfig类的源码 7.MainThreadSubscription类的源码 总结 将Rxandroid(1.2.1)…

Retrofit + RxAndroid 实践总结

在接入 Retrofit RxAndroid 之前,项目代码中主要存在如下问题: 服务器 API 的定义方式不一致,有的集中定义,有的定义在业务代码中,没有分类不便于维护。Request / Response / API 三者没有对应关系(Reque…

Rxjava3 RxAndroid

文章目录 Rxjava && Rxandroid引用方式 概念流程图代码示例ObservableObservable#subscribeOn(NonNull Scheduler scheduler)Observable#observeOn(NonNull Scheduler scheduler)ObservableSubscribeOnObservableObserveOn本文开头的代码示例等同于如下代码 Schedulers…

RxJava和RxAndroid学习记录

目录 1 概念和说明 1.1 响应式编程 1.2 RxJava 1.3 关于RxJava和RxAndroid 1.4 关于响应式编程和普通编程 2. 基本使用 2.1 基本元素关系图 2.2 代码示例: 2.3 关于subscribe() 2.4 线程调度 2.4.1 线程调度 2.4.2 RxJava内置的常用…

RxAndroid的基础使用

作为一个android开发者,在开发应用的过程中避免不了异步这个问题。android系统为我们提供了Handler这个类帮助我们进行线程间的通信和切换,但是GitHub上也有很多其他非常优秀的开源框架来帮助我们进行异步处理,比如今天学习的RxAndroid。 简…

rxandroid 基础知识

概述 在Android 中, 使用 rxandroid , rxandroid和rxJava的关系是,rxandroid包 依赖rxJava包,在其功能上增加了一些Android特有功能,项目中如果不需要指定rxJava包的版本,只需引入rxandroid包即可,如果需要更改 rxandroid包中默认的rxJava包版本 , 在项目中引入指定的rxJava包即…

RxAndroid使用初探;简洁、优雅、高效

引言 RxAndroid是一个开发库、是一种代码风格、也是一种思维方式。 正如标题所言,RxAndroid的特点是简洁、优雅、高效,它的优点是多线程切换简单、数据变换容易、代码简洁可读性好、第三方支持丰富易于开发;缺点是学习成本较高、出错难以排查。 用途与优势 起源 RxAndroid…

RxAndroid的学习和研究

1.什么是RxAndroid RxAndroid的含义为响应式编程,Rx含义是响应式编程,其本质就是观察者模式,以观察者(Observer)和订阅者(Subscriber)为基础的异步响应方式。    Observables发出一系列事件&a…

linux基本功系列之dd命令实战

文章目录 前言🚀🚀🚀一. dd 命令介绍二. 语法格式及常用选项三. 参考案例3.1 创建指定大小的文件3.2 清空磁盘数据3.3 给磁盘做备份还原3.4 把光盘拷贝到root下3.5 内存不足的处理方法 四. 文中出现的概念解释swapon命令介绍4.2 /dev/zero 介…

Linux系统中dd命令用法详解

命令介绍: Linux dd 命令用于读取、转换并输出数据。dd 可从标准输入或文件中读取数据,根据指定的格式来转换数据,再输出到文件、设备或标准输出。 参数介绍 if 代表输入文件。如果不指定 if,默认就会从 stdin 中读取输入。of …

dd 命令详解

dd命令是Linux/Unix下的一个很常见的文件拷贝工具。 我们先列下dd命名的常用的参数,再详细分析: bsBYTES read and write up to BYTES bytes at a time cbsBYTES convert BYTES bytes at a time convCONVS convert the file as pe…

dd命令使用总结

dd命令介绍 dd是Linux下一个非常有用的命令,该命令用于读取、转换并输出数据;dd命令在Android shell下也支持使用。 语法格式: dd [option]dd指令选项详解 iffile:输入文件名,缺省为标准输入 offile:输…

dd命令相关整理

对于一个软件测试人员而言,工作开展前就是准备自己的测试环境,那么重装系统就是首当其冲的一个必备技能。最近因为手边工作环境没有windows的系统,所以没有条件利用软碟通这类刻录软件直接刻录启动盘。被逼无奈之下用命令来刻录,整…

Linux:shell 脚本 自动解压压缩文件tar.gz到指定目录

具体情境 Ubuntu16.04系统,将.tar.gz格式的文件从/home/myftp/upload/nuodongiot目录自动解压到/home/myftp/upload/backupcopy目录中,并将源目录/home/myftp/upload/nuodongiot中的文件移动至/home/myftp/upload/extarct目录中 该过程进行单个文件进行…

tar解压文件至指定目录,不包含原目录

1、tar解压文件至指定目录,不包含原目录 要解压的压缩包原目录结构如下 tar -zxf log.tar.gz --strip-components 1 -C /opt/new_test注: --strip-components 1 解压至下一级目录,若为2则解压至下下级目录 2、压缩只指定的目录&#xff0c…

linux gz解压 指定目,linux解压tar.gz到指定文件夹或目录

1. 前言 本文主要讲解如何解压tar.gz到指定文件夹或目录,tar是Linux系统上的一种打包与压缩工具。 2. linux解压tar文件使用案例 Linux下使用tar命令把当前目录下的zcwyou.tar.gz解压到指定的目录/123/abc/ ,前提要保证存在/123/abc/这个目录。 [root@zcwyou ~]# tar -zxvf zc…

Linux tar 命令 将归档内指定文件解压到指定目录

首先介绍一下 tar 命令: 用途:打包文件(制作归档文件)、释放归档文件 格式: tar [选项]... 归档文件名 源文件或目录 tar [选项]... 归档文件名 [-C 目标目录] 常用命令选项: -c 创建 .tar 格式…