机器学习与Tensorflow(2)——神经网络及Tensorflow实现

时间:2024-01-22 14:04:08

神经网络算法以及Tensorflow的实现

一、多层向前神经网络(Multilayer Feed-Forward Neural Network)

 

  1. 多层向前神经网络由三部分组成:输入层(input layer), 隐藏层 (hidden layers), 输入层 (output layers)
  2. 每层由单元(units)组成
  3. 输入层(input layer)是由训练集的实例特征向量传入
  4. 经过连接结点的权重(weight)传入下一层,上一层的输出是下一层的输入
  5. 隐藏层的个数可以是任意的,输入层有一层,输出层有一层
  6. 每个单元(unit)也可以被称作神经结点(根据生物学来源定义)
  7. 以上成为2层的神经网络(输入层不算)
  8. 一层中加权的求和(输入乘以权重在加上偏向),然后根据非线性方程转化输出
  9. 作为多层向前神经网络,理论上,如果有足够多的隐藏层(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)
  • 算法详细介绍:
  1. 初始化权重(weights)和偏向(bias): 随机初始化在-1到1之间,或者-0.5到0.5之间,每个单元有一个偏向
  2. 对于每一个训练实例X,执行以下步骤:

由输入层向前传送(前向传播):输入层==>权重和偏向==>非线性处理==>输出层(预测结果)
根据误差(error)反向传送:误差==>输出层==>隐藏层==>输入层(通常利用梯度下降算法)(更新权重和偏向)

3.终止条件

权重的更新低于某个阈值
预测的错误率低于某个阈值
达到预设一定的循环次数

