练习numpy实现卷积

学习链接: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()

练习numpy实现卷积_第1张图片

你可能感兴趣的:(python,深度学习)