Python创建简单的神经网络实例讲解


Posted in Python onJanuary 04, 2021

在过去的几十年里,机器学习对世界产生了巨大的影响,而且它的普及程度似乎在不断增长。最近,越来越多的人已经熟悉了机器学习的子领域,如神经网络,这是由人类大脑启发的网络。在本文中,将介绍用于一个简单神经网络的 Python 代码,该神经网络对于一个 1x3 向量,分类第一个元素是否为 10。

步骤1: 导入 NumPy、 Scikit-learn 和 Matplotlib

import numpy as np
from sklearn.preprocessing import MinMaxScaler
import matplotlib.pyplot as plt

我们将在这个项目中使用上述三个库。NumPy 将用于创建向量和矩阵以及数学操作。Scikit-learn 将用于缩放数据,Matplotlib 将用于在神经网络训练期间绘图。

步骤2: 创建一个训练和测试数据集

神经网络在大型和小型数据集的学习趋势方面都很擅长。然而,数据科学家必须意识到过拟合的危险,这在使用小数据集的项目中更为明显。过拟合是当一个算法训练和建模过于接近一组数据点,以至于它不能很好地推广到新的数据点。

通常情况下,过拟合的机器学习模型在训练的数据集上有很高的准确性,但是作为一个数据科学家,目标通常是尽可能精确地预测新的数据点。为了确保根据预测新数据点的好坏来评估模型,而不是根据对当前数据点的建模好坏来评估模型,通常将数据集拆分为一个训练集和一个测试集(有时是一个验证集)。

input_train = np.array([[0, 1, 0], [0, 1, 1], [0, 0, 0], 
   [10, 0, 0], [10, 1, 1], [10, 0, 1]])
output_train = np.array([[0], [0], [0], [1], [1], [1]])
input_pred = np.array([1, 1, 0])
 
 
input_test = np.array([[1, 1, 1], [10, 0, 1], [0, 1, 10], 
   [10, 1, 10], [0, 0, 0], [0, 1, 1]])
output_test = np.array([[0], [1], [0], [1], [0], [0]])

在这个简单的神经网络中,我们将1x3向量分类,10作为第一个元素。使用 NumPy 的 array 函数创建输入和输出训练集和测试集,并创建 input_pred 以测试稍后将定义的 prediction 函数。训练和测试数据由6个样本组成,每个样本具有3个特征,由于输出已经给出,我们理解这是监督式学习的一个例子。

第三步: 扩展数据集

许多机器学习模型不能理解例如单位之间的区别,自然而然地对高度的特征应用更多的权重。这会破坏算法预测新数据点的能力。此外,训练具有高强度特征的机器学习模型将会比需要的慢,至少如果使用梯度下降法。这是因为当输入值在大致相同的范围内时,梯度下降法收敛得更快。

scaler = MinMaxScaler()
input_train_scaled = scaler.fit_transform(input_train)
output_train_scaled = scaler.fit_transform(output_train)
input_test_scaled = scaler.fit_transform(input_test)
output_test_scaled = scaler.fit_transform(output_test)

在我们的训练和测试数据集中,这些值的范围相对较小,因此可能没有必要进行特征扩展。然而,这样可以使得小伙伴们使用自己喜欢的数字,而不需要更改太多的代码。由于 Scikit-learn 包及其 MinMaxScaler 类,在 Python 中实现特征伸缩非常容易。只需创建一个 MinMaxScaler 对象,并使用 fit_transform 函数将非缩放数据作为输入,该函数将返回相同的缩放数据。Scikit-learn 包中还有其他缩放功能,我鼓励您尝试这些功能。

第四步: 创建一个神经网络类

要熟悉神经网络的所有元素,最简单的方法之一就是创建一个神经网络类。这样一个类应该包括所有的变量和函数,将是必要的神经网络工作正常。

