Je suis un débutant à Keras et je viens d'écrire un exemple de jouet. Il signale un TypeError
. Le code et l'erreur sont les suivants:
Code:
inputs = keras.Input(shape=(3, ))
cell = keras.layers.SimpleRNNCell(units=5, activation='softmax')
label = keras.layers.RNN(cell)(inputs)
model = keras.models.Model(inputs=inputs, outputs=label)
model.compile(optimizer='rmsprop',
loss='mae',
metrics=['acc'])
data = np.array([[1, 2, 3], [3, 4, 5]])
labels = np.array([1, 2])
model.fit(x=data, y=labels)
Erreur:
Traceback (most recent call last):
File "/Users/david/Documents/code/python/Tensorflow/test.py", line 27, in <module>
run()
File "/Users/david/Documents/code/python/Tensorflow/test.py", line 21, in run
label = keras.layers.RNN(cell)(inputs)
File "/Users/david/anaconda3/lib/python3.6/site-packages/tensorflow/python/keras/layers/recurrent.py", line 619, in __call__
...
File "/Users/david/anaconda3/lib/python3.6/site-packages/tensorflow/python/ops/init_ops.py", line 473, in __call__
scale /= max(1., (fan_in + fan_out) / 2.)
TypeError: unsupported operand type(s) for +: 'NoneType' and 'int'
Alors, comment puis-je y faire face?
L'entrée d'une couche RNN aurait la forme de (num_timesteps, num_features)
, c'est-à-dire que chaque échantillon se compose de num_timesteps
pas de temps où chaque pas de temps est un vecteur de longueur num_features
. De plus, le nombre de pas de temps (c'est-à-dire num_timesteps
) peut être variable ou inconnue (c'est-à-dire None
) mais le nombre de fonctionnalités (c'est-à-dire num_features
) doit être fixe et spécifié depuis le début. Par conséquent, vous devez modifier la forme du calque d'entrée pour qu'il soit cohérent avec le calque RNN. Par exemple:
inputs = keras.Input(shape=(None, 3)) # variable number of timesteps each with length 3
inputs = keras.Input(shape=(4, 3)) # 4 timesteps each with length 3
inputs = keras.Input(shape=(4, None)) # this is WRONG! you can't do this. Number of features must be fixed
Ensuite, vous devez également modifier la forme des données d'entrée (c'est-à-dire data
) ainsi pour être cohérent avec la forme d'entrée que vous avez spécifiée (c'est-à-dire qu'elle doit avoir une forme de (num_samples, num_timesteps, num_features)
).
En remarque, vous pouvez définir la couche RNN plus simplement en utilisant directement la couche SimpleRNN
:
label = keras.layers.SimpleRNN(units=5, activation='softmax')(inputs)
Je pense que @ la réponse d'aujourd'hui est très claire. Cependant, pas complet. L'essentiel ici est que, si votre entrée ne contient pas num_features
, vous devez créer un calque Embedding
à côté de l'entrée.
Donc, si vous utilisez:
inputs = keras.Input(shape=(3,))
embedding = Embedding(voc_size, embed_dim, ..)
X = embedding(inputs)
ça marche aussi.