一、基本概念

1. 背景

     1.1 以人脑中的神经网络为启发,历史上出现过很多不同版本
     1.2 最著名的算法是1980年的 backpropagation 

2. 多层向前神经网络(Multilayer Feed-Forward Neural Network)

     2.1 Backpropagation被使用在多层向前神经网络上
     2.2 多层向前神经网络由以下部分组成:
           输入层(input layer), 隐藏层 (hidden layers), 输入层 (output layers)
 
     2.3 每层由单元(units)组成
     2.4 输入层(input layer)是由训练集的实例特征向量传入
     2.5 经过连接结点的权重(weight)传入下一层,一层的输出是下一层的输入
     2.6 隐藏层的个数可以是任意的,输入层有一层,输出层有一层
     2.7 每个单元(unit)也可以被称作神经结点,根据生物学来源定义
     2.8 以上成为2层的神经网络(输入层不算)
     2.8 一层中加权的求和,然后根据非线性方程转化输出
     2.9 作为多层向前神经网络,理论上,如果有足够多的隐藏层(hidden layers) 和足够大的训练集, 可以模     
          拟出任何方程
 

3. 设计神经网络结构

     3.1 使用神经网络训练数据之前,必须确定神经网络的层数,以及每层单元的个数
     3.2 特征向量在被传入输入层时通常被先标准化(normalize)到0和1之间 (为了加速学习过程)
     3.3 离散型变量可以被编码成每一个输入单元对应一个特征值可能赋的值
          比如:特征值A可能取三个值(a0, a1, a2), 可以使用3个输入单元来代表A。
                    如果A=a0, 那么代表a0的单元值就取1, 其他取0;
                    如果A=a1, 那么代表a1de单元值就取1,其他取0,以此类推
 
     3.4 神经网络即可以用来做分类(classification)问题,也可以解决回归(regression)问题
          3.4.1 对于分类问题,如果是2类,可以用一个输出单元表示(0和1分别代表2类)
                                         如果多余2类,每一个类别用一个输出单元表示
                   所以输入层的单元数量通常等于类别的数量
 
          3.4.2 没有明确的规则来设计最好有多少个隐藏层
                    3.4.2.1 根据实验测试和误差,以及准确度来实验并改进
 

4. 交叉验证方法(Cross-Validation)

          
                    
 
          K-fold cross validation 

5. Backpropagation算法

     5.1 通过迭代性的来处理训练集中的实例
     5.2 对比经过神经网络后输入层预测值(predicted value)与真实值(target value)之间
     5.3 反方向(从输出层=>隐藏层=>输入层)来以最小化误差(error)来更新每个连接的权重(weight)
     5.4 算法详细介绍
           输入:D:数据集,l 学习率(learning rate), 一个多层前向神经网络
           输入:一个训练好的神经网络(a trained neural network)
 
          5.4.1 初始化权重(weights)和偏向(bias): 随机初始化在-1到1之间,或者-0.5到0.5之间,每个单元有          
                    一个偏向
          5.4.2 对于每一个训练实例X,执行以下步骤:

  5.4.3 终止条件
                         5.4.3.1 权重的更新低于某个阈值
                         5.4.3.2 预测的错误率低于某个阈值
                         5.4.3.3 达到预设一定的循环次数

二、感知机的推导过程(只有一层,没有激活函数)

 

三、加入激活函数

四、防止局部极小值,增加冲量项

五、代码实现

import numpy as np

