昨天介绍完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
<<: D31 - 用 Swift 和公开资讯,打造投资理财的 Apps { 台股申购功能扩充,算出价差.2}
Abstract 每个开发者势必都会用到一些Cache暂存工具,但依据小编在业界与各国开发者经验交手...
托管代码(managed code) 微软特定用语 简单来说 managed code 就是由一个 ...
NIST SP 800-34的第一个版本使用术语最大允许中断(Maximum Allowable ...
当我们拿到一个现有的 Web Component 时 , 如果直接在 Vue 专案中使用会抱错 今天...
因为有使用到Arduino IDE,再加上今年以前的暑训都是在上Arduino,所以还是特别安排一天...