准备数据
# print(img)
# 读取图片
img = skimage.data.chelsea()
# 将图片转换为黑白
img = skimage.color.rgb2gray(img)
plt.imshow(img,cmap='gray')
<matplotlib.image.AxesImage at 0x1c25f70ad0>
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
# 现在我们有了卷积核和图片
print(img.shape)
print(ll_filter.shape)
# print(ll_filter)
(300, 451)
(2, 3, 3)
def conv_(img,conv_filter):
filter_size = conv_filter.shape[0]
print(filter_size)
result = np.zeros((img.shape))
# print(np.uint16(np.arange(filter_size/2,img.shape[0]-filter_size/2-2)))
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
# for r in np.uint16(np.arange(filter_size/2))
conv_ 方法是返回一个做了卷积后的图片,传入两个参数第一个 img 为一张灰度图,因为只有一个通道(channel)。虽然这 conv_filter 卷积核。filter_size 获取卷积核大小这里 的卷积核。然后一张图片,我们需要图片进行卷积进行处理,然后就是遍历图片,每次通过 curr_region 在图片上从左上角到右下角进行游走获取卷积核大小矩阵然后和卷积做元素相乘后取和,将结果赋值给新的图片的像素
print(np.arange(1.5,10.5))
print(np.uint16(np.arange(1.5,10.5)))
[1.5 2.5 3.5 4.5 5.5 6.5 7.5 8.5 9.5]
[1 2 3 4 5 6 7 8 9]
feature_maps = np.zeros((img.shape[0]-ll_filter.shape[1]+1,
img.shape[1] - ll_filter.shape[1]+1,
ll_filter.shape[0]))
print(feature_maps.shape)
(298, 449, 2)
这里我们创建 feature_maps 特征,(334,634) 我们对图片进行补 0 以保证卷积后图片保持与卷积前图片大小一致。因为有连个卷积所以卷积后深度为2
for filter_idx in range(ll_filter.shape[0]):
print("Filter",filter_idx + 1)
# 当前卷积核
curr_filter = ll_filter[filter_idx,:]
print(len(curr_filter.shape))
conv_map = conv_(img,curr_filter)
feature_maps[:, :, filter_idx] = conv_map
print(feature_maps.shape)
plt.figure(figsize=(12,6))
plt.subplot(1,2,1)
plt.imshow(feature_maps[:,:,0],cmap="gray")
plt.subplot(1,2,2)
plt.imshow(feature_maps[:,:,1],cmap="gray")
Filter 1
2
3
Filter 2
2
3
(298, 449, 2)
<matplotlib.image.AxesImage at 0x1c2631d250>
output_14_2.png
激活函数
这里激活函数使用 relu,我们可以看一看 relu 的样子,如果输出小于求取 0 ,大于 0 情况就取该值。
<img src="images/relu.jpeg"/>
def relu(feature_map):
# 定义 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
feature_maps_rule = relu(feature_maps)
print(feature_maps_rule.shape)
plt.figure(figsize=(12,6))
plt.subplot(1,2,1)
plt.imshow(feature_maps_rule[:,:,0],cmap="gray")
plt.subplot(1,2,2)
plt.imshow(feature_maps_rule[:,:,1],cmap="gray")
(298, 449, 2)
<matplotlib.image.AxesImage at 0x1c268e1350>
output_17_2.png
池化层
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
feature_map_relu_pool = pooling(feature_maps_rule, 2, 2)
plt.figure(figsize=(12,6))
plt.subplot(1,2,1)
plt.imshow(feature_map_relu_pool[:,:,0],cmap="gray")
plt.subplot(1,2,2)
plt.imshow(feature_map_relu_pool[:,:,1],cmap="gray")
<matplotlib.image.AxesImage at 0x10aab1650>
output_20_1.png
最后希望大家关注我们微信公众号
wechat.jpeg
网友评论