欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

卷积神经网络--卷积层--代码初级实现

程序员文章站 2022-06-26 11:30:13
...

       3D特征图表示为 [H x W x D],其中 H是高度,W是宽度,D是深度。理解3D特征图是打开卷积层的钥匙,3D特征图可以看作D个2D数据,每个2D数据的尺寸均是 [H x W],称为特征图,3D特征图总共有D特征图。升级做法如下:每个特征图都分别与一个卷积核进行卷积运算,这样就得到D个特征图,这D个特征图先进行矩阵相加,得到一个特征图,再给该特征图的每一个元素再加一个相同的偏置,最终得到一个新的特征图

卷积层运算过程初级代码实现:

def conv2D(input_2Ddata, kern):
	(h, w) = input_2Ddata# 输入数据的宽度和高度
	(kern_h, kern_w) = kern.shape# 卷积核的宽度和高度
	padding_h = (kern_h-1)//2#根据卷积核的大小,计算原图像边缘应添加的0的层数。例如,卷积核大小是3x3,则(3-1)//2 = 1,即上下边缘各添加1层。卷积核大小是5x5,则(5-1)//2 = 2,即上下边缘各添加2层。
	padding_w = (kern_w-1)//2
	padding = np.zeros(shape = (h+2*padding_h, w+2*padding_w))#创建一个与原图像边缘扩充后的大小一致的矩阵。
	padding[padding_h:-padding_h,padding_w:-padding_w] = input_2Ddata#将原图像数据存入其中,并置于正中间位置,扩充的边缘不能占据。
	output_2Ddata = np.zeros(shape = (h, w))#输出数据的尺寸和输入数据一致,并用于保存输入数据和卷积核卷积后的结果。
	for i in range(h):
		for j in range(w):
			window = padding[i:i+kern_h,i:i+kern_w]#局部窗口
			output_2Ddata[i,j] = np.sum(kern*window)#输入数据和卷积核卷积
		return output_2Ddata
#########################################################################
h = 32 #输入数据的高度
w = 48 #输入数据的宽度
in_d = 12#输入数据的深度
out_d = 24#输出数据的深度,(通过24个卷积核组卷积,产生的24个输出特征矩阵)
input_3Ddata = np.random.randn(h, w, in_d)
output_3Ddata = np.zeros(shape(h, w, out_d))#24层,每层保存了,每个卷积核组计算的特征结果

(kern_h, kern_w) = (3, 3)#或者(5, 5)
kerns = np.random.randn(out_d,h, w, in_d)#4D卷积核(保存了24个不同卷积核组,每个卷积核组的每层卷积核大小值)。
bias = np.random.randn(out_d)#产生的24个输出特征矩阵,每个矩阵都要加一个偏置。

for m in range(out_d):#每个卷积核组,产生的特征矩阵,并存入output_3Ddata每层中。
	for k in range(in_d):
		input_2Ddata = input_3Ddata[:,:,k]#提取input_3Ddata第k层数据,作为输入数据
		kern = kerns[m, :, :,k]#提取每个卷积核组的每层卷积核
		output_3Ddata += conv2D(input_2Ddata, kern)#卷积后的结果保存其中,12层特征都相加,产生最终特征。
	output_3Ddata[:, :, m] += bias[m]#m每层卷积核组产生的特征矩阵,还要加上同一偏置。