一文入门BP神经网络——从原理到应用(应用篇)
来源:互联网 发布:定义二维数组可缺省 编辑:程序博客网 时间:2024/06/05 16:45
- 辅助函数
- 前向传播过程
- 反向传播过程
- 测试结果
本文是一文搞定BP神经网络——从原理到应用(原理篇)的姊妹篇,主要使用python实现我们之前推导的公式。本文难免会有叙述不合理的地方,希望读者可以在评论区反馈。我会及时吸纳大家的意见,并在之后的chat里进行说明。
本文参考了一些资料,在此一并列出。
- http://neuralnetworksanddeeplearning.com/chap2.html
- https://www.deeplearning.ai/ coursera对应课程视频讲义
- coursera华盛顿大学机器学习专项
- 周志华《机器学习》
- 李航《统计学习方法》
- 张明淳《工程矩阵理论》
本文代码和数据库文件在这里下载http://download.csdn.net/download/u014303046/10035014.
1. 辅助函数
辅助函数主要包括激活函数以及激活函数的反向传播过程函数:
其中,激活函数反向传播代码对应公式4和9.
def sigmoid(z): """ 使用numpy实现sigmoid函数 参数: Z numpy array 输出: A 激活值(维数和Z完全相同) """ return 1/(1 + np.exp(-z))def relu(z): """ 线性修正函数relu 参数: z numpy array 输出: A 激活值(维数和Z完全相同) """ return np.array(z>0)*zdef sigmoidBackward(dA, cacheA): """ sigmoid的反向传播 参数: dA 同层激活值 cacheA 同层线性输出 输出: dZ 梯度 """ s = sigmoid(cacheA) diff = s*(1 - s) dZ = dA * diff return dZdef reluBackward(dA, cacheA): """ relu的反向传播 参数: dA 同层激活值 cacheA 同层线性输出 输出: dZ 梯度 """ Z = cacheA dZ = np.array(dA, copy=True) dZ[Z <= 0] = 0 return dZ
另外一个重要的辅助函数是数据读取函数和参数初始化函数:
def loadData(dataDir): """ 导入数据 参数: dataDir 数据集路径 输出: 训练集,测试集以及标签 """ train_dataset = h5py.File(dataDir+'/train.h5', "r") train_set_x_orig = np.array(train_dataset["train_set_x"][:]) # your train set features train_set_y_orig = np.array(train_dataset["train_set_y"][:]) # your train set labels test_dataset = h5py.File(dataDir+'/test.h5', "r") test_set_x_orig = np.array(test_dataset["test_set_x"][:]) # your test set features test_set_y_orig = np.array(test_dataset["test_set_y"][:]) # your test set labels classes = np.array(test_dataset["list_classes"][:]) # the list of classes train_set_y_orig = train_set_y_orig.reshape((1, train_set_y_orig.shape[0])) test_set_y_orig = test_set_y_orig.reshape((1, test_set_y_orig.shape[0])) return train_set_x_orig, train_set_y_orig, test_set_x_orig, test_set_y_orig, classesdef iniPara(laydims): """ 随机初始化网络参数 参数: laydims 一个python list 输出: parameters 随机初始化的参数字典(”W1“,”b1“,”W2“,”b2“, ...) """ np.random.seed(1) parameters = {} for i in range(1, len(laydims)): parameters['W'+str(i)] = np.random.randn(laydims[i], laydims[i-1])/ np.sqrt(laydims[i-1]) parameters['b'+str(i)] = np.zeros((laydims[i], 1)) return parameters
2. 前向传播过程
对应公式1和2.
def forwardLinear(W, b, A_prev): """ 前向传播 """ Z = np.dot(W, A_prev) + b cache = (W, A_prev, b) return Z, cachedef forwardLinearActivation(W, b, A_prev, activation): """ 带激活函数的前向传播 """ Z, cacheL = forwardLinear(W, b, A_prev) cacheA = Z if activation == 'sigmoid': A = sigmoid(Z) if activation == 'relu': A = relu(Z) cache = (cacheL, cacheA) return A, cachedef forwardModel(X, parameters): """ 完整的前向传播过程 """ layerdim = len(parameters)//2 caches = [] A_prev = X for i in range(1, layerdim): A_prev, cache = forwardLinearActivation(parameters['W'+str(i)], parameters['b'+str(i)], A_prev, 'relu') caches.append(cache) AL, cache = forwardLinearActivation(parameters['W'+str(layerdim)], parameters['b'+str(layerdim)], A_prev, 'sigmoid') caches.append(cache) return AL, caches
3. 反向传播过程
线性部分反向传播对应公式5和6。
def linearBackward(dZ, cache): """ 线性部分的反向传播 参数: dZ 当前层误差 cache (W, A_prev, b)元组 输出: dA_prev 上一层激活的梯度 dW 当前层W的梯度 db 当前层b的梯度 """ W, A_prev, b = cache m = A_prev.shape[1] dW = 1/m*np.dot(dZ, A_prev.T) db = 1/m*np.sum(dZ, axis = 1, keepdims=True) dA_prev = np.dot(W.T, dZ) return dA_prev, dW, db
非线性部分对应公式3、4、5和6 。
def linearActivationBackward(dA, cache, activation): """ 非线性部分的反向传播 参数: dA 当前层激活输出的梯度 cache (W, A_prev, b)元组 activation 激活函数类型 输出: dA_prev 上一层激活的梯度 dW 当前层W的梯度 db 当前层b的梯度 """ cacheL, cacheA = cache if activation == 'relu': dZ = reluBackward(dA, cacheA) dA_prev, dW, db = linearBackward(dZ, cacheL) elif activation == 'sigmoid': dZ = sigmoidBackward(dA, cacheA) dA_prev, dW, db = linearBackward(dZ, cacheL) return dA_prev, dW, db
完整反向传播模型:
def backwardModel(AL, Y, caches): """ 完整的反向传播过程 参数: AL 输出层结果 Y 标签值 caches 【cacheL, cacheA】 输出: diffs 梯度字典 """ layerdim = len(caches) Y = Y.reshape(AL.shape) L = layerdim diffs = {} dAL = - (np.divide(Y, AL) - np.divide(1 - Y, 1 - AL)) currentCache = caches[L-1] dA_prev, dW, db = linearActivationBackward(dAL, currentCache, 'sigmoid') diffs['dA' + str(L)], diffs['dW'+str(L)], diffs['db'+str(L)] = dA_prev, dW, db for l in reversed(range(L-1)): currentCache = caches[l] dA_prev, dW, db = linearActivationBackward(dA_prev, currentCache, 'relu') diffs['dA' + str(l+1)], diffs['dW'+str(l+1)], diffs['db'+str(l+1)] = dA_prev, dW, db return diffs
4. 测试结果
打开你的jupyter notebook,运行我们的BP.ipynb文件,首先导入依赖库和数据集,然后使用一个循环来确定最佳的迭代次数大约为2000:
【图6】
最后用一个例子来看一下模型的效果——判断一张图片是不是猫:
【图7】
好了,测试到此结束。你也可以自己尝试其它的神经网络结构和测试其它图片。
阅读全文
1 0
- 一文入门BP神经网络——从原理到应用(应用篇)
- 一文搞定BP神经网络——从原理到应用(原理篇)
- BP神经网络从理论到应用(一):C++实现
- 【神经网络】零基础入门神经网络:从原理、主要类型到行业应用
- 机器学习——BP神经网络算法应用(上)
- 机器学习——BP神经网络算法应用(下)
- BP神经网络(四)——应用案例
- BP神经网络的原理及简单应用
- 零基础入门神经网络:从原理、主要类型到行业应用
- BP神经网络的应用
- BP神经网络(一)——基本概念
- 130行代码实现BP神经网络原理及应用举例
- BP神经网络原理与应用-基于电影评分预测案例
- Access数据库从入门到进门——应用篇
- FPGA视觉从入门到放弃——稀疏编码的原理与简单应用
- 从神经网络到BP算法(纯理论推导)
- CNN感性认识(一)——BP神经网络
- BP神经网络——从二次代价函数(Quadratic cost)到交叉熵(cross-entropy cost)代价函数
- python学习笔记(九)——类和对象
- Fliptile POJ
- 实验七:将menu设计为可重用的子系统
- linux下svn服务器搭建
- python3.5 tensorflow安装简明教程(Linux下Anaconda安装)
- 一文入门BP神经网络——从原理到应用(应用篇)
- 基于java的几种排序方式分析和比较
- win7休眠后打开电脑提示bootmgr is missing,且无法按f2进入BIOS模式解决
- BZOJ 3003: LED
- Elasticsearch数据迁移
- Java中this和super的用法总结
- Java包、类等之间的访问权限
- 机器学习笔记-非线性变换(Nonlinear Transformation)
- Flash2X EXE Packager(SWF转换器) v3.0.1 绿色中文汉化版下载