热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Caffe实战(三):从零构建ResNet之网络架构详解

本文将详细介绍如何使用Caffe构建ResNet网络架构,重点在于网络各层的定义及其参数配置。我们将通过具体的代码示例,帮助读者理解ResNet的核心组件及其实现细节。

在前文中,我们已经完成了两个关键函数的定义,接下来我们将基于这些函数构建完整的 ResNet 网络。为了更好地理解网络的构建过程,我们再次回顾 ResNet 的结构表:



































层名

输出尺寸

20层 ResNet

Conv1

32 X 32

Kernel_size=3 X 3
Num_output = 16
Stride = 1
Pad = 1

Conv2_x

32 X 32

{3X3,16; 3X3,16} X 3

Conv3_x

16 X 16

{3X3,32; 3X3,32} X 3

Conv4_x

8 X 8

{3X3,64; 3X3,64} X 3

InnerProduct

1 X 1

Average pooling
10-d fc


在 Conv1 层中,我们对输入图像进行一次卷积处理。从 Conv2_x 到 Conv4_x,每个阶段包含 3 个残差块,每个块内的卷积核数量依次翻倍(16, 32, 64),同时特征图的尺寸逐渐减半(32, 16, 8)。尽管输入图像的实际尺寸可能是 28 X 28,但为了简化说明,我们假设输入图像的尺寸为 32 X 32。


大多数卷积层使用 3 X 3 的卷积核,且通常设置 padding 为 1,以保持输出尺寸与输入尺寸一致。例如,从 Conv1 到 Conv2_x,由于通道数相同,可以直接将输入和输出相加。然而,从 Conv2_x 到 Conv3_x,以及从 Conv3_x 到 Conv4_x,由于通道数不同且输出尺寸不同,我们采用了论文中提出的 B 方法,即使用 1 X 1 的卷积核来调整输入的维度,使其与输出匹配。这种设计确保了残差连接的有效性。


在 ResNet 的实现中,当投影步长(projection_stride)为 1 时,表示输入和输出的维度相同,可以直接相加;当投影步长为 2 时,则需要使用 1 X 1 的卷积核,步长设为 2,以使输出尺寸减半。以下是 ResNet 函数的一个示例实现:




图 14 展示了网络的结构图。


使用 draw_net.py 工具绘制网络结构图时,至少需要提供两个参数:prototxt 文件的路径和图像保存的位置。参数 --rankdir=TB 表示网络结构从上到下绘制,其他选项包括 BT、LR(从左到右)、RL。需要注意的是,某些高版本的 Caffe 可能会出现 ‘int’ object has no attribute '_values' 的错误,解决方法请参考:https://github.com/BVLC/caffe/issues/5324



图 15 显示了 draw_net.py 绘制的网络结构图。由于图像较长,这里仅展示了部分结构。接下来,我们需要生成 solver 的 prototxt 文件。


步骤 3:创建 solver 的 prototxt 文件


在 caffe-master/examples/pycaffe 目录下有一个 tools.py 文件,该文件可以帮助我们生成所需的 solver prototxt 文件。首先,在 /ResNet 目录下创建一个 tools 文件夹,并将 tools.py 文件复制到该文件夹中。为了确保系统能够找到 tools.py 文件,我们需要在 init_path.py 中添加以下代码:


tools_path = osp.join(this_dir, 'tools')
add_path(tools_path)

这样,ResNet/tools 路径就被添加到系统中,系统可以找到 tools.py 文件。接着,在 mydemo.py 文件的开头,在 import init_path 之后添加 import tools,以导入 tools.py 文件。最后,在 mydemo.py 文件的末尾,make_net() 函数之后添加以下代码:


# 将内容写入 res_net_model 文件夹中的 res_net_solver.prototxt
solver_dir = this_dir + '/res_net_model/res_net_solver.prototxt'
solver_prototxt = tools.CaffeSolver()
solver_prototxt.write(solver_dir)

生成的 res_net_solver.prototxt 文件包含了各种 solver 参数,如 base_lr(基础学习率)设置为 0.1,lr_policy 设置为 multistep 等。具体参数如下所示:


def __init__(self, testnet_prototxt_path=this_dir+"/../res_net_model/test.prototxt",
trainnet_prototxt_path=this_dir+"/../res_net_model/train.prototxt", debug=False):

self.sp = {}

# 关键参数
self.sp['base_lr'] = '0.1'
self.sp['momentum'] = '0.9'

# 速度相关
self.sp['test_iter'] = '100'
self.sp['test_interval'] = '500'

# 显示设置
self.sp['display'] = '100'
self.sp['snapshot'] = '2500'
self.sp['snapshot_prefix'] = '/home/your_name/ResNet/res_net_model/snapshot/snapshot'

# 学习率策略
self.sp['lr_policy'] = 'multistep'
self.sp['step_value'] = '32000'
self.sp['step_value1'] = '48000'

# 其他重要参数
self.sp['gamma'] = '0.1'
self.sp['weight_decay'] = '0.0001'
self.sp['train_net'] = '"' + trainnet_prototxt_path + '"'
self.sp['test_net'] = '"' + testnet_prototxt_path + '"'

# 很少更改的参数
self.sp['max_iter'] = '100000'
self.sp['test_initialization'] = 'false'
self.sp['average_loss'] = '25'
self.sp['iter_size'] = '1'

