python实现BP神经网络回归预测模型


Posted in Python onAugust 09, 2019

神经网络模型一般用来做分类,回归预测模型不常见,本文基于一个用来分类的BP神经网络,对它进行修改,实现了一个回归模型,用来做室内定位。模型主要变化是去掉了第三层的非线性转换,或者说把非线性激活函数Sigmoid换成f(x)=x函数。这样做的主要原因是Sigmoid函数的输出范围太小,在0-1之间,而回归模型的输出范围较大。模型修改如下:

python实现BP神经网络回归预测模型

python实现BP神经网络回归预测模型

代码如下:

#coding: utf8
''''
author: Huangyuliang
'''
import json
import random
import sys
import numpy as np
 
#### Define the quadratic and cross-entropy cost functions
class CrossEntropyCost(object):
 
  @staticmethod
  def fn(a, y):
    return np.sum(np.nan_to_num(-y*np.log(a)-(1-y)*np.log(1-a)))
 
  @staticmethod
  def delta(z, a, y):
    return (a-y)
 
#### Main Network class
class Network(object):
 
  def __init__(self, sizes, cost=CrossEntropyCost):
 
    self.num_layers = len(sizes)
    self.sizes = sizes
    self.default_weight_initializer()
    self.cost=cost
 
  def default_weight_initializer(self):
 
    self.biases = [np.random.randn(y, 1) for y in self.sizes[1:]]
    self.weights = [np.random.randn(y, x)/np.sqrt(x)
            for x, y in zip(self.sizes[:-1], self.sizes[1:])]
  def large_weight_initializer(self):
 
    self.biases = [np.random.randn(y, 1) for y in self.sizes[1:]]
    self.weights = [np.random.randn(y, x)
            for x, y in zip(self.sizes[:-1], self.sizes[1:])]
  def feedforward(self, a):
    """Return the output of the network if ``a`` is input."""
    for b, w in zip(self.biases[:-1], self.weights[:-1]): # 前n-1层
      a = sigmoid(np.dot(w, a)+b)
 
    b = self.biases[-1]  # 最后一层
    w = self.weights[-1]
    a = np.dot(w, a)+b
    return a
 
  def SGD(self, training_data, epochs, mini_batch_size, eta,
      lmbda = 0.0,
      evaluation_data=None,
      monitor_evaluation_accuracy=False): # 用随机梯度下降算法进行训练
 
    n = len(training_data)
 
    for j in xrange(epochs):
      random.shuffle(training_data)
      mini_batches = [training_data[k:k+mini_batch_size] for k in xrange(0, n, mini_batch_size)]
      
      for mini_batch in mini_batches:
        self.update_mini_batch(mini_batch, eta, lmbda, len(training_data))
      print ("Epoch %s training complete" % j)
      
      if monitor_evaluation_accuracy:
        print ("Accuracy on evaluation data: {} / {}".format(self.accuracy(evaluation_data), j))
     
  def update_mini_batch(self, mini_batch, eta, lmbda, n):
    """Update the network's weights and biases by applying gradient
    descent using backpropagation to a single mini batch. The
    ``mini_batch`` is a list of tuples ``(x, y)``, ``eta`` is the
    learning rate, ``lmbda`` is the regularization parameter, and
    ``n`` is the total size of the training data set.
    """
    nabla_b = [np.zeros(b.shape) for b in self.biases]
    nabla_w = [np.zeros(w.shape) for w in self.weights]
    for x, y in mini_batch:
      delta_nabla_b, delta_nabla_w = self.backprop(x, y)
      nabla_b = [nb+dnb for nb, dnb in zip(nabla_b, delta_nabla_b)]
      nabla_w = [nw+dnw for nw, dnw in zip(nabla_w, delta_nabla_w)]
    self.weights = [(1-eta*(lmbda/n))*w-(eta/len(mini_batch))*nw
            for w, nw in zip(self.weights, nabla_w)]
    self.biases = [b-(eta/len(mini_batch))*nb
            for b, nb in zip(self.biases, nabla_b)]
 
  def backprop(self, x, y):
    """Return a tuple ``(nabla_b, nabla_w)`` representing the
    gradient for the cost function C_x. ``nabla_b`` and
    ``nabla_w`` are layer-by-layer lists of numpy arrays, similar
    to ``self.biases`` and ``self.weights``."""
    nabla_b = [np.zeros(b.shape) for b in self.biases]
    nabla_w = [np.zeros(w.shape) for w in self.weights]
    # feedforward
    activation = x
    activations = [x] # list to store all the activations, layer by layer
    zs = [] # list to store all the z vectors, layer by layer
    for b, w in zip(self.biases[:-1], self.weights[:-1]):  # 正向传播 前n-1层
 
      z = np.dot(w, activation)+b
      zs.append(z)
      activation = sigmoid(z)
      activations.append(activation)
