TensorFlow实现神经网络

目录

TensorFlow游乐场

神经网络参数与TensorFlow变量

TensorFlow实现神经网络模型

placeholder详解


文中测试代码均来自书《TensorFlow实战Google深度学习框架》。

TensorFlow游乐场

TensorFlow游乐场

可视化训练神经网络,实现可视化训练。

神经网络参数与TensorFlow变量

tensorflow中支持的随机数生成函数:

函数名称 随机数分布 主要参数
tf.random_normal 正态分布 平均值、标准差、取值类型
tf.truncated_normal 正态分布,但如果随机出来的值偏离平均值超过2个标准差,那么这个数将会被重新随机 平均值、标准差、取值类型
tf.random_uniform 平均分布 最小、最大取值,取值类型
tf.random_gamma Gamma分布 形状参数alpha、尺度参数beta、取值类型

tensorflow支持使用常数来初始化一个变量,常用的常量生成函数如下表

函数名称 功能 实例
tf.zeros 产生全0的数组 tf.zeros([2,3],int32)->[[0,0,0],[0,0,0]]
tf.ones   产生全1的数组 tf.ones([2,3],int32)->[[1,1,1],[1,1,1]]
tf.fill   产生一个全部为给定数字的数组 tf.fill([2,3],9)->[[9,9,9],[9,9,9]]
tf.constant   产生一个给定值的常量 tf.constant([1,2,3])->[1,2,3]

TensorFlow实现神经网络模型

训练神经网络三个步骤:

  1. 定义神经网络的结构和前向传播的输出算法。
  2. 定义损失函数以及选择反向传播算法。
  3. 生成会话(tf.Session)并且在训练数据上反复运行反向传播优化算法。

反向传播算法实现了一个迭代的过程;在每次迭代的开始,首先选取一小部分训练数据batch。 
然后,batch样例会通过前向传播算法得到神经网络模型的预测结果。训练数据都是有正确答案标注的,所以可以计算出当前神经网络模型的预测答案与正确答案之间的距离。 
最后,基于预测值和真实值之间的差距,反向传播算法会相应更新神经网络参数的取值,使batch上神经网络模型的预测结果和真实情况更加接近。

代码,讲解在注释中:

import tensorflow as tf
# Numpy是一个科学计算工具包,这里通过Numpy工具包生成模拟数据集
from numpy.random import RandomState

batch_size = 8  # 定义训练数据batch的大小

# 定义神经网络的参数
# tf.Variable是TensorFlow的变量定义函数,这一行可以产生一个2x3的矩阵,元素均值为stddev=1,seed为随机种子
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大小。
# 训练数据时需要把数据分成比较小的batch;测试时,需要一次性使用全部数据;
# 当数据集比较小时这样比较方便测试
# 当数据集比较大时,将大量数据放入一个batch可能会导致内存溢出
# 定义placeholder作为存放输入数据的地方。维度不一定要定义,如果维度是确定的,给定维度会降低出错概率
#
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)

# 定义损失函数和反向传播算法
y = tf.sigmoid(y)
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)  # RandomState公开了许多用于生成从各种概率分布中抽取的随机数的方法
data_size = 128
X = rdm.rand(data_size, 2)

# 定义规则来给出样本的标签.此处,x1+x2<1的样例被认为是正样本(零件合格)
# 其他样本不合格;
# 此处0表示负样本,1表示正样本
# 大部分解决分类问题的神经网络都会采用0和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(sess.run(w1))
    print(sess.run(w2))

    # 设定训练轮数
    STEPS = 5000
    for i in range(STEPS):
        # 每次选取batch_size个样本进行训练
        start = (i * batch_size) % data_size
        end = min(start+batch_size, data_size)

        # 通过选取的样本训练神经网络并更新参数
        # feed_dict是一个字典(map)
        # 训练
        sess.run(train_step, feed_dict={x: X[start:end], y_: Y[start:end]})
        if i % 1000 == 0:
            # 隔一段时间计算所有数据的交叉熵并输出
            total_cross_entropy = sess.run(cross_entropy, feed_dict={x: X, y_: Y})
            print("第%d轮,所有数据上的交叉熵为%g" % (i, total_cross_entropy))

    print(sess.run(w1))
    print(sess.run(w2))

placeholder详解

参考博文:tf.placeholder函数说明

Tensorflow的设计理念称之为计算流图,在编写程序时,首先构筑整个系统的graph,代码并不会直接生效,这一点和python的其他数值计算库(如Numpy等)不同,graph为静态的,类似于docker中的镜像。然后,在实际的运行时,启动一个session,程序才会真正的运行。这样做的好处就是:避免反复地切换底层程序实际运行的上下文,tensorflow帮你优化整个系统的代码。我们知道,很多python程序的底层为C语言或者其他语言,执行一行脚本,就要切换一次,是有成本的,tensorflow通过计算流图的方式,帮你优化整个session需要执行的代码,还是很有优势的。

       所以placeholder()函数是在神经网络构建graph的时候在模型中的占位,此时并没有把要输入的数据传入模型,它只会分配必要的内存。等建立session,在会话中,运行模型的时候通过feed_dict()函数向占位符喂入数据。
 

你可能感兴趣的:(机器学习,TensorFlow)