def __init__ (self, is_training, config, input_)

1   def __init__(self, is_training, config, input_):
2  
3  
4 
5 
6      self._is_training = is_training
7      self._input = input_
8      self._rnn_params = None
9      self._cell = None
10     self.batch_size = input_.batch_size
11     self.num_steps = input_.num_steps
12     size = config.hidden_size
13     vocab_size = config.vocab_size
14
15     with tf.device("/cpu:0"):
16         embedding = tf.get_variable("embedding", [vocab_size, size], dtype=data_type())
17         inputs = tf.nn.embedding_lookup(embedding, input_.input_data)
18
19     if is_training and config.keep_prob < 1:
20         inputs = tf.nn.dropout(inputs, config.keep_prob)
21
22     output, state = self._build_rnn_graph(inputs, config, is_training)
23
24     softmax_w = tf.get_variable("softmax_w", [size, vocab_size], dtype=data_type())
25     softmax_b = tf.get_variable("softmax_b", [vocab_size], dtype=data_type())
26     logits = tf.nn.xw_plus_b(output, softmax_w, softmax_b)
27     # Reshape logits to be a 3-D tensor for sequence loss
28     logits = tf.reshape(logits, [self.batch_size, self.num_steps, vocab_size])
29
30     # Use the contrib sequence loss and average over the batches
31     loss = tf.contrib.seq2seq.sequence_loss(
32         logits,
33         input_.targets,
34         tf.ones([self.batch_size, self.num_steps], dtype=data_type()),
35         average_across_timesteps=False,
36         average_across_batch=True
37     )
38
39     # Update the cost
40     self._cost = tf.reduce_sum(loss)
41     self._final_state = state
42
43     if not is_training:
44         return
45
46     self._lr = tf.Variable(0.0, trainable=False)
47     tvars = tf.trainable_variables()
48     grads, _ = tf.clip_by_global_norm(tf.gradients(self._cost, tvars), config.max_grad_norm)
49     optimizer = tf.train.GradientDescentOptimizer(self._lr)
50     self._train_op = optimizer.apply_gradients(
51         zip(grads, tvars),
52         global_step=tf.train.get_or_create_global_step()
53     )
54
55     self._new_lr = tf.placeholder(tf.float32, shape=[], name="new_learning_rate")
56     self._lr_update = tf.assign(self._lr, self._new_lr)
  • 第15行 with tf.device("/cpu:0") 表示切換為 CPU 運算,"/cpu:0" 的 "0" 表示設備號,直接設為 0 即可

表示第 16, 17 行的 embedding 與 inputs 變數將存在主機的記憶體中而不是顯示卡記憶體。

參考 [0] tf.device() 指定運行設備、[1] TensorFlow using GPUs

  • 第16行 embedding = tf.get_variable( "embedding", [vocab_size, size], dtype=data_type())

tf.get_variable(name, shape, initializer): name是變數的名稱,shape是變數的維度,initializer是變數初始化的方式

故 "embedding" 是變數名稱;[vocab_size, size] 是變數 embedding 的維度,表示 embedding 二維矩陣,矩陣 size = vocab_size (列) x size (行);初始化 embedding 的方式為 data_type () 函數

參考 [2] tf.get_variable 函數的使用

  • 第17行 inputs = tf.nn.embedding_lookup(embedding, input_.input_data)

tf.nn.embedding_lookup 函數的用法主要是擷取一個 Tensor 裡面索引對應的元素。

tf.nn.embedding_lookup(embedding, input_.input_data)embedding 就是 tensor,input_.input_data 就是 embedding 對應的索引

參考 [3] tf.nn.embedding_lookup()

第19, 20 行:

  • if is_training and config.keep_prob < 1:
        inputs = tf.nn.dropout(inputs, config.keep_prob)
    

is_training 表示要訓練 model;config.keep_prob < 1 表示 keep_prob 是一個合理的機率值 (0~1之間),

inputs 使用 tf.nn.dropout 函數避免 overfitting。用法是以 "keep_prob" 的機率值隨機 deactivate 部分 inputs 中的資料

參考 [4] tf.nn.dropout()

  • 第22行 output, state = self._build_rnn_graph(inputs, config, is_training)