class NeuralNetwork():
 def __init__(self, ):
 self.inputSize = 3
 self.outputSize = 1
 self.hiddenSize = 3
 
 
 self.W1 = np.random.rand(self.inputSize, self.hiddenSize)
 self.W2 = np.random.rand(self.hiddenSize, self.outputSize)
 
 
 self.error_list = []
 self.limit = 0.5
 self.true_positives = 0
 self.false_positives = 0
 self.true_negatives = 0
 self.false_negatives = 0
 
 
 def forward(self, X):
 self.z = np.matmul(X, self.W1)
 self.z2 = self.sigmoid(self.z)
 self.z3 = np.matmul(self.z2, self.W2)
 o = self.sigmoid(self.z3)
 return o
 
 
 def sigmoid(self, s):
 return 1 / (1 + np.exp(-s))
 
 
 def sigmoidPrime(self, s):
 return s * (1 - s)
 
 
 def backward(self, X, y, o):
 self.o_error = y - o
 self.o_delta = self.o_error * self.sigmoidPrime(o)
 self.z2_error = np.matmul(self.o_delta,
     np.matrix.transpose(self.W2))
 self.z2_delta = self.z2_error * self.sigmoidPrime(self.z2)
 self.W1 += np.matmul(np.matrix.transpose(X), self.z2_delta)
 self.W2 += np.matmul(np.matrix.transpose(self.z2),
    self.o_delta)
 
 
 def train(self, X, y, epochs):
 for epoch in range(epochs):
  o = self.forward(X)
  self.backward(X, y, o)
  self.error_list.append(np.abs(self.o_error).mean())
 
 
 def predict(self, x_predicted):
 return self.forward(x_predicted).item()
 
 
 def view_error_development(self):
 plt.plot(range(len(self.error_list)), self.error_list)
 plt.title('Mean Sum Squared Loss')
 plt.xlabel('Epoch')
 plt.ylabel('Loss')
 
 
 def test_evaluation(self, input_test, output_test):
 for i, test_element in enumerate(input_test):
  if self.predict(test_element) > self.limit and \
   output_test[i] == 1:
  self.true_positives += 1
  if self.predict(test_element) < self.limit and \
   output_test[i] == 1:
  self.false_negatives += 1
  if self.predict(test_element) > self.limit and \
   output_test[i] == 0:
  self.false_positives += 1
  if self.predict(test_element) < self.limit and \
   output_test[i] == 0:
  self.true_negatives += 1
 print('True positives: ', self.true_positives,
  '\nTrue negatives: ', self.true_negatives,
  '\nFalse positives: ', self.false_positives,
  '\nFalse negatives: ', self.false_negatives,
  '\nAccuracy: ',
  (self.true_positives + self.true_negatives) /
  (self.true_positives + self.true_negatives +
  self.false_positives + self.false_negatives))

步骤4.1: 创建一个 Initialize 函数

当我们在 Python 中创建一个类以便正确地初始化变量时,会调用 __init__ 函数。

Python创建简单的神经网络实例讲解

def __init__(self, ):
 self.inputSize = 3
 self.outputSize = 1
 self.hiddenSize = 3
 
 
 self.W1 = torch.randn(self.inputSize, self.hiddenSize)
 self.W2 = torch.randn(self.hiddenSize, self.outputSize)
 
 
 self.error_list = []
 self.limit = 0.5
 self.true_positives = 0
 self.false_positives = 0
 self.true_negatives = 0
 self.false_negatives = 0

Python创建简单的神经网络实例讲解

在这个例子中,我选择了一个有三个输入节点、三个隐藏层节点和一个输出节点的神经网络。以上的 __init__ 函数初始化描述神经网络大小的变量。inputSize 是输入节点的数目,它应该等于输入数据中特征的数目。outputSize 等于输出节点数,hiddenSize 描述隐藏层中的节点数。此外,我们的网络中不同节点之间的权重将在训练过程中进行调整。

除了描述神经网络的大小和权重的变量之外,我还创建了几个在创建神经网络对象时初始化的变量,这些对象将用于评估目的。误差列表将包含每个时期的平均绝对误差(MAE) ,这个极限将描述一个向量应该被分类为一个向量,元素10作为第一个元素而不是。然后,还有一些变量可以用来存储真实阳性、假阳性、真实阴性和假阴性的数量。

步骤4.2: 创建一个前向传播函数

前向传播函数的作用是通过神经网络的不同层次进行迭代,以预测特定 epoch 的输出。然后,根据预测输出和实际输出之间的差异,在反向传播的过程中更新权重。

def forward(self, X):
 self.z = np.matmul(X, self.W1)
 self.z2 = self.sigmoid(self.z)
 self.z3 = np.matmul(self.z2, self.W2)
 o = self.sigmoid(self.z3)
 return o

为了计算每一层中每个节点的值,前一层中节点的值将被乘以适当的权重,然后应用非线性激活函数来扩大最终输出函数的可能性。在这个例子中,我们选择了 Sigmoid 作为激活函数,但也有许多其他的选择。

