Как мне получить сетевые активации всех устройств на всех уровнях сети во всех временных интервалах?

#tensorflow #keras #neural-network #recurrent-neural-network

Вопрос:

Я хотел бы изучить деятельность всех подразделений во всех слоях рекуррентной нейронной сети в течение многих временных периодов.

В приведенном ниже коде я создал модель Keras со SimpleRNN слоем и Dense слоем.

Если я использую параметр return_sequences=True при инициализации RNN, я могу получить действия RNN , если я это сделаю rnn(inputs) , для любого подходящего inputs массива. И я также могу получить информацию о действиях единицы вывода с течением времени, выполнив model(inputs) это .

Но если я хочу и то, и другое, то делаю и rnn(inputs) то, и другое и model(inputs) выполняю вычисления дважды. Есть ли способ избежать выполнения вычислений дважды, имея доступ к действиям всех подразделений с течением времени? Спасибо!

 SEED=42
tf.random.set_seed(SEED)
np.random.seed(SEED)

timesteps = 3
embedding_dim = 4
units = 2
num_samples = 5

input_shape = (num_samples, timesteps, embedding_dim)
model = Sequential([
    SimpleRNN(units, stateful=True, batch_input_shape=input_shape, return_sequences=True, activation="linear", 
              recurrent_initializer="identity", bias_initializer="ones"), 
    Dense(1)])

some_initial_state = np.ones((num_samples, units))
some_initial_state[0,0] = 0.123
rnn = model.layers[0]
rnn.reset_states(states=some_initial_state)


some_initial_state, rnn(np.zeros((num_samples, timesteps, embedding_dim))), model(np.zeros((num_samples, timesteps, embedding_dim)))
 

Со следующим выводом:

 (array([[0.123, 1.   ],
    [1.   , 1.   ],
    [1.   , 1.   ],
    [1.   , 1.   ],
    [1.   , 1.   ]]),
<tf.Tensor: shape=(5, 3, 2), dtype=float32, numpy=
array([[[1.123    , 2.       ],
     [2.1230001, 3.       ],
     [3.1230001, 4.       ]],

    [[2.       , 2.       ],
     [3.       , 3.       ],
     [4.       , 4.       ]],

    [[2.       , 2.       ],
     [3.       , 3.       ],
     [4.       , 4.       ]],

    [[2.       , 2.       ],
     [3.       , 3.       ],
     [4.       , 4.       ]],

    [[2.       , 2.       ],
     [3.       , 3.       ],
     [4.       , 4.       ]]], dtype=float32)>,
<tf.Tensor: shape=(5, 3, 1), dtype=float32, numpy=
array([[[1.971611 ],
     [2.4591472],
     [2.9466834]],

    [[2.437681 ],
     [2.9252172],
     [3.4127533]],

    [[2.437681 ],
     [2.9252172],
     [3.4127533]],

    [[2.437681 ],
     [2.9252172],
     [3.4127533]],

    [[2.437681 ],
     [2.9252172],
     [3.4127533]]], dtype=float32)>)
 

Ответ №1:

Вам понадобится модель с несколькими выходами, использующая функциональный API, которая будет выглядеть следующим образом:

 SEED=42
tf.random.set_seed(SEED)
np.random.seed(SEED)

timesteps = 3
embedding_dim = 4
units = 2
num_samples = 5

inputs = Input(batch_shape=(num_samples, timesteps, embedding_dim))
# initial state as Keras Input
initial_state = Input((units,))
rnn = SimpleRNN(units, stateful=True, return_sequences=True, activation="linear", 
                recurrent_initializer="identity", bias_initializer="ones")
hidden = rnn(inputs, initial_state=initial_state)
dense = Dense(1)(hidden)

# The initial state is a extra input and the model has two outputs
model = Model([inputs, initial_state], outputs=[hidden, dense])

some_input = np.zeros((num_samples, timesteps, embedding_dim))
some_initial_state = np.ones((num_samples, units))
some_initial_state[0,0] = 0.123
rnn_output, dense_output = model([some_input, some_initial_state])

some_initial_state, rnn_output, dense_output
 

Обратите внимание, что вам не нужно использовать RNN с отслеживанием состояния для установки начальных состояний с помощью функционального API. Кроме того, дважды выполнив прямой проход в вашем примере, второй вывод будет соответствовать другому состоянию RNN (что, я считаю, не является желаемым результатом).