I could not understand the difference between TimeDistributed(Conv1D)
and Conv1D
in TensorFlow Keras. In this example, it is given that TimeDistrbuted(Dense)
and Dense
are equivalent as it applies to the last dimension. I can see the same outputs for TimeDistributed(Conv1D)
and Conv1D
except for shape (as in code below). Is it applicable for Conv1D
also?
a, b, c = 2, 3, 2
# inputs = np.random.random([a, b, c]).astype(np.float32)
inputs = np.arange(a*b*c).reshape(a, b, c)
input_shape = np.shape(inputs)
print(f'Input :{inputs.tolist()}')
def init_cnn_weights(model, layer):
wt = model.layers[layer].get_weights()
wt[0] = 2*np.ones(wt[0].shape)
wt[1] = np.zeros_like(wt[1])
model.layers[layer].set_weights(wt)
def get_model1_and_output(nf, nk):
inp = tf.keras.Input(shape=(a, b, c))
curr_layer = tf.keras.layers.TimeDistributed(tf.keras.layers.Conv1D(nf,nk))(inp)
model = tf.keras.models.Model(inputs=inp, outputs=curr_layer)
init_cnn_weights(model, 1)
# print(model.summary())
output = model.predict(np.expand_dims(inputs, axis=0))
return model, output
def get_model2_and_output(nf, nk):
inp = tf.keras.Input(shape=(b, c))
curr_layer = tf.keras.layers.Conv1D(nf,nk)(inp)
model = tf.keras.models.Model(inputs=inp, outputs=curr_layer)
init_cnn_weights(model, 1)
# print(model.summary())
output = model.predict(inputs)
# output = model.predict(np.concatenate((inputs, inputs), axis=0))
return model, output
nf = 2
nk = 2
model1, output1 = get_model1_and_output(nf, nk)
print(f'With TD: Output :{output1.tolist()}')
model2, output2 = get_model2_and_output(nf, nk)
print(f'Without TD: Output :{output2.tolist()}')
print(f'With TD: weights,bias :{model1.get_weights()}')
print(f'Without TD: weights,bias:{model2.get_weights()}')
print(f'With TD: Output.shape :{output1.shape}')
print(f'Without TD: Output.shape:{output2.shape}')
print(f'With TD: param shape :{model1.get_weights()[0].shape}')
print(f'Without TD: param shape :{model2.get_weights()[0].shape}')
Output:
Input :[[[0, 1], [2, 3], [4, 5]], [[6, 7], [8, 9],
[10, 11]]]
With TD: Output :[[[[12.0, 12.0], [28.0, 28.0]], [[60.0, 60.0], [76.0, 76.0]]]]
Without TD: Output :[[[12.0, 12.0], [28.0, 28.0]], [[60.0, 60.0], [76.0, 76.0]]]
With TD: weights,bias :[array([[[2., 2.],
[2., 2.]],
[[2., 2.],
[2., 2.]]], dtype=float32), array([0., 0.], dtype=float32)]
Without TD: weights,bias:[array([[[2., 2.],
[2., 2.]],
[[2., 2.],
[2., 2.]]], dtype=float32), array([0., 0.], dtype=float32)]
With TD: Output.shape :(1, 2, 2, 2)
Without TD: Output.shape:(2, 2, 2)
With TD: param shape :(2, 2, 2)
Without TD: param shape :(2, 2, 2)