昨天介紹完CNN卷積神經網路,今天要來研究CNN卷積神經網路正向傳播程式:
首先先決定資料集大小:
#只取前1000筆資料,因為實際資料太多
train_images = mnist.train_images()[:1000]
train_labels = mnist.train_labels()[:1000]
test_images = mnist.test_images()[:1000]
test_labels = mnist.test_labels()[:1000]
print("train shape:",train_images.shape)
print("train labels:",train_labels.shape)
print("train images:",test_images.shape)
print("train labels:",test_labels.shape)
所以一張圖為28X28 共1000張
train shape: (1000, 28, 28)
train labels: (1000,)
train images: (1000, 28, 28)
train labels: (1000,)
首先建立3X3卷積層正向運算,程式如下
class Conv3x3:
def __init__(self, num_filters):
self.num_filters = num_filters
#從N(0,1/81)分布取num_filters個3X3filters
self.filters = np.random.randn(num_filters, 3, 3) / 9
#設定成積範圍
def iterate_regions(self, image):
#一張圖大小28X28
h, w = image.shape
#因為3x3 所以只會有(0,1,2),(1,2,3)....(25,26,27)-->共26個所以意思是28-2
for i in range(h - 2):
for j in range(w - 2):
im_region = image[i:(i + 3), j:(j + 3)]
#返回 照片3X3範圍 和左上角座標
yield im_region, i, j
#正向運算
def forward(self, input_use):
self.last_input = input_use
h, w = input_use.shape
#設置和iterate_regions個數相同(26個)大小0矩陣共num_filters個
output = np.zeros((h - 2, w - 2, self.num_filters))
for im_region, i, j in self.iterate_regions(input_use):
#這就是卷積-->3X3和3X3各自對應點乘完後加總後放到對應點
output[i, j] = np.sum(im_region * self.filters, axis=(1, 2))
return output # 28x28x1 -> 26x26x8
接下來是最大池化層正向運算:
class MaxPool2: #(取2X2)
#設定成積範圍
def iterate_regions(self, image):
h, w, _ = image.shape
#取 一半距離是因為他是以2*2移動且非卷積而是切割
new_h = h // 2
new_w = w // 2
#所以是26/2-->13塊
for i in range(new_h):
for j in range(new_w):
#(0,2),(2,4)....(24,26)
im_region = image[(i * 2):(i * 2 + 2), (j * 2):(j * 2 + 2)]
yield im_region, i, j
#正向運算
def forward(self, input_use):
self.last_input = input_use
h, w, num_filters = input_use.shape
output = np.zeros((h // 2, w // 2, num_filters))
#取範圍內最大值
for im_region, i, j in self.iterate_regions(input_use):
output[i, j] = np.amax(im_region, axis=(0, 1))
return output
最後是全連接層正向傳播,程式如下:
class Softmax:
def __init__(self, input_len, nodes):
#取N(0,1/(input_len)**2)的分布取(input_len, nodes)大小
self.weights = np.random.randn(input_len, nodes) / input_len
self.biases = np.zeros(nodes)
def forward(self, input_use):
self.last_input_shape = input_use.shape
#展平
input_use = input_use.flatten()
self.last_input = input_use
input_len, nodes = self.weights.shape
#輸入乘上W加上誤差-->wx+b
totals = np.dot(input_use, self.weights) + self.biases
self.last_totals = totals
#帶入exp裡
exp = np.exp(totals)
#算機率值
return exp / np.sum(exp, axis=0)
(資料來源:https://zhuanlan.zhihu.com/p/102119808並加上註解程式)
好,今天CNN正向傳播程式算是研究完,明天就來研究CNN的反向傳播程式
男孩走到屋子內,他發現那個站著人就是剛剛在森林深處看到的士兵雕像,只是不同的是,雕像身上有了裂痕,雕像在男孩走進後,開始碎裂,最後化成一堆石塊,男孩在石塊堆裡面好像有東西,於是男孩用手撥開石堆,拿起了這個物品,是一枚戒指,上面刻著木棉花的圖案,突然男孩湧出一股想要戴上戒指衝動,於是男孩伸出食指後,戴上了戒指,而戒指發出了橙色的光芒
--|再次想起,是痛苦是回憶還是懷念 |-- MM.CS