TensorFlow学习笔记(1) 计算图、张量、会话及简单的神经网络

 

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

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

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

四、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函数生成新的计算图,另外tf.Graph.device可以指定运算的设备。

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,初始值为0
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')))#1

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')))#0


g3 = tf.Graph()
with g3.device('/gpu:0'):#制定运算再gpu0上
    result = a+b

计算图可以有效的整理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.]
tf中常用集合
集合名称集合内容使用场景
tf.GraphKeys.VARIABLES所有变量持久化TensorFlow模型
tf.GraphKeys.TRAINABLE_VARIABLES可学习的变量模型训练、生成模型可视化内容
tf.GraphKeys.SUMMARIES日志生成相关张量TensorFlow计算可视化
tf.GraphKeys.QUEUE_RUNNERS处理输入的QueueRunner输入处理
tf.GRaphKeys.MOVING_AVEGAGE_VARIABLES所有计算了滑动平均值的变量计算变量的滑动平均值

 

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

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

import tensorflow as tf
a = tf.constant([1, 2], name='a',type=float32)
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)。

  • name:通过“node:src_output"的形式给出,其中node表示节点的名称,src_output表示当前张量来自节点的第几个输出。上面的result中‘add:0’说明这个张量是计算节点‘add’输出的的第一个结果。
  • shape:表示张量的维度信息,shape=(2,)表示该向量为一维向量,长度为2
  • type:表示张量的类型,必须同类型的张量才能进行运算,上面ab的类型都为float32,其中b因为".0"默认,a指定了type

三、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([2,3],int32)) #全0数组[[0,0,0],[0,0,0]]
z = tf.Variable(tf.ones([3])) #全1数组 [1,1,1]
z = tf.Variable(tf.fill([2,3], 9)) #全9数组[[9,9,9],[9,9,9]]
z = tf.Variable(tf.constant([1,2,3])) #[1,2,3]

c1 = tf.constant([3])   
#代表向量,shape=(1, )的一维constant
c2 = tf.constant([[3]]) 
#代表1*1的矩阵,shape=(1, 1)的二维constant

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

weights=tf.Variable(tf.random_normal([2,3],stddev=1))
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机制用于提供输入数据。placehoder意为占位符,再定义计算图时定义一个位置,当真正进行计算时,再将数据输入进去。

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)))
#tf.clip_by_value表示y进行截断操作,使其值落在一定范围内
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的大小
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)#x有128组数据
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))

 

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值