Loading...
Navigation
Table of Contents

TensorFlow BasicsData

Reference


Interactive Session

#使用交互式会话
sess = tf.InteractiveSession()
a = tf.constant(5.0)
b = tf.constant(6.0)
c = a * b
print(c.eval())
sess.close()
#使用普通式会话
a = tf.constant(5.0)
b = tf.constant(6.0)
c = a * b
with tf.Session():
    print(c.eval())

CheetSheet

  • tf.add_n([tensor1, tensor2,...], name=None) Adds all input tensors element-wise

  • tf.expand_dims(input, axis=None, name=None, dim=None) 在axis维度上增加一维. 比如有一个shape为[height, width, channels]的图片, 可以通过tf.expand_dims(image, 0)把shape变成[1, height, width, channels].

  • tf.tile(tensor, multiples, name=None) 把tensor在每一个维度上复制multiples遍. multiples的长度必须和tensor的维度一致; tile从最里面那一维开始复制

>>> a = tf.constant([1,2])
>>> tf.tile(a,[2]).eval()
array([1, 2, 1, 2])
>>> a = tf.constant([[1,2], [3,4]])
>>> tf.tile(a,[2,3]).eval()
array([[1, 2, 1, 2, 1, 2],
       [3, 4, 3, 4, 3, 4],
       [1, 2, 1, 2, 1, 2],
       [3, 4, 3, 4, 3, 4]])
  • tf.nn.softmax_cross_entropy_with_logits(logits, labels, name=None)

    • logits是神经网络最后一层的输出, 如果有batch的话, 大小是[batch_size, num_class]; labels大小同上, 但是不一定必须是one-hot的([0, 1, 0, 0]), 也可以是概率分布([0, 0.1, 0.9, 0]); 如果labels是index序列(shape=[batch_size]), 则用sparse_softmax_cross_entropy_with_logits().
    • 执行流程: 先对logits做一个softmax变换, 得到大小为[batch_size, num_classes]的概率向量, 然后和实际label做一个交叉熵. 其结果的值越小, 说明预测越准确
    • 注意, 这个函数的返回值是一个向量, 其维度为样本个数. 如果要求交叉熵,需再做一步tf.reduce_sum()来对向量里面所有元素求和,得到loss. 注意这里是没有除以样本个数, 因为loss函数不带正则化项时, 除不除无所谓
    • 更多参考这里
  • 获取全部的变量和trainable变量.

all_vars = tf.global_variables() #all_vars是一个list
all_trainable_vars = tf.trainable_variables()
>>> logits = tf.constant([[1.0, 2.0, 3.0],[1.0, 2.0, 3.0],[1.0, 2.0, 3.0]]) #NN的输出
>>> y_pred = tf.nn.softmax(logits) #1. 做softmax
>>> tf.Session().run(y_pred)
array([[ 0.09003057,  0.24472848,  0.66524094],
       [ 0.09003057,  0.24472848,  0.66524094],
       [ 0.09003057,  0.24472848,  0.66524094]], dtype=float32)
>>> y_real = tf.constant([[0.0, 0.0, 1.0],[0.0, 0.0, 1.0],[0.0, 0.0, 1.0]]) #真实labels
>>> loss1 = -tf.reduce_sum(y_real*tf.log(y_pred)) #2. 做交叉熵
>>> tf.Session().run(loss1)
1.222818

>>> loss2 = tf.reduce_sum(tf.nn.softmax_cross_entropy_with_logits(labels=y_real, logits=logits))
#必须指定谁是labels, 谁是logits
>>> tf.Session().run(loss2)
1.2228179

stack/unstack

>>> sess = tf.InteractiveSession()
>>> a = tf.constant([1, 2, 3])
>>> b = tf.constant([4, 5, 6])
>>> c = tf.stack([a, b],axis=1)
>>> c.eval()
array([[1, 4],
       [2, 5],
       [3, 6]])
>>> d = tf.unstack(c,axis=0)
>>> sess.run(d)
[array([1, 4]), array([2, 5]), array([3, 6])]
>>> e = tf.unstack(c,axis=1)
>>> sess.run(e)
[array([1, 2, 3]), array([4, 5, 6])]

name/scope

tf.variable_scope()主要结合tf.get_variable()来使用, 方便变量共享, 推荐使用这个.

with tf.variable_scope('v_scope') as scope1:
    weights1 = tf.get_variable('weights', shape=[2,3])
    bias2 = tf.Variable([0.52], name='bias2')
    是可以结合tf.Variable()一块使用, 但不推荐这样用
