(Je pense que c'est à cause du conflit de version car les auteurs ont utilisé keras.engine.topology.Layer )
Avec tensorflow == 2.2.0 et keras == 2.4.3 , j'essaie d'apprendre le mécanisme d'attention et j'ai importé le code de quelque part comme:
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-25-1ab1f1ef1ed7> in <module>
5 x = lstm_layer(embedding)
6 x = Dropout(0.25)(x)
----> 7 merged = Attention(maxlen)(x)
8 merged = Dense(256, activation='relu')(merged)
9 merged = Dropout(0.25)(merged)
/opt/conda/lib/python3.7/site-packages/tensorflow/python/keras/engine/base_layer.py in __call__(self, *args, **kwargs)
895 # Build layer if applicable (if the `build` method has been
896 # overridden).
--> 897 self._maybe_build(inputs)
898 cast_inputs = self._maybe_cast_inputs(inputs)
899
/opt/conda/lib/python3.7/site-packages/tensorflow/python/keras/engine/base_layer.py in _maybe_build(self, inputs)
2414 # operations.
2415 with tf_utils.maybe_init_scope(self):
-> 2416 self.build(input_shapes) # pylint:disable=not-callable
2417 # We must set also ensure that the layer is marked as built, and the build
2418 # shape is stored since user defined build functions may not be calling
<ipython-input-20-86a01469b2e5> in build(self, input_shape)
23 name='{}_W'.format(self.name),
24 regularizer=self.W_regularizer,
---> 25 constraint=self.W_constraint)
26 self.features_dim = input_shape[-1]
27 if self.bias:
TypeError: add_weight() got multiple values for argument 'name'
Le problème est quand j'essaye d'utiliser,
lstm_layer = LSTM(300, dropout=0.25, recurrent_dropout=0.25, return_sequences=True) inp = Input(shape=(maxlen,), dtype='int32') embedding= embedding_layer(inp) x = lstm_layer(embedding) x = Dropout(0.25)(x) merged = Attention(maxlen)(x) merged = Dense(256, activation='relu')(merged) merged = Dropout(0.25)(merged) merged = BatchNormalization()(merged) outp = Dense(len(int_category), activation='softmax')(merged) AttentionLSTM = Model(inputs=inp, outputs=outp) AttentionLSTM.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['acc']) AttentionLSTM.summary()
il renvoie une erreur comme TypeError: add_weight () a obtenu plusieurs valeurs pour l'argument 'nom'
Le traçage complet de l'erreur est:
from keras import backend as K
from keras.engine.topology import Layer
from keras import initializers, regularizers, constraints
from keras.layers import Dense, Input, LSTM, Bidirectional, Activation, Conv1D, GRU, TimeDistributed
from keras.layers import Dropout, Embedding, GlobalMaxPooling1D, MaxPooling1D, Add, Flatten, SpatialDropout1D
from keras.layers import GlobalAveragePooling1D, BatchNormalization, concatenate
from keras.layers import Reshape, merge, Concatenate, Lambda, Average
from keras.models import Sequential, Model
from keras.initializers import Constant
from keras.layers.merge import add
class Attention(Layer):
def __init__(self, step_dim,
W_regularizer=None, b_regularizer=None,
W_constraint=None, b_constraint=None,
bias=True, **kwargs):
self.supports_masking = True
self.init = initializers.get('glorot_uniform')
self.W_regularizer = regularizers.get(W_regularizer)
self.b_regularizer = regularizers.get(b_regularizer)
self.W_constraint = constraints.get(W_constraint)
self.b_constraint = constraints.get(b_constraint)
self.bias = bias
self.step_dim = step_dim
self.features_dim = 0
super(Attention, self).__init__(**kwargs)
def build(self, input_shape):
assert len(input_shape) == 3
self.W = self.add_weight((input_shape[-1],),
initializer=self.init,
name='{}_W'.format(self.name),
regularizer=self.W_regularizer,
constraint=self.W_constraint)
self.features_dim = input_shape[-1]
if self.bias:
self.b = self.add_weight((input_shape[1],),
initializer='zero',
name='{}_b'.format(self.name),
regularizer=self.b_regularizer,
constraint=self.b_constraint)
else:
self.b = None
self.built = True
def compute_mask(self, input, input_mask=None):
return None
def call(self, x, mask=None):
features_dim = self.features_dim
step_dim = self.step_dim
eij = K.reshape(K.dot(K.reshape(x, (-1, features_dim)), K.reshape(self.W, (features_dim, 1))), (-1, step_dim))
if self.bias:
eij += self.b
eij = K.tanh(eij)
a = K.exp(eij)
if mask is not None:
a *= K.cast(mask, K.floatx())
a /= K.cast(K.sum(a, axis=1, keepdims=True) + K.epsilon(), K.floatx())
a = K.expand_dims(a)
weighted_input = x * a
return K.sum(weighted_input, axis=1)
def compute_output_shape(self, input_shape):
return input_shape[0], self.features_dim
4 Réponses :
Le problème vient car la fonction add_weight prend la valeur des tuples de forme. Essayez d'écrire " shape = shape (YOUR INPUT)". Cela devrait résoudre le problème.
Bonjour Jayesh, ce n'est pas une information très utile. Pourriez-vous s'il vous plaît rapporter le code ci-dessus avec les modules appropriés importés et le "shape = shape (input)" correctement placé dans votre version? Cela nous aiderait beaucoup plus. Bienvenue dans la communauté.
Désolé pour la confusion, mais je pense que vous avez déjà examiné cette question et y avez parfaitement répondu.
Ouais Jayesh, j'ai en fait utilisé une partie de votre réponse. :)
J'ai partiellement résolu le problème. Au moins pour la partie add_weight ():
Voir ci-dessous,
from keras import backend as K
from keras.engine.topology import Layer
from keras import initializers, regularizers, constraints
from keras.layers import Dense, Input, LSTM, Bidirectional, Activation, Conv1D, GRU, TimeDistributed
from keras.layers import Dropout, Embedding, GlobalMaxPooling1D, MaxPooling1D, Add, Flatten, SpatialDropout1D
from keras.layers import GlobalAveragePooling1D, BatchNormalization, concatenate
from keras.layers import Reshape, merge, Concatenate, Lambda, Average
from keras.models import Sequential, Model
from keras.initializers import Constant
from keras.layers.merge import add
class Attention(keras.layers.Layer):
def __init__(self, step_dim,
W_regularizer=None, b_regularizer=None,
W_constraint=None, b_constraint=None,
bias=True, **kwargs):
self.supports_masking = True
self.init = initializers.get('glorot_uniform')
self.W_regularizer = regularizers.get(W_regularizer)
self.b_regularizer = regularizers.get(b_regularizer)
self.W_constraint = constraints.get(W_constraint)
self.b_constraint = constraints.get(b_constraint)
self.bias = bias
self.step_dim = step_dim
self.features_dim = 0
super(Attention, self).__init__(**kwargs)
def build(self, input_shape):
assert len(input_shape) == 3
self.W = self.add_weight(shape=(input_shape[-1],),
name='{}_W'.format(self.name),
initializer=self.init,
regularizer=self.W_regularizer,
constraint=self.W_constraint)
self.features_dim = input_shape[-1]
if self.bias:
self.b = self.add_weight((input_shape[1],),
name='{}_b'.format(self.name),
initializer='zero',
regularizer=self.b_regularizer,
constraint=self.b_constraint)
else:
self.b = None
self.built = True
def compute_mask(self, input, input_mask=None):
return None
def call(self, x, mask=None):
features_dim = self.features_dim
step_dim = self.step_dim
eij = K.reshape(K.dot(K.reshape(x, (-1, features_dim)), K.reshape(self.W, (features_dim, 1))), (-1, step_dim))
if self.bias:
eij += self.b
eij = K.tanh(eij)
a = K.exp(eij)
if mask is not None:
a *= K.cast(mask, K.floatx())
a /= K.cast(K.sum(a, axis=1, keepdims=True) + K.epsilon(), K.floatx())
a = K.expand_dims(a)
weighted_input = x * a
return K.sum(weighted_input, axis=1)
def compute_output_shape(self, input_shape):
return input_shape[0], self.features_dim
En apportant les modifications ci-dessus, j'obtiens les sorties suivantes:
Je reçois un avertissement de Tensorflow
"WARNING:tensorflow:Model failed to serialize as JSON. Ignoring... Layer AttentionWithContext has arguments in `__init__` and therefore must override `get_config`".
Lorsque j'essaie d'évaluer l'algorithme sur l'ensemble de données de test, j'obtiens l'erreur suivante:
Je ne sais pas comment résoudre ces deux problèmes, donc je publierai probablement une question différente parce qu'elle sort du cadre de celle-ci.
Je pense que cela est dû à un conflit de version. Veuillez partager une fois que vous l'aurez découvert. J'ai essayé de le faire et j'ai échoué car en raison du changement de version, le flux de travail a changé.
@Deshwal vous parlez de la dernière erreur? de la fonction de test?
Lorsque vous modifiez la structure comme vous l'avez fait, une nouvelle erreur générera de temps en temps à cause du flux de travail modifié de 1.15 à 2.0
J'ai eu le même problème et j'ai changé d'environnement. mon venv comme suit:
absl-py==0.11.0 astor==0.8.1 cached-property==1.5.2 certifi==2020.6.20 click==7.1.2 cycler==0.10.0 gast==0.4.0 google-pasta==0.2.0 grpcio==1.33.2 h5py==3.0.0 importlib-metadata==2.0.0 joblib==0.17.0 Keras==2.2.4 Keras-Applications==1.0.8 Keras-Preprocessing==1.1.2 kiwisolver==1.3.1 Markdown==3.3.3 matplotlib==3.3.2 nltk==3.5 numpy==1.18.1 pandas==0.25.3 Pillow==8.0.1 protobuf==3.13.0 pyparsing==2.4.7 python-dateutil==2.8.1 pytz==2020.4 PyYAML==5.3.1 regex==2020.10.28 scikit-learn==0.23.2 scipy==1.5.4 six==1.15.0 sklearn==0.0 tensorboard==1.14.0 tensorflow==1.14.0 tensorflow-estimator==1.14.0 termcolor==1.1.0 threadpoolctl==2.1.0 tqdm==4.51.0 Werkzeug==1.0.1 wrapt==1.12.1 zipp==3.4.0
La méthode add_weights est appelée trois fois dans le code, essayez de la corriger avec 'shape ='.
J'ai le même problème sur TF version 2.2.0 et Keras 2.3.1
Avez-vous trouvé une solution pour résoudre ce problème?