tensorflow-->论文代码阅读总结

张量介绍

tensorflow 中我们要处理的张量通常有二维,三维,甚至四维,那么该如何判断给定张量的维度呢?以及各个维度上的大小呢?

简单来说,从给定张量的最外层开始,判断次外层相同等级的括号,有几对,如有 n 对,则 n 为该张量第一个维度上的大小,然后依次同理向内层。

例如 [ [1,2,3], [4,5,6]] shape (2,3) [ [ [1,2,3], [4,5,6] ] ] shape (1,2,3)

tf.slice

该函数在 tensorflow 官方网站tf.slice有详细的介绍,但是个人感觉不太直观。

直接举例来说:

t = tf.constant([[[1, 1, 1], [2, 2, 2]],
                 [[3, 3, 3], [4, 4, 4]],
                 [[5, 5, 5], [6, 6, 6]]])
#这里t的shape为(3, 2, 3)
#tf.slice:第一个参数为input张量,第二个参数可以理解为坐标,该坐标可以定位到input张量中某一个元素作为起始位置元素,第三个参数可以理解为从起始位置元素开始,取各维度上size个元素,形成新的张量,该张量shape即为第二参数。

tf.slice(t, [1, 0, 0], [1, 1, 3])  # [[[3, 3, 3]]]
#我们看上面这个例子,第二个参数[1, 0, 0],其中t的第一个维度大小为3,
#t[0, :, :] = [[1, 1, 1], [2, 2, 2]]
#t[1, :, :] = [[3, 3, 3], [4, 4, 4]]
#t[2, :, :] = [[5, 5, 5], [6, 6, 6]]
那么t[1, 0, :] = [[3, 3, 3]]; t[1, 0, 0] = 3
那么起始位置元素为3,再看第二个参数[1, 1, 3],首先看第一个维度为1,即在维度1方向上选取大小为1的元素(注意是以3为起始位置,并且这里指的元素不是指一个数字,而是以维度为单位,第一个维度大小为3),这时可以确定选定的为[[3, 3, 3], [4, 4, 4]],然后第二个维度上选取的大小也为1(第二个维度大小为2,只选取以3为起始位置的第一个),可以在细的得出选定的为[[3, 3, 3]],再看第三个维度上选取的大小为3,则就是[[3, 3, 3]]]

以下同理
tf.slice(t, [1, 0, 0], [1, 2, 3])  # [[[3, 3, 3],
                                   #   [4, 4, 4]]]
tf.slice(t, [1, 0, 0], [2, 1, 3])  # [[[3, 3, 3]],
                                   #  [[5, 5, 5]]]

tf.tile

tensorflow 官网 API tf.title

tile(
    input,#任意维度的tensor
    multiples,#一维的张量,其长度必须和input的维度个数相等
    name=None
)

很简单的一个函数,就是将input重复multiples次
举例来说:
a = tf.constant([[1, 2, 3,], [4, 5, 6]])#shape为(2, 3)
b = tf.constant([2, 3])# 表示在第一个维度上重复2次,在第二个维度上重复3次
执行tf.tile(a, b)后
其结果如下:
[[1 2 3 1 2 3 1 2 3]
 [4 5 6 4 5 6 4 5 6]
 [1 2 3 1 2 3 1 2 3]
 [4 5 6 4 5 6 4 5 6]]

同理以下例子:
a = tf.constant([[1, 2, 3,], [4, 5, 6]])#shape为(2, 3)
b = tf.constant([2, 2])
执行tf.tile(a, b)后,结果如下:
[[1 2 3 1 2 3]
 [4 5 6 4 5 6]
 [1 2 3 1 2 3]
 [4 5 6 4 5 6]]

sess.run与eval区别

这是一个很简单的问题

If you have a Tensor t, calling t.eval() is equivalent to calling tf.get_default_session().run(t).

The most important difference is that you can use sess.run() to fetch the values of many tensors in the same step:

t = tf.constant(42.0)
u = tf.constant(37.0)
tu = tf.mul(t, u)
ut = tf.mul(u, t)
with sess.as_default():
   tu.eval()  # runs one step
   ut.eval()  # runs one step
   sess.run([tu, ut])  # evaluates both tensors in a single step

tf.Variable与tf.get_variable()区别

使用 tf.Variable 时,如果检测到命名冲突,系统会自己处理。使用 tf.get_variable() 时,系统不会处理冲突,而会报错。

由此需要共享变量的时候,需要使用 tf.get_variable() 。在不同的 variable_scope 中,可以定义相同的变量,会自动在变量前面加上不同 variable_scope name 加以区别,推荐使用 tf.get_variable

sparse_softmax_cross_entropy_with_logits 与 softmax_cross_entropy_with_logits 区别

