(本博文主要是对《tensorflow:实战Google深度学习框架》:tensorflow入门章节完整的神经网络样例程序做更详细的解读(完整的程序见文本末))
《tensorflow:实战Google深度学习框架》密码:zyd1
代码段分析:
一 、构建神经网络模型,主要是:
(1)通过定义神经网络参数,对于不确定参数取值的参数,通常采用随机数充当初始化参数。
(2)定义神经网络前向传播过程、反向传播过程
注意事项:
对于不确定训练时采用的喂的数据大小(数量)我们可以使用占位函数tf.placeholder() 临时顶替输入输出量,对于数据集比较小的情况,我们可以一次性将数据喂全部数据(将batch_size 等于 数据集数据数量),减少迭代次数,但是当数据过大时,采用这种方法会导致程序大量消耗内存,甚至使内存溢出。
神经网络的前向传播过程就是计算图结构,而对于反向传播过程,tensorflow提供了多种损失函数模型以及反向传播算法,我们仅仅需要根据自身情况选取相应的模型及算法即可。
# 定义神经网络的参数。
#采用一层隐藏层,包含三个神经元
w1 = tf.Variable(tf.random_normal( [2,3] , stddev = 1 , seed = 1))
w2 = tf.Variable(tf.random_normal( [3,1] , stddev = 1 , seed = 1))
# 在shape的一个维度上使用None可以方便的使用不同的batch的大小。
x = tf.placeholder(tf.float32 , shape = (None , 2) , name = 'x-input')
y_ = tf.placeholder(tf.float32, shape = (None , 1) , name = 'y-input')
# 定义神经网络的前向传播过程。
a = tf.matmul(x , w1)
y = tf.matmul(a , w2)
# 定义损失函数和反向传播的算法。
cross_entropy = -tf.reduce_mean( y_ * tf.log( tf.clip_by_value( y , 1e-10 , 1.0) ))
train_step = tf.train.AdamOptimizer( 0.001 ).minimize(cross_entropy)
二、获取数据集及其标签(由于该例程没有数据集提供,所以通过生成模拟数据集并制定规则将每个数据贴上相应的label(标签),模拟二分类问题)
# 通过随机数生成一个模拟数据集。
rdm = RandomState(1)
dataset_size = 128
X = rdm.rand(dataset_size , 2)
# 定义规则来给出样本的标签,将所有 x1 + x2 < 1 的样例认为为正样本,添加 1 标签 。
Y = [[ int(x1 + x2 < 1) ] for ( x1 ,x2 ) in X]
三、创建会话(Session)运行Tensorflow程序
1.初始化变量,生成神经网络初始化参数(初始化参数通常作用不大,仅仅是一个顶替作用,神经网络的本质作用就是优化不断这些参数)
with tf.Session() as sess:
# 初始化变量 。
init_op = tf.global_variables_initializer()
sess.run(init_op)
2.开始训练迭代。
训练的过程为将训练样本调用反向传播算法 ,反向传播算法调用损失函数计算交叉嫡 ,反向传播函数自动调整神经网络中的每一个参数达到减小交叉嫡的效果,通过不断的循环迭代不断优化神经网络参数。
# 定义迭代的次数 。
STEPS = 5000
for i in range(STEPS):
# 每次选取batch_size个样本进行训练 。
start = (i * batch_size ) % dataset_size
end = min(start + batch_size , dataset_size )
# 通过选取的样本训练神经网络并更新参数
sess.run(train_step , feed_dict = { x : X[start : end ] , y_ : Y[start : end]})
# 每迭代1000次计算并输出交叉嫡 。
if i % 1000 == 0 :
total_cross_entropy = sess.run( cross_entropy , feed_dict = {x :X ,y_ :Y })
print("after % d training step(s) , cross entropy on all data is %g"%( i , total_cross_entropy))
四、通过不断优化神经网络中的参数,获取优化后可用的神经网络模型
完整例程代码:
import tensorflow as tf
# numpy是一个科学计算的工具包,这里通过numpy工具包生成模拟数据集。
from numpy.random import RandomState
# 定义训练数据batch的大小。
batch_size = 8
# 定义神经网络的参数。
w1 = tf.Variable(tf.random_normal( [2,3] , stddev = 1 , seed = 1))
w2 = tf.Variable(tf.random_normal( [3,1] , stddev = 1 , seed = 1))
# 在shape的一个维度上使用None可以方便的使用不同的batch的大小。
x = tf.placeholder(tf.float32 , shape = (None , 2) , name = 'x-input')
y_ = tf.placeholder(tf.float32, shape = (None , 1) , name = 'y-input')
# 定义神经网络的前向传播过程。
a = tf.matmul(x , w1)
y = tf.matmul(a , w2)
# 定义损失函数和反向传播的算法。
cross_entropy = -tf.reduce_mean( y_ * tf.log( tf.clip_by_value( y , 1e-10 , 1.0) ))
train_step = tf.train.AdamOptimizer( 0.001 ).minimize(cross_entropy)
# 通过随机数生成一个模拟数据集。
rdm = RandomState(1)
dataset_size = 128
X = rdm.rand(dataset_size , 2)
# 定义规则来给出样本的标签,将所有 x1 + x2 < 1 的样例认为为正样本,添加 1 标签 。
Y = [[ int(x1 + x2 < 1) ] for ( x1 ,x2 ) in X]
# 创建一个会话来运行Tensorflow程序 。
with tf.Session() as sess:
# 初始化变量 。
init_op = tf.global_variables_initializer()
sess.run(init_op)
# 打印训练前的神经网络参数。
print( "w1: " , sess.run(w1))
print( "w2: " , sess.run(w2))
# 定义迭代的次数 。
STEPS = 5000
for i in range(STEPS):
# 每次选取batch_size个样本进行训练 。
start = (i * batch_size ) % dataset_size
end = min(start + batch_size , dataset_size )
# 通过选取的样本训练神经网络并更新参数
sess.run(train_step , feed_dict = { x : X[start : end ] , y_ : Y[start : end]})
# 每迭代1000次计算并输出交叉嫡 。
if i % 1000 == 0 :
total_cross_entropy = sess.run( cross_entropy , feed_dict = {x :X ,y_ :Y })
print("after % d training step(s) , cross entropy on all data is %g"%( i , total_cross_entropy))
# 输出训练后神经网络参数的值
print("w1: ", sess.run(w1))
print("w2: ", sess.run(w2))