def tanh(x):
return np.tanh(x) def tanh_deriv(x):
return 1.0 - np.tanh(x) * np.tanh(x) def logistic(x):
return 1 / (1 + np.exp(-x)) def logistic_deriv(x):
return logistic(x) * (1 - logistic(x)) class NeuralNetwork:
def __init__(self, layers, activation="tanh"):
if activation == "logistic":
self.activation = logistic
self.activation_deriv = logistic_deriv
elif activation == "tanh":
self.activation = tanh
self.activation_deriv = tanh_deriv self.weights = []
# len(layers)layer是一个list[10,10,3],则len(layer)=3
for i in range(1, len(layers) - 1):
# 初始化 权值范围 [-0.25,0.25)
# [0,1) * 2 - 1 => [-1,1) => * 0.25 => [-0.25,0.25)
# 加1是增加了一个bias
self.weights.append((2 * np.random.random((layers[i - 1] + 1, layers[i] + 1)) - 1) * 0.25)
self.weights.append((2 * np.random.random((layers[i] + 1, layers[i + 1])) - 1) * 0.25)
# print(len(self.weights)) def fit(self, x, y, learning_rate=0.2, epochs=10000):
x = np.atleast_2d(x) # 确保X是一个二维的数据集,每一行代表一个实例
temp = np.ones([x.shape[0], x.shape[1] + 1])
temp[:, 0:-1] = x
x = temp # 以上三行就是为了给x增加一个值全为1的维度,作为bias,w[-1] * 1=bias
y = np.array(y) for k in range(epochs): # 开始迭代,采用随机梯度,每次抽取一个实例
i = np.random.randint(x.shape[0]) # x.shape[0] is the number of the trainingset samples
a = [x[i]] # choose a sample randomly to train the model
for l in range(len(self.weights)):
# 正向进行计算更新,把第一层的输出,作为下一层的输入,此处用了一个小递归,a[l]
a.append(self.activation(np.dot(a[l], self.weights[l])))
error = y[i] - a[-1] # a[-1]就是我们最终预测的输出
deltas = [error * self.activation_deriv(a[-1])]
for l in range(len(a) - 2, 0, -1): # 从倒数第二层到第0层,每次回退一层
deltas.append(deltas[-1].dot(self.weights[l].T) * self.activation_deriv(a[l]))
deltas.reverse() # 从后往前计算出所有的delta,然后反转
for i in range(len(self.weights)):
layer = np.atleast_2d(a[i])
delta = np.atleast_2d(deltas[i])
self.weights[i] += learning_rate * layer.T.dot(delta) def predict(self, x):
x = np.array(x)
temp = np.ones(x.shape[0] + 1)
temp[0:-1] = x
a = temp
for l in range(0, len(self.weights)):
a = self.activation(np.dot(a, self.weights[l]))
return a if __name__ == '__main__':
nn = NeuralNetwork([2, 2, 1], 'tanh')
x = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])
y = np.array([0, 1, 1, 0])
nn.fit(x, y)
for i in [[0, 0], [0, 1], [1, 0], [1, 1]]:
print(i, nn.predict(i))

结果

[0, 0] [-0.00096734]
[0, 1] [0.99820279]
[1, 0] [0.99812838]
[1, 1] [-0.01110901]

显示一下数据集

from sklearn.datasets import load_digits
import pylab as pl digits = load_digits()
print(digits.data.shape) # (1797, 64)
pl.gray()
pl.matshow(digits.images[0])
pl.show()

六、手写字识别

import numpy as np
from sklearn.datasets import load_digits
from sklearn.metrics import confusion_matrix, classification_report
from sklearn.preprocessing import LabelBinarizer
from ml08BP_neuralNetwork import NeuralNetwork
from sklearn.model_selection import train_test_split # 加载数据集
digits = load_digits()
X = digits.data
y = digits.target
# 处理数据,使得数据处于0,1之间,满足神经网络算法的要求
X -= X.min()
X /= X.max()
# 层数:
# 输出层10个数字
# 输入层64因为图片是8*8的,64像素
# 隐藏层假设100 nn = NeuralNetwork([64, 100, 10], 'logistic')
# 分隔训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y)
# 转化成sklearn需要的二维数据类型
labels_train = LabelBinarizer().fit_transform(y_train)
labels_test = LabelBinarizer().fit_transform(y_test)
print("start fitting")
# 训练3000次
nn.fit(X_train, labels_train, epochs=3000)
predictions = []
for i in range(X_test.shape[0]):
o = nn.predict(X_test[i])
# np.argmax:第几个数对应最大概率值
predictions.append(np.argmax(o)) # 打印预测相关信息
print(confusion_matrix(y_test, predictions))
print(classification_report(y_test, predictions))

结果

矩阵对角线代表预测正确的数量,发现正确率很多

这张表更直观地显示出预测正确率:  共450个案例,成功率94%