呼叫 _build_rnn_graph() 函數,並傳入參數 inputs, config, is_training,將結果回傳給 output, state 變數中儲存。

第24, 25行

  • softmax_w = tf.get_variable("softmax_w", [size, vocab_size], dtype=data_type())
    softmax_b = tf.get_variable("softmax_b", [vocab_size], dtype=data_type())
    

softmax_w & softmax_b 是變數名稱;

softmax_w 是二維資料,大小為 size x vocab_size,以 data_type() 初始化;

softmax_b 是一維資料,大小為 vocab_size,以 data_type() 初始化

  • 第26行 logits = tf.nn.xw_plus_b(output, softmax_w, softmax_b)

logits = output 乘以 softmax_w 加上 softmax_b;logits, output and softmax_w 為 2-D tensor 資料;softmax_b 為 1-D tensor 資料

參考 [5] tf.nn.xw_plus_b()

第27, 28行

  • # Reshape logits to be a 3-D tensor for sequence loss
    logits = tf.reshape(logits, [self.batch_size, self.num_steps, vocab_size])
    

tf.reshape (tensor, shape, name=None) 表示將 "tensor" 改為 "shape" 的維度;

故 logits 改為維度 [self.batch_size, self.num_steps, vocab_size] (三維 self.batch_size x self.num_steps x vocab_size)

第30~37行

  • # Use the contrib sequence loss and average over the batches
    loss = tf.contrib.seq2seq.sequence_loss(
        logits,
        input_.targets,
        tf.ones([self.batch_size, self.num_steps], dtype=data_type()),
        average_across_timesteps=False,
        average_across_batch=True
    )
    

(計算 loss 略)

第39~41行

  • # Update the cost
    self._cost = tf.reduce_sum(loss)
    self._final_state = state
    

( 更新 cost 與 final state 略 )

第43, 44行

  • if not is_training:
        return
    

如果不是要訓練資料,則直接略過之後的程式碼,直接 return

  • 第46行 self._lr = tf.Variable(0.0, trainable=False)

指定 self._lr 變數的值為 0.0,且在 training model 的過程中,此值不可被改變

lr 是 learning rate 的縮寫。

變數在計算過程中是可變的,並且在訓練過程中會自動更新或優化。

如果不允許變數被 tensorflow 更動,只能在 tensorflow 以外,以手動的方式更新,需要以 trainable=False 聲明變數是不可訓練的。

  • 第47行 tvars = tf.trainable_variables()

tvars 變數中儲存的是所有設定為 trainable=True 的變數;

tf.trainable_variables(scope=None) returns all variables created with trainable=True [6] tf.trainable_variables()

目前大概查到 tf.trainable_variables() 是為了處理gradient explosion或者gradients vanishing的問題。當在一次迭代中權重的更新過於迅猛的話,很容易導致loss divergence。

  • grads, _ = tf.clip_by_global_norm(tf.gradients(self._cost, tvars), config.max_grad_norm)
    

參考 [7] tf.clip_by_global_norm CSDN [8] tf.clip_by_global_norm Tensorflow

  • optimizer = tf.train.GradientDescentOptimizer(self._lr)
    

optimizer 是一個 GradientDescentOptimizer 的物件,產生 GradientDescentOptimizer 物件時需要 self._lr (learning rate) 參數

參考 [9] tf.train.GradientDescentOptimizer()

  • self._train_op = optimizer.apply_gradients(
        zip(grads, tvars),
        global_step=tf.train.get_or_create_global_step()
    )
    

由於 apply_gradients () 不知道如何解釋,在附件中將 source code 貼上

  • self._new_lr = tf.placeholder(tf.float32, shape=[], name="new_learning_rate")
    
  • self._lr_update = tf.assign(self._lr, self._new_lr)
    

Reference

[0] tf.device() 指定運行設備

[1] TensorFlow using GPUs

[2] tf.get_variable 函數的使用

[3] tf.nn.embedding_lookup()

[4] tf.nn.dropout()

[5] tf.nn.xw_plus_b()

[6] tf.trainable_variables()

[7] tf.clip_by_global_norm CSDN

[8] tf.clip_by_global_norm Tensorflow

[9] tf.train.GradientDescentOptimizer()

results matching ""

    No results matching ""