学习链接:Building Convolutional Neural Network using NumPy from Scratch - KDnuggets
卷积层、激活函数、池化层
import numpy as np
import skimage.data
import matplotlib.pyplot as plt
def conv_(img, conv_filter):
filter_size = conv_filter.shape[0]
result = np.zeros((img.shape))
for r in np.uint16(np.arange(filter_size/2, img.shape[0]-filter_size/2 - 2)):
for c in np.uint16(np.arange(filter_size/2, img.shape[1]-filter_size/2 - 2)):
curr_region = img[r:r+filter_size, c:c+filter_size]
curr_result = curr_region * conv_filter
conv_sum = np.sum(curr_result)
result[r, c] = conv_sum
final_result = result[np.uint16(filter_size/2):result.shape[0]-np.uint16(filter_size/2), np.uint16(filter_size/2):result.shape[1]-np.uint16(filter_size/2)]
return final_result
def conv(img, conv_filter):
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_maps = np.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
def relu(feature_map):
relu_out = np.zeros(feature_map.shape)
for map_num in range(feature_map.shape[-1]):
for r in np.arange(0,feature_map.shape[0]):
for c in np.arange(0,feature_map.shape[1]):
relu_out[r, c, map_num] = np.max(feature_map[r,c,map_num], 0)
return relu_out
def pooling(feature_map, size=2, stride=2):
pool_out = np.zeros((np.uint16((feature_map.shape[0]-size+1)/stride), np.uint16((feature_map.shape[1]-size+1)/stride),feature_map.shape[-1]))
for map_num in range(feature_map.shape[-1]):
r2 = 0
for r in np.arange(0,feature_map.shape[0]-size-1, stride):
c2 = 0
for c in np.arange(0,feature_map.shape[1]-size-1, stride):
pool_out[r2, c2, map_num] = np.max(feature_map[r:r+size, c:c+size])
c2 = c2 + 1
r2 = r2 + 1
return pool_out
运行展示:
img = skimage.data.chelsea()
gray = skimage.color.rgb2gray(img)
l1_filter = np.zeros((2,3,3))
l1_filter[0,:,:] = np.array([[[-1,0,1],[-1,0,1],[-1,0,1]]])
l1_filter[1,:,:] = np.array([[[1,1,1],[0,0,0],[-1,-1,-1]]])
l1_feature_map = conv(gray, l1_filter)
l1_feature_map_relu = relu(l1_feature_map)
l1_feature_map_relu_pool = pooling(l1_feature_map_relu, 2, 2)
plt.subplot(421)
plt.imshow(img)
plt.subplot(422)
plt.imshow(gray)
plt.subplot(423)
plt.imshow(l1_feature_map[...,0])
plt.subplot(424)
plt.imshow(l1_feature_map[...,1])
plt.subplot(425)
plt.imshow(l1_feature_map_relu[...,0])
plt.subplot(426)
plt.imshow(l1_feature_map_relu[...,1])
plt.subplot(427)
plt.imshow(l1_feature_map_relu_pool[...,0])
plt.subplot(428)
plt.imshow(l1_feature_map_relu_pool[...,1])
plt.show()