神经网络NN简单理解以及算法
2017-08-15 16:07
225 查看
1.什么是神经网络
1.1 背景 :
以人脑中的神经网络为启发,历史上出现过很多不同版本最著名的算法是1980年的 backpropagation
1.2 多层向前神经网络(Multilayer Feed-Forward Neural Network)
Backpropagation被使用在多层向前神经网络上多层向前神经网络由以下部分组成:
输入层(input layer), 隐藏层 (hidden layers), 输入层 (output layers)
每层由单元Unit组成
连接Unit之间有权重weights
输入层用来输入数据
隐藏层数量可以是任意的
理论上有足够多的数据以及足够多的隐藏层,该网络可以模拟出任何方程
需要进行非线性的转换
以上构成2层的神经网络 输入层不作为一层
2. 主要算法介绍
2.1 关于非线性转化方程(non-linear transformation function)
代码中叫做 sigmoid / sigmoidDer (命名不当,理解就好)- 双曲函数(tanh) 以及 导数
numpy库提供了tanh函数 : numpy.tanh(x)
导数为 : 1.0−tanh(x)2
- 逻辑函数(logistic function) 以及 导数
函数为 : logistic(x)=11+e−x
导数为 : logistic(x)⋅(1−logistic(x))
2.2 BackPropagation 算法
简单的说就是通过迭代性的来处理训练集中的实例,经过神经网络后输入层预测值(predicted value)与真实值(target value)之间的误差不断调整权重weight来使其更加准确,最后反向计算误差来更新连接之间的权重weight算法大致流程 :
建立神经网络
算法输入数据集 学习率(步长alpha)
初始化权重(weights)和偏向(bias): 随机初始化在-1到1之间,或者-0.5到0.5之间,每个单元有一个偏向
向前更新传送
根据误差反向更新(weights)
终止条件
2.3 基于算法的几个公式
向前更新传送过程
公式1:Oj=∑iOiwij+θj
按照上图就是 Oj=y1w1j+y2w2j+...+ynwnj+θj
根据误差(error)反向传送过程
公式2 : 对于输出层 Errj=Oj(1−Oj)(Tj−Oj) 其中T为target,就是实际结果,Oj(1−Oj) 正好是logistic函数的导数,眼熟不…
公式3 : 对于隐藏层 Errj=Oj(1−Oj)∑kwjk⋅Errk 由于计算的时候是从后向前计算的 最后需要逆置一下
公式4 : 对于weights wij=alpha⋅Errj⋅Oi
3. 简单算法实现
注意:本简单实现算法迭代过程使用了随机化,可以更改其条件达到更好的精确性# coding:utf-8 from numpy import * def tan(x): return tanh(x) def tanDer(x): # tanh的导数 return 1.0 - tanh(x) * tanh(x) def logistic(x): return 1 / (1 + exp(-x)) def logisticDer(x): # logistic的导数 return logistic(x) * (1 - logistic(x)) class NN(object): def __init__(self, layer, sigmoid=tan, sigmoidD=tanDer): # layer是个列表 分别存着每一层的元素个数 self.weights = [] self.sigmoid = sigmoid self.sigmoid_der = sigmoidD for i in range(1, len(layer) - 1): # 随机 生成weight 和 bias self.weights.append((2 * random.random((layer[i - 1] + 1, layer[i] + 1)) - 1) * 0.25) self.weights.append((2 * random.random((layer[i] + 1, layer[i + 1])) - 1) * 0.25) def fit(self, x, y, alpha=0.02, loopNum=10000): # 步长与循环次数 默认0.02 / 10000 x = atleast_2d(x) # 至少2维 tempx = ones([x.shape[0], x.shape[1] + 1]) # 多加一列 tempx[:, 0:-1] = x # 最后一列的1是常数 x = tempx y = array(y) for k in range(loopNum): # 随机选择下标 index = random.randint(x.shape[0]) units = [x[index]] # 当前单元(Unit)格的数值 for i in range(len(self.weights)): # 进过两次运算后计算出输出层(预测值) -- 公式 1 units.append(self.sigmoid(dot(units[i], self.weights[i]))) # dot all a1b1+a2b2..... error = y[index] - units[-1] # Tj - Oj deltas = [error * self.sigmoid_der(units[-1])] # 反向 输出层误差 -- 公式 2 for i in range(len(units) - 2, 0, -1): # 隐藏层误差 -- 公式 3 deltas.append(deltas[-1].dot(self.weights[i].T) * self.sigmoid_der(units[i])) deltas.reverse() # 从后往前更新 所以逆转一下 for i in range(len(self.weights)): unit = atleast_2d(units[i]) delta = atleast_2d(deltas[i]) self.weights[i] += alpha * unit.T.dot(delta) # 根据公式不断更新weights -- 公式 4 def predict(self, x): x = array(x) temp = ones(x.shape[0] + 1) temp[0:-1] = x unit = temp for i in range(0, len(self.weights)): # 不用保留之前层的数值,只保留最后一层数值,并且放入到sigmoid函数中 unit = self.sigmoid(dot(unit, self.weights[i])) # 数值*weight参数 return unit if __name__ == '__main__': '''简单数学逻辑运算''' x = array([[0, 0], [0, 1], [1, 0], [1, 1]]) y = array([1, 0, 0, 1]) nn = NN([2, 2, 1], tan, tanDer) nn.fit(x, y) for i in [[0, 0], [0, 1], [1, 0], [1, 1]]: print i,int(nn.predict(i) > 0.5) print '01 is over\n' '''从numpy库导入数据进行数字识别''' from sklearn.datasets import load_digits from sklearn.metrics import confusion_matrix, classification_report from sklearn.preprocessing import LabelBinarizer from sklearn.cross_validation import train_test_split digits = load_digits() X = digits.data y = digits.target X -= X.min() X /= X.max() # for X range : 0-1 nn = NN([64, 500, 10], logistic) X_train, X_test, y_train, y_test = train_test_split(X, y) # 随机切分数据集 labels_train = LabelBinarizer().fit_transform(y_train) # 二值化label labels_test = LabelBinarizer().fit_transform(y_test) # 比如1就是 01000000000 print "start fitting number" nn.fit(X_train, labels_train, alpha=0.001, loopNum=50000) predictions = [] # 预测值 for i in range(X_test.shape[0]): o = nn.predict(X_test[i]) predictions.append(argmax(o)) # argmax(o) 返回o数组中最大的元素的下标 print confusion_matrix(y_test, predictions) # 对比数值 print classification_report(y_test, predictions) # 分类报告 # print predictions
4. 输出数据 以及 简单分析
''' [0, 0] 1 [0, 1] 0 [1, 0] 0 [1, 1] 1 01 is over start fitting number [[42 0 0 0 0 0 0 0 0 0] [ 0 33 1 0 0 0 0 0 2 7] [ 0 0 40 0 0 0 0 0 0 0] [ 0 1 0 40 0 3 0 2 3 0] [ 0 0 0 0 47 0 0 0 2 0] [ 0 0 0 0 0 43 0 0 0 3] [ 0 0 0 0 0 0 41 0 0 0] [ 0 0 0 0 0 1 0 47 1 1] [ 0 3 0 0 0 1 0 1 43 0] [ 0 0 0 0 0 2 0 0 1 39]] precision recall f1-score support 0 1.00 1.00 1.00 42 1 0.89 0.77 0.82 43 2 0.98 1.00 0.99 40 3 1.00 0.82 0.90 49 4 1.00 0.96 0.98 49 5 0.86 0.93 0.90 46 6 1.00 1.00 1.00 41 7 0.94 0.94 0.94 50 8 0.83 0.90 0.86 48 9 0.78 0.93 0.85 42 avg / total 0.93 0.92 0.92 450 ''' # 分析 # 关于01的与或运算应该是很准确了 原始数据进行了sigmoid函数计算 # 关于数字识别 第一个矩阵对角线上说明正确的个数 # 第二个矩阵 有正确率以及反向正确率 450张训练正确率93%尚可 # 可以改变参数比如步长,随机循环次数等等.....
什么是神经网络
1 背景
2 多层向前神经网络Multilayer Feed-Forward Neural Network
主要算法介绍
1 关于非线性转化方程non-linear transformation function
2 BackPropagation 算法
3 基于算法的几个公式
简单算法实现
输出数据 以及 简单分析
相关文章推荐
- 索引 视图 存储过程和函数 简单理解 以及使用创建方法
- Diffie-Hellman密钥交换算法简单理解
- nova组件中子模块简介以及简单功能理解
- HMM理解以及相关算法
- KNN 算法,以及与Kmeans的简单对比
- 对MapReduce的简单理解以及归纳总结
- Java NIO 的简单读写 以及理解
- 简单理解算法篇--贪心算法
- 索引 视图 存储过程和函数 简单理解 以及使用创建方法
- 【C#】深度理解虚方法 继承 以及接口的简单使用
- PCA降维算法总结以及matlab实现PCA(个人的一点理解)
- PCA降维算法总结以及matlab实现PCA(个人的一点理解)
- [算法]递归算法中sort的递归理解以及原地归并和自顶向下递归排序
- (java)签名算法的使用以及正则表达式的简单使用
- PCA降维算法总结以及matlab实现PCA(个人的一点理解)
- AdaBoost (Adaptive Boosting) 自适应增强 简单理解算法与matlab实现
- 几种垃圾收集算法的简单理解
- Java NIO 的简单读写 以及理解
- Spring MVC---3.0 简单入门以及相关理解
- 索引 视图 存储过程和函数 简单理解 以及使用创建方法