0609-搭建ResNet网络

pytorch完整教程目录:https://www.cnblogs.com/nickchen121/p/14662511.html

一、ResNet 网络概述

Kaiming He 的深度残差网络(ResNet)相比较传统的深度深度神经网络,解决了训练极深网络的梯度消失问题。

这里选取 ResNet34 讲解 ResNet 的网络结构,它的网络结构如下图所示:

在上述的网络中,除了最开始的卷积池化和最后的池化全连接之外,网络中有很多结构相似的单元,这些重复单元的共同点就是有个跨层直连的 shortcut。ResNet 中将一个跨层直连的单元称为 Residual block,它的结构如下图所示:

对于 Residual block,左边部分是普通的卷积网络结构,右边是直连,如果输入和输出的通道数不一致,或者它的步长不为 1,就需要有一个专门的单元将二者装换成一致的,让它们可以相加。

并且从上图可以发现 Residual block 的大小也是有规律的,在最开始的 pool 之后又连续的几个一模一样的 Residual block 单元,这些单元的通道数一样,在这里我们把这几个拥有多个 Residual block 单元的结构称作 layer,注意这个 layer 和之前介绍的 layer 不同,这里的 layer 是几个层的集合。

由于 Redisual block 和 layer 出现了很多次,我们可以把它们实现为一个子 Module 或函数。在这里我们把 Residual block 实现为一个子 Module,而让 layer 实现为一个函数。

下面我们将尽量按照这三个规则去实现 ResNet 网络:

  • 对模型中的重复部分,实现为子 module 或用函数生成相应的 module
  • nn.Modulenn.Funcitonal 结合使用
  • 尽量使用 nn.Sequential

二、利用 torch 实现 ResNet34 网络

import torch as t
from torch import nn
from torch.nn import functional as F class ResidualBlock(nn.Module):
"""
实现子 module:Residual Block
""" def __init__(self, inchannel, outchannel, stride=1, shortcut=None):
super(ResidualBlock, self).__init__() # 由于 Residual Block 分为左右两部分,因此定义左右两边的 layer
# 定义左边
self.left = nn.Sequential(
# Conv2d 参数:in_channel,out_channel,kernel_size,stride,padding
nn.Conv2d(inchannel, outchannel, 3, stride, 1, bias=False),
nn.BatchNorm2d(outchannel),
nn.ReLU(inplace=True),
nn.Conv2d(outchannel, outchannel, 3, 1, 1, bias=False),
nn.BatchNorm2d(outchannel))
# 定义右边
self.right = shortcut def forward(self, x):
out = self.left(x)
residual = x if self.right is None else self.right(x) # 检测右边直连的情况
out += residual
return F.relu(out) class ResNet(nn.Module):
"""
实现主 module:ResNet34
ResNet34 包含多个 layer,每个 layer 又包含多个 residual block
用子 module 实现 residual block,用 _make_layer 函数实现 layer
""" def __init__(self, num_classes=1000):
super(ResNet, self).__init__()
# 前几层图像转换
self.pre = nn.Sequential(
nn.Conv2d(3, 64, 7, 2, 3, bias=False),
nn.BatchNorm2d(64),
nn.ReLU(inplace=True),
nn.MaxPool2d(3, 2, 1),
) # 重复的 layer 分别有 3,4,6,3 个 residual block
self.layer1 = self._make_layer(64, 128, 3)
self.layer2 = self._make_layer(128, 256, 4, stride=2)
self.layer3 = self._make_layer(256, 512, 6, stride=2)
self.layer4 = self._make_layer(512, 512, 3, stride=2) # 分类用的全连接
self.fc = nn.Linear(512, num_classes) def _make_layer(self, inchannel, outchannel, block_num, stride=1):
"""
构建 layer,包含多个 residual block
"""
shortcut = nn.Sequential(
nn.Conv2d(inchannel, outchannel, 1, stride, bias=False),
nn.BatchNorm2d(outchannel)) layers = []
layers.append(ResidualBlock(inchannel, outchannel, stride, shortcut)) for i in range(1, block_num):
layers.append(ResidualBlock(outchannel, outchannel)) return nn.Sequential(*layers) def forward(self, x):
x = self.pre(x) x = self.layer1(x)
x = self.layer2(x)
x = self.layer3(x)
x = self.layer4(x) x = F.avg_pool2d(x, 7)
x = x.view(x.size(0), -1) return self.fc(x)
res_net = ResNet()
inp = t.autograd.Variable(t.randn(1, 3, 224, 224))
output = res_net(inp)
output.size()
torch.Size([1, 1000])

