卷积的数学意义及信号学应用 卷积(转自wiki百科) 卷积神经网络(CNN)之一维卷积、二维卷积、三维卷积详解

一、卷积的数学意义

   从数学上讲,卷积与加减乘除同样是一种运算,其运算的根本操做是将两个函数的其中一个先平移,而后再与另外一个函数相称后的累加和。这个运算过程当中,由于涉及到积分、级数的操做,因此看起来很复杂。在卷积(转自wiki百科)中已经讲过了卷积的定义以下所示:html

对于定义在连续域的函数,卷积定义为ios

 (f * g )(t) = \int f(\tau) g(t - \tau)\, d\tau

 

对于定义在离散域的函数,卷积定义为网络

(f * g)[m] = \sum_n {f[n] g[m - n]}

  这里令U(x,y) = f(x)g(y) ,考虑到函数 f 和 g 应该地位平等,即变量 x 和 y 应该地位平等,一种可取的办法就是沿直线 x+y = t将U(x,y)卷起来。下面为t取实际值的时候的坐标图,能够看到不一样取值的t能够遍历整个平面。函数

  将x+y=t中t取一次定值(这个定值多是咱们想要知道的某时刻的结果或着某种特征,由咱们赋值),代入到U(x,y)中,就至关于U(x,y)所在平面沿着x+y=t直线作一次旋转以下列动图所示:post

  这里即是完成了整个卷积的降维过程,完成降维过程后,U(x,y)也就从一个二元函数 U(x,y) = f(x)g(y) 被卷成一元函数 V(x)=f(x)g(t-x),最后再对x求积分(即遍历降维后的轴上的特征点之和)。学习

二、卷积的C语言编写

  编写卷积的程序,须要根据其离散方程组来进行了解。前面已经知道了卷积的离散函数的定义公式为:url

(f * g)[m] = \sum_n {f[n] g[m - n]}

  

在用C语言等其余语言进行实现是能够采用定义,利用两个for循环完成代码。 spa

  根据离散公式,能够编写以下C++代码:.net

#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>

using namespace std;
float min(float a, float b)
{
	return a < b ? a : b;
}
void convolution(float *input1, float *input2, float *output, int mm, int nn)
{
	float *xx = new float[mm + nn - 1];
	float *tempinput2 = new float[mm + nn - 1];
	for (int i = 0; i < nn; i++)
	{
		tempinput2[i] = input2[i];
	}
	for (int i = nn; i < mm + nn - 1; i++)
	{
		tempinput2[i] = 0.0;
	}
	// do convolution 
	for (int i = 0; i < mm + nn - 1; i++)
	{
		xx[i] = 0.0;
		int tem = (min(i, mm)) == mm ? mm - 1 : min(i, mm);
		for (int j = 0; j <= tem; j++)
		{
			xx[i] += (input1[j] * tempinput2[i - j]);
		}
	}
	// set value to the output array 
	for (int i = 0; i < mm + nn - 1; i++)
		output[i] = xx[i];
		delete[] xx;
}

int main()
{
	float a[3] = {2,6,4 };
	float b[5] = {1,2,5,4,8};
	float *c = new float[9];
	convolution(a, b, c, 3, 5);
	for (int i = 0; i < 7; i++)
	{
		cout << c[i] << " ";
	}
	getchar();
	return 0;
}

  

  运行结果如上图所示,打开matlab进行验证有:3d

 

卷积的列表法计算 :

 

如图所示:斜线上数据相加,即是卷积结果;该方法适合用于并行计算求卷积。

 

 

三、卷积的分类

  

1. 二维卷积

  • 图中的输入的数据维度为14×1414×14,过滤器大小为5×55×5,两者作卷积,输出的数据维度为10×1010×10(145+1=1014−5+1=10)。若是你对卷积维度的计算不清楚,能够参考我以前的博客吴恩达深度学习笔记(deeplearning.ai)之卷积神经网络(CNN)(上)

  • 上述内容没有引入channel的概念,也能够说channel的数量为1。若是将二维卷积中输入的channel的数量变为3,即输入的数据维度变为(14×14×314×14×3)。因为卷积操做中过滤器的channel数量必须与输入数据的channel数量相同,过滤器大小也变为5×5×35×5×3。在卷积的过程当中,过滤器与数据在channel方向分别卷积,以后将卷积后的数值相加,即执行10×1010×10次3个数值相加的操做,最终输出的数据维度为10×1010×10。

  • 以上都是在过滤器数量为1的状况下所进行的讨论。若是将过滤器的数量增长至16,即16个大小为10×10×310×10×3的过滤器,最终输出的数据维度就变为10×10×1610×10×16。能够理解为分别执行每一个过滤器的卷积操做,最后将每一个卷积的输出在第三个维度(channel 维度)上进行拼接。

  • 二维卷积经常使用于计算机视觉、图像处理领域。

2. 一维卷积

  • 图中的输入的数据维度为8,过滤器的维度为5。与二维卷积相似,卷积后输出的数据维度为85+1=48−5+1=4。

  • 若是过滤器数量仍为1,输入数据的channel数量变为16,即输入数据维度为8×168×16。这里channel的概念至关于天然语言处理中的embedding,而该输入数据表明8个单词,其中每一个单词的词向量维度大小为16。在这种状况下,过滤器的维度由55变为5×165×16,最终输出的数据维度仍为44。

  • 若是过滤器数量为nn,那么输出的数据维度就变为4×n4×n。

  • 一维卷积经常使用于序列模型,天然语言处理领域。

