Tensorflow学习:搭建神经网络

一、神经网络的实现过程

  1、准备数据集,提取特征,作为输入喂给神经网络(Neural Network, NN)
       2、搭建 NN 结构,从输入到输出(先搭建计算图,再用会话执行)
       3、大量特征数据喂给 NN,迭代优化 NN 参数
       4、使用训练好的模型预测和分类

  由此可见,基于神经网络的机器学习主要分为两个过程,即训练过程和使用过程。训练过程是第一步、第二步、第三步的循环迭代,使用过程是第四步,一旦参数优化完成就可以固定这些参数,实现特定应用了。很多实际应用中,我们会先使用现有的成熟网络结构,喂入新的数据,训练相应模型,判断是否能对喂入的从未见过的新数据作出正确响应,再适当更改网络结构,反复迭代,让机器自动训练参数找出最优结构和参数,以固定专用模型。

 

二、前向传播  

     前向传播就是搭建模型的计算过程, 让模型具有推理能力, 可以针对一组输入给出相应的输出。

  举例:假如生产一批零件, 体积为 x1, 重量为 x2, 体积和重量就是我们选择的特征,把它们喂入神经网络, 当体积和重量这组数据走过神经网络后会得到一个输出。

  假如输入的特征值是:体积 0.7 ,重量 0.5 ,下图是搭建的神经网络框架图

    

  由搭建的神经网络可得, 隐藏层节点 a11=x1* w11+x2*w21=0.14+0.15=0.29, 同理算得节点 a12=0.32, a13=0.38,最终计算得到输出层 Y=-0.015, 这便实现了前向传播过程。

  

  再来推导下图中的代码实现过程。

  第一层:

  (1)x是输入为1*2的矩阵:用x表示输入,是一个1行2列的矩阵,表示一次输入一组特征,这组特征包含了体积和重量两个元素。

  (2)W前节点编号,后节点编号(层数)为待优化的参数:对于第一层的w,前面有两个节点,后面有三个节点。所以w应该是个两行三列的矩阵。表示为

      

    注意神经网络共有几层(或当前是第几层网络)都是指的计算层, 输入不是计算层,所以 a 为第一层网络, a 是一个一行三列矩阵。表示为:a(1) = [a11,a12,a13]=XW(1)

  第二层:

  (1)参数要满足前面三个节点,后面一个节点,所以W(2)是三行一列矩阵。表示为 

  

  我们把每层输入乘以线上的权重w,这样就可以用矩阵乘法输出y了。

  Python代码实现

 1 # (1) 用placeholder 实现输入定义(sess.run 中喂入一组数据)的情况,第一组喂体积 0.7、重量 0.5
 2 import tensorflow as tf
 3 
 4 #定义输入和参数
 5 x=tf.placeholder(tf.float32,shape=(1,2))
 6 w1=tf.Variable(tf.random_normal([2,3],stddev=1,seed=1))
 7 w2=tf.Variable(tf.random_normal([3,1],stddev=1,seed=1))
 8 
 9 #定义前向传播过程
10 a=tf.matmul(x,w1)
11 y=tf.matmul(a,w2)
12 
13 #用会话计算结果
14 with tf.Session() as sess:
15     init_op=tf.global_variables_initializer()
16     sess.run(init_op)
17     print("y is:",sess.run(y,feed_dict={x:[[0.7,0.5]]}))

  运行显示结果为:

y is: [[ 3.0904665]]
 1 # (2) 用 placeholder 实现输入定义(sess.run 中喂入多组数据)的情况
 2 import tensorflow as tf
 3 
 4 #定义输入和参数
 5 x=tf.placeholder(tf.float32,shape=(None,2))
 6 w1=tf.Variable(tf.random_normal([2,3],stddev=1,seed=1))
 7 w2=tf.Variable(tf.random_normal([3,1],stddev=1,seed=1))
 8 
 9 #定义前向传播过程
