神经网络理论基础及Python实现

简介:

一、多层前向神经网络

多层前向神经网络由三部分组成:输出层、隐藏层、输出层,每层由单元组成;

输入层由训练集的实例特征向量传入,经过连接结点的权重传入下一层,前一层的输出是下一层的输入;隐藏层的个数是任意的,输入层只有一层,输出层也只有一层;

除去输入层之外,隐藏层和输出层的层数和为n,则该神经网络称为n层神经网络,如下图为2层的神经网络;

一层中加权求和,根据非线性方程进行转化输出;理论上,如果有足够多的隐藏层和足够大的训练集,可以模拟出任何方程;

二、设计神经网络结构

使用神经网络之前,必须要确定神经网络的层数,以及每层单元的个数;

为了加速学习过程,特征向量在传入输入层前,通常需要标准化到0和1之间;

离散型变量可以被编码成每一个输入单元对应一个特征值可能赋的值

比如:特征值A可能去三个值(a0,a1,a2),那么可以使用3个输入单元来代表A

  • 如果A=a0,则代表a0的单元值取1,其余取0;
  • 如果A=a1,则代表a1的单元值取1,其余取0;
  • 如果A=a2,则代表a2的单元值取1,其余取0;

神经网络既解决分类(classification)问题,也可以解决回归(regression)问题。对于分类问题,如果是两类,则可以用一个输出单元(0和1)分别表示两类;如果多余两类,则每一个类别用一个输出单元表示,所以输出层的单元数量通常等一类别的数量。

没有明确的规则来设计最佳个数的隐藏层,一般根据实验测试误差和准确率来改进实验。

三、交叉验证方法

如何计算准确率?最简单的方法是通过一组训练集和测试集,训练集通过训练得到模型,将测试集输入模型得到测试结果,将测试结果和测试集的真实标签进行比较,得到准确率。

在机器学习领域一个常用的方法是交叉验证方法。一组数据不分成2份,可能分为10份,

  • 第1次:第1份作为测试集,剩余9份作为训练集;
  • 第2次:第2份作为测试集,剩余9份作为训练集;
  • ……

这样经过10次训练,得到10组准确率,将这10组数据求平均值得到平均准确率的结果。这里10是特例。一般意义上将数据分为k份,称该算法为K-fold cross validation,即每一次选择k份中的一份作为测试集,剩余k-1份作为训练集,重复k次,最终得到平均准确率,是一种比较科学准确的方法。

四、BP算法

通过迭代来处理训练集中的实例;

对比经过神经网络后预测值与真实值之间的差;

反方向(从输出层=>隐藏层=>输入层)来最小化误差,来更新每个连接的权重;

4.1、算法详细介绍

输入:数据集、学习率、一个多层神经网络构架;

输出:一个训练好的神经网络;

初始化权重和偏向:随机初始化在-1到1之间(或者其他),每个单元有一个偏向;对于每一个训练实例X,执行以下步骤:

1、由输入层向前传送:

结合神经网络示意图进行分析:

由输入层到隐藏层:

由隐藏层到输出层:

两个公式进行总结,可以得到:

Ij为当前层单元值,Oi为上一层的单元值,wij为两层之间,连接两个单元值的权重值,sitaj为每一层的偏向值。我们要对每一层的输出进行非线性的转换,示意图如下:

当前层输出为Ij,f为非线性转化函数,又称为激活函数,定义如下:

即每一层的输出为:

这样就可以通过输入值正向得到每一层的输出值。

2、根据误差反向传送 对于输出层:其中Tk是真实值,Ok是预测值

对于隐藏层:

权重更新:其中l为学习率

偏向更新:

3、终止条件

偏重的更新低于某个阈值;

预测的错误率低于某个阈值;

达到预设一定的循环次数;

4、非线性转化函数

上面提到的非线性转化函数f,一般情况下可以用两种函数:

(1)tanh(x)函数:

  • tanh(x)=sinh(x)/cosh(x)
  • sinh(x)=(exp(x)-exp(-x))/2
  • cosh(x)=(exp(x)+exp(-x))/2

(2)逻辑函数,本文上面用的就是逻辑函数

五、BP神经网络的python实现

需要先导入numpy模块

 
  1. import numpy as np 

