Tensorflow学习笔记(一)Tensorflow入门

版权声明:水平有限,博客中难免不少纰漏甚至严重错误,希望大家指正。同时撰写最大的目的也在于交流学习,而不在关注和传播。任重而道远,MrYx与您共勉。 https://blog.csdn.net/yexiaohhjk/article/details/83793367

Tensorflow入门

前言:

本文是阅读《TensorFlow:实战Google深度学习框架》第三章提炼出来的笔记,非本人原创。
这一章主要介绍:

  • TensorFlow 名字说明最重要两个概念:Tensor(张量),Flow(流)。
  • tensor张量可以理解为多维数组,flow表达了张量之间通过计算相互转换的过程。
  • 以及计算图,会话的概念与使用。

计算图:

Tensorflow是一个通过计算图的形式来表达计算的编程系统,Tensorflow里面每一个计算都是计算图上的一个节点,而节点之间的边描述了计算之间的依赖关系。

计算图使用:

Tensorflow程序一般分两个阶段:

  • 第一阶段:定义计算图中所有的计算。
  • 第二部分:利用创建的会话tf.Session()来执行计算。
    如下面举例的第一阶段定义a+b的计算。
import tensorflow as tf
a = tf.constant([1.0, 2.0], name = 'a')
b = tf.constant([2.0, 3.0], name = 'b')
result = a + b

注意:
在任何一个tensorflow程序里,系统都会维护一个默认的计算图。也可以尝试用tf.Graph函数生成新的计算图。不同计算图上的张量和运算不会共享,提供了管理张量和计算的机制,计算图也可以通过tf.Graph.device函数指定运行计算的设备。

以下代码展示在不同计算图上定义和使用变量。

import tensorflow as tf

g1 = tf.Graph()
with g1.as_default():
    v = tf.get_variable("v", [1], initializer = tf.zeros_initializer()) # 设置初始值为0

g2 = tf.Graph()
with g2.as_default():
    v = tf.get_variable("v", [1], initializer = tf.ones_initializer())  # 设置初始值为1
    
with tf.Session(graph = g1) as sess:
    tf.global_variables_initializer().run()
    with tf.variable_scope("", reuse=True):
        print(sess.run(tf.get_variable("v")))

with tf.Session(graph = g2) as sess:
    tf.global_variables_initializer().run()
    with tf.variable_scope("", reuse=True):
        print(sess.run(tf.get_variable("v")))

张量:

张量(tensor)是Tensorflow管理数据的形式。
它其实在Tensorflow中并不是直接采用数组形式,而是对运算结果的引用。即它并没有真正保存数字,而是保存这些数字的结果的计算过程。它主要保存三个属性: 名字(name),维度(shape),类型(type)。

张量的使用

张量使用主要两大类:

  • 对中间计算机结果的引用 (例子如上面计算图定义a+b的计算里用result保存a+b)
  • 当计算图构造完成后,获得计算结果
a = tf.constant([1.0, 2.0], name = 'a') # 这里的a就是张量

会话

计算图和张量是组织数据和运算的,会话用来执行定义好的运算。
非常类似python文件的打开关闭操作,Tensorflow中会话也有两种方式。

  • 第一种明确定义会话的生成和关闭函数:
sess = tf.Session()
sess.run(....) # ....是已经定义好计算的张量
sess.close()

-第二种利用上下文管理器,解决了程序异常退出时没有执行到sess.close()资源无法回收的问题。

with tf.Session() as sess:
         sess.run()

神经网络参数与Tensorflow变量:Variable

变量(tf.Variable)的作用就是保存和更新神经网络的参数,其属性和张量一样:名字(name),维度(shape),类型(type)。其中名字和类型定义之后无法改变,维度可以通过validate_shape = false修改,但实践中很少用。

和很多编程语言类似,Tensorflow变量也需要赋给初值,而在神经网络中给变量赋予随机数最常见。
例如:

weights = tf.Variable(tf.random_normal([2, 3], stddev = 2,seed =1 )) #seed参数设置随机种子

tf.random_normal([2, 3]会产生一个2X3均值为0,标准差为2的矩阵。

Tensorflow其他更多随机生成函数以及常数生成函数见博客

同时在Tensorflow中,一个变量的值在备用之前,这个变量初始化过程需要被明确调用

单独调用每个变量初始化函数过于麻烦,Tensorflow提供了tf.global_variables_initializer()函数实现初始化所有变量的过程。例如:

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

Variable变量与Tensor张量相比

上面介绍过TensorFlow的核心概念是张量(tensor),所有的数据都是通过张量的形式来组织。同时在TensorFlow中,变量的声明函数tf.Variable是一个运算。这个运算的输出结果就是一个张量,所以变量只是一种特殊的张量。

通过Tensorflow训练神经网络:placeholder

神经网络每轮迭代训练输入的数据都会通过常量表示。而Tensorflow没生成一个常量都会在计算图里增加一个节点而导致计算图过于庞大。避免这个问题,Tensorflow提供了placeholder机制用于提供输入数据。

placeholder相当于一个等待数据输入的入口变量,又称占位变量。它可以先被定义其类型和名称,维度可以根据提供的数据推导得出,所以不一定要给出。然后通过feed_dict字典来指定定义计算过程里的每个placeholder的取值。

例如:

x = tf.placeholder(tf.float32, shape = (None , 2), name = 'x-input')
# 然后在会话的run()函数里利用feed_dict ={ }的机制输入数据,例子看下面完整程序

完整神经网络样例程序

这个样例里面神经网络选择交叉熵作为损失函数,关于神经网络更多损失函数选取可以看博客博客的总结。

其他的注释的写得很详细,就不多解释。


import tensorflow as tf
#这里通过numpy工具包生成训练数据集
from numpy.random import RandomState

#定义每轮训练数据集的大小
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_size。在训练时候可以把数据划分成比较小的batch
#但是在测试可以一次性使用全部数据。同时当数据集比较大的时候,大量数据放入一个batch可能会导致
#内存溢出。
x = tf.placeholder(tf.float32, shape = (None , 2), name = 'x-input')
y_ = tf.placeholder(tf.float32 , shape =(None ,1), name = 'y-input')

#tf.matmul是矩阵的乘法,定义了神经网络前向传播的过程
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)) + (1 - y_) * tf.log(tf.clip_by_value(1-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 被认为是正样本。
Y = [[int(x1 + x2 < 1)] for (x1,x2) in X]

with tf.Session() as sess:
    init_op = tf.global_variables_initializer()
    #初始化变量
    sess.run(init_op)

    print('Before training w1: ', sess.run(w1))
    print('Before training 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]})
        
        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('After training w1: ', sess.run(w1))
    print('After training w2: ', sess.run(w2))

参考

《TensorFlow实战Google深度学习框架:第三章》

猜你喜欢

转载自blog.csdn.net/yexiaohhjk/article/details/83793367