BP算法应用

BP神经网络(Back Propagation Neural Network)是一种常见的网络,可以用于设计分类器和数值拟合等。本文将介绍一种简单的分类器设计和利用标准BP网络实现二次函数拟合。
首先介绍片BP神经网络的结构,包括输入层,隐藏层和输出层,示意图如下:
BP算法应用_第1张图片
上图展示了BP神经网络的前向传递过程,输入数据进入隐藏层进行计算,最终通过输出层输出,但是由于输出的数据和设定数据可能存在误差因此需要反向传递对网络内的参数进行调整,调整过程将通过循环固定次数或迭代至满足条件后完成参数的修改和调整。各层数据的计算需要前一层的输入,本层的W,b,以及激活函数来进行计算,需要注意的是每一层都需要有非线性的激活函数,若不存在激活函数或是线性激活函数时我们明显的看出无论经过多少层的计算最终都可以化简为单层的线性变换,因此非线性的激活函数尤为重要。常见的激活函数有relu、sigmoid、tanh等,可以根据输入输出的范围进行适当的选择。设每一层(l)输出为al,则有a(l+1)=activate_function(a(l)w+b)
根据BP神经网络的输出和给定输出,需要指标进行评估网络的性能,损失函数就是执行此功能(损失函数也称为代价函数,lost function、cost function)。通常损失函数还将用于反向传递的计算,通过对损失函数求偏导数,再将偏导数乘以学习率即可以作为此层的单次偏移量,通过实现对以上过程的重复迭代网络的损失函数将逐渐降低,在迭代或循环次数达到一定程度后反向传播的效果将明显降低,次数过多时可以停止参数的调整。
前向传递:Z=W
A(l-1)+b, A(l)=G(Z);G是激活函数
反向传递:输入:dA(l) 输出:dA(l-1) , dW(l) , dB(l)
BP算法应用_第2张图片

在简单介绍了BP神经网络的原理和工作流程之后,我们将介绍一个简单的分类器设计,对分类器输入一张图片然后输出判断结果图片是否是猫,这一设计源于吴恩达老师的深度学习课程(需要的可以自行百度)。网络设计之前首先需要对数据进行处理,将一个RGB图片的数据通过矩阵变换调整为一个向量,这个向量就是网络的输入,输入将进行一次线性变换后进行sigmoid非线性并作为隐藏层的输出,此输出在经过一次相同的处理后作为最终输出,由sigmoid函数我们可以知道输出的范围在0,1之间,可以设定阈值为0.5将输出划分为两类即0和1。由于网络规模小,因此识别的能力较差,可以通过增加层数或采用卷积等方式进行调整。代码的实现可以参考吴恩达老师相关课程的 作业。
本文还将介绍一个利用BP神经网络实现二次函数拟合,实现的网络结构基本同上,但是由于二次函数的输出不可能只存在于0,1之间,因此最后一层的激活函数不可采用sigmoid,本文选择了最后一层不添加激活函数,读者也可以自行选择激活函数(但函数的值域应满足自己的需求),对于损失函数选择了预测和实际输出差的平方的均值。如果一个神经网络完全自己搭建,我们需要计算每一层的反向传递,并进行反复迭代,但是在利用TensorFlow进行程序的编写时可以简化这一步骤,无需自行计算反向传递函数,可以直接选择自己需要的损失函数和梯度下降的方法。
Python实现代码如下,需要注意的是代码中的输入有范围因此范围内的预测也相对精准,但是在预测数据远超出范围是拟合的效果可能会很差。

# -*- coding: utf-8 -*-
"""
Created on Fri Sep 28 15:31:11 2018

@author: fine0
"""

from __future__ import print_function
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
 
def add_layer(inputs, in_size, out_size, activation_function=None):
    # add one more layer and return the output of this layer
    Weights = tf.Variable(tf.random_normal([in_size, out_size]))
    biases = tf.Variable(tf.zeros([1, out_size]) + 0.1)
    Wx_plus_b = tf.matmul(inputs, Weights) + biases
    if activation_function is None:
        outputs = Wx_plus_b
    else:
        outputs = activation_function(Wx_plus_b)
    return outputs
 
# Make up some real data
x_data = np.linspace(-1,1,300)[:, np.newaxis]
noise = np.random.normal(0, 0.05, x_data.shape)
y_data = np.square(x_data) - 0.5 + noise
 
# define placeholder for inputs to network
xs = tf.placeholder(tf.float32, [None, 1])
ys = tf.placeholder(tf.float32, [None, 1])
# add hidden layer
l1 = add_layer(xs, 1, 10, activation_function=tf.nn.relu)
# add output layer
prediction = add_layer(l1, 10, 1, activation_function=None)
 
# the error between prediciton and real data
loss = tf.reduce_mean(tf.reduce_sum(tf.square(ys - prediction),
                     reduction_indices=[1]))
train_step = tf.train.GradientDescentOptimizer(0.1).minimize(loss)
 
# important step
init = tf.initialize_all_variables()
sess = tf.Session()
sess.run(init)
 
# plot the real data
fig = plt.figure()
ax = fig.add_subplot(1,1,1)
ax.scatter(x_data, y_data)
plt.ion()
plt.show()
 
for i in range(1000):
    # training
    sess.run(train_step, feed_dict={xs: x_data, ys: y_data})
    if i % 50 == 0:
        # to visualize the result and improvement
        try:
            ax.lines.remove(lines[0])
        except Exception:
            pass
        prediction_value = sess.run(prediction, feed_dict={xs: x_data})
        # plot the prediction
        lines = ax.plot(x_data, prediction_value, 'r-', lw=5)
        plt.pause(0.1)
`

你可能感兴趣的:(BP算法应用)