定义非线性转化函数,由于还需要用到给函数的导数形式,因此一起定义

 
  1. def tanh(x): 
  2.  
  3.     return np.tanh(x) 
  4.  
  5. def tanh_deriv(x): 
  6.  
  7.     return 1.0 - np.tanh(x)*np.tanh(x) 
  8.  
  9. def logistic(x): 
  10.  
  11.     return 1/(1 + np.exp(-x)) 
  12.  
  13. def logistic_derivative(x): 
  14.  
  15.     return logistic(x)*(1-logistic(x))  

设计BP神经网络的形式(几层,每层多少单元个数),用到了面向对象,主要是选择哪种非线性函数,以及初始化权重。layers是一个list,里面包含每一层的单元个数。

 
  1. class NeuralNetwork: 
  2.  
  3.     def __init__(self, layers, activation='tanh'): 
  4.  
  5.         ""
  6.  
  7.         :param layers: A list containing the number of units in each layer. 
  8.  
  9.         Should be at least two values 
  10.  
  11.         :param activation: The activation function to be used. Can be 
  12.  
  13.         "logistic" or "tanh" 
  14.  
  15.         ""
  16.  
  17.         if activation == 'logistic'
  18.  
  19.             self.activation = logistic 
  20.  
  21.             self.activation_deriv = logistic_derivative 
  22.  
  23.         elif activation == 'tanh'
  24.  
  25.             self.activation = tanh 
  26.  
  27.             self.activation_deriv = tanh_deriv 
  28.  
  29.   
  30.  
  31.         self.weights = [] 
  32.  
  33.         for i in range(1, len(layers) - 1): 
  34.  
  35.             self.weights.append((2*np.random.random((layers[i - 1] + 1, layers[i] + 1))-1)*0.25) 
  36.  
  37.             self.weights.append((2*np.random.random((layers[i] + 1, layers[i + 1]))-1)*0.25)  

实现算法

 
  1. def fit(self, X, y, learning_rate=0.2, epochs=10000): 
  2.  
  3.         X = np.atleast_2d(X) 
  4.  
  5.         temp = np.ones([X.shape[0], X.shape[1]+1]) 
  6.  
  7.         temp[:, 0:-1] = X 
  8.  
  9.         X = temp 
  10.  
  11.         y = np.array(y) 
  12.  
  13.   
  14.  
  15.         for k in range(epochs): 
  16.  
  17.             i = np.random.randint(X.shape[0]) 
  18.  
  19.             a = [X[i]] 
  20.  
  21.   
  22.  
  23.             for l in range(len(self.weights)): 
  24.  
  25.                 a.append(self.activation(np.dot(a[l], self.weights[l]))) 
  26.  
  27.             error = y[i] - a[-1] 
  28.  
  29.             deltas = [error * self.activation_deriv(a[-1])] 
  30.  
  31.   
  32.  
  33.             for l in range(len(a) - 2, 0, -1): 
  34.  
  35.                 deltas.append(deltas[-1].dot(self.weights[l].T)*self.activation_deriv(a[l])) 
  36.  
  37.             deltas.reverse() 
  38.  
  39.   
  40.  
  41.             for i in range(len(self.weights)): 
  42.  
  43.                 layer = np.atleast_2d(a[i]) 
  44.  
  45.                 delta = np.atleast_2d(deltas[i]) 
  46.  
  47.                 self.weights[i] += learning_rate * layer.T.dot(delta)  

实现预测

 
  1. def predict(self, x): 
  2.  
  3.        x = np.array(x) 
  4.  
  5.        temp = np.ones(x.shape[0]+1) 
  6.  
  7.        temp[0:-1] = x 
  8.  
  9.        a = temp 
  10.  
  11.        for l in range(0, len(self.weights)): 
  12.  
  13.            a = self.activation(np.dot(a, self.weights[l])) 
  14.  
  15.        return a  

