in ludwig/features/base_feature.py [0:0]
def concat_dependencies(self, hidden, other_features_hidden):
if len(self.dependencies) > 0:
dependencies_hidden = []
for dependency in self.dependencies:
# the dependent feature is ensured to be present in final_hidden
# because we did the topological sort of the features before
dependency_final_hidden = other_features_hidden[dependency]
if len(hidden.shape) > 2:
if len(dependency_final_hidden.shape) > 2:
# matrix matrix -> concat
assert hidden.shape[1] == \
dependency_final_hidden.shape[1]
dependencies_hidden.append(dependency_final_hidden)
else:
# matrix vector -> tile concat
sequence_max_length = hidden.shape[1]
multipliers = tf.concat(
[[1], [sequence_max_length], [1]],
0
)
tiled_representation = tf.tile(
tf.expand_dims(dependency_final_hidden, 1),
multipliers
)
# todo future: maybe modify this with TF2 mask mechanics
sequence_length = sequence_length_3D(hidden)
mask = tf.sequence_mask(
sequence_length,
sequence_max_length
)
tiled_representation = tf.multiply(
tiled_representation,
tf.cast(mask[:, :, tf.newaxis], dtype=tf.float32)
)
dependencies_hidden.append(tiled_representation)
else:
if len(dependency_final_hidden.shape) > 2:
# vector matrix -> reduce concat
reducer = self.dependency_reducers[dependency]
dependencies_hidden.append(
reducer(dependency_final_hidden)
)
else:
# vector vector -> concat
dependencies_hidden.append(dependency_final_hidden)
try:
hidden = tf.concat([hidden] + dependencies_hidden, -1)
except:
raise ValueError(
'Shape mismatch while concatenating dependent features of '
'{}: {}. Concatenating the feature activations tensor {} '
'with activation tensors of dependencies: {}. The error is '
'likely due to a mismatch of the second dimension (sequence'
' length) or a difference in ranks. Likely solutions are '
'setting the maximum_sequence_length of all sequential '
'features to be the same, or reduce the output of some '
'features, or disabling the bucketing setting '
'bucketing_field to None / null, as activating it will '
'reduce the length of the field the bucketing is performed '
'on.'.format(
self.feature_name,
self.dependencies,
hidden,
dependencies_hidden
)
)
return hidden