TensorFlow学习笔记(1) TensorFlow入门

一、TensorFlow计算模型——计算图(Computational Graph)

TensorFlow——Tensor和Flow。Tensor意为张量,可以理解为多维数组。Flow意为流,表达了张量之间通过计算相互转化的过程。TensorFlow中每一个计算都是计算图上的一个节点,节点之间的边描述了计算之间的依赖关系。

TensorFlow程序一般分为两个阶段:定义计算图和执行计算,以下代码为定义计算图的样例:

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.get_default_graph()可以获得当前默认的计算图,例如以下代码为如何获取默认计算图及一个运算所属的计算图:

tf.get_default_graph() #默认计算图
a.graph #a张量所属计算图
print(a.graph is tf.get_default_graph())
#由于没有特意指定a的计算图,所以计算图应该为当前默认计算图,输出为True

TensorFlow支持通过tf.Graph函数生成新的计算图。不同计算图的张量和运算不会共享:

import tensorflow as tf

#生成计算图g1,并在其中定义变量v,初始值为1
g1 = tf.Graph()
with g1.as_default():
    v = tf.get_variable("v", shape = [1], initializer=tf.ones_initializer())

#生成计算图g1,并在其中定义变量v,初始值为1
g2 = tf.Graph()
with g2.as_default():
    v = tf.get_variable("v", shape = [1], initializer=tf.zeros_initializer())

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

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

计算图可以有效的整理TensorFlow程序中的资源。比如通过tf.add_to_collection可以将资源加入一个或多个集合中,然后通过tf.get_collection获取集合中的资源:

# tf.add_to_collection:把变量放入一个集合,把很多变量变成一个列表
# tf.get_collection:从一个结合中取出全部变量,是一个列表
# tf.add_n:把一个列表的东西都依次加起来

import tensorflow as tf
v1 = tf.get_variable(name='v1', shape=[1], initializer=tf.constant_initializer(0))
tf.add_to_collection('loss', v1)
v2 = tf.get_variable(name='v2', shape=[1], initializer=tf.constant_initializer(2))
tf.add_to_collection('loss', v2)

with tf.Session() as sess:
    sess.run(tf.initialize_all_variables())
    print(tf.get_collection('loss'))
    print(sess.run(tf.add_n(tf.get_collection('loss'))))

# 输出:
# [<tensorflow.python.ops.variables.Variable object at 0x7f6b5d700c50>,
# <tensorflow.python.ops.variables.Variable object at 0x7f6b5d700c90>]
# [ 2.]

二、TensorFlow数据模型——张量(tensor)

张量可以简单理解为多维数组。零阶张量为一个数,一阶张量为向量,即一维数组,n阶张量为n维数组。但在张量中并没有直接保存数字,而是保存如何得到这些数的计算过程。比如如下代码,并不会得到加法结果,卫视得到对结果的一个引用:

import tensorflow as tf
a = tf.constant([1.0, 2.0], name='a')
b = tf.constant([2.0, 3.0], name='b')
result = tf.add(a, b)
print(result)
# 输出:Tensor("add:0", shape=(2,), dtype=float32)

一个张量主要保存了三个属性:名字(name),维度(shape),类型(type)。在上面的result中‘add:0’即为name,说明这个张量是计算节点‘add’输出的的第一个结果。维度为(2,)一维数组,长度为2。类型为float32。

三、TensorFlow运行模型——会话(session)

会话用来执行定义好的计算,拥有并管理TensorFlow程序运行时的所有资源,一般使用如下方法:

with tf.Session() as sess:
    sess.run(...)
#通过python的上下文管理机制,所有计算放在with内就可以,上下文管理器退出时,自动释放所有资源

在计算图中,TensorFlow会自动生成一个默认的计算图,若无特殊指定并加入运算。会话也有类似机制,但不会自动生成默认会话。当会话被特殊指定之后可以通过tf.Tensor.eval函数来计算一个张量的取值:

sess = tf.Session()
with sess.as_default():,
    print(result.eval)

###以下代码亦可以完成相同功能###
sess =tf.Session()
print(sess.run(result))
#print(result.eval(session=sess))

四、TensorFlow实现神经网络

