1. 影像歸一化
影像歸一化是指對影像進行了一系列標準的處理變換,使之變換為一固定標準形式的過程,該標準影像稱作歸一化影像。
在機器學習中,不同評價指標(即特徵向量中的不同特徵,就是所述的不同評價指標)往往具有不同的量綱和量綱單位,這樣的情況會影響到資料分析的結果。為了消除指標之間的量綱影響,需要進行資料標準化處理,以解決資料指標之間的可比性。原始資料經過資料標準化處理後,各指標處於同一數量級,適合進行綜合對比評價。其中,最典型的就是資料的歸一化處理。簡而言之,歸一化的目的就是使得預處理的資料被限定在一定的範圍內(比如[0,1]或者[-1,1]),從而消除奇異樣本資料導致的不良影響。
在深度學習中,通常在模型訓練前都會對影像進行歸一化處理,而對影像進行歸一化處理是將特徵值大小調整到相近的範圍,不歸一化處理時,如果特徵值較大時,梯度值也會較大,特徵值較小時,梯度值也會較小。在模型反向傳播時,梯度值更新與學習率一樣,當學習率較小時,梯度值較小會導致更新緩慢,當學習率較大時,梯度值較大會導致模型不易收斂,因此為了使模型訓練收斂平穩,對影像進行歸一化操作,把不同維度的特徵值調整到相近的範圍內,就可以採用統一的學習率加速模型訓練。
2. 影像歸一化的常用方法及Python應用
2.1 Min-Max歸一化
透過遍歷影像矩陣中的每一個畫素,設定max和min,進行資料的歸一化處理,公式如下:
(1)線性函式將原始資料用線性化的方法轉換到[0,1]的範圍,計算結果x’為歸一化後的資料,x為原始資料。(2)Min-Max歸一化方法比較適用在數值比較集中的情況。
(3)缺點:如果max和min不穩定,很容易使得歸一化結果不穩定,使得後續使用效果也不穩定。實際使用中可以用經驗常量來替代max和min。
測試程式碼如下:
img = cv.imread('lenna.jpg')
gray = cv.cvtColor(img,cv.COLOR_BGR2GRAY)
h,w = gray.shape
mn = np.min(gray)
mx = np.max(gray)
norm = np.zeros((h,w),dtype=np.float32) # 自定義空白單通道影像,用於存放歸一化影像
for i in range(h):
for j in range(w):
norm[i,j] = (gray[i,j] - mn) / (mx - mn)
#norm[i,j] = gray[i,j] / 255
print('歸一化前:')
print(gray)
print('歸一化後:')
print(norm)
plt.subplot(121), plt.imshow(gray, 'gray'), plt.title('gray')
plt.axis('off')
plt.subplot(122), plt.imshow(norm, 'gray'), plt.title('normalization')
plt.axis('off')
plt.show()
歸一化前後灰度影像矩陣如下所示:
歸一化前後灰度影像對比如下所示:
2.2 z-score標準化
z-score標準化公式如下:
其中,μ、σ分別為原始資料集的均值和方法。
(1)將原始資料集歸一化為均值為0、方差1的資料集。
(2)該種歸一化方式要求原始資料的分佈可以近似為高斯分佈,否則歸一化的效果會變得很糟糕。
(3)應用場景:在分類、聚類演算法中,需要使用距離來度量相似性的時候、或者使用PCA技術進行降維的時候,z-score standardization表現更好。
測試程式碼如下:
img = cv.imread('lenna.jpg')
gray = cv.cvtColor(img,cv.COLOR_BGR2GRAY)
h,w = gray.shape
x_mean = np.mean(gray)
vari = np.sqrt((np.sum((gray-x_mean)**2))/(h*w))
norm = np.zeros((h,w),dtype=np.float32) # 自定義空白單通道影像,用於存放歸一化影像
for i in range(h):
for j in range(w):
norm[i,j] = (gray[i,j] - x_mean) / vari
#norm[i,j] = gray[i,j] / 127.5 - 1
print('歸一化前:')
print(gray)
print('歸一化後:')
print(norm)
plt.subplot(121), plt.imshow(gray, 'gray'), plt.title('gray')
plt.axis('off')
plt.subplot(122), plt.imshow(norm, 'gray'), plt.title('normalization')
plt.axis('off')
plt.show()
歸一化前後灰度影像矩陣如下所示:
歸一化前後灰度影像對比如下所示:
2.3 神經網路歸一化
該歸一化方法經常用在資料分化比較大的場景,有些數值很大,有些很小。透過一些數學函式,將原始值進行對映。該方法包括log,反正切等,需要根據資料分佈的情況,決定非線性函式的曲線。
2.3.1 log對數函式歸一化
y = log10(x),即以10為底的對數轉換函式,對應的歸一化方法為:
其中max表示樣本資料的最大值,並且所有樣本資料均要大於等於1。
測試程式碼如下:
img = cv.imread('lenna.jpg')
gray = cv.cvtColor(img,cv.COLOR_BGR2GRAY)
h,w = gray.shape
norm = np.zeros((h,w),dtype=np.float32) # 自定義空白單通道影像,用於存放歸一化影像
norm = np.log10(gray) / np.log10(gray.max())
print('歸一化前:')
print(gray)
print('歸一化後:')
print(norm)
plt.subplot(121), plt.imshow(gray, 'gray'), plt.title('gray')
plt.axis('off')
plt.subplot(122), plt.imshow(norm, 'gray'), plt.title('normalization')
plt.axis('off')
plt.show()
歸一化前後灰度影像矩陣如下所示:
歸一化前後灰度影像對比如下所示:
2.3.2 反正切函式歸一化
對應的歸一化方法為:x' = atan(x)*(2/pi)
使用這個方法需要注意的是如果想對映的區間為[0,1],則資料都應該大於等於0,小於0的資料將被對映到[-1,0]區間上。
測試程式碼如下:
img = cv.imread('lenna.jpg')
gray = cv.cvtColor(img,cv.COLOR_BGR2GRAY)
h,w = gray.shape
norm = np.zeros((h,w),dtype=np.float32) # 自定義空白單通道影像,用於存放歸一化影像
norm = np.arctan(gray) * (2 / np.pi)
print('歸一化前:')
print(gray)
print('歸一化後:')
print(norm)
plt.subplot(121), plt.imshow(gray, 'gray'), plt.title('gray')
plt.axis('off')
plt.subplot(122), plt.imshow(norm, 'gray'), plt.title('normalization')
plt.axis('off')
plt.show()
歸一化前後灰度影像矩陣如下所示:
歸一化前後灰度影像對比如下所示:
2.4 L2範數歸一化
定義:特徵向量中每個元素均除以向量的範數,即如下公式:
向量x(x1,x2,...,xn)的L2範數定義為:
測試程式碼如下:
img = cv.imread('lenna.jpg')
gray = cv.cvtColor(img,cv.COLOR_BGR2GRAY)
h,w = gray.shape
norm = np.zeros((h,w),dtype=np.float32) # 自定義空白單通道影像,用於存放歸一化影像
for i in range(h):
for j in range(w):
norm_x = 0.0 + gray[i,j]**2
norm_x = np.sqrt(norm_x)
norm = gray / norm_x
print('歸一化前:')
print(gray)
print('歸一化後:')
print(norm)
plt.subplot(121), plt.imshow(gray, 'gray'), plt.title('gray')
plt.axis('off')
plt.subplot(122), plt.imshow(norm, 'gray'), plt.title('normalization')
plt.axis('off')
plt.show()
歸一化前後灰度影像矩陣如下所示:
歸一化前後灰度影像對比如下所示:
3. opencv-python中歸一化方法的應用
opencv-python中使用cv2.normalize()函式實現歸一化,其函式原型如下:
cv2.normalize(src[, dst[, alpha[, beta[, norm_type[, dtype[, mask]]]]]]) → dst
引數說明:
src:輸入陣列;
dst:輸出陣列,陣列的大小和原陣列一致;
alpha:1.用來規範值。2.規範範圍,並且是下限;
beta:只用來規範範圍並且是上限;
norm_type:歸一化選擇的數學公式型別;
dtype:當為負,輸出在大小深度通道數都等於輸入,當為正,輸出只在深度與輸入不同,不同的地方由dtype決定;
mark:掩碼。選擇感興趣區域,選定後只能對該區域進行操作。
歸一化選擇的數學公式型別有如下幾種:
NORM_MINMAX:陣列的數值被平移或縮放到一個指定的範圍,線性歸一化,一般較常用;
NORM_INF:矩陣中絕對值的最大值;
NORM_L1:歸一化陣列的L1-範數(絕對值的和);
NORM_L2:歸一化陣列的(歐幾里德)L2-範數。
測試程式碼如下(以NORM_MINMAX為例):
img = cv.imread('lenna.jpg')
gray = cv.cvtColor(img,cv.COLOR_BGR2GRAY)
h,w = gray.shape
norm = np.zeros((h,w),dtype=np.float32) # 自定義空白單通道影像,用於存放歸一化影像
cv.normalize(gray, norm, alpha=0, beta=1, norm_type=cv.NORM_MINMAX, dtype=cv.CV_32F)
# norm = np.uint8(norm*255.0)
print('歸一化前:')
print(gray)
print('歸一化後:')
print(norm)
plt.subplot(121), plt.imshow(gray, 'gray'), plt.title('gray')
plt.axis('off')
plt.subplot(122), plt.imshow(norm, 'gray'), plt.title('normalization')
plt.axis('off')
plt.show()
歸一化前後灰度影像矩陣如下所示,可以發現與2.1節Min-Max歸一化處理結果一致:
歸一化前後灰度影像對比如下所示: