神经网络与深度学习（四）—手写数字识别示例上

1）定义类

# -*- coding: utf-8 -*-#!/usr/bin/env python3import randomimport numpy as npclass Network(object): def __init__(self,sizes): self.num_layers=len(sizes) self.sizes=sizes self.biases=[np.random.randn(y,1) for y in sizes[1:]] '''创建一个偏差向量''' self.weights=[np.random.randn(y,x) for x,y in zip(sizes[:-1],sizes[1:])] '''创建一个权重偏差矩阵''

>>> a = [1,2,3]>>> b = [4,5,6]>>> c = [4,5,6,7,8]>>> zipped = zip(a,b) # 打包为元组的列表[(1, 4), (2, 5), (3, 6)]>>> zip(a,c) # 元素个数与最短的列表一致[(1, 4), (2, 5), (3, 6)]>>> zip(*zipped) # 与 zip 相反，可理解为解压，返回二维矩阵式[(1, 2, 3), (4, 5, 6)]

2）前馈算法（feedforward）

def feedforward(self,a): for b,w in zip(self.biases,self.weights): a=sigmoid(np.dot(w,a)+b) return a

3)随机梯度下降算法（SGD）

def SGD(self,training_data,epochs,mini_batch_size,eta,test_data=None): if test_data:n_test=len(test_data) '''测试集大小''' n=len(training_data) '''训练集大小''' for j in range(epochs): '''循环次数''' random.shuffle(training_data) '''打乱数据''' mini_batches=[training_data[k:k+mini_batch_size] for k in range(0, n, mini_batch_size)] for mini_batch in mini_batches: self.update_minibatch(mini_batch,eta) '''将训练数据全都分成小的小的数据集当作列表更新，还有学习率''' if test_data: print("Epoch:/".format(j,self.evaluate(test_data),n_test)) '''这里通过索引来格式化字符串''' else: print("Epoch complete".format(j)) '''数据已经检索完毕'''

4）更新小的数据集

def update_minibatch(self,mini_batch,eta): nabla_b=[np.zeros(b.shape) for b in self.biases] nabla_w=[np.zeros(w.shape) for w in self.weights] '''初始化生成相对应的偏导数矩阵''' for x,y in mini_batch: delta_nabla_b,delta_nabla_w=self.backprop(x,y) '''更新偏导数矩阵''' nabla_b=[nb+dnb for nb,dnb in zip(nabla_b,delta_nabla_b)] nabla_w=[nw+dnw for nw,dnw in zip(nabla_w,delta_nabla_w)] '''求偏导数和''' self.weights=[w-(eta/len(mini_batch))*nw for w,nw in zip(self.weights,nabla_w)] self.biases=[b-(eta/len(mini_batch))*nb for b,nb in zip(self.biases,nabla_b)] '''公式20和21'''

5）BP算法更新梯度

def backprop(self,x,y): nabla_b=[np.zeros(b.shape) for b in self.biases] nabla_w=[np.zeros(w.shape) for w in self.weights] '''初始化偏置和权重矩阵''' activation=x activations=[x] zs=[]

'''第一步，初始化每层的激励值''' for b,w in zip(self.biases,self.weights): z=np.dot(w,activation)+b '''点乘''' zs.append(z) activation=sigmoid(z) activations.append(activation) '''第二步，正向更新（feedforward）激励值''' delta=self.cost_derivative(activations[-1],y)

'''第三步，求误差error''' sigmoid_prime(zs[-1]) nabla_b[-1]=delta nabla_w[-1]=np.dot(delta,activations[-2].transpose()) '''第五步，先求出最后一层的w和b，transpose矩阵转置''' for l in range(2,self.num_layers):

'''第四步，从倒数第二层开始更新''' z=zs[-l] sp=sigmoid_prime(z) delta = np.dot(self.weights[-l+1].transpose(),delta)*sp

'''从后一层开始更新，计算delta(error)''' nabla_b[-l]=delta nabla_w[-l]=np.dot(delta,activations[-l-1].transpose())

'''第五步，更新偏导数''' return (nabla_b,nabla_w)

6）计算准确率和代价函数求偏导

def evaluate(self,test_data): test_results=[(np.argmax(self.feedforward(x)),y)

for (x,y) in test_data]

'''输出测试集的神经网络输出值和期望值''' return sum(int(x==y)for (x,y) in test_results) '''返回结果中的正确数总个数（布尔值和）'''

def cost_derivative(self,output_activations,y): return (output_activations-y)

'''代价函数求偏导'''

7）其他

def sigmoid(z): return 1.0/(1.0+np.exp(-z))def sigmoid_prime(z): return sigmoid(z)*(1-sigmoid(z))

• 发表于:
• 原文链接http://kuaibao.qq.com/s/20180407G17T9H00?refer=cp_1026
• 腾讯「云+社区」是腾讯内容开放平台帐号（企鹅号）传播渠道之一，根据《腾讯内容开放平台服务协议》转载发布内容。
• 如有侵权，请联系 yunjia_community@tencent.com 删除。

2021-12-09

2021-12-09

2021-12-09

2021-12-09

2021-12-09

2021-12-09

2018-05-08

2021-12-09

2021-12-09

2021-12-09

2021-12-09

2021-12-09