tensorflow杂项

杂项,后期整理

1.tf.sampled_softmax_loss

此函数和tf.nn.nce_loss是差不多的, 取样求loss

def sampled_softmax_loss(
                          weights, #[num_classes, dim]
                         biases,  #[num_classes]
                         inputs,  #[batch_size, dim]
                         labels,  #[batch_size, num_true]
                         num_sampled,
                         num_classes,
                         num_true=1,
                         sampled_values=None,
                         remove_accidental_hits=True,
                         partition_strategy="mod",
                         name="sampled_softmax_loss")

关于参数labels:一般情况下,num_true为1, labels的shpae为[batch_size, 1]。假设我们有1000个类别, 使用one_hot形式的label的话, 我们的labels的shape是[batch_size, num_classes]。显然,如果num_classes非常大的话,会影响计算性能。所以,这里采用了一个稀疏的方式,即:使用3代表了[0,0,0,1,0….]

2.tf.contrib.layers.embed_sequence

tf.contrib.layers.embed_sequenceembed_sequence(
    ids,
    vocab_size=None,
    embed_dim=None,
    unique=False,
    initializer=None,
    regularizer=None,
    trainable=True,
    scope=None,
    reuse=None
)

一般用于seq2seq网络,可以完成对输入序列数据的嵌入工作。一般只需关注前三个参数即可。
ids:形状为[batch_size, seq_length],也就是输入数据
vocab_size:输入数据为字典的长度
embed_dim:想要的嵌入矩阵的维度

3.tf.contrib.layers.embed_sequence

tf.stride_slice(data, begin, end)
tf.slice(data, begin, end)
tf.stride_slice的end是开区间,tf.slice的end是闭区间。
一般有一个常用的小技巧是tf.stride_slice(data, [0, 0], [rows, -1]),可以截掉最后一列,很实用。

import tensorflow as tf
data = [[[1, 1, 1], [2, 2, 2]],
            [[3, 3, 3], [4, 4, 4]],
            [[5, 5, 5], [6, 6, 6]]]
x = tf.strided_slice(data,[0,0,0],[1,1,1])
with tf.Session() as sess:
    print(sess.run(x))
#就是第0行到第一行,然后弄完[[[1, 1, 1], [2, 2, 2]]],再第0行到第一行,弄完
#[[[1, 1, 1]]],再到第0列到第一列,弄完[[[1]]]

4.tf.contrib.seq2seq.TrainingHelper

A helper for use during training. Only reads inputs.
Returned sample_ids are the argmax of the RNN output logits.

helper = tf.contrib.seq2seq.TrainingHelper(
    input=input_vectors,
    sequence_length=input_lengths)

5.tf.contrib.seq2seq.BasicDecoder

用于构造一个decoder

decoder = tf.contrib.seq2seq.BasicDecoder(
    cell=cell,
    helper=helper,
    initial_state=cell.zero_state(batch_size, tf.float32))

6.tf.contrib.seq2seq.dynamic_decode

用于构造一个动态decoder,返回的内容是:就是3个返回值
(final_outputs, final_state, final_sequence_lengths),final_outputs是一个元祖,包含两项(rnn_outputs, sample_id),他们的说明如下:
rnn_output:[batch_size, decoder_targets_length, vocab_size],保存是decoder中每个时间步的输出,很容易理解。
sample_id:[batch_size],保存最终的编码结果,可以表示最后的答案

#新版本的tensorflow是3个返回值,注意了
outputs, _ , _= tf.contrib.seq2seq.dynamic_decode(
   decoder=decoder,
   output_time_major=False,
   impute_finished=True,
   maximum_iterations=20)

7.tf.tile

通过复制input的multiples时间来创建新的张量。输出的张量的第i维是input[i] * multiples[i] ,通俗点就是沿着“i”维度input值被复制了multiples[i]次。比如:

a = tf.constant([[1, 2],[2, 3],[3, 4]], dtype=tf.float32)
tile_a_1 = tf.tile(a, [3,1])

with tf.Session() as sess:
    print(sess.run(tile_a_1))
#结果是:
[[1. 2.]
 [2. 3.]
 [3. 4.]
 [1. 2.]
 [2. 3.]
 [3. 4.]
 [1. 2.]
 [2. 3.]
 [3. 4.]]

8.tf.contrib.seq2seq.GreedyEmbeddingHelper

这是用于seq2seq中帮助建立Decoder的一个类,在预测时使用,示例代码如下:

helper = tf.contrib.seq2seq.GreedyEmbeddingHelper(
      embedding=embedding,
      #可以结合7,知道为啥tf.tile要batch_size了吧
      start_tokens=tf.tile([GO_SYMBOL], [batch_size]),
      end_token=END_SYMBOL)

9.tf.sequence_mask

函数原型

sequence_mask(
    lengths,
    maxlen=None, #maxlen:标量整数张量,返回张量的最后维度的大小;默认值是lengths中的最大值。
    dtype=tf.bool,
    name=None
)

返回一个表示每个单元的前N个位置的mask张量。如果lengths的形状为[d_1, d_2, ..., d_n],由此产生的张量mask有dtype类型和形状[d_1, d_2, ..., d_n, maxlen],并且:mask[i_1, i_2, ..., i_n, j] = (j < lengths[i_1, i_2, ..., i_n])
例如:

tf.sequence_mask([1, 3, 2], 5)  # [[True, False, False, False, False],
                                #  [True, True, True, False, False],
                                #  [True, True, False, False, False]]

tf.sequence_mask([[1, 3],[2,0]])  # [[[True, False, False],
                                  #   [True, True, True]],
                                  #  [[True, True, False],
                                  #   [False, False, False]]]
#这个就是最大长度是3,所以3列

10.tf.contrib.seq2seq.sequence_loss

sequence_loss(
    logits,
    targets,
    weights,
    average_across_timesteps=True,
    average_across_batch=True,
    softmax_loss_function=None,
    name=None
)

用于计算seq2seq中的loss。当我们的输入是不定长的时候,weights参数常常使用我们tf.sequence_mask()中得到的mask。

11.tf.train.AdamOptimizer

训练需要优化器,这边主要不是讲优化器(真脑残,为啥一个函数分成两个来写)。其实可以用tf.train.Optimizer.minimize(),这个函数用于最小化loss,并更新var_list。这个函数可以拆分成两个函数实现同样的功能:

#该函数对var_list中的变量计算loss的梯度,为minimize()的第一部分,返回一个以#元祖(gradient, variavle)组成的列表
tf.train.Optimizer.compute_gradients(
    loss,var_list=None, gate_gradients=1,
    aggregation_method=None,
    colocate_gradients_with_ops=False, grad_loss=None)


#该函数将计算出的梯度应用到变量上,是函数minimize()的第二部分,返回一个应#用指定梯度的操作,对global_step做自增操作。
tf.train.Optimizer.apply_gradients(
    grads_and_vars, global_step=None, name=None
) 

#上述两个函数组合起来就能对loss进行优化
上一篇:《妥协的完美主义:优秀产品经理的实践指南(卷二)》一2.2 项目管理方法


下一篇:链表删除重复节点