卷积神经网在当下流行深度学习框架如 tensorflow mxnet 都提供 API 很容就能够实现卷积神经网,但是为了更好的掌握和理解卷积神经网,今天要自己试着实现一个卷积神经网。仅使用 NumPy 来实现一个卷积神经网(CNN)。
我们要做的卷积神经网(CNN)包括卷积层(conv)、激活函数用 ReLU 和一个使用 max 的池化层
# 导入依赖
%matplotlib inline
import skimage.data
import matplotlib.pyplot as plt
import numpy as np
准备数据
# print(img)
# 读取图片
img = skimage.data.chelsea()
# 将图片转换为黑白
img = skimage.color.rgb2gray(img)
plt.imshow(img,cmap='gray')
<matplotlib.image.AxesImage at 0x1c242e5090>
output_3_1.png
ll_filter = np.zeros((2,3,3))
用 numpy.zeros 创建 的矩阵作为卷积核集合,这里 2 表示有两个卷积核,卷积核大小都是 因为输入灰度图,也就是只有一个通道,所以个卷积就够了。如果图片是 RGB 3 个通道,我们就需要适当增加卷积核的深度或者用 3 个卷积核来提取特征。
ll_filter[0,:,:] = np.array([[
[-1,0,1],
[-1,0,1],
[-1,0,1]
]])
ll_filter[1,:,:] = np.array([[
[1,1,1],
[0,0,0],
[-1,-1,-1]
]])
print(ll_filter.shape)
print(len(ll_filter.shape))
curr_filter = ll_filter[0, :]
print(curr_filter)
print(len(curr_filter.shape))
(2, 3, 3)
3
[[-1. 0. 1.]
[-1. 0. 1.]
[-1. 0. 1.]]
2
def conv(img, conv_filter):
# 检测图片数据矩阵 3 维 卷积核深度和图片深度是否一致
if len(img.shape) > 2 or len(conv_filter.shape) > 3:
if img.shape[-1] != conv_filter.shape[-1]:
print("Error: Number of channels in both image and filter must match.")
sys.exit()
# 检查卷积核矩阵是否为方阵
if conv_filter.shape[1] != conv_filter.shape[2]:
print('Error: Filter must be a square matrix. I.e. number of rows and columns must match.')
sys.exit()
# 检查矩阵是否为偶数矩阵
if conv_filter.shape[1]%2==0:
print('Error: Filter must have an odd size. I.e. number of rows and columns must be odd.')
sys.exit()
# 初始化 feature map 来保存过滤后图片数据
feature_maps = numpy.zeros((img.shape[0]-conv_filter.shape[1]+1,
img.shape[1]-conv_filter.shape[1]+1,
conv_filter.shape[0]))
# 使用过滤器来提取图片特征
# 卷积核数量数量,分别遍历卷积核
for filter_num in range(conv_filter.shape[0]):
print("Filter ", filter_num + 1)
# 获取每一个卷积核(过滤器)
curr_filter = conv_filter[filter_num, :]
#
if len(curr_filter.shape) > 2: #非单通道的卷积核
conv_map = conv_(img[:, :, 0], curr_filter[:, :, 0])
for ch_num in range(1, curr_filter.shape[-1]):
conv_map = conv_map + conv_(img[:, :, ch_num],
curr_filter[:, :, ch_num])
else: # 单一通道卷积核
conv_map = conv_(img, curr_filter)
feature_maps[:, :, filter_num] = conv_map
return feature_maps
首先要做的工作是检查每个滤波器的深度等于图像通道的数量。然后再进一步检查图片和过滤器最后一维是否相等。
if len(img.shape) > 2 or len(conv_filter.shape) > 3:
if img.shape[-1] != conv_filter.shape[-1]:
print("Error: Number of channels in both image and filter must match.")
sys.exit()
最后希望大家关注我们微信公众号
wechat.jpeg
网友评论