本文建立在理论推导之上,推导部分我通过一系列视频呈现,感兴趣请去我的主页找『戴森与你聊:神经网络小知识』这个合集即可,根据前面所做的推导,本文就通过代码来实现一个简单的三层全连接网络 。#技术技能超级玩家#
文章插图
本文将要实现的一个三层全连接简单网络
0.必要的库我们代码基于Python环境,大家可以把下面的代码写入到一个jupyter notebook中,分节运行并调试 。实现神经网络的基本算法,需要用到一些库,我们先把它们导入进来:
import numpy as npimport matplotlib.pyplot as plot
接下来进入正题!1.给定输入和输出
X = np.array([[1,0,0,0],[1,0,1,1],[0,1,0,1],[1,1,1,0],[1,0,0,1]])print('nInput shape:n',X.shape)y = np.array([[1],[1],[0],[1],[0]])print('nGround truth shape:n',y.shape)
注意: 在之前的推导中(视频中)我们假设一个输入是一个列向量,而这里使用的是矩阵,代表什么呢?在上面(3,4)所表示的输入信号维度中,第一个3是指的样本数目,而第二个4指的是每个样本中的feature的数目 。因此,这里的(3,4)意思就是,输入是三个样本,每个样本用一个 1x4 的向量来表达 。一定注意二者区别,这决定了后面所有矩阵运算时角标的顺序(也就是矩阵相乘时候的顺序) 。还要提醒各位注意观察,样本数目的多少,和后面的权重没有关系!权重的数目只取决于每个样本自身的维度 。这其中有什么原因吗?2. 定义网络结构和参数假定使用以下结构的简单全连接网络,输入层有4个单元,隐藏层3个单元,输出层一个单元
文章插图
numInputNeurons = X.shape[1]numHiddenNeurons = 3numOutputNeurons = 1
3. 初始化权重和偏置参数注意: 权重编号规则,与推导过程中使用的下标编号规则不一致,比如对于权重矩阵,之前推导中我们约定的是先写目标单元,再写起始单元的顺序,这里反过来了,大家可以考虑下为什么?weightsInputHidden = np.random.uniform(size=(numInputNeurons,numHiddenNeurons))print('nThe shape of weight matrix between the input layer and hidden layer is: ',weightsInputHidden.shape)weightsHiddenOutput = np.random.uniform(size=(numHiddenNeurons,numOutputNeurons))print('nThe shape of weight matrix between the hidden layer and output layer is: ',weightsHiddenOutput.shape)biasHidden = np.random.uniform(size=(1,numHiddenNeurons))print('nThe shape of bias matrix of hidden layer: ',biasHidden.shape)biasOutput = np.random.uniform(size=(1,numOutputNeurons))print('nThe shape of bias matrix of output layer is: ',biasOutput.shape)
4. 定义激活函数及其导数函数前向和反向传播都会用到Sigmoid函数以及它的导数,先定义它们:def sigmoid(x):return 1/(1 + np.exp(-x))# Detailed definition of the derivative of sigmoid functiondef derivative_sigmoid(x, original = False):return x * (1 - x)if(original == True):return sigmoid(x) * (1 - sigmoid(x))
文章插图
5. 正向传播 Forward Propagation¶5.1 InputLayer --> HiddenLayer
hiddenIn = np.dot(X, weightsInputHidden) + biasHiddenhiddenActivation = sigmoid(hiddenIn)
注意: 这里涉及到矩阵运算的顺序,仔细分析一下 。主要就是盯着维度的匹配!- 如果输入单元是行向量(本例中就是如此)且有j个元素,输入层的维度就是 1xj,然后后面的矩阵计算就一定要也得到一个维度匹配的行向量;
- 如果输入单元是列向量(前面推导中的情形),那么输入层的维度就是jx1,后面的矩阵计算就要匹配列向量的维度
outputIn = np.dot(hiddenActivation, weightsHiddenOutput) + biasOutputoutputActivation = sigmoid(outputIn)print('nPrediction is: ', outputActivation)
6. 反向传播 Back Propagation误差反传是最重要的一步,分为以下几个关键步骤:6.1 成本函数和成本函数的导数
文章插图
Error = np.square(y - outputActivation)/2E = outputActivation - y
6.2 BP四个基本方程之:输出层神经元误差文章插图
derivativeHidden = derivative_sigmoid(hiddenActivation)derivativeHidden.shapedeltaHidden = np.dot(deltaOutput, weightsHiddenOutput.T) * derivativeHiddendeltaHidden.sha# Learning ratelr = 0.01n
推荐阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- N log N 为什么排序的复杂度为 O
- 乾隆爱孝贤皇后还是孝仪皇后 乾隆皇帝最喜欢的女人是哪一位
- 清平乐村居表达了诗人什么之情 清平乐村居词人在词中勾勒了一幅怎样的画面
- 历史上永琪的母亲怎么死的 历史上的永琪的女儿
- 蜀汉灭亡诸葛亮的责任 诸葛亮死后多少年蜀汉灭亡
- 宋仁宗赵祯时期的大臣 宋仁宗赵祯死后谁继位
- 凯迪拉克运动模式和舒适模式的切换 嘉庆为什么不留着和珅
- 秦朝以少胜多的战役 古代三大战役以少胜多
- 老茶头如何保存好,什么样的老茶头比较好
- 苦瓜茶的副作用,苦瓜茶的好处