卷積神經網絡: 含卷積層,有
寬和高
兩個維度,常用來處理圖像數據。
1.二維卷積(互相關運算)
'''
二維互相關運算:
1. 卷積窗口(又被稱卷積核或過濾器(filter))從輸入數組的最左上方開始,按從左往右、從上往下的順序, 依次在輸入數組上滑動;
2. 當卷積窗口滑動到某一位置時,窗口中的輸入子數組與核數組按元素相乘並求和,得到輸出數組中相應位置的元素;
實現二維互相關運算函數如下:
'''
def corr2d(X,K):
h,w = K.shape ## 獲取卷積核的尺寸(寬,高)
Y = tf.Variable(tf.zeros((X.shape[0] - h + 1, X.shape[1] - w +1)))
for i in range(Y.shape[0]):
for j in range(Y.shape[1]):
Y[i,j].assign(tf.cast(tf.reduce_sum(X[i:i+h, j:j+w] * K), dtype=tf.float32))
return Y
'''測試實例: '''
X = tf.constant([[0,1,2], [3,4,5], [6,7,8]])
K = tf.constant([[0,1], [2,3]])
corr2d(X, K)
2. 二維卷積核+標量偏差(權重weight + 偏差bias)
類似於: Y = K*X+b (K–卷積核, b–偏差)
卷積層的一個應用: 檢測圖像中物體的邊緣,即找到像素變化的位置;
'''
爲實現檢測圖像的中物體的邊緣,需要構造一個頁數的卷積核K;
當它與輸入做互相關運算時,如果橫向相鄰元素相同,輸出爲0; 否則輸出爲非0;
'''
K = tf.constrant([[-1,1]], dtype=tf.float32)
3. 實例測試: 通過給出輸入X和輸出Y,獲取兩者之間的係數權重
在這裏使用卷積的方式來獲取權重係數,但忽略偏差.
#!/bin/bash
# -*-coding:utf-8-*-
import tensorflow as tf
print(tf.__version__)
# 二維卷積計算函數
def corr2d(X, K):
h, w = K.shape
Y = tf.Variable(tf.zeros((X.shape[0] - h + 1, X.shape[1] - w +1)))
for i in range(Y.shape[0]):
for j in range(Y.shape[1]):
Y[i, j].assign(tf.cast(tf.reduce_sum(X[i:i+h, j:j+w] * K), dtype=tf.float32))
return Y
X = tf.Variable(tf.ones((6, 8)))
X[:, 2:6].assign(tf.zeros(X[:, 2:6].shape)) # 輸入數據
K = tf.constant([[1,-1]], dtype = tf.float32) # 卷積核
Y= corr2d(X, K) # 輸出數據
X = tf.reshape(X, (1, 6, 8, 1)) # 重置尺寸
Y = tf.reshape(Y, (1, 6, 7, 1)) # 重置尺寸
# print("X = ", X)
# 根據上一步測試中獲取的X-Y值, 從而反推算其內核K;
conv2d = tf.keras.layers.Conv2D(1, (1, 2))
# print(tf.reshape(conv2d.get_weights()[0], (1, 2)))
print('Y.shape = ', Y.shape)
Y_hat = conv2d(X)
# print(Y_hat)
for i in range(10):
with tf.GradientTape(watch_accessed_variables=False) as tt:
tt.watch(conv2d.weights[0])
Y_hat = conv2d(X)
m_error = (abs(Y_hat - Y)) ** 2
dl = tt.gradient(m_error, conv2d.weights[0])
lr = 3e-2
update = tf.multiply(lr, dl)
update_weights = conv2d.get_weights()
update_weights[0] = conv2d.weights[0] - update
conv2d.set_weights(update_weights)
if(i + 1) % 2 == 0:
print('batch %d, loss %.4f' % (i + 1, tf.reduce_sum(m_error)))
print(tf.reshape(conv2d.get_weights()[0], (1, 2)))
- 互相關運算+卷積運算
問: 卷積層爲何能使用互相關運算替代卷積運算?
答: 在深度學習中核數組都是學出來的:卷積層無論使用互相關運算或卷積運算都不影響模型預測時的輸出;
- 特徵圖+感受野
`特徵圖:` 二維卷積層輸出的二維數組可以看作是輸入在空間維度(寬和高)上某一級的表徵,也叫特徵圖(feature map);
'感受野:' 影響元素x(數組)的前向計算的所有可能輸入區域(可能大於輸入的實際尺寸)叫做x的感受野(receptive field)