Je viens de commencer à jouer avec Keras et à créer des couches personnalisées. Cependant, je suis plutôt dérouté par les nombreux types de couches avec des noms légèrement différents mais avec les mêmes fonctionnalités.
Par exemple, il existe 3 formes différentes de la fonction concaténation de https://keras.io/layers/merge/ et https://www.tensorflow.org/api_docs/python/tf/keras/ backend/concatenate
keras.layers.Concatenate(axis=-1)
keras.layers.concatenate(inputs, axis=-1)
tf.keras.backend.concatenate()
Je sais que le second est utilisé pour les API fonctionnelles, mais quelle est la différence entre les 3? La documentation semble un peu incertaine à ce sujet.
Aussi, pour le troisième, j'ai vu un code qui fait cela ci-dessous. Pourquoi doit-il y avoir la ligne ._keras_shape après la concaténation?
# Concatenate the summed atom and bond features
atoms_bonds_features = K.concatenate([atoms, summed_bond_features], axis=-1)
# Compute fingerprint
atoms_bonds_features._keras_shape = (None, max_atoms, num_atom_features + num_bond_features)
Enfin, sous keras.layers, il semble toujours y avoir 2 doublons. Par exemple, Add () et add (), etc.
Premièrement, le backend: tf.keras.backend.concatenate()
Les fonctions de backend sont supposées être utilisées "à l'intérieur" des couches. Vous ne l'utiliseriez que dans des calques Lambda
, des calques personnalisés, des fonctions de perte personnalisées, des métriques personnalisées, etc.
Cela fonctionne directement sur les "tenseurs".
Ce n'est pas le choix si vous n'allez pas trop loin dans la personnalisation. (Et c'était un mauvais choix dans votre exemple de code - Voir les détails à la fin).
Si vous plongez dans le code keras, vous remarquerez que la couche Concatenate
utilise cette fonction en interne:
import keras.backend as K
class Concatenate(_Merge):
#blablabla
def _merge_function(self, inputs):
return K.concatenate(inputs, axis=self.axis)
#blablabla
Ensuite, la Layer
: keras.layers.Concatenate(axis=-1)
Comme toutes les autres couches de keras, vous instanciez et appelez-le sur tensors.
Assez simple:
#in a functional API model:
inputTensor1 = Input(shape) #or some tensor coming out of any other layer
inputTensor2 = Input(shape2) #or some tensor coming out of any other layer
#first parentheses are creating an instance of the layer
#second parentheses are "calling" the layer on the input tensors
outputTensor = keras.layers.Concatenate(axis=someAxis)([inputTensor1, inputTensor2])
Cela ne convient pas aux modèles séquentiels, sauf si la couche précédente génère une liste (cela est possible mais pas commun).
Enfin, la fonction concaténation du module couches: keras.layers.concatenate(inputs, axis=-1)
Ceci est pas une couche. C'est une fonction qui retournera le tenseur produit par une couche Concatenate
interne.
Le code est simple:
def concatenate(inputs, axis=-1, **kwargs):
#blablabla
return Concatenate(axis=axis, **kwargs)(inputs)
Dans Keras 1, les personnes avaient des fonctions destinées à recevoir des "couches" en entrée et à renvoyer une "couche" en sortie. Leurs noms étaient liés au mot merge
.
Mais comme Keras 2 ne les mentionne ni ne les documente, j'éviterais probablement de les utiliser, et si un ancien code est trouvé, je le mettrais probablement à jour avec un code Keras 2 approprié.
_keras_shape
?Cette fonction backend n'était pas censée être utilisée dans les codes de haut niveau. Le codeur aurait dû utiliser une couche Concatenate
.
atoms_bonds_features = Concatenate(axis=-1)([atoms, summed_bond_features])
#just this line is perfect
Les couches Keras ajoutent la propriété _keras_shape
à tous leurs tenseurs de sortie, et Keras utilise cette propriété pour déduire les formes du modèle entier.
Si vous utilisez une fonction dorsale "en dehors" d'une couche ou d'une perte/métrique, cette propriété n'aura pas cette propriété pour le tenseur de sortie et une erreur apparaîtra indiquant que _keras_shape
n'existe pas.
Le codeur crée une solution de contournement incorrecte en ajoutant la propriété manuellement, alors qu'elle aurait dû être ajoutée par un calque keras approprié. (Cela peut fonctionner maintenant, mais dans le cas de mises à jour keras, ce code sera cassé tandis que les codes appropriés resteront ok)
Historiquement, Keras prend en charge 2 interfaces différentes pour leurs couches, la nouvelle fonctionnelle et l’ancienne, qui nécessite des appels model.add()
, d’où les 2 fonctions différentes.
Pour la TF, leurs fonctions concatenate()
ne font pas tout ce qui est nécessaire au bon fonctionnement de Keras. Par conséquent, les appels supplémentaires permettant de rendre la variable ._keras_shape
correcte et de ne pas perturber Keras qui attend de cette variable une valeur particulière.