初识
在神经网络中,每一层的每个神经元都与下一层的每个神经元相连, 这种连接关系叫全连接(Full Connected)。
左图为全连接网络 右图为卷积神经网络
左图:全连接神经网络(平面),组成:输入层、激活函数、全连接层
右图:卷积神经网络(立体),组成:输入层、卷积层、激活函数、池化层、全连接层
卷积神经网络可以简单地理解为,用滤波器(Filter)将相邻像素之间的"轮廓"过滤出来。
卷积运算基本概念
在数字图像处理中有一种最为基本的处理方法,即线性滤波。将待处理的二维数字看作一个大型矩阵,图像中的每个像素可以看作矩阵中的每个元素,像素的大小就是矩阵中的元素值。这里使用的滤波工具是另一个小型矩阵,这个矩阵被称为卷积核。卷积核的大小远远小于图像矩阵,具体的计算方式就是对于图像大矩阵中的每个像素,计算其周围的像素和卷积核对应位置的乘积,之后将结果相加,最终得到的终值就是该像素的值,这样就完成了一次卷积。最简单的图像卷积方式所示。
卷积实际上是使用两个大小不同的矩阵进行的一种数学运算,需要对高速公路上的跑车进行位置追踪,这也是卷积神经网络图像处理的一个非常重要的应用。摄像头接收到的信号被计算为x(t),表示跑车在路上时刻t的位置。但是往往实际上的处理没这么简单,因为在自然界无时无刻存在着各种影响,比如摄像头传感器的滞后。因此为了得到跑车位置的实时数据,采用的方法就是对测量结果进行均值化处理.但是对于运动中的目标,时间越久的位置则越不可靠,而时间离计算时越短的位置则与真实值的相关性越高。因此可以对不同的时间段赋予不同的权重,即通过一个权值定义来计算
在卷积公式中,第一个参数x被称为“输入数据”,而第二个参数o被称为“核函数”s(t)是输出,即特征映射。数字图像处理卷积运算主要有两种思维,即“稀疏矩阵”与“参数共享”。首先对于稀疏矩阵来说,卷积网络具有稀疏性,即卷积核的大小远远小于输入数据矩阼的大小。 例如当输入一个图片信息时,数据的大小可能为上万的结构,但是使用的卷积核只有几十,这样能够在计算后获取更少的参数特征,极大地减少了后续的计算量。参数共享指的是在特征提取过程中,一个模型在多个参数之中使用相同的参数,在传的神经网络中,每个权重只对其连接的输入输出起作用,当其连接的输入输出元素结束后)不会再用到。参数共享指的是在卷积神经网络中,核的每一个元素都被用在输入的每一个位上,在计算过程中只需学习一个参数集合就能把这个参数应用到所有的图片元素中。
使用卷积对矩阵操作
import struct
import matplotlib.pyplot as plt
import numpy as np
dataMat = np.ones([7,7]) #被卷积矩阵
kernel = np.array([[2,1,1],[3,0,1],[1,1,0]]) #卷积核
def convolve(dataMat , kernel):
m , n = dataMat.shape
km , kn = kernel.shape
newMat = np.ones(((m - km + 1) , (n - kn + 1)))
tempMat = np.ones(((km) , (kn)))
for row in range(m - km + 1):
for col in range(n - kn + 1):
for m_k in range(km):
for n_k in range(kn):
tempMat[m_k , n_k] = dataMat[(row + m_k) , (col + n_k)] * kernel[m_k , n_k]
newMat[row , col] = np.sum(tempMat)
return newMat
newMat = convolve(dataMat , kernel)
print(newMat)
TensorFlow 卷积运算
tf.nn.conv2d(input, filter, strides, padding, use_cudnn_on_gpu=None, data_format=None, name=None)
给定一个input的张量[batch, in_height, in_width, in_channels]和一个过滤器 / 内核张量 [filter_height, filter_width, in_channels, out_channels]后,执行以下操作:
展平filter为一个形状为[filter_height * filter_width * in_channels, output_channels]的二维矩阵。
从input中按照filter大小提取图片子集形成一个大小为[batch, out_height, out_width, filter_height * filter_width * in_channels]的虚拟张量。
循环每个图片子集,右乘filter矩阵。
import tensorflow as tf
input = tf.Variable(tf.random_normal([1 , 3 , 3 , 1]))
filter = tf.Variable(tf.ones([1 ,1 , 1 , 1]))
init = tf.global_variables_initializer()
with tf.Session() as sess:
sess.run(init)
conv2d = tf.nn.conv2d(input , filter , strides = [1 , 1 , 1 , 1] , padding = 'VALID')
print(sess.run(conv2d))