Разбор tf.nn.rnn_cell.GRUCell в тензорном потоке C ++ и понимание того, какие операции выполняются внутри GRUCell? - PullRequest
0 голосов
/ 26 октября 2018

Я создал образец сценария, в котором я создал GRUCells для прямого и обратного направления и передал его в слой bidirectional_rnn.

import tensorflow as tf
import numpy as np
from tensorflow.python.framework import graph_util
import os

X_batch = np.array([
                    [[0., 1., 2.], [8., 2., 1.], [9., 8., 7.]],
                    [[3., 4., 5.], [9., 7., 4.], [0., 0., 0.]],
                    [[6., 7., 8.], [3., 6., 7.], [6., 5., 4.]],
                    [[9., 0., 1.], [0., 0., 0.], [0., 0., 0.]]
                   ])

batch = 4
n_steps = 3
input_size = 3
inputs = tf.placeholder(tf.float32, [batch, n_steps, input_size])

def biGRU(inputs, n_hidden, batch_size):
    gru_fw = tf.nn.rnn_cell.GRUCell(n_hidden)
    gru_bw = tf.nn.rnn_cell.GRUCell(n_hidden)
    output, _states = tf.nn.bidirectional_dynamic_rnn(gru_fw, gru_bw, inputs, dtype=tf.float32)
    final_outputs = tf.concat([output[0], output[1]], 2)
    return final_outputs

biGRU_model = biGRU(inputs, 4, batch)

with tf.Session() as sess:
    tb_dir = 'test_tensorboard/'
    if not os.path.exists(tb_dir):
      os.makedirs(tb_dir)
    check_write = tf.summary.FileWriter(tb_dir, sess.graph)
    init = tf.global_variables_initializer()
    init.run()
    sess.run(biGRU_model, feed_dict={inputs: X_batch})
    variables_names =[v.name for v in tf.trainable_variables()]
    values = sess.run(variables_names)
    for k,v in zip(variables_names, values):
        print(k, v)

    output_node_name = "concat"
    # remove training nodes
    removed_train_graph_def = graph_util.remove_training_nodes(sess.graph_def, protected_nodes=None)
    # convert variable nodes to const nodes
    const_graph_def = graph_util.convert_variables_to_constants(sess, removed_train_graph_def, output_node_name.split(","))
    gd_dir = 'test_graphdef/'
    if not os.path.exists(gd_dir):
      os.makedirs(gd_dir)
    tf.train.write_graph(const_graph_def, gd_dir, 'test_gru.pbtxt', as_text=True) 
    tf.train.write_graph(const_graph_def, gd_dir, 'test_gru.pb', as_text=False)

Этот скрипт будет печатать обучаемые переменные и журналы дампов в папку test_tensorboard для просмотра в тензорной панели, а также выгружать файлы pb и pbtxt в папку test_graphdef. Пожалуйста, просмотрите изображение gru_cells_in_fw_bw.png где вы можете увидеть grucells и посмотреть kernal_bias_in_grucell.png , где вы можете увидеть ядро ​​и смещение. Пример сценария напечатает веса и смещения, которые находятся внутри этой ячейки gru.

Моя цель - проанализировать tf.nn.rnn_cell.GRUCell и получить все параметры для него. Здесь могут быть параметры ядра и смещения, а также другие параметры. Вы можете увидеть другие параметры кроме ядра и смещения здесь https://www.tensorflow.org/api_docs/python/tf/nn/rnn_cell/GRUCell

Когда я анализировал 'test_gru.pb' в c ++, я не получил op: "GRUCell" как один опнод. Например, если мы создадим tf.nn.conv2d в модели, мы получим op: «Conv2D» как один OpNode, поэтому мне будет легко получить параметры.

Итак, наконец, мой вопрос: каковы операции внутри GRUCell? Другими словами, если я посмотрю на test_gru.pb в Netron , я смогу увидеть множество опно-узлов, которые выполняют операцию GRUCell, так как я могу определить, какие из них устанавливают опно-узлы?

Заранее спасибо !!

...