# 最后一层,不用非线性
    b = self.biases[-1]
    w = self.weights[-1]
    z = np.dot(w, activation)+b
    zs.append(z)
    activation = z
    activations.append(activation)
    # backward pass 反向传播
    delta = (self.cost).delta(zs[-1], activations[-1], y)  # 误差 Tj - Oj 
    nabla_b[-1] = delta
    nabla_w[-1] = np.dot(delta, activations[-2].transpose()) # (Tj - Oj) * O(j-1)
 
    for l in xrange(2, self.num_layers):
      z = zs[-l]  # w*a + b
      sp = sigmoid_prime(z) # z * (1-z)
      delta = np.dot(self.weights[-l+1].transpose(), delta) * sp # z*(1-z)*(Err*w) 隐藏层误差
      nabla_b[-l] = delta
      nabla_w[-l] = np.dot(delta, activations[-l-1].transpose()) # Errj * Oi
    return (nabla_b, nabla_w)
 
  def accuracy(self, data):
 
    results = [(self.feedforward(x), y) for (x, y) in data] 
    alist=[np.sqrt((x[0][0]-y[0])**2+(x[1][0]-y[1])**2) for (x,y) in results]
 
    return np.mean(alist)
 
  def save(self, filename):
    """Save the neural network to the file ``filename``."""
    data = {"sizes": self.sizes,
        "weights": [w.tolist() for w in self.weights],
        "biases": [b.tolist() for b in self.biases],
        "cost": str(self.cost.__name__)}
    f = open(filename, "w")
    json.dump(data, f)
    f.close()
 
#### Loading a Network
def load(filename):
  """Load a neural network from the file ``filename``. Returns an
  instance of Network.
  """
  f = open(filename, "r")
  data = json.load(f)
  f.close()
  cost = getattr(sys.modules[__name__], data["cost"])
  net = Network(data["sizes"], cost=cost)
  net.weights = [np.array(w) for w in data["weights"]]
  net.biases = [np.array(b) for b in data["biases"]]
  return net
 
def sigmoid(z):
  """The sigmoid function.""" 
  return 1.0/(1.0+np.exp(-z))
 
def sigmoid_prime(z):
  """Derivative of the sigmoid function."""
  return sigmoid(z)*(1-sigmoid(z))

调用神经网络进行训练并保存参数:

#coding: utf8
import my_datas_loader_1
import network_0
 
training_data,test_data = my_datas_loader_1.load_data_wrapper()
#### 训练网络,保存训练好的参数
net = network_0.Network([14,100,2],cost = network_0.CrossEntropyCost)
net.large_weight_initializer()
net.SGD(training_data,1000,316,0.005,lmbda =0.1,evaluation_data=test_data,monitor_evaluation_accuracy=True)
filename=r'C:\Users\hyl\Desktop\Second_158\Regression_Model\parameters.txt'
net.save(filename)

第190-199轮训练结果如下:

python实现BP神经网络回归预测模型

调用保存好的参数,进行定位预测:

#coding: utf8
import my_datas_loader_1
import network_0
import matplotlib.pyplot as plt
 
test_data = my_datas_loader_1.load_test_data()
#### 调用训练好的网络,用来进行预测
filename=r'D:\Workspase\Nerual_networks\parameters.txt'   ## 文件保存训练好的参数
net = network_0.load(filename)                ## 调用参数,形成网络
fig=plt.figure(1)
ax=fig.add_subplot(1,1,1)
ax.axis("equal") 
# plt.grid(color='b' , linewidth='0.5' ,linestyle='-')    # 添加网格
x=[-0.3,-0.3,-17.1,-17.1,-0.3]                ## 这是九楼地形的轮廓
y=[-0.3,26.4,26.4,-0.3,-0.3]
m=[1.5,1.5,-18.9,-18.9,1.5]
n=[-2.1,28.2,28.2,-2.1,-2.1]
ax.plot(x,y,m,n,c='k')
 
