My model consists of an Embedding layer and a SimpleRNN layer. I have obtained the hidden states at all steps with model.predict
, and plotted them against the steps. I find that the hidden states converge to zero but I am not sure if I can infer anything from that. Therefore plotting their gradients with respect to the model inputs might provide me some further insights. I would like some help with obtaining these gradients.
My model:
batch_size = 9600 # batch size can take a smaller value, e.g. 100
inp= Input(batch_shape= (batch_size, input_length), name= 'input')
emb_out= Embedding(input_dim, output_dim, input_length= input_length,
weights= [Emat], trainable= False, name= 'embedding')(inp)
rnn= SimpleRNN(200, return_sequences= True, return_state= False, stateful= True,
batch_size= (batch_size, input_length, 100), name= 'simpleRNN')
h0 = tf.random.uniform((batch_size, 200))
rnn_allstates = rnn(emb_out, initial_state=h0)
print(rnn_allstates.shape) # (9600, 1403, 200)
model_rnn = Model(inputs=inp, outputs= rnn_allstates, name= 'model_rnn')
model_rnn.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['acc'])
model_rnn.summary()
>>>
Layer (type) Output Shape Param #
=================================================================
input (InputLayer) [(9600, 1403)] 0
_________________________________________________________________
embedding (Embedding) (9600, 1403, 100) 4348900
_________________________________________________________________
simpleRNN (SimpleRNN) (9600, 1403, 200) 60200
=================================================================
Obtaining the hidden states:
rnn_ht = model_rnn.predict(xtr_pad) # xtr_pad.shape = (9600,1403)
rnn_ht_red= np.mean(rnn_ht, 2)
rnn_ht_red= np.mean(rnn_ht_red,0)
steps= [t for t in range(1403)]
plt.plot(steps, rnn_ht_red, linestyle= 'dotted')
Attempt to obtain gradients:
sess= k.get_session()
# The hidden states tf.Variable shaped (n_samples = 9600, n_steps = 1403, n_units = 200):
states_var= model_rnn.output
# A list of hidden states variable for all time steps, aggregated over samples and RNN units:
ht_vars= [states_var[:, t, :] for t in range(1403)] # each item in list has shape (9600, 200)
ht_vars_agg= [tf.reduce_mean(ht,[0,1]) for ht in ht_vars] # each item in list has shape (), because I wish to obtain a SINGLE gradient value at each time step.
# Create gradient function and feed data:
dhtdx_vars= [k.gradients(ht, model_rnn.input) for ht in ht_vars_agg]
dhtdx= [sess.run(pd, feed_dict={model_rnn.input: xtr_pad} ) for pd in dhtdx_vars ]
The following error points to the last line above
TypeError: Fetch argument None has invalid type <class 'NoneType'>
Every backend gradient item in dhtdx_vars
is [None]. When I remove the aggregation line the same error still persists.
An attempt with gradient tape also returns None Error in the computed gradient.
with tf.GradientTape() as tape:
x= model_rnn.input
ht = model_rnn(x)
grad = tape.gradient(ht, model_rnn.input)
Thanks in advance for any help.