概述
本文通过手动实现RGB图的卷积运算过程,深刻理解卷积运算
导入模块
import tensorflow as tf
from tensorflow.keras import Sequential
from tensorflow.keras.layers import Input,Conv2D, MaxPool2D,GlobalAveragePooling2D,BatchNormalization
from tensorflow.keras.layers import Activation
import matplotlib.pyplot as plt
from PIL import Image
import numpy as np
读取图片
path=r"C:\Users\mym\Desktop\文件接收柜\timgxingxing.jpg"
im = Image.open(path)
img=np.array(im)
print('输入图shape:',img.shape)
转维度
img_batch = img.reshape(1,img.shape[0],img.shape[1],img.shape[2])
print('输入图shape:',img_batch.shape)
建立模型
model=Sequential()
model.add(Conv2D(1, (3, 3),input_shape=img_batch.shape[1:]))
model.summary()
运行模型
prd=model.predict(img_batch)
"""
第一维度:输入图片的数量
第二、三维度:图片高、宽
第四维度:卷积核数量
1个3通道图,即3个二维矩阵,经过1个卷积核运算后,其结果是1个二维矩阵
也就是说:3通道图运算结果与灰度图 的维度相同
"""
prd.shape
转成二维
# 转成2维
conv_result=prd.reshape(prd.shape[1:3])
conv_result.shape
查看卷积结果
conv_result
查看权重
# 查看卷积核,3通道图,也就是3个卷积核
w,b=model.layers[0].get_weights()
w.shape
转成2维矩阵
# 转成2维矩阵
w2=w.reshape(w.shape[0:3])
w2.shape
实现卷积函数
# 卷积运算
def run_conv(data,kernel,step=1):
"""
data:要计算的图像数据
kernel:卷积核值
step:步长
"""
data_w=data.shape[1]
data_h=data.shape[0]
# print(data_w,data_h)
# 卷积核大小
kernel_w=kernel.shape[1]
kernel_h=kernel.shape[0]
# 结果大小
result_w=(data_w-kernel_w)//step+1
result_h=(data_h-kernel_h)//step+1
# 输入数据的滑块索引
data_w_index=0
data_h_index=0
result_data=np.zeros((result_h,result_w))
# print(result_h,result_w)
res_w_index=0
res_h_index=0
while (data_w_index+kernel_w)<=data_w:
while (data_h_index+kernel_h)<=data_h:
img_area=data[data_h_index:data_h_index+kernel_h,data_w_index:data_w_index+kernel_w]
result_data[res_h_index][res_w_index]=np.sum(img_area*kernel)
data_h_index+=step
res_h_index+=1
data_w_index+=step
data_h_index=0
res_w_index+=1
res_h_index=0
return result_data
my_conv=run_conv(img,w2)
my_conv.shape
运行
my_conv=run_conv(img,w2)
my_conv.shape
查看卷积结果
my_conv
查看卷积结果和手动实现结果的差
# 查看卷积结果和手动实现结果的差
for i in range(conv_result.shape[0]):
for j in range(conv_result.shape[1]):
if (conv_result[i,j] - my_conv[i,j]) >0.0001:
print(i,j,">>>",conv_result[i,j],'-',my_conv[i,j],"=",conv_result[i,j]-my_conv[i,j])