Python >> Tutoriel Python >  >> Python Tag >> Array

Comment concevoir un réseau de neurones pour prédire des tableaux à partir de tableaux

Ce que vous essayez de construire s'appelle un De-noising autoencoder . Le but ici est de pouvoir reconstruire un échantillon sans bruit en introduisant artificiellement du bruit dans un jeu de données, le nourrir vers un encoder , puis essayez de le régénérer sans bruit à l'aide d'un decoder .

Cela peut être fait avec n'importe quelle forme de données, y compris l'image et le texte.

Je recommanderais de lire plus à ce sujet. Il existe différents concepts qui garantissent une formation appropriée du modèle, notamment la compréhension de l'exigence d'un goulot d'étranglement au milieu pour assurer une compression et une perte d'informations appropriées, sinon le modèle apprend simplement à multiplier par 1 et renvoie la sortie.

Voici un exemple de code. Vous pouvez en savoir plus sur ce type d'architecture ici, écrit par l'auteur de Keras lui-même.

from tensorflow.keras import layers, Model, utils, optimizers

#Encoder
enc = layers.Input((99,))
x = layers.Dense(128, activation='relu')(enc)
x = layers.Dense(56, activation='relu')(x)
x = layers.Dense(8, activation='relu')(x) #Compression happens here

#Decoder
x = layers.Dense(8, activation='relu')(x)
x = layers.Dense(56, activation='relu')(x)
x = layers.Dense(28, activation='relu')(x)
dec = layers.Dense(99)(x)

model = Model(enc, dec)

opt = optimizers.Adam(learning_rate=0.01)

model.compile(optimizer = opt, loss = 'MSE')

model.fit(x_train, y_train, epochs = 20)

Attention, les encodeurs automatiques supposent que les données d'entrée ont une structure sous-jacente et peuvent donc être compressed dans un espace de dimension inférieure, que le décodeur peut utiliser pour régénérer les données. L'utilisation de séquences générées aléatoirement comme données peut ne pas donner de bons résultats car sa compression ne fonctionnera pas sans perte massive d'informations qui n'ont elles-mêmes aucune structure.

Comme la plupart des autres réponses le suggèrent, vous n'utilisez pas correctement les activations. Étant donné que l'objectif est de régénérer un vecteur à 99 dimensions avec des valeurs continues, il serait logique de NE PAS utiliser sigmoïde, mais plutôt de travailler avec tanh comme il compresses (-1,1) ou pas d'activation de couche finale, et non gates (0-1) les valeurs.

Voici un auto-encodeur Denoising avec conv1d et deconv1d couches. Le problème ici est que la saisie est trop simple. Voyez si vous pouvez générer des fonctions paramétriques plus complexes pour les données d'entrée.

from tensorflow.keras import layers, Model, utils, optimizers

#Encoder with conv1d
inp = layers.Input((99,))
x = layers.Reshape((99,1))(inp)
x = layers.Conv1D(5, 10)(x)
x = layers.MaxPool1D(10)(x)
x = layers.Flatten()(x)
x = layers.Dense(4, activation='relu')(x) #<- Bottleneck!

#Decoder with Deconv1d
x = layers.Reshape((-1,1))(x)
x = layers.Conv1DTranspose(5, 10)(x)
x = layers.Conv1DTranspose(2, 10)(x)
x = layers.Flatten()(x)
out = layers.Dense(99)(x)

model = Model(inp, out)

opt = optimizers.Adam(learning_rate=0.001)
model.compile(optimizer = opt, loss = 'MSE')
model.fit(x_train, y_train, epochs = 10, validation_data=(x_test, y_test))
Epoch 1/10
188/188 [==============================] - 1s 7ms/step - loss: 2.1205 - val_loss: 0.0031
Epoch 2/10
188/188 [==============================] - 1s 5ms/step - loss: 0.0032 - val_loss: 0.0032
Epoch 3/10
188/188 [==============================] - 1s 5ms/step - loss: 0.0032 - val_loss: 0.0030
Epoch 4/10
188/188 [==============================] - 1s 5ms/step - loss: 0.0031 - val_loss: 0.0029
Epoch 5/10
188/188 [==============================] - 1s 5ms/step - loss: 0.0030 - val_loss: 0.0030
Epoch 6/10
188/188 [==============================] - 1s 5ms/step - loss: 0.0029 - val_loss: 0.0027
Epoch 7/10
188/188 [==============================] - 1s 5ms/step - loss: 0.0028 - val_loss: 0.0029
Epoch 8/10
188/188 [==============================] - 1s 5ms/step - loss: 0.0028 - val_loss: 0.0025
Epoch 9/10
188/188 [==============================] - 1s 5ms/step - loss: 0.0028 - val_loss: 0.0025
Epoch 10/10
188/188 [==============================] - 1s 5ms/step - loss: 0.0026 - val_loss: 0.0024
utils.plot_model(model, show_layer_names=False, show_shapes=True)


