文章目录
ResNet论文:
https://arxiv.org/abs/1512.03385
本文主要参考视频:https://www.bilibili.com/video/BV1T7411T7wa
https://www.bilibili.com/video/BV14E411H7Uw
ResNet的网络结构图如图所示:

这是ResNet不同层数的网络 结构图。
可以看到,结构大差不差。不论是18层、34层、50层、还是101层、152层。
上来都是一个7x7的卷积层,然后是一个3x3的最大池化下采样。
然后就是按照图中的conv2_x、conv3_x、conv4_x、conv5_x中的残差结构。
最后再跟一个平均池化下采样,和全连接层,sofmax输出。
我们先看一下前两层。

首先呢,ResNet使用ImagesNet数据集,采用的默认输入尺寸是224x224,RGB图像,三通道
按照表中,我们可以看到,图片输入之后,首先是一个7x7,64,stride 2
也就是一个卷积层,卷积核大小为7x7,输出通道为64(也就是卷积核个数),stride=2。
没说padding,我们需要自己算一下,表里写了这一层的输出是112x112
补充一点知识:
假设输入图片为 W x W 卷积核大小为F x F,步长stride=S,padding=P(填充的像素数)
则输出图像的大小 W2 =(W - F +2P)/S +1可以注意到这个公式中有除法,一般我们做卷积时除不尽的时候都向下取整
可以参考pytorch官方文档:https://pytorch.org/docs/stable/generated/torch.nn.Conv2d.html#torch.nn.Conv2d
但是我们做池化的时候,也可以采用向上取整
参看pytorch官方文档:https://pytorch.org/docs/stable/generated/torch.nn.MaxPool2d.html#torch.nn.MaxPool2d
有一个参数ceil_mode,默认是floor是向下取整,可以设置为True,向上取整
ceil_mode – when True, will use ceil instead of floor to compute the output shape有的时候池化会选择向上取整(最大池化和平均池化有时取整方式不同)
那就是说 112 = (224 - 7 + 2P)/ 2 + 1
化简后就是 111 = (217 + 2P)/2 = 108.5+P
所以P=3 所以Padding是3
所以我们输入图片进来,第一层是in_channel=3,out_channel=64,kernel_size=7,stride=2,padding=3
没有偏置bias。经过这一层我们会得到大小为112x112的尺寸,通道数为64
然后经过一个3x3的最大池化下采样,stride=2
W o u t = ( W i n − F + 2 P ) / S + 1 W_{out}= (W_{in} - F + 2P)/S + 1 Wout=(Win−F+2P)/S+1
池化层也采用向下取整。所以 56=(112 - 3 + 2P)/2 +1 计算出来P=1
所以第二层池化层是in_channel=64,out_channel=64,kernel_size=3,stride=2,padding=1
经过池化层,我们会得到一个56x56,64通道的输出,紧接着就是conv2_x中对应的一系列残差结构
经过前面两层,我们得到一个56x56,64通道的输出
紧接着是conv2_x
这就是残差块,残差块大致有两种类型,一种是两层卷积的,一种的三层卷积的,就是途中红框画的。

比如如果是ResNet34,那么池化层之后,就是两个3x3,64的卷积层,这两个组成一个残差块。
如果是ResNet50,那么池化层之后就是1x1,64的卷积层 + 3x3,64的卷积层 + 1x1,256的卷积层,三个组成一个残差块。
后面写的x3就代表有三个这样的残差块连接一起
如下图所示,关于残差结构的原理,不多说了,这里主要讲实现。

有几个点需要注意:
以ResNet34为例,按照表格里面写的,池化之后,我们的大小是56x56x64,那么经过conv2_x之后我们的输出还是56x56x64
输入和输出特征矩阵的大小一样,那么就说明stride=1,padding=1
因为公式 W o u t = ( W i n − F + 2 P ) / S + 1 W_{out}= (W_{in} - F + 2P)/S + 1 Wout=(Win−F+2P)/S+1
要保证一样,那就S=1,不然的话,大于1就没法一样,然后计算padding可知,也是1
所以经过这两层之后呢,得到的还是56x56x64的特征图,可以直接与残差块那个分支相加。
但是呢这里需要注意,我们看conv3_x,是3x3,128通道,也就是说经过conv2_x后得到的56x56,64通道
到conv3_x里面升维了,并且大小也变了,变成28x28了
这时候要注意一个问题,分支与主分支的结果就无法相加了,大小不一致,维度不一致啊
怎么办呢,所以还有一种虚线连接的残差块,如图