for i in range(len(test_data)):  
  pre = net.feedforward(test_data[i][0]) # pre 是预测出的坐标    
  bx=pre[0]
  by=pre[1]          
  ax.scatter(bx,by,s=4,lw=2,marker='.',alpha=1) #散点图  
  plt.pause(0.001)
plt.show()

定位精度达到了1.5米左右。定位效果如下图所示:

python实现BP神经网络回归预测模型

真实路径为行人从原点绕环形走廊一圈。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python计算三角函数之asin()方法的使用
May 15 Python
Python实现复杂对象转JSON的方法示例
Jun 22 Python
深入理解Python中range和xrange的区别
Nov 26 Python
Python实现的生成格雷码功能示例
Jan 24 Python
利用Python实现微信找房机器人实例教程
Mar 10 Python
django rest framework 实现用户登录认证详解
Jul 29 Python
Python中six模块基础用法
Dec 08 Python
Python验证码截取识别代码实例
May 16 Python
scrapy与selenium结合爬取数据(爬取动态网站)的示例代码
Sep 28 Python
Python爬虫过程解析之多线程获取小米应用商店数据
Nov 14 Python
python爬虫泛滥的解决方法详解
Nov 25 Python
Python爬虫实战案例之爬取喜马拉雅音频数据详解
Dec 07 Python
Django ORM 聚合查询和分组查询实现详解
Aug 09 #Python
解决Django后台ManyToManyField显示成Object的问题
Aug 09 #Python
详解Python中的正斜杠与反斜杠
Aug 09 #Python
图文详解Django使用Pycharm连接MySQL数据库
Aug 09 #Python
Django ORM多对多查询方法(自定义第三张表&ManyToManyField)
Aug 09 #Python
Django使用Jinja2模板引擎的示例代码
Aug 09 #Python
在Django admin中编辑ManyToManyField的实现方法
Aug 09 #Python
You might like
PHP在XP下IIS和Apache2服务器上的安装
2006/09/05 PHP
PHP截取汉字乱码问题解决方法mb_substr函数的应用
2008/03/30 PHP
探讨:array2xml和xml2array以及xml与array的互相转化
2013/06/24 PHP
php模仿asp Application对象在线人数统计实现方法
2015/01/04 PHP
PHP中把错误日志保存在系统日志中(Windows系统)
2015/06/23 PHP
详谈php中 strtr 和 str_replace 的效率问题
2017/05/14 PHP
Javascript 中的 && 和 || 使用小结
2010/04/25 Javascript
页面回到顶部的三种实现(锚标记,js)
2012/10/01 Javascript
jQuery setTimeout()函数使用方法
2013/04/07 Javascript
node.js中的url.format方法使用说明
2014/12/10 Javascript
JavaScript数据类型之基本类型和引用类型的值
2015/04/01 Javascript
AngularJS基础 ng-repeat 指令简单示例
2016/08/03 Javascript
表单input项使用label同时引用Bootstrap库导致input点击效果区增大问题
2016/10/11 Javascript
详解axios在node.js中的post使用
2017/04/27 Javascript
vue过滤器用法实例分析
2019/03/15 Javascript
vue中keep-alive组件的入门使用教程
2019/06/06 Javascript
Vue修改项目启动端口号方法
2019/11/07 Javascript
推荐几个不错的console调试技巧实现
2019/12/20 Javascript
Element-UI+Vue模式使用总结
2020/01/02 Javascript
解决vue单页面多个组件嵌套监听浏览器窗口变化问题
2020/07/30 Javascript
Python基于opencv的图像压缩算法实例分析
2018/05/03 Python
Python全局变量与局部变量区别及用法分析
2018/09/03 Python
使用Django2快速开发Web项目的详细步骤
2019/01/06 Python
对Python协程之异步同步的区别详解
2019/02/19 Python
Python 200行代码实现一个滑动验证码过程详解
2019/07/11 Python
python3的url编码和解码,自定义gbk、utf-8的例子
2019/08/22 Python
python能做什么 python的含义
2019/10/12 Python
python3.7调试的实例方法
2020/07/21 Python
给女朋友的道歉信
2014/01/10 职场文书
给面试官的感谢信
2014/02/01 职场文书
总会计师岗位职责
2014/02/19 职场文书
食品工程专业求职信
2014/06/15 职场文书
项目工作说明书
2014/07/29 职场文书
个人授权委托书范本格式
2014/10/12 职场文书
台风停课通知
2015/04/24 职场文书
如何解决goland,idea全局搜索快捷键失效问题
2022/04/03 Golang