不到 50 行代码便实现了这样一个网络,看起来是那么不可思议,如果对此感兴趣的同学还可以取消尝试实现 Google 的 Inception 网络。

三、torchvision 中的 resnet34网络调用

前面我们讲过一个 hub 模块,里面存储了很多网络结构。不仅如此,和 torch 配套的图像工具包 torchvision 也实现了深度学习中的大多数经典的模型,其中就包括了 ResNet34,非常简单,可以通过以下两行代码调用这个网络:

from torchvision import models
res_net = models.resnet34()
inp = t.autograd.Variable(t.randn(1, 3, 224, 224))
output = res_net(inp)
output.size()
torch.Size([1, 1000])

本例中的 ResNet34 的实现参考了 torchvision 中的实现并做了一定的调整,有兴趣的同学可以去阅读相对应的源码。

四、第六章总结

这一章详细的介绍了 torch 中的 nn 工具箱,但是你说详细吗?又不是那么详细,还有很多很多地方我们需要去补漏,如果想深入各个部分的同学们,可以去参考官方文档。

当然,我更建议学一部分常用的基础,然后在实践中学习更加完善、更加系统的知识体系。因此,我们将在未来的实战项目中不断地巩固 nn 这个工具箱的使用。

最后,随着 nn 的落幕,torch 的地基也算是落幕了,剩下的都是一些边边角角的知识点,但是还是借用古人的一句话:路漫漫其修远兮,任重而道远。

