分享

人工智能实践-搭建神经网络

 生物_医药_科研 2019-11-22

张量、计算图、会话

基于Tensorflow搭建神经网络时,使用张量表示数据;使用计算图搭建神经网络;使用会话执行计算图,优化线上的权重(参数),得到模型。

张量Tensor

张量即多维数组,阶表示的是张量的维数。张量可以表示0阶到n阶数组。

数据类型

tf.float32(32位浮点) tf.int32(32位整型) ...

张量加法
 import tensorflow as tf
 a = tf.constant([1.0, 2.0])
 b = tf.constant([3.0, 4.0])
 result = a + b
 print(result)

显示结果:Tensor('add:0', shape=(2,), dtype=float32),其中add:0表示张量名,shape=(2,)表示维度为1,包含2个元素。数据类型为32位浮点。

计算图Graph

上述张量加法就是一个计算图,计算图只描述计算过程,不进行实际的运算。

计算图: 搭建神经网络中一个或者多个节点的计算过程,只搭建,不运算。下图即是搭建节点y的计算过程。


会话Session

执行计算图中节点运算。

实现方法

通过Sesssion()函数,在sess.run()中实现计算。

 with tf.Session() as sess:
  print sess.run(y)
示例
 import tensorflow as tf
 x = tf.constant([[1.0,2.0]]) #x是一行两列
 w = tf.constant([[3.0], [4.0]]) #w是两行一列
 y = tf.matmul(x,w)
 print y #计算图
 with tf.Session() as sess:
  print sess.run(y) #计算结果
 
 #输出结果
 Tensor('matmul:0',shape(1,1),dtype=float32)
 [[11.]]

参数

参数即是神经元线上的权重W,用变量表示,一般会随机生成初始值。

参数的生成方法为:w = tf.Variable(tf.random_normal([2,3], stddev=2, mean=0, seed=1))

其中tf.random_normal表示生成的参数符合正态分布,可以替换为tf.truncated_normal()(去掉过大偏离点的正态分布)以及tf.random_uniform()(平均分布)。[2,3], stddev=2, mean=0, seed=1表示生成2×3矩阵,标准差为2,均值为0,随机种子为1。标准差、均值以及随机种子没有特殊要求可以不写。当随机种子不指定,每次运行生成的随机数将不一致。

 tf.zeros    #生成全0数组, tf.zeros([3,2],int32)生成[[0,0],[0,0],[0,0]]
 tf.ones #生成全1数组, tf.ones([3,2],int32)生成[[1,1],[1,1],[1,1]]
 tf.fill #生成全定值数组, tf.fill([3,2],6)生成[[6,6],[6,6],[6,6]]
 tf.constant([3,2,1]) #直接给定值, tf.constant([3,2,1])生成[3,2,1]

神经网络实现过程

NN实现过程

  1. 准备数据集,提取特征,作为输入喂入神经网络

  2. 搭建网络结构,从输入到输出(先搭建计算图,后用会话计算)

  3. 大量数据特征喂入神经网络,迭代优化网络参数

  4. 使用训练好的模型预测和分类

其中步骤2对应神经网络的前向传播,计算输出;3对应神经网络的反向传播,进行参数的优化和模型的训练。

前向传播

搭建模型,实现神经网络的推理。

示例:生产一批零件,将体积x1和重量x2作为特征输入神经网络,最后输出一个数值。

推导过程

变量的初始化、计算图节点的运算都需要使用会话(with结构)实现

 with tf.Session() as sess:
  sess.run() #run()中写待初始化、计算的内容。

变量初始化:sess.run函数中用tf.global_variables_initializer()实现

 init_op = tf.global_variables_initializer()
 sess.run(init_op)

计算图节点运算:sess.run函数中写入待运算的节点

 sess.run(y)

节点运算中数据的输入: 先使用tf.placeholder占位,在sess.run函数中用feed_dict输入具体数据

 #喂入一组数据
 x = tf.placeholder(tf.float32, shape=(1,2)) #用于输入的占位,shape中1表示一组数据,2表示每组数据包括2个特征
 sess.run(y, feed_dict={x:[[0.5,0.6]]})
 
 #喂入多组数据
 x = tf.placeholder(tf.float32, shape=(None, 2)) #None表示组数未定,2表示每组数据包括2个特征
 sess.run(y, feed_dict={x:[[0.1,0.2],[0.3,0.4],[0.4,0.5]]})