四、利用神经网络实现回归问题——非线性回归

 1 #程序:
 2 import os
 3 os.environ[\'TF_CPP_MIN_LOG_LEVEL\'] = \'2\'
 4 import tensorflow as tf
 5 import numpy as np
 6 import matplotlib.pyplot as plt     #python中画图工具包
 7 #使用numpy生成200个随机点(样本点)
 8 x_data = np.linspace(-0.5, 0.5, 200)[:, np.newaxis]      #使用numpy生成200个随机点,[:, np.newaxis]增加维度(x_data 是一个200行1列的数据)
 9 noise = np.random.normal(0, 0.02, x_data.shape)         #生成随机噪声干扰项(形状同x_data)  
10 y_data = np.square(x_data) + noise               #构造类似于二次函数的点图形
11 #定义两个placeholder
12 x = tf.placeholder(tf.float32, [None, 1])    #x、y的维度为任意行,1列(根据样本来定义的维度)
13 y = tf.placeholder(tf.float32, [None, 1])
14 #定义神经网络隐藏层L1(该神经网络的神经元数量为(1-10-1))
15 Weights_L1 = tf.Variable(tf.random_normal([1, 10]))    #随机产生10个权重
16 Biases_L1 = tf.Variable(tf.zeros([1, 10]))    #0初始化偏向
17 Wx_plus_B_L1 = tf.matmul(x, Weights_L1) + Biases_L1    #L1层进行加权求和
18 L1 = tf.nn.tanh(Wx_plus_B_L1)   #根据非线性方程(双曲正切函数)转化输出
19 #定义神经网络输出层
20 Weights_L2 = tf.Variable(tf.random_normal([10, 1]))  
21 Biases_L2 = tf.Variable(tf.zeros([1, 1]))   
22 Wx_plus_B_L2 = tf.matmul(L1, Weights_L2) + Biases_L2    #将L1的输出作为输出层的输入
23 prediction = tf.nn.tanh(Wx_plus_B_L2)         #预测值
24 #定义二次代价函数
25 loss = tf.reduce_mean(tf.square(y - prediction))
26 #使用随机梯度下降法进行训练,使得二次代价函数最小
27 train_step = tf.train.GradientDescentOptimizer(0.1).minimize(loss)
28 #变量初始化
29 init = tf.global_variables_initializer()
30 #定义会话
31 with tf.Session() as sess:
32     sess.run(init)
33     for _ in range(2000):     #进行2000次训练学习
34         sess.run(train_step, feed_dict = {x:x_data, y:y_data}) 
35     #获得预测值
36     prediction_value = sess.run(prediction, feed_dict = {x:x_data})
37     #画图
38     plt.figure()
39     plt.scatter(x_data, y_data)
40     plt.plot(x_data, prediction_value, \'r-\', lw = 5)    
41     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程序实现

 1 import os
 2 os.environ[\'TF_CPP_MIN_LOG_LEVEL\'] = \'2\'
 3 import tensorflow as tf
 4 from tensorflow.examples.tutorials.mnist import input_data
 5 #载入数据集
 6 mnist = input_data.read_data_sets(\'MNIST_data\', one_hot=True)
 7 #每个批次的大小(即每次训练的图片数量)
 8 batch_size = 50
 9 #计算一共有多少个批次
10 n_bitch = mnist.train.num_examples // batch_size
11 #定义两个placeholder
12 x = tf.placeholder(tf.float32, [None, 784])
13 y = tf.placeholder(tf.float32, [None, 10])
14 #创建一个只有输入层(784个神经元)和输出层(10个神经元)的简单神经网络
15 Weights = tf.Variable(tf.zeros([784, 10]))
16 Biases = tf.Variable(tf.zeros([10]))
17 Wx_plus_B = tf.matmul(x, Weights) + Biases
18 prediction = tf.nn.softmax(Wx_plus_B)
19 #二次代价函数
20 loss = tf.reduce_mean(tf.square(y - prediction))
21 #使用梯度下降法
22 train_step = tf.train.GradientDescentOptimizer(0.1).minimize(loss)
23 #初始化变量
24 init = tf.global_variables_initializer()
25 #结果存放在一个布尔型列表中
26 correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(prediction, 1)) #argmax返回一维张量中最大的值所在的位置,标签值和预测值相同,返回为True
27 #求准确率
28 accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32)) #cast函数将correct_prediction的布尔型转换为浮点型,然后计算平均值即为准确率
29 
30 with tf.Session() as sess:
31     sess.run(init)
32     #将测试集循环训练20次
33     for epoch in range(21):
34         #将测试集中所有数据循环一次
35         for batch in range(n_bitch):
36             batch_xs, batch_ys = mnist.train.next_batch(batch_size)   #取测试集中batch_size数量的图片及对应的标签值
37             sess.run(train_step, feed_dict={x:batch_xs, y:batch_ys})  #将上一行代码取到的数据进行训练
38         acc = sess.run(accuracy, feed_dict={x:mnist.test.images, y:mnist.test.labels})  #准确率的计算
39         print(\'Iter: \' + str(epoch) + \',Testing Accuracy= \' + str(acc))       

 

 

#执行结果

 1 #执行结果:(因为已经下载过数据集,如果第一次运行,是提示下载成功)
 2 Extracting MNIST_data\train-images-idx3-ubyte.gz
 3 Extracting MNIST_data\train-labels-idx1-ubyte.gz
 4 Extracting MNIST_data\t10k-images-idx3-ubyte.gz
 5 Extracting MNIST_data\t10k-labels-idx1-ubyte.gz
 6 Iter : 0,Testing Accuracy = 0.8599
 7 Iter : 1,Testing Accuracy = 0.8806
 8 Iter : 2,Testing Accuracy = 0.8909
 9 Iter : 3,Testing Accuracy = 0.8963
10 Iter : 4,Testing Accuracy = 0.9006
11 Iter : 5,Testing Accuracy = 0.9034
12 Iter : 6,Testing Accuracy = 0.9047
13 Iter : 7,Testing Accuracy = 0.9069
14 Iter : 8,Testing Accuracy = 0.908
15 Iter : 9,Testing Accuracy = 0.9094
16 Iter : 10,Testing Accuracy = 0.9113
17 Iter : 11,Testing Accuracy = 0.9127
18 Iter : 12,Testing Accuracy = 0.9137
19 Iter : 13,Testing Accuracy = 0.9144
20 Iter : 14,Testing Accuracy = 0.9144
21 Iter : 15,Testing Accuracy = 0.9156
22 Iter : 16,Testing Accuracy = 0.9156
23 Iter : 17,Testing Accuracy = 0.9171
24 Iter : 18,Testing Accuracy = 0.9173
25 Iter : 19,Testing Accuracy = 0.9177
26 Iter : 20,Testing Accuracy = 0.9179
View Code

 

#准确率不是很高,但是我只是构建了最简单的输入输出层。我会根据之后所学去优化程序,提高准确率