TensorFlow游乐场(http://playground.tensorflow.org)实现可视化训练过程。

神经网络的输出是通过前向传播算法得到的,这里介绍最简单的全连接网络结构的前向传播算法。计算神经网络的前向传播结果需要三部分信息:1.神经网络的输入,即实体中提取的特征向量。设为x;2.神经网络的链接结构即节点、神经元。设为a,y;3.每个神经元的参数,即W。则用TensorFlow程序实现神经网络的前向传播过程为:

a = tf.matmul(x, w1)
y = tf.matmul(a, w2)

在TF中,变量(tf.Variable)的作用就是保存和更新神经网络的参数,一般使用随机数给TF中的变量初始化:

'''
以下代码产生一个2*3的矩阵,矩阵中的元素是均值是0,标准差为2的随机数,随机数分布为正太分布
'''
weights = tf.Variable(tf.random_normal([2, 3], stddev = 2,mean = 0))

TF也允许通过常数来初始化一个变量,比如:

z = tf.Variable(tf.zeros([3])) #全0数组
z = tf.Variable(tf.ones([3])) #全1数组
z = tf.Variable(tf.fill([3], 9)) #全9数组
z = tf.Variable(tf.constant([3])) #3

也可以通过其他变量的初始化来初始化新的变量:

w2 = tf.Variable(weights.initial_value()) #初始值与weights相同
w3 = tf.Variable(weights.initial_value() * 2.0 )

通过变量实现的前向传播的过程:

import tensorflow as tf

#声明w1、w2两个变量,通过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))


x = tf.constant([[0.7, 0.9]])

#前向传播算法
a = tf.matmul(x, w1)
y = tf.matmul(a, w2)

#初始化所有变量
init_op = tf.initialize_all_variables()

with tf.Session() as sess:
    sess.run(init_op)
    print(sess.run(y))

所有的变量都会被加入GraphKeys.VARIABLES这个集合,通过tf.variables可以得到计算图上的所有变量。在声明变量时可以通过变量声明函数中的trainable参数为True,那么该变量则会被加入GraphKeys.TRAINABLE_VARIABLES,TF将优化其,通过tf.trainable_variables得到所有需要优化的变量。若trainable参数为Flase,则TF不会优化他。

为了方便训练数据的输入,TF提供了placeholder机制用于提供输入数据:

import tensorflow as tf

w1 = tf.Variable(tf.random_normal([2, 3], stddev=1))
w2 = tf.Variable(tf.random_normal([3, 1], stddev=1))

x = tf.placeholder(tf.float32, shape=(3, 2), name='input')

a = tf.matmul(x, w1)
y = tf.matmul(a, w2)

init_op = tf.initialize_all_variables()

with tf.Session() as sess:
    sess.run(init_op)
    print(sess.run(y, feed_dict={x:[[0.7, 0.9], [0.1, 0.4], [0.5, 0.8]]}))

在得到前向传播结果之后,即y,需要定义一个损失函数来描述预测值与真实值之间的差距,然后通过反向传播算法来调整神经网络参数的取值使得差距可以被缩小:

cross_entropy = -tf.reduce_mean(y_* tf.log(tf.clip_by_value(y, 1e-10, 1.0)))
learning_rate = 0.001
train_step = tf.train.AdamOptimizer(learning_rate).minimize(cross_entropy)

其中,cross_entropy定义了真实值与预测值之间的交叉熵。train_step定义了反向传播的优化方法,目前TF支持七种优化器,常用的有三种:tf.train.GradientDescentOptimizer\tf.train.AdamOptimizer\tf.train.MomentumOptimizer。

综合以上所说,
训练神经网络的过程可以分为三个步骤:

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

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

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

import tensorflow as tf
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))
x = tf.placeholder(tf.float32, shape=(None, 2), name='x-input')
y_ = tf.placeholder(tf.float32, shape=(None, 1), name='y-input') #y_ 为真实值
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)))
learning_rate = 0.001
train_step = tf.train.AdamOptimizer(learning_rate).minimize(cross_entropy)

# 通过模拟数随机生成数据集
# 假设x1、x2为零件的某特征值,若x1+x2<1,则零件合格y=1,否则零件不合格y=0
rdm = RandomState(1)
dataset_size = 128
X = rdm.rand(dataset_size, 2)
Y = [[int(x1+x2 < 1)] for (x1, x2) in X]

init_op = tf.initialize_all_variables()

# 生成会话并在训练数据上反复运行反向传播优化算法
with tf.Session() as sess:
    sess.run(init_op)
    print('Before training...')
    print('w1\n', sess.run(w1))
    print('w2\n', sess.run(w2))

    STEPS = 5000
    for i in range(STEPS):
        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 % 500 == 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('After training...')
    print('w1\n', sess.run(w1))
    print('w2\n', sess.run(w2))

猜你喜欢

转载自blog.csdn.net/qyf394613530/article/details/79225280