卷積神經網路(convolutional neural network
)是含有卷積層(convolutional layer
)的神經網路
二維互相關運算
通常在卷積層中使用更加直觀的互相關(cross-correlation
)運算,在二維卷積層中,乙個二維輸入陣列和乙個二維核(kernel
)陣列通過互相關運算輸出乙個二維陣列.核陣列在卷積計算中又稱卷積核或過濾器(filter
)卷積核視窗(又稱卷積視窗)的形狀取決於卷積核的高和寬.在二維互相關運算中,卷積視窗從輸入陣列的最左上方開始,按從左往右、從上往下的順序,依次在輸入陣列上滑動。當卷積視窗滑動到某一位置時,視窗中的輸入子陣列與核陣列按元素相乘並求和,得到輸出陣列中相應位置的元素。
將上述過程實現在corr2d
函式裡。它接受輸入陣列x
與核陣列k
,並輸出陣列y
from mxnet import autograd, nd
from mxnet.gluon import nn
def corr2d(x, k): # 本函式已儲存在d2lzh包中方便以後使用
# 核陣列的長寬
h, w = k.shape
# 輸出置0,同時計算出輸出陣列y的長寬
y = nd.zeros((x.shape[0] - h + 1, x.shape[1] - w + 1))
#列舉y的長寬
for i in range(y.shape[0]):
for j in range(y.shape[1]):
#依次計算x*k再求和
y[i, j] = (x[i: i + h, j: j + w] * k).sum()
return y
二維卷積層#con2d類繼承block類
class conv2d(nn.block):
def __init__(self, kernel_size, **kwargs):
super(conv2d, self).__init__(**kwargs)
#使用get函式獲得param例項,shape=初始化的卷積shape
self.weight = self.params.get('weight', shape=kernel_size)
#使用get函式獲得param例項,shape=(1,)
self.bias = self.params.get('bias', shape=(1,))
def forward(self, x):
#卷積計算
return corr2d(x, self.weight.data()) + self.bias.data()
卷積視窗形狀為\(p \times q\)的卷積層稱為\(p \times q\)卷積層。同樣,\(p \times q\)卷積或\(p \times q\)卷積核說明卷積核的高和寬分別為\(p\)和\(q\)。
影象中物體邊緣檢測
乙個卷積層的簡單應用:檢測影象中物體的邊緣,即找到畫素變化的位置.構造一張\(6\times 8\)的影象(即高和寬分別為6畫素和8畫素的影象)。它中間\(4\)列為黑(\(0\)),其餘為白(\(1\))
x = nd.ones((6, 8))
x[:, 2:6] = 0
x#output:
[[1. 1. 0. 0. 0. 0. 1. 1.]
[1. 1. 0. 0. 0. 0. 1. 1.]
[1. 1. 0. 0. 0. 0. 1. 1.]
[1. 1. 0. 0. 0. 0. 1. 1.]
[1. 1. 0. 0. 0. 0. 1. 1.]
[1. 1. 0. 0. 0. 0. 1. 1.]]
構造乙個高和寬分別為\(1\)和\(2\)的卷積核\(k\)。當它與輸入做互相關運算時,如果橫向相鄰元素相同,輸出為\(0\);否則輸出為非\(0\)
k = nd.array([[1, -1]])
輸入x
和我們設計的卷積核k
做互相關運算.將從白到黑的邊緣和從黑到白的邊緣分別檢測成了1
和-1
。其餘部分的輸出全是0
y = corr2d(x, k)
y#output
[[ 0. 1. 0. 0. 0. -1. 0.]
[ 0. 1. 0. 0. 0. -1. 0.]
[ 0. 1. 0. 0. 0. -1. 0.]
[ 0. 1. 0. 0. 0. -1. 0.]
[ 0. 1. 0. 0. 0. -1. 0.]
[ 0. 1. 0. 0. 0. -1. 0.]]
通過資料學習核陣列
使用物體邊緣檢測中的輸入資料x
和輸出資料y
來學習我們構造的核陣列k
首先構造乙個卷積層,將其卷積核初始化成隨機數組。接下來在每一次迭代中,我們使用平方誤差來比較y和卷積層的輸出,然後計算梯度來更新權重.簡單起見,這裡的卷積層忽略了偏差
使用gluon
提供的conv2d
類來實現這個例子:
# 構造乙個輸出通道數為1(將在「多輸入通道和多輸出通道」一節介紹信道),核陣列形狀是(1, 2)的二
# 維卷積層
conv2d = nn.conv2d(1, kernel_size=(1, 2))
#初始化權重引數
conv2d.initialize()
# 二維卷積層使用4維輸入輸出,格式為(樣本, 通道, 高, 寬),這裡批量大小(批量中的樣本數)和通
# 道數均為1
#重新reshape
x = x.reshape((1, 1, 6, 8))
y = y.reshape((1, 1, 6, 7))
#迭代十次
for i in range(10):
with autograd.record():
#將卷積層應用在x上計算出**值
y_hat = conv2d(x)
#計算出平方損失
l = (y_hat - y) ** 2
l.backward()
# 簡單起見,這裡忽略了偏差
# 利用梯度迭代
conv2d.weight.data()[:] -= 3e-2 * conv2d.weight.grad()
if (i + 1) % 2 == 0:
print('batch %d, loss %.3f' % (i + 1, l.sum().asscalar()))
互相關運算和卷積運算
有點沒看懂
特徵圖和感受野
二維卷積層輸出的二維陣列可以看作輸入在空間維度(寬和高)上某一級的表徵,也叫特徵圖(feature map
)
影響元素\(x\)的前向計算的所有可能輸入區域(可能大於輸入的實際尺寸)叫做\(x\)的感受野(receptive field
)
經過卷積層的特徵提取之後,新生成的元素的感受野是原輸入陣列的部分元素
二維卷積層的原理
主要介紹二維卷積層的工作原理 卷積神經網路是含有卷積層的神經網路 在二維卷積層中,乙個二維輸入陣列和乙個二維核陣列通過互相關運算輸出乙個二維陣列。例如 輸入陣列 3x3的二維陣列 核陣列 2x2的二維陣列 該陣列在卷積計算中又稱卷積核或過濾器 在二維互相關運算中,卷積視窗從輸入陣列的最左上方開始,按...
二維卷積詳細解釋
其中,矩陣a和b的尺寸分別為ma na即mb nb 對矩陣a補零,第一行之前和最後一行之後都補mb 1行,第一列之前和最後一列之後都補nb 1列 注意conv2不支援其他的邊界補充選項,函式內部對輸入總是補零 之所以都是 1是因為卷積核要在影象a上面移動,移動的時候需要滿足兩者至少有一列或者一行是重...
二維矩陣與二維矩陣之間的卷積
最近在學習數字影象處理 digital image processing,dip 這門課,感覺有些吃力。由於在數字訊號處理 digital singal processing,dsp 這門課中只學了一維矩陣之間的卷積運算。假設我們的卷積核h為kernel矩陣 33 待處理矩陣f x,y 為 55 h...