10 a=tf.matmul(x,w1)
11 y=tf.matmul(a,w2)
12 
13 #用会话计算结果
14 with tf.Session() as sess:
15     init_op=tf.global_variables_initializer()
16     sess.run(init_op)
17     print("y is:",sess.run(y,feed_dict={x:[[0.7,0.5],[0.2,0.3],[0.3,0.4],[0.4,0.5]]})

  运行显示结果为:

y is: [[ 3.0904665 ]
 [ 1.2236414 ]
 [ 1.72707319]
 [ 2.23050475]]

三、后向传播

  反向传播:训练模型参数,在所有参数上使用梯度下降,使 NN 模型在训练数据上的损失函数最小。

  损失函数(loss): 计算得到的预测值 y 与已知答案 y_的差距。损失函数的计算有很多方法,均方误差 MSE 是比较常用的方法之一。

  均方误差 MSE: 求前向传播计算结果与已知答案之差的平方再求平均。 

  数学公式为:

  用tensorflow函数表示为:loss_mse = tf.reduce_mean(tf.square(y_ - y))

  反向传播训练方法: 以减小 loss 值为优化目标。

  一般有梯度下降、 momentum 优化器、 adam 优化器等优化方法。这三种优化方法用 tensorflow 的函数可以表示为:

  train_step=tf.train.GradientDescentOptimizer(learning_rate).minimize(loss)

  train_step=tf.train.MomentumOptimizer(learning_rate, momentum).minimize(loss)

  train_step=tf.train.AdamOptimizer(learning_rate).minimize(loss)

  学习率:决定每次参数更新的幅度。

  优化器中都需要一个叫做学习率的参数,使用时,如果学习率选择过大会出现震荡不收敛的情况,如果学习率选择过小,会出现收敛速度慢的情况。我们可以选个比较小的值填入,比如 0.01、0.001。

  

  以上是后向传播中常用的概念,更多详细优化方法见后续随笔。其中几种反向传播训练方法的区别、反向传播参数更新推导过程 见MOOC北大tensorflow课程,第三讲 Tensorflow框架的助教笔记。

  Python代码实现

  随机产生 32 组生产出的零件的体积和重量,训练 3000 轮,每 500 轮输出一次损失函数。

 1 import tensorflow as tf
 2 import numpy as np
 3 BATCH_SIZE = 8                          # 一次不能喂太多数据
 4 SEED = 23455                            # 产生与视频教程中统一的随机数
 5 
 6 #基于seed产生随机数
 7 rdm = np.random.RandomState(SEED)
 8 #随机数返回32行2列的矩阵 表示32组 体积和重量 作为输入数据集
 9 X = rdm.rand(32,2)
10 #从X这个32行2列的矩阵中 取出一行 判断如果和小于1 给Y赋值1 如果和不小于1 给Y赋值0 (这里只是人为的定义)
11 #作为输入数据集的标签(正确答案) 
12 Y_ = [[int(x0 + x1 < 1)] for (x0, x1) in X]
13 print "X:\n",X
14 print "Y_:\n",Y_
15 
16 #1定义神经网络的输入、参数和输出,定义前向传播过程。
17 x = tf.placeholder(tf.float32, shape=(None, 2))
18 y_= tf.placeholder(tf.float32, shape=(None, 1))
19 
20 w1= tf.Variable(tf.random_normal([2, 3], stddev=1, seed=1))
21 w2= tf.Variable(tf.random_normal([3, 1], stddev=1, seed=1))
22 
23 a = tf.matmul(x, w1)
24 y = tf.matmul(a, w2)
25 
26 #2定义损失函数及反向传播方法。
27 loss_mse = tf.reduce_mean(tf.square(y-y_)) 
28 train_step = tf.train.GradientDescentOptimizer(0.001).minimize(loss_mse)   # 三种优化方法选择一个就可以 
29 #train_step = tf.train.MomentumOptimizer(0.001,0.9).minimize(loss_mse)
30 #train_step = tf.train.AdamOptimizer(0.001).minimize(loss_mse)
31 
32 #3生成会话,训练STEPS轮
33 with tf.Session() as sess:
34     init_op = tf.global_variables_initializer()
35     sess.run(init_op)
36     # 输出目前(未经训练)的参数取值。
37     print "w1:\n", sess.run(w1)
38     print "w2:\n", sess.run(w2)
39     print "\n"
40     
41     # 训练模型。
42     STEPS = 3000
43     for i in range(STEPS):
44         start = (i*BATCH_SIZE) % 32
45         end = start + BATCH_SIZE
46         sess.run(train_step, feed_dict={x: X[start:end], y_: Y_[start:end]})
47         if i % 500 == 0:
48             total_loss = sess.run(loss_mse, feed_dict={x: X, y_: Y_})
49             print("After %d training step(s), loss_mse on all data is %g" % (i, total_loss))
50     
51     # 输出训练后的参数取值。
52     print "\n"
53     print "w1:\n", sess.run(w1)
54     print "w2:\n", sess.run(w2)

   运行显示结果为

X:
[[ 0.83494319  0.11482951]
 [ 0.66899751  0.46594987]
 [ 0.60181666  0.58838408]
 [ 0.31836656  0.20502072]
 [ 0.87043944  0.02679395]
 [ 0.41539811  0.43938369]
 [ 0.68635684  0.24833404]
 [ 0.97315228  0.68541849]
 [ 0.03081617  0.89479913]
 [ 0.24665715  0.28584862]
 [ 0.31375667  0.47718349]
 [ 0.56689254  0.77079148]
 [ 0.7321604   0.35828963]
 [ 0.15724842  0.94294584]
 [ 0.34933722  0.84634483]
 [ 0.50304053  0.81299619]
 [ 0.23869886  0.9895604 ]
 [ 0.4636501   0.32531094]
 [ 0.36510487  0.97365522]
 [ 0.73350238  0.83833013]
 [ 0.61810158  0.12580353]
 [ 0.59274817  0.18779828]
 [ 0.87150299  0.34679501]
 [ 0.25883219  0.50002932]
 [ 0.75690948  0.83429824]
 [ 0.29316649  0.05646578]
 [ 0.10409134  0.88235166]
 [ 0.06727785  0.57784761]
 [ 0.38492705  0.48384792]
 [ 0.69234428  0.19687348]
 [ 0.42783492  0.73416985]
 [ 0.09696069  0.04883936]]
Y_:
[[1], [0], [0], [1], [1], [1], [1], [0], [1], [1], [1], [0], [0], [0], [0], [0], [0], [1], [0], [0], [1], [1], [0], [1], [0], [1], [1], [1], [1], [1], [0], [1]]
w1:
[[-0.81131822  1.48459876  0.06532937]
 [-2.4427042   0.0992484   0.59122431]]
w2:
[[-0.81131822]
 [ 1.48459876]
 [ 0.06532937]]


After 0 training step(s), loss_mse on all data is 5.13118
After 500 training step(s), loss_mse on all data is 0.429111
After 1000 training step(s), loss_mse on all data is 0.409789
After 1500 training step(s), loss_mse on all data is 0.399923
After 2000 training step(s), loss_mse on all data is 0.394146
After 2500 training step(s), loss_mse on all data is 0.390597


w1:
[[-0.70006633  0.9136318   0.08953571]
 [-2.3402493  -0.14641267  0.58823055]]
w2:
[[-0.06024267]
 [ 0.91956186]
 [-0.0682071 ]]

   由神经网络的实现结果,我们可以看出,总共训练3000轮,每轮从X的数据集和Y的标签中抽取相对应的从start开始到end结束个特征值和标签,喂入神经网络,用sess.run求出loss,每500轮打印一次loss值。经过

3000轮后,我们打印出最终训练好的参数w1、w2。

四、搭建神经网络的过程

  通过以上的内容,我们可以梳理一下搭建简单神经网络的步骤:

  (1)导入模块,生成模拟数据集

          import

          常量定义

          生成数据集

  (2)前向传播:定义输入、参数和输出

          x=              y_=

          w1=            w2=

          a=              y=

  (3)后向传播:定义损失函数、反向传播方法

          loss=

          train_step=

  (4)生成会话,训练STEPS轮

        with tf.Session as sess:

          init_op = tf.global_variables_initializer()

          sess.run(init_op)

          STEPS = 

            for i in range(STEPS):

            start = 

            end = 

            sess.run(train_step, feed_dict={ })

  以上是搭建简单神经网络的笔记

  本人初学者,有任何错误欢迎指出,谢谢。

猜你喜欢

转载自www.cnblogs.com/wanyu416/p/9009985.html