if debug:
self.sp['max_iter'] = '12'
self.sp['test_iter'] = '1'
self.sp['test_interval'] = '4'
self.sp['display'] = '1'

这些参数的设置依据论文中的推荐值。例如,基础学习率 base_lr 设为 0.1,学习率策略 lr_policy 设为 multistep,分别在 32000 和 48000 迭代次数时将学习率降低 10 倍。权重衰减 weight_decay 设为 0.0001,动量 momentum 设为 0.9。其他参数如 max_iter(最大迭代次数)、test_iter(测试迭代次数)、test_interval(测试间隔)等根据实际需求进行设置。


为了确保工具文件能够正确运行,我们还需要在 tools.py 文件的开头添加以下代码:


import os.path as osp
this_dir = osp.dirname(__file__)

最终,mydemo.py 文件的末尾代码应如下所示:


if __name__ == '__main__':

make_net()

# 定义生成 solver 的路径
solver_dir = this_dir + '/res_net_model/res_net_solver.prototxt'
solver_prototxt = tools.CaffeSolver()
# 将内容写入 res_net_model 文件夹中的 res_net_solver.prototxt
solver_prototxt.write(solver_dir)

执行 mydemo.py 后,生成的 solver prototxt 文件将按照上述设置生成。注意,生成后需要手动将 stepvalue1 改为 stepvalue,因为 tools.py 不能存储相同名称的参数,否则会导致参数被覆盖。


至此,我们已经成功生成了 solver 的 prototxt 文件。


推荐阅读
  • 1.如何在运行状态查看源代码?查看函数的源代码,我们通常会使用IDE来完成。比如在PyCharm中,你可以Ctrl+鼠标点击进入函数的源代码。那如果没有IDE呢?当我们想使用一个函 ... [详细]
  • 本文详细介绍了如何使用 Yii2 的 GridView 组件在列表页面实现数据的直接编辑功能。通过具体的代码示例和步骤,帮助开发者快速掌握这一实用技巧。 ... [详细]
  • 在macOS环境下使用Electron Builder进行应用打包时遇到签名验证失败的问题,具体表现为签名后spctl命令检测到应用程序未通过公证(Notarization)。本文将详细探讨该问题的原因及解决方案。 ... [详细]
  • 深入理解OAuth认证机制
    本文介绍了OAuth认证协议的核心概念及其工作原理。OAuth是一种开放标准,旨在为第三方应用提供安全的用户资源访问授权,同时确保用户的账户信息(如用户名和密码)不会暴露给第三方。 ... [详细]
  • 深入解析Android自定义View面试题
    本文探讨了Android Launcher开发中自定义View的重要性,并通过一道经典的面试题,帮助开发者更好地理解自定义View的实现细节。文章不仅涵盖了基础知识,还提供了实际操作建议。 ... [详细]
  • 本文详细记录了在基于Debian的Deepin 20操作系统上安装MySQL 5.7的具体步骤,包括软件包的选择、依赖项的处理及远程访问权限的配置。 ... [详细]
  • 优化ListView性能
    本文深入探讨了如何通过多种技术手段优化ListView的性能,包括视图复用、ViewHolder模式、分批加载数据、图片优化及内存管理等。这些方法能够显著提升应用的响应速度和用户体验。 ... [详细]
  • Windows服务与数据库交互问题解析
    本文探讨了在Windows 10(64位)环境下开发的Windows服务,旨在定期向本地MS SQL Server (v.11)插入记录。尽管服务已成功安装并运行,但记录并未正确插入。我们将详细分析可能的原因及解决方案。 ... [详细]
  • Explore how Matterverse is redefining the metaverse experience, creating immersive and meaningful virtual environments that foster genuine connections and economic opportunities. ... [详细]
  • PyCharm下载与安装指南
    本文详细介绍如何从官方渠道下载并安装PyCharm集成开发环境(IDE),涵盖Windows、macOS和Linux系统,同时提供详细的安装步骤及配置建议。 ... [详细]
  • 深入理解Tornado模板系统
    本文详细介绍了Tornado框架中模板系统的使用方法。Tornado自带的轻量级、高效且灵活的模板语言位于tornado.template模块,支持嵌入Python代码片段,帮助开发者快速构建动态网页。 ... [详细]
  • PHP 5.2.5 安装与配置指南
    本文详细介绍了 PHP 5.2.5 的安装和配置步骤,帮助开发者解决常见的环境配置问题,特别是上传图片时遇到的错误。通过本教程,您可以顺利搭建并优化 PHP 运行环境。 ... [详细]
  • DNN Community 和 Professional 版本的主要差异
    本文详细解析了 DotNetNuke (DNN) 的两种主要版本:Community 和 Professional。通过对比两者的功能和附加组件,帮助用户选择最适合其需求的版本。 ... [详细]
  • Python自动化处理:从Word文档提取内容并生成带水印的PDF
    本文介绍如何利用Python实现从特定网站下载Word文档,去除水印并添加自定义水印,最终将文档转换为PDF格式。该方法适用于批量处理和自动化需求。 ... [详细]
  • 本文探讨了卷积神经网络(CNN)中感受野的概念及其与锚框(anchor box)的关系。感受野定义了特征图上每个像素点对应的输入图像区域大小,而锚框则是在每个像素中心生成的多个不同尺寸和宽高比的边界框。两者在目标检测任务中起到关键作用。 ... [详细]
author-avatar
手机用户2702932962_848
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有