目錄
- 1 簡介
- 2 使用卷積
- 3 開始編碼
- 4 創建卷積
- 5 查看結果
- 6 瞭解池化
- 7 編寫池化代碼
1 簡介
在本節中,你將瞭解卷積以及它們在計算機視覺場景中如此強大的原因。
在上一節中,我們瞭解瞭如何使用Fashion MNIST數據集爲時尚項目訓練圖像分類器。但這裏有一個明顯的約束:圖像時28×28的,且圖像在圖片居中。
例如,這裏有Fshion MNIST中的幾張圖。
上節我們創建的全連接網絡DNN知識從構成毛衣的原始像素中學到的,那麼考慮一下如何對下面這張圖片進行分類呢?
雖然很明顯這張圖片有靴子,但分類器會因多種原因而失敗。首先,它不是28×28的灰度圖,更重要的是,分類器是從左開始的原始像素上進行訓練的。要解決此問題,可以使用Convolutions
2 使用卷積
卷積是一種過濾器,它通過圖像處理它,並提取在圖像中顯示共性的特徵。在本節中,我們將看到它們的工作原理,並處理圖像以查看是否可以從中提取特徵。
這個過程非常簡單,我們只需掃描圖像中的每個像素,然後查看其相鄰像素。我們可以將這些像素的值乘以濾波器中的等效權重。
下面將通過在2D圖像中來探索卷積的工作原理。
主要是通過scipy的ascent
圖像來證明這一點。這是一個很好的內置圖片 ,有很多角度和線條。
3 開始編碼
首先引入一些Python庫並獲取上升圖片
import cv2
import numpy as np
from scipy import misc
i = misc.ascent()
接下來,使用pyplot
庫來繪製圖形,以便我們知道圖像樣子
import matplotlib.pyplot as plt
%matplotlib inline
plt.grid(False)
plt.gray()
plt.axis("off")
plt.imshow(i)
<matplotlib.image.AxesImage at 0x1bcc4ea6198>
我們可以看到這是一個樓梯間的圖像。我們可以試試是否可以隔離它們,例如:強烈的垂直線。
圖像存儲爲numpy數組,我們可以通過複製該數組來創建轉換後的圖像。
i_transformed = np.copy(i)
size_x = i_transformed.shape[0]
size_y = i_transformed.shape[1]
4 創建卷積
首先,我們將卷積矩陣設爲3×3的數組。
filter = [[-1,-2,-1],[0,0,0],[1,2,1]]
weight = 1
現在我們將計算像素,迭代圖像。
for x in range(1,size_x-1):
for y in range(1,size_y-1):
output_pixel = 0.0
output_pixel = output_pixel + (i[x - 1, y-1] * filter[0][0])
output_pixel = output_pixel + (i[x, y-1] * filter[0][1])
output_pixel = output_pixel + (i[x + 1, y-1] * filter[0][2])
output_pixel = output_pixel + (i[x-1, y] * filter[1][0])
output_pixel = output_pixel + (i[x, y] * filter[1][1])
output_pixel = output_pixel + (i[x+1, y] * filter[1][2])
output_pixel = output_pixel + (i[x-1, y+1] * filter[2][0])
output_pixel = output_pixel + (i[x, y+1] * filter[2][1])
output_pixel = output_pixel + (i[x+1, y+1] * filter[2][2])
output_pixel = output_pixel * weight
if output_pixel<0:
output_pixel = 0
if output_pixel>255:
output_pixel = 255
i_transformed[x,y] = output_pixel
5 查看結果
現在我們可以繪製圖像來查看卷積後的圖像的結果
plt.gray()
plt.grid(False)
plt.imshow(i_transformed)
<matplotlib.image.AxesImage at 0x1bcc875e198>
下面,將考慮卷積覈對圖像的影響。
使用[-1,0,1,-2,0,2,-1,0,1]
爲我們提供了一組非常強大的垂直線:
使用[-1,-2,-1,0,0,0,1,2,1]
提供了一組水平線
6 瞭解池化
除了使用卷積,池化還可以幫助我實現檢測功能。池化的目標是減少圖像中的總信息兩,並同時保持檢測到特徵存在。
其實有許多不同類型的池,但對於本實驗,我們將使用一個稱爲MAX的池。
這裏的想法是迭代圖像,並考慮右側、下方和右下方的像素及其近鄰。取其中最大的加載到新圖像中。因此,新圖像時舊圖像的1/4.
7 編寫池化代碼
此代碼將執行(2,2)池。運行它並查看輸出結果,我們將看到圖像時原始尺寸的1/4,同時保留所有特徵。
new_x = int(size_x/2)
new_y = int(size_y/2)
newImage = np.zeros((new_x,new_y))
for x in range(0,size_x,2):
for y in range(0,size_y,2):
pixels = []
pixels.append(i_transformed[x, y])
pixels.append(i_transformed[x+1, y])
pixels.append(i_transformed[x, y+1])
pixels.append(i_transformed[x+1, y+1])
pixels.sort(reverse=True)
newImage[int(x/2),int(y/2)] = pixels[0]
plt.gray()
plt.grid(False)
plt.imshow(newImage)
<matplotlib.image.AxesImage at 0x1bcc8a401d0>
注意,此時圖像現在是256×256,原始尺寸的1/4,並且檢測到的功能已得到增強。