08机器学习实战之BP神经网络的更多相关文章

  1. 机器学习(一):梯度下降、神经网络、BP神经网络

    这几天围绕论文A Neural Probability Language Model 看了一些周边资料,如神经网络.梯度下降算法,然后顺便又延伸温习了一下线性代数.概率论以及求导.总的来说,学到不少知 ...

  2. 机器学习:从编程的角度理解BP神经网络

    1.简介(只是简单介绍下理论内容帮助理解下面的代码,如果自己写代码实现此理论不够) 1) BP神经网络是一种多层网络算法,其核心是反向传播误差,即: 使用梯度下降法(或其他算法),通过反向传播来不断调 ...

  3. 机器学习:python使用BP神经网络示例

    1.简介(只是简单介绍下理论内容帮助理解下面的代码,如果自己写代码实现此理论不够) 1) BP神经网络是一种多层网络算法,其核心是反向传播误差,即: 使用梯度下降法(或其他算法),通过反向传播来不断调 ...

  4. 机器学习实战(Machine Learning in Action)学习笔记————08.使用FPgrowth算法来高效发现频繁项集

    机器学习实战(Machine Learning in Action)学习笔记————08.使用FPgrowth算法来高效发现频繁项集 关键字:FPgrowth.频繁项集.条件FP树.非监督学习作者:米 ...

  5. 机器学习入门学习笔记:(一)BP神经网络原理推导及程序实现

    机器学习中,神经网络算法可以说是当下使用的最广泛的算法.神经网络的结构模仿自生物神经网络,生物神经网络中的每个神经元与其他神经元相连,当它“兴奋”时,想下一级相连的神经元发送化学物质,改变这些神经元的 ...

  6. 菜鸟之路——机器学习之BP神经网络个人理解及Python实现

    关键词: 输入层(Input layer).隐藏层(Hidden layer).输出层(Output layer) 理论上如果有足够多的隐藏层和足够大的训练集,神经网络可以模拟出任何方程.隐藏层多的时 ...

  7. 【机器学习】BP神经网络实现手写数字识别

    最近用python写了一个实现手写数字识别的BP神经网络,BP的推导到处都是,但是一动手才知道,会理论推导跟实现它是两回事.关于BP神经网络的实现网上有一些代码,可惜或多或少都有各种问题,在下手写了一 ...

  8. 机器学习(4):BP神经网络原理及其python实现

    BP神经网络是深度学习的重要基础,它是深度学习的重要前行算法之一,因此理解BP神经网络原理以及实现技巧非常有必要.接下来,我们对原理和实现展开讨论. 1.原理  有空再慢慢补上,请先参考老外一篇不错的 ...

  9. 简单易学的机器学习算法——神经网络之BP神经网络

    一.BP神经网络的概念     BP神经网络是一种多层的前馈神经网络,其基本的特点是:信号是前向传播的,而误差是反向传播的.详细来说.对于例如以下的仅仅含一个隐层的神经网络模型: watermark/ ...

随机推荐

  1. SQL优化清单

    SQL优化清单 1.from 语句中包含多个表的情况下,把记录数少的表放在前面 2.where 语句中包含多个条件时,将刷选多的条件放前面 3.避免使用select * ,因为这样会去查询所有列的数据 ...

  2. JAVA Number与Math类

    Number类: 当要用到数字的时候,我们除了使用内置数据类型byte,int,double等来声明,我们还把它声明为一个对象: 所有的包装类(Integer.Long.Byte.Double.Flo ...

  3. numpy 库使用

    numpy 库简单使用 一.numpy库简介 Python标准库中提供了一个array类型,用于保存数组类型的数据,然而这个类型不支持多维数据,不适合数值运算.作为Python的第三方库numpy便有 ...

  4. c++学习过程

    作者本人也是一名初学者,我的QQ:2522929921,可以一起交流啊! 希望广大初学者能够一起进步: 1.掌握编程思维真的很重要!!!!***. 2.不能刻意记忆语法规则. 3.在循序渐进的项目实战 ...

  5. Ionic 2 + 手动搭建开发环境教程 【转】

    ionic简介 为什么选用ionic: 彻底开源且免费 性能优异 基于红的发紫的AngularJs 漂亮的UI 强大的命令行(基于更热门的nodejs) 开发团队非常活跃. ngCordova,将主流 ...

  6. border-radius,box-shadow兼容性解决办法

    css3 border-radius不支持IE8/IE7的四种解决方法 标签: cssborder-radius兼容性   时间:2016-07-18 css3 border-radius用于设置HT ...

  7. Selenium-java测试环境搭建

    1.1背景 Selenium也是一个用于Web应用程序测试的工具.Selenium测试直接运行在浏览器中,就像真正的用户在操作一样.支持的浏览器包括IE.Mozilla Firefox.Mozilla ...

  8. docker学习笔记(3)

    docker 搭建私有仓库 docker-registry是官方提供的工具,可以用于构建私有的镜像仓库.本文内容基于 docker-registry v2.x 版本. 安装运行 docker-regi ...

  9. 《团队-爬虫豆瓣top250项目-团队一阶段互评》

    团队名称:咣咣踹电脑 学号:2015035107217姓名:耿文浩 得分10 原因:组长带领的好,任务分配的好,积极帮助组员解决问题 学号:2015035107213姓名:周鑫 得分8 原因:勇于分担 ...

  10. js 防抖 debounce 与 节流 throttle

    debounce(防抖) 与 throttle(节流) 主要是用于用户交互处理过程中的性能优化.都是为了避免在短时间内重复触发(比如scrollTop等导致的回流.http请求等)导致的资源浪费问题. ...