3. 三维卷积

这里采用代数的方式对三维卷积进行介绍,具体思想与一维卷积、二维卷积相同。

  • 假设输入数据的大小为a1×a2×a3a1×a2×a3,channel数为cc,过滤器大小为ff,即过滤器维度为f×f×f×cf×f×f×c(通常不写channel的维度),过滤器数量为nn。

  • 基于上述状况,三维卷积最终的输出为(a1f+1)×(a2f+1)×(a3f+1)×n(a1−f+1)×(a2−f+1)×(a3−f+1)×n。该公式对于一维卷积、二维卷积仍然有效,只有去掉不相干的输入数据维度就行。

  • 三维卷积经常使用于医学领域(CT影响),视频处理领域(检测动做及人物行为)。

 

 

四、卷积的信号学应用

打个比方,往平静的水面里面扔石头。咱们把水面的反应看做是一种冲击响应。水面在t=0时刻石头丢进去的时候会激起高度为h(0)的波纹,但水面不会立马归于平静,随着时间的流逝,波纹幅度会愈来愈小,在t=1时刻,幅度衰减为h(1), 在t=2时刻,幅度衰减为h(2)……直到一段时间后,水面重复归于平静。

从时间轴上来看,咱们只在t=0时刻丢了一块石头,其它时刻并无作任何事,但在t=1,2….时刻,水面是不平静的,这是由于过去(t=0时刻)的做用一直持续到了如今。

那么,问题来了:

若是咱们在t=1时刻也丢入一块石子呢?此时t=0时刻的影响尚未消失(水面尚未恢复平静)新的石子又丢进来了,那么如今激起的波浪有多高呢?答案是当前激起的波浪与t=0时刻残余的影响的叠加。那么t=0时刻对t=1时刻的残余影响有多大呢?


为了便于说明,接下来咱们做一下两个假设:

1. 水面对于“单位石块”的响应是固定的

2. 丢一个两倍于的“单位石块”的石块激起的波纹高度是丢一个石块的两倍(即系统知足线性叠加原理)

如今咱们来计算每一时刻的波浪有多高:

  • t=0时刻:

y(0)=x(0)*h(0);

  • t=1时刻:

当前石块引发的影响x(1)*h(0);

t=0时刻石块x(0)引发的残余影响x(0)*h(1);

y(1)=x(1)*h(0)+ x(0)*h(1);

  • t=2时刻:

当前石块引发的影响x(2)*h(0);

t=0时刻石块x(0)引发的残余影响x(0)*h(2);

t=1时刻石块x(1)引发的残余影响x(1)*h(1);

y(2)=x(2)*h(0)+ x(1)*h(1)+x(0)*h(2);

……

  • t=N时刻:

当前石块引发的影响x(N)*h(0);

t=0时刻石块x(0)引发的残余影响x(0)*h(N);

t=1时刻石块x(1)引发的残余影响x(1)*h(N-1);

y(N)=x(N)*h(0)+ x(N-1)*h(1)+x(N-2)*h(2)+…+x(0)*h(N);

这就是离散卷积的公式了

理解了上面的问题,下面咱们来看看“翻转”是怎么回事:

当咱们每次要丢石子时,站在当前的时间点,系统的对咱们的回应都是h(0),时间轴以后的(h(1),h(2).....)都是对将来的影响。而总体的回应要加上过去对于如今的残余影响。

如今咱们来观察t=4这个时刻。

站在t=0时刻看他对于将来(t=4)时刻(从如今日后4秒)的影响,可见是x(0)*h(4)

站在t=1时刻看他对于将来(t=4)时刻的影响(从如今日后3秒),可见是x(1)*h(3)

站在t=2时刻看他对于将来(t=4)时刻的影响(从如今日后2秒),可见是x(2)*h(2)

站在t=3时刻看他对于将来(t=4)时刻的影响(从如今日后1秒),可见是x(3)*h(1)

因此所谓的翻转只是由于你站立的如今是过去的将来,而由于h(t)始终不变,故h(1)实际上是前一秒的h(1),而前一秒的h(1)就是如今,因此从当前x(4)的角度往左看,你看到的是过去的做用。h(t)未翻转前,当从h(0)往右看,你看到的是如今对于将来的影响,当翻转h(t)以后,从h(0)往左看,你依次看到的愈来愈远的过去对如今的影响,而这个影响,与从x=4向左看的做用影响相对应(都是愈来愈远的过去),做用与做用的响应就对应起来了,这一切的本质,是由于你站立的时间观察点和方向在变。

   

 五、卷积的图像处理原理

    一幅图像在生成的过程当中,会随机产生一些噪点,以下图所示:

 

  噪点在图片中,就至关于在平地上耸起的山峰,是一个与其余数据不符的一个较大值。

     

 

   咱们能够经过卷积操做将噪点经过滤波给滤掉,首先,将图片用矩阵表示出来。

  而后经过下面的核来进行滤波(这个在后面的文章中将会详细讲到,原理与卷积在信号处理中的应用同样)

  通过以下的卷积运算

  就能够完成在图片上的平均滤波的效果了,经过卷积滤波后的效果以下所示:

 

 

 

 

 

 

参考资料

卷积为何叫「卷」积?

如何通俗易懂地解释卷积?

在定义卷积时为何要对其中一个函数进行翻转?

Matlab中fileter和conv的区别及卷积的计算方法

卷积C语言实现

卷积神经网络(CNN)之一维卷积、二维卷积、三维卷积详解

相关文章
相关标签/搜索