0

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)
Amir Charkhi
  • 768
  • 7
  • 23
Vinay
  • 33
  • 5

1 Answers1

0

Timedistributed is not applicable for Conv1D.

Timedistributed is basically used when you have 2D data having timesteps(ex: LSTM or any other recurrent form).