print(weights1.name) #v_scope/weights:0
with tf.variable_scope('v_scope') as scope1:
    weights1 = tf.get_variable('weights', shape=[2,3]) #报错, 因为v_scope/weights已经存在
with tf.variable_scope('v_scope', reuse=True) as scope2: #开始重用变量(共享)
    weights2 = tf.get_variable('weights') #重用weights
    bias1 = tf.get_variable('bias1', shape=[1]) #会报错,
    # 在reuse=True中使用get_variable时, scope中的变量必须已经定义过
print weights2.name #v_scope/weights:0

tf.name_scope主要结合tf.Variable()来使用, 方便变量命名管理. 使用tf.Variable()创建变量, 如果该name已存在的话(或是被tf.Variable()创建, 或是被tf.get_variable()创建)会自动处理.

#在conv1命名空间中声明2个变量
with tf.name_scope('conv1') as scope:
    weights1 = tf.Variable([1.0, 2.0], name='weights')
    bias1 = tf.Variable([0.3], name='bias')
print(weights1.name) #conv1/weights:0
#在conv2命名空间中声明2个变量
with tf.name_scope('conv2') as scope:
    weights2 = tf.Variable([4.0, 2.0], name='weights')
    bias2 = tf.Variable([0.33], name='bias')
print(weights2.name) #conv2/weights:0
#这里的with和python中其他的with是不一样的, 执行完with里边的语句之后,
#conv1/和conv2/空间还是在内存中的
#------
#如果再次执行上面的重复代码(scope同名), 就会再生成新命名空间
with tf.name_scope('conv1') as scope: #其实会变成conv1_1
    weights3 = tf.Variable([1.0, 2.0], name='weights')
    bias3 = tf.Variable([0.3], name='bias')
print(weights3.name) #conv1_1/weights:0

save/restore模型

tf中save模型, restore模型的方法, 参考官方Guide

#开始save模型示例
v1 = tf.get_variable("v1", shape=[3], initializer = tf.zeros_initializer)
v2 = tf.get_variable("v2", shape=[5], initializer = tf.zeros_initializer)
inc_v1 = v1.assign(v1+1)
dec_v2 = v2.assign(v2-1)
saver = tf.train.Saver() #声明一个默认Saver对象
with tf.Session() as sess:
  sess.run(tf.global_variables_initializer()) #会把v1, v2初始化为0
  inc_v1.op.run()
  dec_v2.op.run()
  save_path = saver.save(sess, "/tmp/model.ckpt", global_step=epoch_idx)
  #存到这个文件里, 实际会生成4个文件; global_step表示加上epoch后缀

默认Saver对象会将所有的变量以name: value的形式存储, 所以必须给Variable取好名字. 此外也可指定存储哪些Variable, 以及某个Variable用什么name存储.

saver = tf.train.Saver({"vv1": v1, "vv2": v2}) #用一个dict初始化Saver对象
with tf.Session() as sess:
    save_path = saver.save(sess, "/tmp/model.ckpt", global_step=epoch_idx)
#开始取restore模型示例
v11 = tf.get_variable("v1", shape=[3])
v22 = tf.get_variable("v2", shape=[5], trainable=False)
#v22是不可通过求梯度来更新的, 但是可以赋值
saver = tf.train.Saver({"vv1": v11}) #这里只restore变量v11, 注意维度要一致
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer()) #先初始化所有变量
    saver.restore(sess, "/tmp/model.ckpt") #restore模型

GPU管理

#设置GPU按需增长
config = tf.ConfigProto()
config.gpu_options.allow_growth = True
sess = tf.Session(config=config)

全连接example

def fc(X, out_size):
    in_size = X.shape[1]  # 特征维度
    W = tf.get_variable('weight', shape=[in_size, out_size], initializer=tf.truncated_normal_initializer())
    b = tf.get_variable('bias', [out_size], initializer=tf.zeros_initializer())
    h_fc = tf.nn.relu(tf.nn.xw_plus_b(X, W, b), name='relu')
    return h_fc

X_input = tf.placeholder(dtype=tf.float32, shape=[batch_size, feature_size], name='X_input')
with tf.variable_scope('fc1') as vs:
    h_fc1 = fc(X_input, out_size=64)
with tf.variable_scope('fc2') as vs:
    h_fc2 = fc(h_fc1, out_size=32)
all_vars = tf.global_variables()
for i in range(len(all_vars)):
    print('var {}: '.format(i), all_vars[i])

Last updated on Jul 04, 2018.