步骤4.3: 创建一个反向传播函数

反向传播是对神经网络中不同节点的权值进行更新,从而决定其重要性的过程。

def backward(self, X, y, o):
 self.o_error = y - o
 self.o_delta = self.o_error * self.sigmoidPrime(o)
 self.z2_error = np.matmul(self.o_delta,
     np.matrix.transpose(self.W2))
 self.z2_delta = self.z2_error * self.sigmoidPrime(self.z2)
 self.W1 += np.matmul(np.matrix.transpose(X), self.z2_delta)
 self.W2 += np.matmul(np.matrix.transpose(self.z2),
    self.o_delta)

在上面的代码片段中,输出层的输出错误被计算为预测输出与实际输出之间的差值。然后,在重复整个过程直到到达输入层之前,将这个错误与 Sigmoid 相乘以运行梯度下降法。最后,更新不同层之间的权重。

步骤4.4: 创建一个训练函数

在训练过程中,该算法将运行向前和向后传递,从而更新每个 epoch 的权重。为了得到最精确的权重值,这是必要的。

def train(self, X, y, epochs):
 for epoch in range(epochs):
  o = self.forward(X)
  self.backward(X, y, o)
  self.error_list.append(np.abs(self.o_error).mean())

除了向前和向后传播之外,我们还将平均绝对误差(MAE)保存到一个错误列表中,以便日后观察平均绝对误差在训练过程中是如何演变的。

步骤4.5: 创建一个预测函数

在训练过程中对权重进行了微调之后,该算法就可以预测新数据点的输出。预测的输出数字有望与实际输出数字非常接近。

def predict(self, x_predicted):
 return self.forward(x_predicted).item()

步骤4.6: 绘制平均绝对误差发展图

评价机器学习算法质量的方法有很多。经常使用的测量方法之一是平均绝对误差,这个误差应该随着时间的推移而减小。

def view_error_development(self):
 plt.plot(range(len(self.error_list)), self.error_list)
 plt.title('Mean Sum Squared Loss')
 plt.xlabel('Epoch')
 plt.ylabel('Loss')

Python创建简单的神经网络实例讲解

步骤4.7: 计算精度及其组成部分

真正、假正、真负和假负的数量描述了机器学习分类算法的质量。训练后的神经网络权值更新,使算法能够准确地预测新的数据点。在二进制分类任务中,这些新数据点只能是1或0。根据预测值是否高于或低于定义的限制,算法将新条目分为1或0。

def test_evaluation(self, input_test, output_test):
 for i, test_element in enumerate(input_test):
  if self.predict(test_element) > self.limit and \
   output_test[i] == 1:
  self.true_positives += 1
  if self.predict(test_element) < self.limit and \
   output_test[i] == 1:
  self.false_negatives += 1
  if self.predict(test_element) > self.limit and \
   output_test[i] == 0:
  self.false_positives += 1
  if self.predict(test_element) < self.limit and \
   output_test[i] == 0:
  self.true_negatives += 1
 print('True positives: ', self.true_positives,
  '\nTrue negatives: ', self.true_negatives,
  '\nFalse positives: ', self.false_positives,
  '\nFalse negatives: ', self.false_negatives,
  '\nAccuracy: ',
  (self.true_positives + self.true_negatives) /
  (self.true_positives + self.true_negatives +
  self.false_positives + self.false_negatives))

当运行 test _ evaluation 函数时,我们得到以下结果:

真正: 2

真负: 4

假正: 0

假负: 0

准确性由以下公式给出:

Python创建简单的神经网络实例讲解

由此我们可以推断,在我们的案例中,精确度是1。

第五步: 运行一个脚本来训练和评估神经网络模型

NN = NeuralNetwork()
NN.train(input_train_scaled, output_train_scaled, 200)
NN.predict(input_pred)
NN.view_error_development()
NN.test_evaluation(input_test_scaled, output_test_scaled)

为了尝试我们刚刚构建的神经网络类,我们将首先初始化一个神经网络类型的对象。然后对训练数据进行神经网络训练,在新训练的模型在测试向量上进行测试之前,对算法的权值进行200个 epoch 以上的“修正”。然后,在利用测试数据集对模型进行评估之前,绘制误差图。

第六步: 改进脚本并使用它