我们给出一组数进行预测,我们上面的程序文件保存名称为BP

 
  1. from BP import NeuralNetwork 
  2.  
  3. import numpy as np 
  4.  
  5.   
  6.  
  7. nn = NeuralNetwork([2,2,1], 'tanh'
  8.  
  9. x = np.array([[0,0], [0,1], [1,0], [1,1]]) 
  10.  
  11. y = np.array([1,0,0,1]) 
  12.  
  13. nn.fit(x,y,0.1,10000) 
  14.  
  15. for i in [[0,0], [0,1], [1,0], [1,1]]: 
  16.  
  17.     print(i, nn.predict(i))  

结果如下:

 
  1. ([0, 0], array([ 0.99738862])) 
  2. ([0, 1], array([ 0.00091329])) 
  3.  
  4. ([1, 0], array([ 0.00086846])) 
  5.  
  6. ([1, 1], array([ 0.99751259]))   



作者:佚名

来源:51CTO

相关文章
|
7天前
|
数据采集 存储 API
网络爬虫与数据采集:使用Python自动化获取网页数据
【4月更文挑战第12天】本文介绍了Python网络爬虫的基础知识,包括网络爬虫概念(请求网页、解析、存储数据和处理异常)和Python常用的爬虫库requests(发送HTTP请求)与BeautifulSoup(解析HTML)。通过基本流程示例展示了如何导入库、发送请求、解析网页、提取数据、存储数据及处理异常。还提到了Python爬虫的实际应用,如获取新闻数据和商品信息。
|
8天前
|
安全 Java 数据处理
Python网络编程基础(Socket编程)多线程/多进程服务器编程
【4月更文挑战第11天】在网络编程中,随着客户端数量的增加,服务器的处理能力成为了一个重要的考量因素。为了处理多个客户端的并发请求,我们通常需要采用多线程或多进程的方式。在本章中,我们将探讨多线程/多进程服务器编程的概念,并通过一个多线程服务器的示例来演示其实现。
|
8天前
|
程序员 开发者 Python
Python网络编程基础(Socket编程) 错误处理和异常处理的最佳实践
【4月更文挑战第11天】在网络编程中,错误处理和异常管理不仅是为了程序的健壮性,也是为了提供清晰的用户反馈以及优雅的故障恢复。在前面的章节中,我们讨论了如何使用`try-except`语句来处理网络错误。现在,我们将深入探讨错误处理和异常处理的最佳实践。
|
1月前
|
数据采集 存储 XML
深入浅出:基于Python的网络数据爬虫开发指南
【2月更文挑战第23天】 在数字时代,数据已成为新的石油。企业和个人都寻求通过各种手段获取互联网上的宝贵信息。本文将深入探讨网络爬虫的构建与优化,一种自动化工具,用于从网页上抓取并提取大量数据。我们将重点介绍Python语言中的相关库和技术,以及如何高效、合法地收集网络数据。文章不仅为初学者提供入门指导,也为有经验的开发者提供进阶技巧,确保读者能够在遵守网络伦理和法规的前提下,充分利用网络数据资源。
|
15天前
|
数据采集 网络协议 API
python中其他网络相关的模块和库简介
【4月更文挑战第4天】Python网络编程有多个流行模块和库,如requests提供简洁的HTTP客户端API,支持多种HTTP方法和自动处理复杂功能;Scrapy是高效的网络爬虫框架,适用于数据挖掘和自动化测试;aiohttp基于asyncio的异步HTTP库,用于构建高性能Web应用;Twisted是事件驱动的网络引擎,支持多种协议和异步编程;Flask和Django分别是轻量级和全栈Web框架,方便构建不同规模的Web应用。这些工具使网络编程更简单和高效。
|
27天前
|
运维 安全 网络安全
Python灰帽子网络安全实践
旨在降低网络防范黑客的入门门槛,适合所有中小企业和传统企业。罗列常见的攻击手段和防范方法,让网站管理人员都具备基本的保护能力。Python 编程的简单实现,让网络运维变得更简单。各种黑客工具的理论和原理解剖,让人知其然更知道防范于未来。涉及互联网和局域网,让企业级网管工作更轻松。涵盖Linux&Windows 的知识点。
14 1
|
29天前
|
消息中间件 网络协议 API
Python语言的进程通讯及网络
Python语言的进程通讯及网络
|
1月前
|
机器学习/深度学习 算法框架/工具 Python
如何使用Python的Keras库构建神经网络模型?
如何使用Python的Keras库构建神经网络模型?
8 0
|
1月前
|
Python
如何使用Python的Requests库进行网络请求和抓取网页数据?
如何使用Python的Requests库进行网络请求和抓取网页数据?
12 0
|
1月前
|
网络协议 Python
Python网络编程实现TCP和UDP连接
Python网络编程实现TCP和UDP连接
27 0