深度学习笔记——TensorFlow学习笔记(一)入门

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/mpk_no1/article/details/72848447

之前使用的深度学习框架一直是Keras,Keras的高级封装特性让人们十分容易理解并上手。不过有些时候,由于keras过于封装,反而使得有些时候不能灵活运用。这时候更底层一些的TensorFlow就体现出优势来了。另外,大家知道,keras的底层后端有Theano和TensorFlow两种,如果想要自己实现一个自定义层,就需要调用后端接口实现了。

基于此,最近开始学习一些TensorFlow的知识,因此就在此记录一下学习过程和使用心得吧。

TensorFlow的安装教程网上可以搜到一大堆,我在此就不在赘述了。在安装好TensorFlow和相应的依赖包、加速包CUDA等之后,就可以愉快地开始TensorFlow学习与使用啦~~~~

我使用的TensorFlow版本是1.0.1版本,因此一些使用旧版本0.x的需要注意一些函数和接口的变化。


接下来就开始TensorFlow的学习旅程吧,本文只是前期的一些入门知识总结,接下来会陆续写一些关于TensorFlow的实例。


1.TensorFlow计算模型——计算图

计算图是TensorFlow中最基本的一个概念,TensorFlow中的所有计算都会被转化为计算图上的节点。

TensorFlow程序一般分为两个阶段。在第一个阶段需要定义计算图中所有的计算,第二个阶段为执行计算,得到计算结果。

在TensorFlow程序中,系统会自动维护一个默认的计算图,通过tf.get_default_graph函数可以获取当前默认的计算图。除了使用默认的计算图外,TensorFlow支持通过tf.Graph函数来生成新的计算图,不同计算图上的张量和运行都不会共享

下面是一个生成计算图并定义变量的代码:

import tensorflow as tf

g = tf.Graph()

with g.as_default():

#在计算图中定义变量“v”,并设置初始值为0

v = tf.get_variable("v", initializer = tf.zeros_initializer(shape=[1]))


TensorFlow中的计算图不仅可以用来隔离张量和计算,它还提供了管理张量和计算的机制。计算图可以通过tf.Graph.device函数来指定运行计算的设备,这为TensorFlow使用GPU提供了机制。

g = tf.Graph()

#指定计算运行的设备

with g.device('/gpu:0'):

result = a + b


2.TensorFlow数据模型——张量

张量(tensor)是TensorFlow管理数据的形式,在TensorFlow所有程序中,所有的数据都是通过张量的形式来表示。从功能的角度上来看,张量可以被简单理解为多维数组。其中零阶张量表示标量,也就是一个数;一阶张量表示一个向量,也就是一个一维数组;n阶张量可以理解为一个n维数组。但张量在TensorFlow中的实现并不是直接采用数组的形式,它只是对TensorFlow中运算结果的引用。在张量中并没有真正保存数字,它保存的是如何得到这些数字的计算过程。

张量主要有三个属性:名字(name)、维度(shape)和类型(type)。如:Tensor("add:0", shape=(2,), dtype=float32)

张量的名字不仅是一个张量的唯一标识符,同样也给出了这个张量是如何计算出来的。张量的命名通过“node:src_output”的形式给出,其中node为结点的名称,src_output表示当前张量来自结点的第几个输出。如上面的"add:0"表明这个张量是计算节点"add"输出的第一个结果。

张量的维度描述了张量的维度信息,如上面的“shape=(2,)”说明这个张量是一个一维数组,数组长度为2。TensorFlow程序中维度的对应是一个需要十分注意的地方。

张量的类型表明了数据的类型,TensorFlow会对参与运算的所有张量进行类型检查,当发现类型不匹配时会报错。主要有以下14种类型:tf.int8,tf.int16,tf.int32,tf.int64,tf.uint8,tf.float32,tf.float64,tf.bool,tf.complex64,tf.complex128.


张量的使用:

第一类用途是对中间运算结果的引用,如:

#使用张量记录中间结果

a = tf.constant([1.0, 2.0], name = "a")

b = tf.constant([2.0, 3.0], name = "b")

c = a + b

可以使用c.get_shape函数来获取结果张量的维度信息

张量的第二类使用情况是当计算图构造完成之后,张量可以用来获得计算结果,也就是得到真实的数字。可以使用tf.Session().run(c)语句得到计算结果。


3.TensorFlow运行模型——会话

TensorFlow中使用会话(session)来执行定义好的运算。会话拥有并管理TensorFlow程序运行时的所有资源。

TensorFlow中使用会话的模式有两种,第一种模式需要明确调用会话生成函数和关闭会话函数,代码流程如下:

#创建一个会话

sess = tf.Session()

#使用会话进行运算

sess.run(...)

#关闭会话

sess.close()


上面这种模式在所有计算完成之后需要明确调用Session.close()函数来关闭会话并释放资源。如果程序因为异常而退出,则会导致会话未关闭而资源泄露。因此,为了解决异常退出时资源释放的问题,可以通过Python的上下文管理器来使用会话,这就是第二种模式,代码流程如下:

#创建一个会话

with tf.Session() as sess:

#使用这个会话进行运算,下面两个命令有相同的功能

sess.run(rusult)

result.eval()


通过上面的学习,在了解了TensorFlow的一些基本概念之后,接下来就用一个实例来亲身体验一下吧。

用TensorFlow实现神经网络,主要分为以下3个步骤:

1)定义神经网络的结构和前向传播的输出结果

2)定义损失函数以及选择方向传播优化算法

3)生成会话并在训练数据上反复运行反向传播优化算法

具体代码如下:

import tensorflow as tf

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))
bias1 = tf.Variable(tf.random_normal([3], stddev=1, seed=1))
bias2 = tf.Variable(tf.random_normal([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)

a = tf.nn.relu(tf.matmul(x, w1) + bias1)
y = tf.nn.relu(tf.matmul(a, w2) + bias2)

#定义损失函数和反向传播算法
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)#梯度下降优化算法

#produce the data,通过随机数生成一个模拟数据集
rdm = RandomState(1)
dataset_size = 128
X = rdm.rand(dataset_size, 2)
Y = [[int(x1 + x2 < 1)] for (x1, x2) in X]

#creare a session,创建一个会话来运行TensorFlow程序
with tf.Session() as sess:
    #init all variable,初始化变量
    init_op = tf.initialize_all_variables()
    sess.run(init_op)
    #训练之前查看w1和w2的值
    print sess.run(w1)
    print sess.run(w2)
    #设定训练的轮数
    STEPS = 5000
    for i in range(STEPS):
        #get batch_size samples data to train,每次选取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 steps, cross_entropy on all data is %g" %(i, total_cross_entropy))
    #在训练结束之后,输出神经网络的参数
    print sess.run(w1)
    print sess.run(w2)





猜你喜欢

转载自blog.csdn.net/mpk_no1/article/details/72848447