在分支里面做了一个1x1的卷积层,1x1的卷积层主要是用来升维和降维的。同时通过设置stride可以改变尺寸
所以就通过这个卷积层得到了28x28,128通道的特征图,可以与主分支直接相加了
并且我们通过计算可以算出来,残差块主分支padding=1,右边的分支padding=2
对于ResNet50和101,深层次的ResNet也是按照这样的方法处理的

但是注意啊,这种虚线结构只是为了解决尺寸不一样无法相加的情况
什么情况下需要用这个呢?
对于ResNet18和ResNet34而言,conv3_x,conv4_x和conv5_x的第一层才需要虚线结构。
可以看到表里面,ResNet34的conv3_x的第一层会输出28x28,128通道的,但是输入是56x56,64通道的,所以需要虚线结构,而conv2_x不需要,因为输入输出是一样的。
而对于ResNet50和ResNet101,ResNet152而言,conv2_x和conv3_x,conv4_x和conv5_x的第一层都需要虚线结构
因为ResNet50从conv2_x开始,输入56x56,64通道,输出是56x56,256通道的,所以conv2_x也需要虚线结构,不过这个虚线结构只调整通道数即可。

所以,我们根据表格可以看到ResNet50中,conv3_x有四个残差块,这其中只有第一个会遇到尺寸不一样的问题,需要用虚线结构,别的都不需要。
同样的,conv4_x和conv5_x的第一层也需要
另外再注意一个改进:

Batch Normalization的目的是使我们的一批(Batch)feature map满足均值为0,方差为1的分布规律。
这里关于BN层的原理就不写了,可以看这个视频和博客
https://www.bilibili.com/video/BV1T7411T7wa
https://blog.csdn.net/qq_37541097/article/details/104434557
我们需要知道的是
建议将bn层放在卷积层(Conv)和激活层(例如Relu)之间,且卷积层不要使用偏置bias
所以说,我们实际上的残差网络块应该是如图,这个样子的

