CNN)正是一类强大的、专为处理图像数据(多维矩阵)而设计的神经网络,CNN 的设计是深度学习中的一个里程碑式的技术。在 Transformer 应用到 CV 领域之前,基于卷积神经网络架构的模型在计算机视觉领域中占主导地位,几乎所有的图像识别、目标检测、语义分割、3D目标检测、视频理解等任务都是以 CNN 方法为基础。
卷积神经网络核心网络层是卷积层,其使用了卷积(convolution)这种数学运算,卷积是一种特殊的线性运算。另外,通常来说,卷积神经网络中用到的卷积运算和其他领域(例如工程领域以及纯数学领域)中的定义并不完全一致。
operation 视语境有时译作“操作”,有时译作“运算”,本文不做区分。
convolution)。更一般的,卷积运算的数学公式定义如下:
$$
连续定义: ; h(x)=(f*g)(x) = \int_{-\infty}^{\infty} f(t)g(x-t)dt \tag{1}
$$
$$
离散定义: ; h(x) = (f*g)(x) = \sum^{\infty}_{t=-\infty} f(t)g(x-t) \tag{2}
$$
以上卷积计算公式可以这样理解:
reverse),相当于在数轴上把 $g(t)$ 函数从右边褶到左边去,也就是卷积的“卷”的由来。这里多次滑动过程对应的是 $t$ 的变化过程。那么,卷积的意义是什么呢?可以从卷积的典型应用场景-图像处理来理解:
卷积意义的理解来自知乎问答,有所删减和优化。
本节图片摘自知乎用户马同学的文章。
而卷积核 $g$ 也可以用一个矩阵来表示,如:
$$
g = \begin{bmatrix}
&b_{-1,-1} &b_{-1,0} &b_{-1,1} \
&b_{0,-1} &b_{0,0} &b_{0,1} \
&b_{1,-1} &b_{1,0} &b_{1,1}
\end{bmatrix}
$$
按照卷积公式的定义,则目标图片的第 $(u, v)$ 个像素的二维卷积值为:
$$
(f * g)(u, v)=\sum_{i} \sum_{j} f(i, j)g(u-i, v-j)=\sum_{i} \sum_{j} a_{i,j} b_{u-i,v-j}
$$
展开来分析二维卷积计算过程就是,首先得到原始图像矩阵中 $(u, v)$ 处的矩阵:
$$
f=\begin{bmatrix}
&a_{u-1,v-1} &a_{u-1,v} &a_{u-1,v+1}\
&a_{u,v-1} &a_{u,v} &a_{u,v+1} \
&a_{u+1,v-1} &a_{u+1,v} &a_{u+1,v+1}
\end{bmatrix}
$$
然后将图像处理矩阵翻转(两种方法,结果等效),如先沿 $x$ 轴翻转,再沿 $y$ 轴翻转(相当于将矩阵 $g$ 旋转 180 度):
$$
\begin{aligned}
g &= \begin{bmatrix} &b_{-1,-1} &b_{-1,0} &b_{-1,1}\ &b_{0,-1} &b_{0,0} &b_{0,1} \ &b_{1,-1} &b_{1,0} &b_{1,1} \end{bmatrix} => \begin{bmatrix} &b_{1,-1} &b_{1,0} &b_{1,1}\ &b_{0,-1} &b_{0,0} &b_{0,1} \ &b_{-1,-1} &b_{-1,0} &b_{-1,1} \end{bmatrix} \
&= \begin{bmatrix} &b_{1,1} &b_{1,0} &b_{1,-1}\ &b_{0,1} &b_{0,0} &b_{0,-1} \ &b_{-1,1} &b_{-1,0} &b_{-1,-1} \end{bmatrix} = g^{'}
\end{aligned}
$$
最后,计算卷积时,就可以用 $f$ 和 $g′$ 的内积:
$$
\begin{aligned}
f * g(u,v) &= a_{u-1,v-1} \times b_{1,1} + a_{u-1,v} \times b_{1,0} + a_{u-1,v+1} \times b_{1,-1} \ &+ a_{u,v-1} \times b_{0,1} + a_{u,v} \times b_{0,0} + a_{u,v+1} \times b_{0,-1} \ &+ a_{u+1,v-1} \times b_{-1,1} + a_{u+1,v} \times b_{-1,0} + a_{u+1,v+1} \times b_{-1,-1}
\end{aligned}
$$
计算过程可视化如下动图所示,注意动图给出的是 $g$ 不是 $g'$。
以上公式有一个特点,做乘法的两个对应变量 $a, b$ 的下标之和都是 $(u,v)$,其目的是对这种加权求和进行一种约束,这也是要将矩阵 $g$ 进行翻转的原因。上述计算比较麻烦,实际计算的时候,都是用翻转以后的矩阵,直接求矩阵内积就可以了。
Feature Map)。如果把图像矩阵简写为 $I$,把卷积核 Kernal 简写为 $K$,则目标图片的第 $(i,j)$ 个像素的卷积值为:
$$
h(i,j) = (IK)(i,j)=\sum_m \sum_n I(m,n)K(i-m,j-n) \tag{3}
$$
可以看出,这和一维情况下的卷积公式 2 是一致的。因为卷积的可交换性,我们也可以把公式 3 等价地写作:
$$
h(i,j) = (IK)(i,j)=\sum_m \sum_n I(i-m,j-n)K(m,n) \tag{4}
$$
通常,下面的公式在机器学习库中实现更为简单,因为 $m$ 和 $n$ 的有效取值范围相对较小。
卷积运算可交换性的出现是因为我们将核相对输入进行了翻转(flip),从 $m$ 增 大的角度来看,输入的索引在增大,但是卷积核的索引在减小。我们将卷积核翻转的唯一目 的是实现可交换性。尽管可交换性在证明时很有用,但在神经网络的应用中却不是一个重要的性质。相反,许多神经网络库会实现一个互相关函数(corresponding function),它与卷积相同但没有翻转核:
$$
h(i,j) = (I*K)(i,j)=\sum_m \sum_n I(i+m,j+n)K(m,n) \tag{5}
$$
互相关函数的运算,是两个序列滑动相乘,两个序列都不翻转。卷积运算也是滑动相乘,但是其中一个序列需要先翻转,再相乘。
180 度,$Y$ 为输出矩阵。从上式可以看出,互相关和卷积的区别仅仅在于卷积核是否进行翻转。因此互相关也可以称为不翻转卷积.
离散卷积可以看作矩阵的乘法,然而,这个矩阵的一些元素被限制为必须和另外一些元素相等。在神经网络中使用卷积是为了进行特征抽取,卷积核是否进行翻转和其特征抽取的能力无关(特别是当卷积核是可学习的参数时),因此卷积和互相关在能力上是等价的。事实上,很多深度学习工具中卷积操作其实都是互相关操作,用来**减少一些不必要的操作或开销(不反转 Kernal)**。 总的来说,
在传统图像处理中,线性空间滤波的原理实质上是指指图像 $f$ 与滤波器核 $w$ 进行乘积之和(卷积)运算。核是一个矩阵,其大小定义了运算的邻域,其系数决定了该滤波器(也称模板、窗口滤波器)的性质,并通过设计不同核系数(卷积核)来实现低通滤波(平滑)和高通滤波(锐化)功能,因此我们可以认为卷积是利用某些设计好的参数组合(卷积核)去提取图像空域上相邻的信息。
上述卷积层公式也可以写成这样的形式:$Z = W*A+b$根据卷积层的定义,卷积层有两个很重要的性质:
总而言之,卷积层的作用是提取一个局部区域的特征,不同的卷积核(滤波器)相当于不同的特征提取器。为了提高卷积网络的表示能力,可以在每一层使用多个不同的特征映射,即增加卷积核(滤波器)的数量,以更好地提取图像的特征。
Kernel)在输入矩阵上滑动,并通过下述过程实现卷积计算:
来源论文 Improvement of Damage Segmentation Based on Pixel-Level Data Balance Using VGG-Unet。注意,卷积层的输出
Feature map 的大小取决于输入的大小、Pad 数、卷积核大小和步长。在 Pytorch 框架中,图片(feature map)经卷积 Conv2D 后输出大小计算公式如下:$\left \lfloor N = \frac{W-F+2P}{S}+1 \right \rfloor$。
其中 $\lfloor \rfloor$ 是向下取整符号,用于结果不是整数时进行向下取整(Pytorch 的 Conv2d 卷积函数的默认参数 ceil_mode = False,即默认向下取整, dilation = 1),其他符号解释如下:
W×W(默认输入尺寸为正方形)Filter 大小 F×FSPN×N
上图是三通道经过两组过滤器的卷积过程,在这个例子中,输入是三维数据 $3\times 32 \times32$,经过权重参数尺寸为 $2\times 3\times 5\times 5$ 的卷积层后,输出为三维 $2\times 28\times 28$,维数并没有变化,只是每一维内部的尺寸有了变化,一般都是要向更小的尺寸变化,以便于简化计算。
假设三维卷积(也叫滤波器)尺寸为 $(c_{in}, k, k)$,一共有 $c_{out}$ 个滤波器,即卷积层参数尺寸为 $(c_{out}, c_{in}, k, k)$ ,则标准卷积层有以下特点:
feature map 的数量等于滤波器数量 $c_{out}$,即卷积层参数值确定后,feature map 的数量也确定,而不是根据前向计算自动计算出来;Pytorch 框架中对应的卷积层 api 如下:
class torch.nn.Conv2d(in_channels, out_channels, kernel_size, stride=1, padding=0, dilation=1, groups=1, bias=True)
主要参数解释:
in_channels(int) – 输入信号的通道。out_channels(int) – 卷积产生的通道。kerner_size(int or tuple) - 卷积核的尺寸。stride(int or tuple, optional) - 卷积步长,默认值为 1 。padding(int or tuple, optional) - 输入的每一条边补充 0 的层数,默认不填充。dilation(int or tuple, optional) – 卷积核元素之间的间距,默认取值 1 。groups(int, optional) – 从输入通道到输出通道的阻塞连接数。bias(bool, optional) - 如果 bias=True,添加偏置。###### Pytorch卷积层输出大小验证
import torch
import torch.nn as nn
import torch.autograd as autograd
# With square kernels and equal stride
# output_shape: height = (50-3)/2+1 = 24.5,卷积向下取整,所以 height=24.
m = nn.Conv2d(16, 33, 3, stride=2)
# # non-square kernels and unequal stride and with padding
# m = nn.Conv2d(16, 33, (3, 5), stride=(2, 1), padding=(4, 2)) # 输出shape: torch.Size([20, 33, 28, 100])
# # non-square kernels and unequal stride and with padding and dilation
# m = nn.Conv2d(16, 33, (3, 5), stride=(2, 1), padding=(4, 2), dilation=(3, 1)) # 输出shape: torch.Size([20, 33, 26, 100])
input = autograd.Variable(torch.randn(20, 16, 50, 100))
output = m(input)
print(output.shape) # 输出shape: torch.Size([20, 16, 24, 49])
值得注意的是,与卷积层一样,汇聚层也可以通过改变填充和步幅以获得所需的输出形状。
Pytorch 框架中对应的聚合层 api 如下:
class torch.nn.MaxPool2d(kernel_size, stride=None, padding=0, dilation=1, return_indices=False, ceil_mode=False)
主要参数解释:
kernel_size(int or tuple):max pooling 的窗口大小。stride(int or tuple, optional):max pooling的窗口移动的步长。默认值是kernel_size`。padding(int or tuple, optional):默认值为 0,即不填充像素。输入的每一条边补充 0 的层数。dilation:滑动窗中各元素之间的距离。ceil_mode:默认值为 False,即上述公式默认向下取整,如果设为 True,计算输出信号大小的时候,公式会使用向上取整。示例代码:Pytorch中池化层默认ceil mode = false,而Caffe只实现了ceil mode= true的计算方式。
import torch
import torch.nn as nn
import torch.autograd as autograd
# 大小为3,步幅为2的正方形窗口池
m = nn.MaxPool2d(kernel_size=3, stride=2, padding=1)
# pool of non-square window
input = autograd.Variable(torch.randn(20, 16, 50, 32))
output = m(input)
print(output.shape) # torch.Size([20, 16, 25, 16])
一个简单的 CNN 网络连接图如下所示。
经典 CNN 网络的总结,可参考我之前写的文章-经典 backbone 网络总结。
目前,卷积网络的整体结构趋向于使用更小的卷积核(比如 $1 \times 1$ 和 $3 \times 3$) 以及更深的结构(比如层数大于 50)。另外,由于卷积层的操作性越来越灵活(同样可完成减少特征图分辨率),汇聚层的作用越来越小,因此目前的卷积神经网络逐渐趋向于全卷积网络。
另外,可通过这个网站可视化 cnn 的全部过程。
我想在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对比网络编程基础知识
1.postman介绍Postman一款非常流行的API调试工具。其实,开发人员用的更多。因为测试人员做接口测试会有更多选择,例如Jmeter、soapUI等。不过,对于开发过程中去调试接口,Postman确实足够的简单方便,而且功能强大。2.下载安装官网地址:https://www.postman.com/下载完成后双击安装吧,安装过程极其简单,无需任何操作3.使用教程这里以百度为例,工具使用简单,填写URL地址即可发送请求,在下方查看响应结果和响应状态码常用方法都有支持请求方法:getpostputdeleteGet、Post、Put与Delete的作用get:请求方法一般是用于数据查询,
Ⅰ软件测试基础一、软件测试基础理论1、软件测试的必要性所有的产品或者服务上线都需要测试2、测试的发展过程3、什么是软件测试找bug,发现缺陷4、测试的定义使用人工或自动的手段来运行或者测试某个系统的过程。目的在于检测它是否满足规定的需求。弄清预期结果和实际结果的差别。5、测试的目的以最小的人力、物力和时间找出软件中潜在的错误和缺陷6、测试的原则28原则:20%的主要功能要重点测(eg:支付宝的支付功能,其他功能都是次要的)80%的错误存在于20%的代码中7、测试标准8、测试的基本要求功能测试性能测试安全性测试兼容性测试易用性测试外观界面测试可靠性测试二、质量模型衡量一个优秀软件的维度①功能性功
ES一、简介1、ElasticStackES技术栈:ElasticSearch:存数据+搜索;QL;Kibana:Web可视化平台,分析。LogStash:日志收集,Log4j:产生日志;log.info(xxx)。。。。使用场景:metrics:指标监控…2、基本概念Index(索引)动词:保存(插入)名词:类似MySQL数据库,给数据Type(类型)已废弃,以前类似MySQL的表现在用索引对数据分类Document(文档)真正要保存的一个JSON数据{name:"tcx"}二、入门实战{"name":"DESKTOP-1TSVGKG","cluster_name":"elasticsear
是否可以在不实际下载文件的情况下检查文件是否存在?我有这么大的(~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
(本文是网络的宏观的概念铺垫)目录计算机网络背景网络发展认识"协议"网络协议初识协议分层OSI七层模型TCP/IP五层(或四层)模型报头以太网碰撞路由器IP地址和MAC地址IP地址与MAC地址总结IP地址MAC地址计算机网络背景网络发展 是最开始先有的计算机,计算机后来因为多项技术的水平升高,逐渐的计算机变的小型化、高效化。后来因为计算机其本身的计算能力比较的快速:独立模式:计算机之间相互独立。 如:有三个人,每个人做的不同的事物,但是是需要协作的完成。 而这三个人所做的事是需要进行协作的,然而刚开始因为每一台计算机之间都是互相独立的。所以前面的人处理完了就需要将数据
一、什么是MQTT协议MessageQueuingTelemetryTransport:消息队列遥测传输协议。是一种基于客户端-服务端的发布/订阅模式。与HTTP一样,基于TCP/IP协议之上的通讯协议,提供有序、无损、双向连接,由IBM(蓝色巨人)发布。原理:(1)MQTT协议身份和消息格式有三种身份:发布者(Publish)、代理(Broker)(服务器)、订阅者(Subscribe)。其中,消息的发布者和订阅者都是客户端,消息代理是服务器,消息发布者可以同时是订阅者。MQTT传输的消息分为:主题(Topic)和负载(payload)两部分Topic,可以理解为消息的类型,订阅者订阅(Su