提供的代码可以很容易地修改,以处理其他类似的情况。我们鼓励读者尝试改变变量并使用自己的数据等等。改进或变更的潜在想法包括但不限于:

  1. 泛化代码以适用于任何输入和输出大小的数据
  2. 使用平均绝对误差以外的另一个度量来衡量误差
  3. 使用其他的缩放函数

到此这篇关于Python创建简单的神经网络实例讲解的文章就介绍到这了,更多相关如何在Python中创建一个简单的神经网络内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
Python计算程序运行时间的方法
Dec 13 Python
python按照多个字符对字符串进行分割的方法
Mar 17 Python
Python简单格式化时间的方法【strftime函数】
Sep 18 Python
Scrapy-redis爬虫分布式爬取的分析和实现
Feb 07 Python
利用Python找出序列中出现最多的元素示例代码
Dec 08 Python
在cmd命令行里进入和退出Python程序的方法
May 12 Python
解决python中无法自动补全代码的问题
Dec 04 Python
Python设计模式之代理模式实例详解
Jan 19 Python
详解python中index()、find()方法
Aug 29 Python
python3中编码获取网页的实例方法
Nov 16 Python
Django通过设置CORS解决跨域问题
Nov 26 Python
用ldap作为django后端用户登录验证的实现
Dec 07 Python
python实现跨年表白神器--你值得拥有
Jan 04 #Python
Python列表元素删除和remove()方法详解
Jan 04 #Python
python3列表删除大量重复元素remove()方法的问题详解
Jan 04 #Python
关于python中remove的一些坑小结
Jan 04 #Python
python中remove函数的踩坑记录
Jan 04 #Python
python 日志模块logging的使用场景及示例
Jan 04 #Python
python 邮件检测工具mmpi的使用
Jan 04 #Python
You might like
PHP 获取目录下的图片并随机显示的代码
2009/12/28 PHP
Ext.data.PagingMemoryProxy分页一次性读取数据的实现代码
2010/04/07 PHP
PHP 命令行参数详解及应用
2011/05/18 PHP
模板引擎smarty工作原理以及使用示例
2014/05/25 PHP
浅谈PHP值mysql操作类
2016/06/29 PHP
php输出含有“#”字符串的方法
2017/01/18 PHP
thinkPHP框架实现多表查询的方法
2018/06/14 PHP
PHP中通过getopt解析GNU C风格命令行选项
2019/11/18 PHP
图片连续滚动代码[兼容IE/firefox]
2009/06/11 Javascript
javaScript 简单验证代码(用户名,密码,邮箱)
2009/09/28 Javascript
jquery UI 1.72 之datepicker
2009/12/29 Javascript
基于JQuery的密码强度验证代码
2010/03/01 Javascript
JS window对象的top、parent、opener含义介绍
2013/12/03 Javascript
Javascript显示和隐藏ul列表的方法
2015/07/15 Javascript
JavaScript作用域示例详解
2016/07/07 Javascript
JS从数组中随机取出几个数组元素的方法
2016/08/02 Javascript
vue中路由验证和相应拦截的使用详解
2017/12/13 Javascript
vue实现点击关注后及时更新列表功能
2018/06/26 Javascript
如何封装了一个vue移动端下拉加载下一页数据的组件
2019/01/06 Javascript
vue-cli2与vue-cli3在一台电脑共存的实现方法
2019/09/25 Javascript
vue下的@change事件的实现
2019/10/25 Javascript
Python基于聚类算法实现密度聚类(DBSCAN)计算【测试可用】
2018/12/26 Python
python实现月食效果实例代码
2019/06/18 Python
基于Python安装pyecharts所遇的问题及解决方法
2019/08/12 Python
Python字典中的值为列表或字典的构造实例
2019/12/16 Python
英国Amara家居法国网站:家居装饰,现代装饰和豪华礼品
2016/12/15 全球购物
黑猩猩商店:The Chimp Store
2020/02/12 全球购物
百度吧主申请感言
2014/01/12 职场文书
申请任职学生会干部自荐书范文
2014/02/13 职场文书
迎国庆演讲稿
2014/09/15 职场文书
2015年乡镇党务公开工作总结
2015/05/19 职场文书
导游词之秦始皇兵马俑博物馆
2019/09/29 职场文书
pytorch 梯度NAN异常值的解决方案
2021/06/05 Python
Lakehouse数据湖并发控制陷阱分析
2022/03/31 Oracle
如何通过cmd 连接阿里云服务器
2022/04/18 Servers
MySQL 原理优化之Group By的优化技巧
2022/08/14 MySQL