The difference is simple:

 1. For sparse_softmax_cross_entropy_with_logits, labels must have the shape [batch_size] and the dtype int32 or int64. Each label is an int in range [0, num_classes-1].
 2. For softmax_cross_entropy_with_logits, labels must have the shape [batch_size, num_classes] and dtype float32 or float64.

Labels used in softmax_cross_entropy_with_logits are the one hot version of labels used in sparse_softmax_cross_entropy_with_logits.

Another tiny difference is that with sparse_softmax_cross_entropy_with_logits, you can give -1 as a label to have loss 0 on this label.

tf.train.exponential_decay

tf.train.exponential_decay(
    learning_rate,
    global_step,
    decay_steps,
    decay_rate,
    staircase=False,
    name=None
)

当我们训练模型时,我们希望随着训练步数的增加,学习率会越来越小,通俗的说,就是希望训练开始快点到最优点附近,然后再慢慢的渐近最优点,防止由于学习率过高一下越过了最优点。恩,就这么简单。

这个方法的计算公式:
decayed_learning_rate = learning_rate *
                        decay_rate ^ (global_step / decay_steps)

tf.add_to_collection,tf.get_collection和tf.add_n的用法

tf.add_to_collection:把变量放入一个集合,把很多变量变成一个列表

tf.get_collection:从一个结合中取出全部变量,是一个列表

扫描二维码关注公众号,回复: 192433 查看本文章

tf.add_n:把一个列表的东西都依次加起来

tf.sparse_tensor_dense

将多维的 SparseTensor 转换成 denseTensor

tf.sparse_tensor_to_dense(
    sp_input,## sparseTensor
    default_value=0,
    validate_indices=True,
    name=None
)

直接看例子:

import tensorflow as tf


sparseTensor = tf.SparseTensor(indices=[[0, 0], [1, 2]], values=[1, 2], dense_shape=[3, 4]) 
denseTensor = tf.sparse_tensor_to_dense(sparseTensor, 0)

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


输出:
[[1 0 0 0]
 [0 0 2 0]
 [0 0 0 0]]

tf.sparse_to_dense

这个方法就比较厉害了,在自然语言处理里面可以用来快速的生成 mask 矩阵。

tf.sparse_to_dense(
    sparse_indices,## 这个可以类似是sparseTensor里面的indices,也就是非零元素的位置索引。
    output_shape,
    sparse_values,
    default_value=0,
    validate_indices=True,
    name=None
)

直接举例来说:

import tensorflow as tf
import numpy as np
batch_size = 10


Y = tf.placeholder("int32", [None, 1]) 
# 如果你的batch_size不是已知的,也可以用batch_size = tf.shape(Y)[0]来获得
reshape = tf.reshape(tf.range(0,batch_size,1),[batch_size,1])

tmp = tf.concat([reshape, Y], axis=1)
onehotY = tf.sparse_to_dense(tf.concat([reshape,Y],axis=1),[batch_size,10],1.0,0.0)

with tf.Session() as sess:
    y = np.arange(10).reshape((10,1))
    print sess.run(reshape)
    print sess.run(tf.concat([reshape, Y], axis=1), feed_dict={Y: y}) 
    print (sess.run(onehotY, feed_dict={Y: y}))

输出:
[[0]
 [1]
 [2]
 [3]
 [4]
 [5]
 [6]
 [7]
 [8]
 [9]]
[[0 0]##生成稀疏矩阵的非零元素的索引
 [1 1]
 [2 2]
 [3 3]
 [4 4]
 [5 5]
 [6 6]
 [7 7]
 [8 8]
 [9 9]]
[[1. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 1. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 1. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 1. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 1. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 1. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 1. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 1. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 0. 1. 0.]
 [0. 0. 0. 0. 0. 0. 0. 0. 0. 1.]]

这个方法可以很有效率的生成 onehot 矩阵。需要强调下 sparse_indices 参数:

  • 一个值
  • 一个一维向量
    这两种情况下,返回值是一个一维向量, output_shape 也只能是一个长度为1的 list ,其唯一元素值代表返回的一维向量的长度,对应 sparse_indices 中每个整型值,返回的向量中每个值都被置为 sparse_values ,其他值为 default_value

  • 一个二维矩阵,而且每行两列
    这种情况下,返回值是二维矩阵, output_shape 是一个长度为2的 list ,代表了矩阵的 shape 。对 sparse_indices 的每一行元素 [i,j] ,返回的二维矩阵 K Kij 被设为 sparse_values

tf.unsorted_segment_sum

这个方法比较厉害

unsorted_segment_sum(
    data,
    segment_ids,
    num_segments,##output的长度
    name=None
)

这里写图片描述

在一些自然语言处理的任务中(例如完形填空,需要得到某个词),模型最后得出词序列的概率分布,这个概率分布就是上图中的 data ,而对应的词 id 为上图中的 segment_ids ,那么对应 id 为0的词概率为 5+1+3=9

后续继续更新

猜你喜欢

转载自blog.csdn.net/mr_tyting/article/details/80148019