示例

示例1,在定义输入时直接指定具体值。

 #coding:utf-8##python程序中写入该行指定编码格式为utf-8,支持中文
 #两层简单神经网络(全连接)
 import tensorflow as tf ##导入tensorflow模块,命名为tf
 
 #定义输入和参数
 x = tf.constant([[0.7, 0.5]]) #输入x为一行两列
 w1 = tf.Variable(tf.random_normal([2,3], stddev=1, seed=1)) #随机生成参数w1为2行3列
 w2 = tf.Variable(tf.random_normal([3,1], stddev=1, seed=1)) #随机生成参数w2为3行1列
 
 #定义前向传播过程
 a = tf.matmul(x, w1) #a是x和w1的矩阵乘法
 y = tf.matmul(a, w2) #y是a和w2的矩阵乘法
 
 #使用会话计算结果
 with tf.Session() as sess:
  init_op = tf.global_variables_initializer()
  sess.run(init_op) #变量初始化
  print('y is:', sess.run(y)) #计算y
 
 ##输出
 y is: [[3.0904665]]

示例2,在定义输入时使用placeholder()占位,一次喂入一组特征。

 #coding:utf-8
 import tensorflow as tf
 
 #定义输入和参数
 x = tf.placeholder(tf.float32, shape=(1,2))
 w1 = tf.Variable(tf.random_normal([2,3], stddev=1, seed=1))
 w2 = tf.Variable(tf.random_normal([3,1], stddev=1, seed=1))
 
 #定义前向传播
 a = tf.matmul(x, w1)
 y = tf.matmul(a, w2)
 
 #使用会话计算结果
 with tf.Session() as sess:
  init_op = tf.global_variables_initializer()
  sess.run(init_op)
  print('y is:', sess.run(y, feed_dict={x:[[0.7, 0.5]]}))
 
 ##输出
 y is: [[3.0904665]]

示例3,在定义输入时使用placeholder()占位,一次喂入多组特征。

 #coding:utf-8
 import tensorflow as tf
 
 #定义输入和参数
 x = tf.placeholder(tf.float32, shape=(None,2))
 w1 = tf.Variable(tf.random_normal([2,3], stddev=1, seed=1))
 w2 = tf.Variable(tf.random_normal([3,1], stddev=1, seed=1))
 
 #定义前向传播
 a = tf.matmul(x, w1)
 y = tf.matmul(a, w2)
 
 #使用会话计算结果
 with tf.Session() as sess:
  init_op = tf.global_variables_initializer()
  sess.run(init_op)
  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]]}))
  print('w1:', sess.run(w1))
  print('w2:', sess.run(w2))
 
 ##输出
 y is: [[3.0904665]
  [1.2236414]
  [1.7270732]
  [2.2305048]]
 w1: [[-0.8113182 1.4845988 0.06532937]
  [-2.4427042 0.0992484 0.5912243 ]]
 w2: [[-0.8113182 ]
  [ 1.4845988 ]
  [ 0.06532937]]

反向传播

反向传播目的在于优化模型参数。其在所有参数上进行梯度下降,使得神经网络模型在训练数据集上的损失函数最小。

损失函数loss

预测值(y)与已知答案(y_)的差距。均方误差就是一种常用的损失函数。

均方误差MSE:表示为 ,使用tensorflow表示为loss = tf.reduce_mean(tf.square(y_-y))

反向传播训练方法

反向传播目标是减小loss值。

常用的方法:

 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)

其中学习率learning_rate决定了参数每次更新的幅度,可以先设置较小的值进行训练。