Pour que le modèle fonctionne, vous devez apporter quelques modifications

  1. Tout d'abord, votre problème est un problème de régression et non un problème de classification. Vous devez donc changer la perte de l'entropie croisée en erreur quadratique moyenne (mse)

  2. Ensuite, vous devez modifier la sortie de votre dernière couche pour générer des valeurs brutes

EDIT :Après réflexion, car j'ai mal vu le type d'entrée, comme suggéré par @desertnaut, il est préférable d'utiliser la sortie brute du modèle

Quoi qu'il en soit, il est préférable d'utiliser un encodeur automatique comme suggéré par @AkshaySehgal car de cette façon vous forcez le débruitage, faisant de l'apprentissage net dans l'espace compressé la fonction sous-jacente

model = tf.keras.models.Sequential()
model.add(tf.keras.layers.Flatten(input_shape=(99,)))
model.add(tf.keras.layers.Dense(768, activation=tf.nn.relu))
model.add(tf.keras.layers.Dense(768, activation=tf.nn.relu))
model.add(tf.keras.layers.Dense(99))

model.compile(optimizer = 'adam',
         loss = 'mean_squared_error',
         metrics = ['mse'])

model.fit(x_train, y_train, epochs = 20)

sortie :

Epoch 1/20
188/188 [==============================] - 2s 9ms/step - loss: 28.7281 - mse: 28.7281
Epoch 2/20
188/188 [==============================] - 2s 9ms/step - loss: 1.6866 - mse: 1.6866
Epoch 3/20
188/188 [==============================] - 2s 9ms/step - loss: 0.5031 - mse: 0.5031
Epoch 4/20
188/188 [==============================] - 2s 9ms/step - loss: 0.3126 - mse: 0.3126
Epoch 5/20
188/188 [==============================] - 2s 9ms/step - loss: 0.2186 - mse: 0.2186
Epoch 6/20
188/188 [==============================] - 2s 9ms/step - loss: 0.1420 - mse: 0.1420
Epoch 7/20
188/188 [==============================] - 2s 9ms/step - loss: 0.1334 - mse: 0.1334
Epoch 8/20
188/188 [==============================] - 2s 9ms/step - loss: 0.1193 - mse: 0.1193
Epoch 9/20
188/188 [==============================] - 2s 9ms/step - loss: 0.1174 - mse: 0.1174
Epoch 10/20
188/188 [==============================] - 2s 9ms/step - loss: 0.0813 - mse: 0.0813
Epoch 11/20
188/188 [==============================] - 2s 9ms/step - loss: 0.0334 - mse: 0.0334
Epoch 12/20
188/188 [==============================] - 2s 9ms/step - loss: 0.0592 - mse: 0.0592
Epoch 13/20
188/188 [==============================] - 2s 9ms/step - loss: 0.0162 - mse: 0.0162
Epoch 14/20
188/188 [==============================] - 2s 9ms/step - loss: 0.0255 - mse: 0.0255
Epoch 15/20
188/188 [==============================] - 2s 9ms/step - loss: 0.0208 - mse: 0.0208
Epoch 16/20
188/188 [==============================] - 2s 9ms/step - loss: 0.0365 - mse: 0.0365
Epoch 17/20
188/188 [==============================] - 2s 9ms/step - loss: 0.0236 - mse: 0.0236
Epoch 18/20
188/188 [==============================] - 2s 9ms/step - loss: 0.0155 - mse: 0.0155
Epoch 19/20
188/188 [==============================] - 2s 9ms/step - loss: 0.0204 - mse: 0.0204
Epoch 20/20
188/188 [==============================] - 2s 9ms/step - loss: 0.0145 - mse: 0.0145

<tensorflow.python.keras.callbacks.History at 0x7f60d19256d8>

Si vous en avez besoin, j'ai également construit le modèle dans keras en utilisant colab. Vous pouvez consulter les résultats directement depuis mon carnet