【TensorFlow学习笔记】基础篇(四)— —搭建神经网络的八股:准备、前传、反传、迭代

绪论

神经网络的实现过程— —
① 准备数据集,提取特征,作为输入喂给神经网络
(Neural Network,NN)
② 搭建NN结构,从输入到输出(先搭建计算图,再用会话执行)
(NN前向传播算法–>计算输出)
③ 大量特征数据喂给NN,迭代优化NN参数
(NN反向传播算法–>优化参数训练模型)
④ 使用训练好的模型预测和分类



1.准备数据: import、常量定义、生成数据集

参数:线上的权重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]产生2*3矩阵,stddev标准差为2,mean均值为0,seed随机种子
  • 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 直接给值 tf.constant([3,2,1]) 生成[3,2,1]

如何制作自己的图片训练集

2.前向传播:搭建模型,实现推理

(x=、y_=、W1=、W2=、a=、y=)
例如:生产一批零件,将体积x1和重量x2位特征喂入神经网络,当体积和重量这组数据输入神经网络后会得到一个输出。

  • Input:以输入的特征值是:体积0.7 重量0.5为例。

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

在这里插入图片描述
在这里插入图片描述
神经网络共有几层(或当前是第几层网络)都是指的计算层,输入层不是计算层,所以a为第一层网络,

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

with tf.Session() as sess:
  sess.run()
  • 变量初始化
    initialize_all_variables 在V1.9中没有用了。改 global_variables_initializer 替代。
init_op = tf.global_variables_initializer()
  sess.run(init_op)
  • 计算图节点运算(在sess.run函数中写入带运算的节点)
sess.run(y)
  • 用tf.placeholder占位,在sess.run函数中用feed_dict喂数据

① 喂一组数据(shape = (1,2) 1代表一组数据,2代表两个特征):

x = tf.placeholder(tf.float32,shape=12))
sess.run(y,feed_dict={x:[[0.5,0.6]]})

② 喂多组数据(None表示不知道几组数据):

x = tf.placeholder(tf.float32,shape=None2))
sess.run(y,feed_dict={x:[[0.1,0.2],[0.2,0.3],[0.3,0.4],[0.4,0.5]]})

示例代码:

#coding:utf-8
#两层简单的神经网络(全连接)
import tensorflow as tf

#定义输入和参数
#用placeholder实现输入定义(sess.run中喂一组数据)
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)

#y用会话计算结果
with tf.Session() as sess:
  init_op = tf.global_variables_initializer()
  sess.run(init_op)
  print "y is:\n",sess.run(y,feed_dict={x:[[0.7,0.5],[0.2,0.3],[0.3,0.4],[0.4,0.5]]})
  print "w1:\n",sess.run(w1)
  print "w2:\n",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]]

3.反向传播:定义损失函数、反向传播方法

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

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

均方误差MSE: 在TensorFlow中用代码表示如下
在这里插入图片描述

loss =tf.reduce_mean(tf.square(y_ - y)) 

反向传播训练方法:以减小loss值为优化目标,分别有3种不同的方法可以使用——梯度下降、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)

这个引用块拿来解释下这三种优化方法:(这里是搬运自网上的,等会再总结下)

tf.train.GradientDescentOptimizer()
使用随机梯度下降算法,使参数沿着梯度的反方向,即总损失减小的方向移动,实现更新参数。

tf.train.MomentumOptimizer()
在更新参数时,利用了超参数,实现更新参数。

tf.train.AdamOptimizer()
是利用自适应学习率的优化算法,Adam 算法和随机梯度下降算法不同。随机梯度下降算法保持单一的学习率更新所有的参数,学习率在训练过程中并不会改变。而 Adam 算法通过计算梯度的一阶矩估计和二阶矩估计而为不同的参数设计独立的自适应性学习率。 学习率:决定每次参数更新的幅度。优化器中都需要一个叫做学习率的参数,使用时,如果学习率选择过大会出现震荡不收敛的情况,如果学习率选择过小,会出现收敛速度慢的情况。我们可以选个比较小的值填入,比如0.01、0.001。

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

示例代码:

#coding:uddf-8
#导入模块,生成模拟数据集
import tensorflow as tf
import numpy as np
BATCH_SIZE = 8
seed = 23455 #真正编程时不用定义这个

#基于seed产生随机数
rng = np.random.RandomState(seed)
#随机数返回32行2列的矩阵 表示32组 体积和重量 作为输入数据集
X = rng.rand(32,2)
#从X这个32行2列的矩阵中 取出1行 判断如果和小于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))
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_))
train_step = tf.train.GradientDescentOptimizer(0.001).minimize(loss)

#y生成会话,训练STEPS轮
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
  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 step(s) , loss on all data is %g" %(i,total_loss))

  #输出训练后的参数取值
  print "\n"
  print "w1:\n",sess.run(w1)
  print "w2:\n",sess.run(w2)

4.迭代循环:生成会话,训练迭代STEPS轮

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:)

总结

模块化搭建思想(多个py文件,方便扩展) — —

  • 生成数据集(input_data.py)
  • 前向传播就是搭建网络,设计网络结构(forward.py)
  • 反向传播就是训练网络,优化网络参数(backward.py)
发布了28 篇原创文章 · 获赞 2 · 访问量 2811

猜你喜欢

转载自blog.csdn.net/Jarvis_lele/article/details/104976018