0609-搭建ResNet网络的更多相关文章

  1. Caffe 议事(二):从零开始搭建 ResNet 之 网络的搭建(上)

    3.搭建网络: 搭建网络之前,要确保之前编译 caffe 时已经 make pycaffe 了. 步骤1:导入 Caffe 我们首先在 ResNet 文件夹中建立一个 mydemo.py 的文件,本参 ...

  2. 学习笔记-ResNet网络

    ResNet网络 ResNet原理和实现 总结 一.ResNet原理和实现 神经网络第一次出现在1998年,当时用5层的全连接网络LetNet实现了手写数字识别,现在这个模型已经是神经网络界的“hel ...

  3. 从零开始自己搭建复杂网络2(以Tensorflow为例)

    从零开始自己搭建复杂网络(以DenseNet为例) DenseNet 是一种具有密集连接的卷积神经网络.在该网络中,任何两层之间都有直接的连接,也就是说,网络每一层的输入都是前面所有层输出的并集, 而 ...

  4. Caffe 议事(一):从零开始搭建 ResNet 之 残差网络结构介绍和数据准备

    声明:Caffe 系列文章是我们实验室 黄佳斌 大神所写的内部学习文档,已经获得他的授权允许. 本参考资料是在 Ubuntu14.04 版本下进行,并且默认 Caffe 所需的环境已经配置好,下面教大 ...

  5. 陈云pytorch学习笔记_用50行代码搭建ResNet

    import torch as t import torch.nn as nn import torch.nn.functional as F from torchvision import mode ...

  6. ResNet网络再剖析

    随着2018年秋季的到来,提前批和内推大军已经开始了,自己也成功得当了几次炮灰,不过在总结的过程中,越是了解到自己的不足,还是需要加油. 最近重新复习了resnet网络,又能发现一些新的理念,感觉很f ...

  7. CentOS6.8环境下搭建yum网络仓库

    CentOS6.8环境下搭建yum网络仓库 本文利用ftp服务,在CentOS6.8系统下搭建一个yum仓库,然后用另一台虚拟机访问该仓库.并安装程序包 安装ftp服务 查询ftp服务是否安装 [ro ...

  8. 从零开始自己搭建复杂网络(以Tensorflow为例)

    从零开始自己搭建复杂网络(以MobileNetV2为例) tensorflow经过这几年的发展,已经成长为最大的神经网络框架.而mobileNetV2在经过Xception的实践与深度可分离卷积的应用 ...

  9. 关于路由器漏洞利用,qemu环境搭建,网络配置的总结

    FAT 搭建的坑 1 先按照官方步骤进行,完成后进行如下步骤 2 修改 move /firmadyne into /firmware-analysis-toolkit navigate to the ...

  10. Hyperledger Fabric手动生成CA证书搭建Fabric网络

    之前介绍了使用官方脚本自动化启动一个Fabric网络,并且所有的证书都是通过官方的命令行工具cryptogen直接生成网络中的所有节点的证书.在开发环境可以这么简单进行,但是生成环境下还是需要我们自定 ...

随机推荐

  1. JS输出为[object object]

    问题描述:在控制台打印时应输出对象,但是却输出[object object] 解决办法:先将数据转换为json格式,然后再转换为json对象 JSON.parse(JSON.stringify(use ...

  2. 使用 xunit 编写测试代码

    使用 xunit 编写测试代码 Intro xunit 是 .NET 里使用非常广泛的一个测试框架,有很多测试项目都是在使用 xunit 作为测试框架,不仅仅有很多开源项目在使用,很多微软的项目也在使 ...

  3. 下载HLS视频到本地

    现在绝大多数网站播放视频都采用HLS技术,像腾讯优酷爱奇艺等等.本篇博文将介绍如何下载这样的视频到本地. 前言 因疫情影响,上课部分课程采用腾讯课堂上课,腾讯课堂有直播回放功能,但这个功能腾讯显然没有 ...

  4. 大数据开发-Spark-Streaming处理数据到mysql

    前面一篇讲到streamin读取kafka数据加工处理后写到kafka数据,大数据开发-Spark-开发Streaming处理数据 && 写入Kafka是针对比如推荐领域,实时标签等场 ...

  5. wxWidgets源码分析(7) - 窗口尺寸

    目录 窗口尺寸 概述 窗口Size消息的处理 用户调整Size消息的处理 调整窗口大小 程序调整窗口大小 wxScrolledWindow设置窗口大小 获取TextCtrl控件最合适大小 窗口尺寸 概 ...

  6. 《C++ Primer》笔记 第6章 函数

    任意两个形参都不能同名,而且函数最外层作用域中的局部变量也不能使用与函数形参一样的名字(形参就相当于该函数的局部变量). 形参名是可选的,但是由于我们无法使用未命名的形参,所以形参一般都应该有个名字. ...

  7. 2020年HTML5考试模拟题整理(一)

    1.哪个元素被称为媒体元素的子元素? 答案:<track>. <track> 标签为媒体元素(比如 <audio> and <video>)规定外部文本 ...

  8. Kibana 插件环境搭建教程

    原文 环境背景, Kibana 7.4.0, Elasticsearch 7.4.0 注意, 执行以下命令时, 尽量在管理员权限的命令行窗口里执行, 避免一些没有权限的报错; 1. 准备 Kibana ...

  9. Go语言|类型转换和类型别名

    类型转换 同类型之间的转换 Go语言中只有强制类型转换,没有隐式类型转换.该语法只能在两个类型之间支持相互转换的时候使用. import "fmt" func main() { v ...

  10. LNMP配置——Nginx配置 —— 配置静态文件不记录日志并添加过期时间

    一.配置 #vi /usr/local/nginx/conf/vhost/test.com.conf 写入; server { listen 80; server_name test.com test ...