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)