至此,整个ResNet的网络结构就清晰了。其中需要注意的点主要就是:
conv3_x、conv4_x、conv5_x中的第一层需要用虚线结构conv2_x、conv3_x、conv4_x、conv5_x中的第一层都需要用虚线结构我想在Ruby中创建一个用于开发目的的极其简单的Web服务器(不,不想使用现成的解决方案)。代码如下:#!/usr/bin/rubyrequire'socket'server=TCPServer.new('127.0.0.1',8080)whileconnection=server.acceptheaders=[]length=0whileline=connection.getsheaders想法是从命令行运行这个脚本,提供另一个脚本,它将在其标准输入上获取请求,并在其标准输出上返回完整的响应。到目前为止一切顺利,但事实证明这真的很脆弱,因为它在第二个请求上中断并出现错误:/usr/b
网络编程套接字网络编程基础知识理解源`IP`地址和目的`IP`地址理解源MAC地址和目的MAC地址认识端口号理解端口号和进程ID理解源端口号和目的端口号认识`TCP`协议认识`UDP`协议网络字节序socket编程接口`sockaddr``UDP`网络程序服务器端代码逻辑:需要用到的接口服务器端代码`udp`客户端代码逻辑`udp`客户端代码`TCP`网络程序服务器代码逻辑多个版本服务器单进程版本多进程版本多线程版本线程池版本服务器端代码客户端代码逻辑客户端代码TCP协议通讯流程TCP协议的客户端/服务器程序流程三次握手(建立连接)数据传输四次挥手(断开连接)TCP和UDP对比网络编程基础知识
目录前言滤波电路科普主要分类实际情况单位的概念常用评价参数函数型滤波器简单分析滤波电路构成低通滤波器RC低通滤波器RL低通滤波器高通滤波器RC高通滤波器RL高通滤波器部分摘自《LC滤波器设计与制作》,侵权删。前言最近需要学习放大电路和滤波电路,但是由于只在之前做音乐频谱分析仪的时候简单了解过一点点运放,所以也是相当从零开始学习了。滤波电路科普主要分类滤波器:主要是从不同频率的成分中提取出特定频率的信号。有源滤波器:由RC元件与运算放大器组成的滤波器。可滤除某一次或多次谐波,最普通易于采用的无源滤波器结构是将电感与电容串联,可对主要次谐波(3、5、7)构成低阻抗旁路。无源滤波器:无源滤波器,又称
最近在学习CAN,记录一下,也供大家参考交流。推荐几个我觉得很好的CAN学习,本文也是在看了他们的好文之后做的笔记首先是瑞萨的CAN入门,真的通透;秀!靠这篇我竟然2天理解了CAN协议!实战STM32F4CAN!原文链接:https://blog.csdn.net/XiaoXiaoPengBo/article/details/116206252CAN详解(小白教程)原文链接:https://blog.csdn.net/xwwwj/article/details/105372234一篇易懂的CAN通讯协议指南1一篇易懂的CAN通讯协议指南1-知乎(zhihu.com)视频推荐CAN总线个人知识总
深度学习部署:Windows安装pycocotools报错解决方法1.pycocotools库的简介2.pycocotools安装的坑3.解决办法更多Ai资讯:公主号AiCharm本系列是作者在跑一些深度学习实例时,遇到的各种各样的问题及解决办法,希望能够帮助到大家。ERROR:Commanderroredoutwithexitstatus1:'D:\Anaconda3\python.exe'-u-c'importsys,setuptools,tokenize;sys.argv[0]='"'"'C:\\Users\\46653\\AppData\\Local\\Temp\\pip-instal
我完全不是程序员,正在学习使用Ruby和Rails框架进行编程。我目前正在使用Ruby1.8.7和Rails3.0.3,但我想知道我是否应该升级到Ruby1.9,因为我真的没有任何升级的“遗留”成本。缺点是什么?我是否会遇到与普通gem的兼容性问题,或者甚至其他我不太了解甚至无法预料的问题? 最佳答案 你应该升级。不要坚持从1.8.7开始。如果您发现不支持1.9.2的gem,请避免使用它们(因为它们很可能不被维护)。如果您对gem是否兼容1.9.2有任何疑问,您可以在以下位置查看:http://www.railsplugins.or
如何学习ruby的正则表达式?(对于假人) 最佳答案 http://www.rubular.com/在Ruby中使用正则表达式时是一个很棒的工具,因为它可以立即将结果可视化。 关于ruby-我如何学习ruby的正则表达式?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/1881231/
是否可以在不实际下载文件的情况下检查文件是否存在?我有这么大的(~40mb)文件,例如:http://mirrors.sohu.com/mysql/MySQL-6.0/MySQL-6.0.11-0.glibc23.src.rpm这与ruby不严格相关,但如果发件人可以设置内容长度就好了。RestClient.get"http://mirrors.sohu.com/mysql/MySQL-6.0/MySQL-6.0.11-0.glibc23.src.rpm",headers:{"Content-Length"=>100} 最佳答案
我在这方面尝试了很多URL,在我遇到这个特定的之前,它们似乎都很好:require'rubygems'require'nokogiri'require'open-uri'doc=Nokogiri::HTML(open("http://www.moxyst.com/fashion/men-clothing/underwear.html"))putsdoc这是结果:/Users/macbookair/.rvm/rubies/ruby-2.0.0-p481/lib/ruby/2.0.0/open-uri.rb:353:in`open_http':404NotFound(OpenURI::HT
深度学习12.CNN经典网络VGG16一、简介1.VGG来源2.VGG分类3.不同模型的参数数量4.3x3卷积核的好处5.关于学习率调度6.批归一化二、VGG16层分析1.层划分2.参数展开过程图解3.参数传递示例4.VGG16各层参数数量三、代码分析1.VGG16模型定义2.训练3.测试一、简介1.VGG来源VGG(VisualGeometryGroup)是一个视觉几何组在2014年提出的深度卷积神经网络架构。VGG在2014年ImageNet图像分类竞赛亚军,定位竞赛冠军;VGG网络采用连续的小卷积核(3x3)和池化层构建深度神经网络,网络深度可以达到16层或19层,其中VGG16和VGG