[PYTHON] Précautions lors de l'utilisation de tf.keras.layers.TimeDistributed pour la couche personnalisée tf.keras

Objectif de cet article

tf.tf pour la couche personnalisée définie dans keras.keras.layers.J'ai eu une erreur lors de l'utilisation de TimeDistributed, je vais donc partager le contenu et la solution.



 version
- Python: 3.6.9
- Tensorflow: 2.1.0

## table des matières
 - Qu'est-ce que tf.keras.layers.TimeDistributed?
 - Qu'est-ce qu'un calque personnalisé?
 --Introduction du contenu d'erreur lorsque tf.keras.layers.TimeDistributed est appliqué à la couche personnalisée
 --Solution ci-dessus

## Qu'est-ce que tf.keras.layers.TimeDistributed?
 Il est utilisé lorsque vous souhaitez faire agir un calque de manière répétée dans le sens du temps. ([Référence](https://www.tensorflow.org/api_docs/python/tf/keras/layers/TimeDistributed))

```python
from tensorflow.keras import Input, Model
from tensorflow.keras.layers import TimeDistributed, Dense

temporal_dim = 4
emb_dim = 16
inputs = Input((temporal_dim, 8))
outputs = TimeDistributed(Dense(emb_dim))(inputs)
model = Model(inputs, outputs)
model.summary()
"""
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
input_1 (InputLayer)         [(None, 4, 8)]            0         
_________________________________________________________________
time_distributed (TimeDistri (None, 4, 16)             144       
=================================================================
Total params: 144
Trainable params: 144
Non-trainable params: 0
_________________________________________________________________
"""

Note) Le résultat ci-dessus ne dépend pas de la présence ou de l'absence de tf.keras.layers.TimeDistributed '', car tf.keras.layers.Dense '' n'affecte que la dernière dimension. Je suis reconnaissant de l'utiliser pour des calques avec une forme d'entrée limitée, comme `` tf.keras.layers.Embedding ''.

tf.keras.layers.L'intégration est par lots_Il ne peut être utilisé que pour le tenseur 2D avec taille, donc si vous souhaitez intégrer un tenseur 3D, tf.keras.layers.Vous devez utiliser TimeDistributed pour parcourir la direction unidimensionnelle supplémentaire manquante.(Utilisé dans le modèle recommandé)


## Qu'est-ce qu'un calque personnalisé

#### **`tf.Dans keras, tf.keras.layers.Vous pouvez hériter d'un calque pour définir un calque personnalisé.`**

tf.Il existe de nombreuses couches utiles implémentées dans keras, et vous pouvez les combiner en tf..keras.Nous allons créer un modèle. Un grand nombre de modèles peuvent être implémentés avec uniquement la couche standard.



 Si vous souhaitez effectuer un traitement plus flexible, vous pouvez l'implémenter en tant que couche personnalisée sans perdre la ressemblance `` tf.keras ''. ([Référence](https://www.tensorflow.org/tutorials/customization/custom_layers))

### Exemple .1: Combinez le standard `` `` tf.keras.layers```
 Dans ce cas, utilisez `` `` .__ init__ () `` `` pour générer une instance de `` tf.keras.layers```, et utilisez `` `.call ()` `` `pour traiter la couche réelle. Est défini.

 (Les couches suivantes sont les mêmes que `` `` tf.keras.layers.Dense '')

```python
import tensorflow as tf
from tensorflow.keras.layers import Dense

class Linear(tf.keras.layers.Layer):
    def __init__(self, emb_dim, *args, **kwargs):
        super(Linear_error, self).__init__(*args, **kwargs)
        self.dense = Dense(emb_dim)

    def call(self, x):
        return self.dense(x)

Exemple .2: définir une variable apprenable

Pour utiliser l'API de niveau inférieur, vous pouvez écrire:

class Linear(tf.keras.layers.Layer):
    def __init__(self, emb_dim):
        super(Linear, self).__init__()
        self.emb_dim = emb_dim

    def build(self, input_shape):
        self.kernel = self.add_weight(
            "kernel", shape=[int(input_shape[-1]), self.emb_dim]
        )

    def call(self, x):
        return tf.matmul(x, self.kernel)

Erreur: tf.keras.layers.TimeDistributed pour la couche personnalisée ne fonctionne pas

Utilisez `` tf.keras.layers.TimeDistributed '' pour les calques personnalisés comme indiqué ci-dessous.

from tensorflow.keras import Input
from tensorflow.keras.layers import TimeDistributed

temporal_dim = 4
emb_dim = 16
inputs = Input((temporal_dim, 8))

outputs = TimeDistributed(Linear(emb_dim))(inputs)
assert outputs.shape.rank == 3
assert outputs.shape[1] == temporal_dim
assert outputs.shape[2] == emb_dim

Ensuite, l'erreur suivante est renvoyée. (Extrait)

/usr/local/lib/python3.6/dist-packages/tensorflow_core/python/keras/engine/base_layer.py:773: in __call__
    outputs = call_fn(cast_inputs, *args, **kwargs)
/usr/local/lib/python3.6/dist-packages/tensorflow_core/python/keras/layers/wrappers.py:270: in call
    output_shape = self.compute_output_shape(input_shape).as_list()
/usr/local/lib/python3.6/dist-packages/tensorflow_core/python/keras/layers/wrappers.py:212: in compute_output_shape
    child_output_shape = self.layer.compute_output_shape(child_input_shape)

>     raise NotImplementedError
E     NotImplementedError

/usr/local/lib/python3.6/dist-packages/tensorflow_core/python/keras/engine/base_layer.py:564: NotImplementedError

Ceci est un message indiquant que la couche personnalisée `` .compute_output_shape () '' est manquante, veuillez donc l'implémenter vous-même.

Dans tf.keras.layers, input_shape et output_shape ne sont pas déterminés tant que .build () '' ou .call () '' n'est pas appelé. Cependant, tf.keras.layers.TimeDistributed correspond au moment où la forme_ouput_shape de la couche placée dans l'argument est générée en tant qu'instance (c'est-à-dire `` .build () `` ou `` `.call ()` `. Essayez de savoir avant `). `` `` tf.keras.layers fournit une méthode appelée .compute_output_shape () '' pour un tel cas. Pour autant que je puisse voir Code, j'essaye de construire, mais s'il s'agit d'une couche personnalisée `` NotImplementedError '' est déclenché sans une compilation réussie.

Solution

Remplacez `` .compute_output_shape () '' lors de la définition d'un calque personnalisé pour définir explicitement output_shape.

class Linear(tf.keras.layers.Layer):
    def __init__(self, emb_dim, *args, **kwargs):
        super(Linear, self).__init__(*args, **kwargs)
        self.emb_dim = emb_dim
        self.dense = Dense(self.emb_dim)

    def call(self, x):
        return self.dense(x)

    def compute_output_shape(self, input_shape):
        output_shape = input_shape[0:-1] + [self.emb_dim]
        return output_shape

S'il s'agit de cette couche personnalisée, cela fonctionnera normalement même si je vais à tf.keras.layers.TimeDistributed```.

Recommended Posts

Précautions lors de l'utilisation de tf.keras.layers.TimeDistributed pour la couche personnalisée tf.keras
Précautions lors de l'utilisation de l'instruction for dans les pandas
Précautions lors de l'utilisation de Chainer
Précautions lors de l'utilisation de Pit avec Python
Précautions lors de l'utilisation de l'analyse des traits TextBlob
Précautions lors de l'utilisation de codecs et de pandas
Précautions lors de l'utilisation de la fonction urllib.parse.quote
Précautions lors de l'utilisation de phantomjs de python
Précautions lors de l'utilisation de six avec Python 2.5
[python, multitraitement] Comportement des exceptions lors de l'utilisation du multitraitement
Précautions lors de l'utilisation de la bibliothèque google-cloud avec GAE / py
Précautions concernant cv2.cvtcolor
Écriture de couche personnalisée tf.keras recommandée et comportement de nom de variable
Précautions lors de l'utilisation de sqlite3 de macOS Sierra (10.12) avec le multitraitement
Emplacement de modification du code lors de l'utilisation de plotly gratuitement
Précautions lors du calcul avec une chaîne pour TmeStampType de PySpark