神经网络算法以及 Tensorflow 的实现
一, 多层向前神经网络(Multilayer Feed-Forward Neural Network)
多层向前神经网络由三部分组成: 输入层(input layer), 隐藏层 (hidden layers), 输入层 (output layers)
每层由单元 (units) 组成
输入层 (input layer) 是由训练集的实例特征向量传入
经过连接结点的权重 (weight) 传入下一层, 上一层的输出是下一层的输入
隐藏层的个数可以是任意的, 输入层有一层, 输出层有一层
每个单元 (unit) 也可以被称作神经结点(根据生物学来源定义)
以上成为 2 层的神经网络(输入层不算)
一层中加权的求和(输入乘以权重在加上偏向), 然后根据非线性方程转化输出
作为多层向前神经网络, 理论上, 如果有足够多的隐藏层(hidden layers) 和足够大的训练集, 可以模拟出任何方程
二, 神经网络结构设计
使用神经网络训练数据之前, 必须确定神经网络的层数, 以及每层单元的个数
特征向量在被传入输入层时通常被先标准化 (normalize) 到 0 和 1 之间 (为了加速学习过程)
离散型变量可以被编码成每一个输入单元对应一个特征值可能赋的值
比如: 特征值 A 可能取三个值(a0, a1, a2), 可以使用 3 个输入单元来代表 A.
如果 A=a0, 那么代表 a0 的单元值就取 1, 其他取 0;
如果 A=a1, 那么代表 a1de 单元值就取 1, 其他取 0, 以此类推
神经网络即可以用来做分类 (classification) 问题, 也可以解决回归 (regression) 问题
对于分类问题, 如果是 2 类, 可以用一个输出单元表示(0 和 1 分别代表 2 类)
如果多于 2 类, 每一个类别用一个输出单元表示
所以输入层的单元数量通常等于类别的数量
没有明确的规则来设计最好有多少个隐藏层
根据实验测试和误差, 以及准确度来实验并改
三, Backpropagation 算法
通过迭代思想来处理训练集中的实例
对比经过神经网络后输入层预测值 (predicted value) 与真实值 (target value) 之间
反方向 (从输出层 => 隐藏层 =>输入层)来以最小化误差 (error) 来更新每个连接的权重(weight)
算法详细介绍:
初始化权重 (weights) 和偏向(bias): 随机初始化在 - 1 到 1 之间, 或者 - 0.5 到 0.5 之间, 每个单元有一个偏向
对于每一个训练实例 X, 执行以下步骤:
由输入层向前传送 (前向传播): 输入层 ==> 权重和偏向 ==>非线性处理 ==>输出层(预测结果)
根据误差 (error) 反向传送: 误差 ==>输出层 ==>隐藏层 ==>输入层(通常利用梯度下降算法)(更新权重和偏向)
3. 终止条件
权重的更新低于某个阈值
预测的错误率低于某个阈值
达到预设一定的循环次数
四, 利用神经网络实现回归问题 -- 非线性回归
- # 程序:
- import os
- os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
- import tensorflow as tf
- import numpy as np
- import matplotlib.pyplot as plt #python 中画图工具包
- #使用 numpy 生成 200 个随机点(样本点)
- x_data = np.linspace(-0.5, 0.5, 200)[:, np.newaxis] #使用 numpy 生成 200 个随机点,[:, np.newaxis]增加维度(x_data 是一个 200 行 1 列的数据)
- noise = np.random.normal(0, 0.02, x_data.shape) #生成随机噪声干扰项(形状同 x_data)
- y_data = np.square(x_data) + noise #构造类似于二次函数的点图形
- #定义两个 placeholder
- x = tf.placeholder(tf.float32, [None, 1]) #x,y 的维度为任意行, 1 列(根据样本来定义的维度)
- y = tf.placeholder(tf.float32, [None, 1])
- #定义神经网络隐藏层 L1(该神经网络的神经元数量为(1-10-1))
- Weights_L1 = tf.Variable(tf.random_normal([1, 10])) #随机产生 10 个权重
- Biases_L1 = tf.Variable(tf.zeros([1, 10])) #0 初始化偏向
- Wx_plus_B_L1 = tf.matmul(x, Weights_L1) + Biases_L1 #L1 层进行加权求和
- L1 = tf.nn.tanh(Wx_plus_B_L1) #根据非线性方程 (双曲正切函数) 转化输出
- #定义神经网络输出层
- Weights_L2 = tf.Variable(tf.random_normal([10, 1]))
- Biases_L2 = tf.Variable(tf.zeros([1, 1]))
- Wx_plus_B_L2 = tf.matmul(L1, Weights_L2) + Biases_L2 #将 L1 的输出作为输出层的输入
- prediction = tf.nn.tanh(Wx_plus_B_L2) #预测值
- #定义二次代价函数
- loss = tf.reduce_mean(tf.square(y - prediction))
- #使用随机梯度下降法进行训练, 使得二次代价函数最小
- train_step = tf.train.GradientDescentOptimizer(0.1).minimize(loss)
- #变量初始化
- init = tf.global_variables_initializer()
- #定义会话
- with tf.Session() as sess:
- sess.run(init)
- for _ in range(2000): #进行 2000 次训练学习
- sess.run(train_step, feed_dict = {x:x_data, y:y_data})
- #获得预测值
- prediction_value = sess.run(prediction, feed_dict = {x:x_data})
- #画图
- plt.figure()
- plt.scatter(x_data, y_data)
- plt.plot(x_data, prediction_value, 'r-', lw = 5)
- plt.show()
- # 执行结果:
五, 利用神经网络实现分类问题 --MNIST 数据集分类相关介绍及其简单实现
1. MNINST 数据集介绍
MINST 数据集官网: http://yann.lecun.com/exdb/mnist/
MINST 数据集分类: MNIST 手写数字数据库具有 60000 个示例的训练集和 10000 个示例的测试集
每一张图片包含 28*28 个像素, 将其变成一个 1 行 28*28=784 列的向量. 图片中的像素值介于 0-1 之间.
60000 个示例的训练集是一个 [60000,784] 的张量.
MNIST 数据集的标签是 0-9 的数字.
'one-hot vector': 某一位维度的数字是 1, 其余维度的数字是 0.
将 MNIST 数据集的标签转换为'one-hot vector', 比如标签 5, 用该种方法表示为:[0000010000]
2. softmax 函数(归一化指数函数)
作用:
将一个含任意实数的 k 维向量'压缩'到另一个 k 维向量中, 使得每一个元素的范围都在 (0,1) 之间, 并且所有元素的和位 1.
形式:
常用于基于概率的多分类问题中
举例理解:
比如 MNIST 数据集识别结果为(1,5,3)
则:
- exp(1)= 2.718;exp(5)= 148.413;exp(3)= 20.086
- exp(1)+ exp(5)+ exp(3)= 171.217
- P1 = exp(1)% ( exp(1)+ exp(5)+ exp(3))= 0.016
- P5 = exp(5)% ( exp(1)+ exp(5)+ exp(3))= 0.867
- P3 = exp(3)% ( exp(1)+ exp(5)+ exp(3))= 0.117
因为结果为 5 的概率最大. 所以, 最终识别结果应该是 5.
3. 构建简单的神经网络来进行 MNIST 数据集识别
784 个神经元作为输入, 无隐藏层, 10 个神经元为输出
4.Tensorflow 程序实现
- import os
- os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
- import tensorflow as tf
- from tensorflow.examples.tutorials.mnist import input_data
- #载入数据集
- mnist = input_data.read_data_sets('MNIST_data', one_hot=True)
- #每个批次的大小(即每次训练的图片数量)
- batch_size = 50
- #计算一共有多少个批次
- n_bitch = mnist.train.num_examples // batch_size
- #定义两个 placeholder
- x = tf.placeholder(tf.float32, [None, 784])
- y = tf.placeholder(tf.float32, [None, 10])
- #创建一个只有输入层 (784 个神经元) 和输出层 (10 个神经元) 的简单神经网络
- Weights = tf.Variable(tf.zeros([784, 10]))
- Biases = tf.Variable(tf.zeros([10]))
- Wx_plus_B = tf.matmul(x, Weights) + Biases
- prediction = tf.nn.softmax(Wx_plus_B)
- #二次代价函数
- loss = tf.reduce_mean(tf.square(y - prediction))
- #使用梯度下降法
- train_step = tf.train.GradientDescentOptimizer(0.1).minimize(loss)
- #初始化变量
- init = tf.global_variables_initializer()
- #结果存放在一个布尔型列表中
- correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(prediction, 1)) #argmax 返回一维张量中最大的值所在的位置, 标签值和预测值相同, 返回为 True
- #求准确率
- accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32)) #cast 函数将 correct_prediction 的布尔型转换为浮点型, 然后计算平均值即为准确率
- with tf.Session() as sess:
- sess.run(init)
- #将测试集循环训练 20 次
- for epoch in range(21):
- #将测试集中所有数据循环一次
- for batch in range(n_bitch):
- batch_xs, batch_ys = mnist.train.next_batch(batch_size) #取测试集中 batch_size 数量的图片及对应的标签值
- sess.run(train_step, feed_dict={x:batch_xs, y:batch_ys}) #将上一行代码取到的数据进行训练
- acc = sess.run(accuracy, feed_dict={x:mnist.test.images, y:mnist.test.labels}) #准确率的计算
- print('Iter:' + str(epoch) + ',Testing Accuracy=' + str(acc))
- # 执行结果
- # 执行结果:(因为已经下载过数据集, 如果第一次运行, 是提示下载成功)
- Extracting MNIST_data\train-images-idx3-ubyte.gz
- Extracting MNIST_data\train-labels-idx1-ubyte.gz
- Extracting MNIST_data\t10k-images-idx3-ubyte.gz
- Extracting MNIST_data\t10k-labels-idx1-ubyte.gz
- Iter : 0,Testing Accuracy = 0.8599
- Iter : 1,Testing Accuracy = 0.8806
- Iter : 2,Testing Accuracy = 0.8909
- Iter : 3,Testing Accuracy = 0.8963
- Iter : 4,Testing Accuracy = 0.9006
- Iter : 5,Testing Accuracy = 0.9034
- Iter : 6,Testing Accuracy = 0.9047
- Iter : 7,Testing Accuracy = 0.9069
- Iter : 8,Testing Accuracy = 0.908
- Iter : 9,Testing Accuracy = 0.9094
- Iter : 10,Testing Accuracy = 0.9113
- Iter : 11,Testing Accuracy = 0.9127
- Iter : 12,Testing Accuracy = 0.9137
- Iter : 13,Testing Accuracy = 0.9144
- Iter : 14,Testing Accuracy = 0.9144
- Iter : 15,Testing Accuracy = 0.9156
- Iter : 16,Testing Accuracy = 0.9156
- Iter : 17,Testing Accuracy = 0.9171
- Iter : 18,Testing Accuracy = 0.9173
- Iter : 19,Testing Accuracy = 0.9177
- Iter : 20,Testing Accuracy = 0.9179
- View Code
- # 准确率不是很高, 但是我只是构建了最简单的输入输出层. 我会根据之后所学去优化程序, 提高准确率
来源: https://www.cnblogs.com/guoruxin/p/10151990.html