示例
 #coding:utf-8
 import tensorflow as tf
 import numpy as np #python的科学计算模块
 #一次喂入神经网络的数据,
 BATCH_SIZE = 8
 #每次运行随机生成相同的数字
 seed = 23455
 
 #基于seed产生随机数
 rng = np.random.RandomState(seed)
 #随机数返回32行2列的矩阵,表示32组体积、重量,作为输入数据集
 X = rng.rand(32, 2)
 #从X中取出一行,判断如果体积、重量之和小于1,Y赋值1,否则Y赋值0
 Y = [[int(x0 + x1 < 1)] for (x0, x1) in X] #人为给定判断标准
 print('X:\n', X)
 print('Y:\n', Y)
 
 #定义神经网络的输入、输出
 x = tf.placeholder(tf.float32, shape=(None, 2)) #输入包括两个特征,输入组数未知(None)
 y_ = tf.placeholder(tf.float32, shape=(None, 1))
 #定义神经网络的参数
 w1 = tf.Variable(tf.random_normal([2, 3], stddev=1, seed=1)) #隐藏层包括三个神经元
 w2 = tf.Variable(tf.random_normal([3, 1], stddev=1, seed=1))
 #定义神经网络的前向传播过程
 a = tf.matmul(x, w1)
 y = tf.matmul(a, w2)
 
 #定义神经网络的损失函数
 loss = tf.reduce_mean(tf.square(y - y_)) #使用均方误差计算loss
 #定义神经网络的反向传播方法
 train_step = tf.train.GradientDescentOptimizer(0.001).minimize(loss) #梯度下降
 #train_step = tf.train.MomentumOptimizer(0.001, 0.9).minimize(loss)
 #train_step = tf.train.AdamOptimizer(0.001).minimize(loss)
 
 #生成会话
 with tf.Session() as sess:
  init_op = tf.global_variables_initializer()
  sess.run(init_op) #初始化所有变量
  print('w1:\n', sess.run(w1))
  print('w2:\n', sess.run(w2))
  print('\n')
  STEPS = 3000 #训练3000轮
  for i in range(STEPS):
  start = (i*BATCH_SIZE) % 32
  end = start + BATCH_SIZE
  sess.run(train_step, feed_dict={x:X[start:end], y_:Y[start:end]})
  if i % 500 == 0:
  total_loss = sess.run(loss, feed_dict={x:X, y_:Y})
  print('After %d training steps, loss on all data is %g' % (i, total_loss))
 
  print('\n')
  print('w1:\n', sess.run(w1))
  print('w2:\n', sess.run(w2))
 
 #输出结果
 w1:
  [[-0.8113182 1.4845988 0.06532937]
  [-2.4427042 0.0992484 0.5912243 ]]
 w2:
  [[-0.8113182 ]
  [ 1.4845988 ]
  [ 0.06532937]]
 
 After 0 training steps, loss on all data is 5.13118
 After 500 training steps, loss on all data is 0.429111
 After 1000 training steps, loss on all data is 0.409789
 After 1500 training steps, loss on all data is 0.399923
 After 2000 training steps, loss on all data is 0.394146
 After 2500 training steps, loss on all data is 0.390597
 
 w1:
  [[-0.7000663 0.9136318 0.08953571]
  [-2.3402493 -0.14641264 0.5882305 ]]
 w2:
  [[-0.06024266]
  [ 0.91956186]
  [-0.06820708]]

神经网络搭建“八股”

至此,可以介绍神经网络搭建的“八股”,也即是神经网络搭建的一般框架。神经网络的搭建包括准备、前向传播、反向传播、迭代四个部分。

准备

  • import

  • 常量定义

  • 生成数据集

前向传播

  • 定义输入和已知答案

  • 定义网络参数

  • 定义推理过程及输出(矩阵乘法)

反向传播

  • 定义损失函数

  • 定义反向传播方法

迭代

  • 生成会话,训练一定轮数

 #会话模板
 with tf.Session() as sess:
  init_op = tf.global_variables_initializer()
  sess.run(init_op) #初始化参数
 
  STEPS = 3000 #定义循环轮数
  for i in range(STEPS):
  start =
  end =
  sess.run(train_step, feed_dict) #对反向传播过程进行运算

参考上述4个步骤我们可以搭建出一个极简的神经网络模型。后续我们会分享更多模型细节的实现方法。

*以上就是《人工智能实践:Tensorflow笔记》课程人工神经网络搭建的个人笔记,如有不足还请多多指教

课程地址:https://www.icourse163.org/course/PKU-1002536002

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多