[PYTHON] Tout en conservant la structure du modèle de classification d'image (mnist), attachez un auto-encodeur pour améliorer la précision de bout en bout. [tensorflow, keras, mnist, autoencder]

Objectif

Réfléchissez aux moyens d'améliorer la précision même lorsque le nombre de données utilisées est petit

Contrainte

Puisque nous ne décrivons pas comment récupérer des données ou écrire un ajustement de modèle, comment récupérer des données est ici, et comment écrire ajustement, compiler est [ici](https :: Voir //qiita.com/kzrn3318/items/d792cdd42d485662037c).

Le code entier est [ici](https://github.com/kzrn3318/Comparison-of-a-simple-cnn-model-and-a-model-with-cnn-in-the-middle-layer-of-autoencoder /blob/master/git%E7%94%A8.ipynb)
prétraitement des données

Divisez simplement par 255 et mettez à l'échelle, ce qui est également courant en tant que prétraitement.

x_train = x_train / 255
x_test = x_test / 255

Avant amélioration

Le modèle de classification avant l'amélioration était facile à régler, mais je pense qu'il existe un moyen d'obtenir plus de précision.

structure du modèle

model.png

code modèle

Modèle de classification Mnist avant amélioration


inp = Input(shape=(28,28,1),name="inp2")
p3 = Conv2D(32,2,2,padding="same")(inp)
p3 = Conv2D(16,2,2,padding="same")(p3)
p3 = MaxPooling2D(2,2,padding="same")(p3)
p3 = Conv2D(8,2,2,padding="same")(p3)
p3 = MaxPooling2D(2,2,padding="same")(p3)
p3 = Conv2D(8,2,2,padding="same")(p3)
p3 = MaxPooling2D(2,2,padding="same")(p3)
p3 = Flatten()(p3)
p3 = Dense(128,activation="relu")(p3)
p3 = Dense(64,activation="relu")(p3)
out = Dense(10,activation="softmax")(p3)

Les noms et les noms de variables sont les mêmes qu'après, de sorte qu'il est facile de confirmer que la structure est la même plus tard.

prétraitement des données

Avant l'amélioration, vous pouvez entrer la taille de 28 * 28 telle quelle, il n'y a donc rien de spécial à faire.

J'ai appris les conditions comme suit.

Cette condition reste la même après l'amélioration.

Apprentissage
Epoch 1/10000
100/100 [==============================] - 0s 4ms/step - loss: 2.2860 - acc: 0.1250 - val_loss: 2.2386 - val_acc: 0.1500
Epoch 2/10000
100/100 [==============================] - 0s 2ms/step - loss: 1.9977 - acc: 0.2575 - val_loss: 1.7996 - val_acc: 0.3200
Epoch 3/10000
100/100 [==============================] - 0s 3ms/step - loss: 1.6415 - acc: 0.3825 - val_loss: 1.6337 - val_acc: 0.3650
Epoch 4/10000
100/100 [==============================] - 0s 2ms/step - loss: 1.4488 - acc: 0.4475 - val_loss: 1.4533 - val_acc: 0.4500
Epoch 5/10000
100/100 [==============================] - 0s 2ms/step - loss: 1.2776 - acc: 0.5325 - val_loss: 1.3028 - val_acc: 0.5000
Epoch 6/10000
100/100 [==============================] - 0s 2ms/step - loss: 1.1254 - acc: 0.5863 - val_loss: 1.2225 - val_acc: 0.5450
Epoch 7/10000
100/100 [==============================] - 0s 2ms/step - loss: 0.9990 - acc: 0.6275 - val_loss: 1.1432 - val_acc: 0.6000
Epoch 8/10000
100/100 [==============================] - 0s 2ms/step - loss: 0.8964 - acc: 0.6812 - val_loss: 1.1002 - val_acc: 0.6600
Epoch 9/10000
100/100 [==============================] - 0s 2ms/step - loss: 0.8101 - acc: 0.7237 - val_loss: 1.0833 - val_acc: 0.6550
Epoch 10/10000
100/100 [==============================] - 0s 2ms/step - loss: 0.7583 - acc: 0.7300 - val_loss: 1.0636 - val_acc: 0.6700
Epoch 11/10000
100/100 [==============================] - 0s 2ms/step - loss: 0.6986 - acc: 0.7625 - val_loss: 1.0313 - val_acc: 0.6450
Epoch 12/10000
100/100 [==============================] - 0s 2ms/step - loss: 0.6530 - acc: 0.7650 - val_loss: 1.0362 - val_acc: 0.6800
Epoch 13/10000
100/100 [==============================] - 0s 2ms/step - loss: 0.5929 - acc: 0.7962 - val_loss: 1.0390 - val_acc: 0.6850
Epoch 14/10000
100/100 [==============================] - 0s 2ms/step - loss: 0.5830 - acc: 0.7887 - val_loss: 1.0353 - val_acc: 0.6700
Epoch 15/10000
100/100 [==============================] - 0s 2ms/step - loss: 0.5379 - acc: 0.8163 - val_loss: 1.0150 - val_acc: 0.6900
Epoch 16/10000
100/100 [==============================] - 0s 2ms/step - loss: 0.5073 - acc: 0.8288 - val_loss: 1.0049 - val_acc: 0.6750
Epoch 17/10000
100/100 [==============================] - 0s 2ms/step - loss: 0.4809 - acc: 0.8325 - val_loss: 1.0357 - val_acc: 0.7100
Epoch 18/10000
100/100 [==============================] - 0s 3ms/step - loss: 0.4510 - acc: 0.8438 - val_loss: 1.0232 - val_acc: 0.6900
Epoch 19/10000
100/100 [==============================] - 0s 2ms/step - loss: 0.4356 - acc: 0.8438 - val_loss: 1.0402 - val_acc: 0.6700
Epoch 20/10000
100/100 [==============================] - 0s 2ms/step - loss: 0.4083 - acc: 0.8625 - val_loss: 1.0361 - val_acc: 0.7000
Epoch 21/10000
100/100 [==============================] - 0s 2ms/step - loss: 0.4188 - acc: 0.8537 - val_loss: 0.9956 - val_acc: 0.6900
Epoch 22/10000
100/100 [==============================] - 0s 2ms/step - loss: 0.3855 - acc: 0.8675 - val_loss: 1.0222 - val_acc: 0.7050
Epoch 23/10000
100/100 [==============================] - 0s 2ms/step - loss: 0.3491 - acc: 0.8863 - val_loss: 1.0171 - val_acc: 0.7000
Epoch 24/10000
100/100 [==============================] - 0s 2ms/step - loss: 0.3160 - acc: 0.8900 - val_loss: 1.0814 - val_acc: 0.7050
Epoch 25/10000
100/100 [==============================] - 0s 2ms/step - loss: 0.3231 - acc: 0.8813 - val_loss: 1.0660 - val_acc: 0.7000
Epoch 26/10000
100/100 [==============================] - 0s 2ms/step - loss: 0.3102 - acc: 0.8813 - val_loss: 1.1023 - val_acc: 0.7150
Epoch 27/10000
100/100 [==============================] - 0s 2ms/step - loss: 0.2892 - acc: 0.8988 - val_loss: 1.0896 - val_acc: 0.7100
Epoch 28/10000
100/100 [==============================] - 0s 2ms/step - loss: 0.2597 - acc: 0.9087 - val_loss: 1.1387 - val_acc: 0.6900
Epoch 29/10000
100/100 [==============================] - 0s 2ms/step - loss: 0.2442 - acc: 0.9175 - val_loss: 1.1421 - val_acc: 0.7250
Epoch 30/10000
100/100 [==============================] - 0s 2ms/step - loss: 0.2295 - acc: 0.9162 - val_loss: 1.1753 - val_acc: 0.7100
Epoch 31/10000
100/100 [==============================] - 0s 2ms/step - loss: 0.2035 - acc: 0.9287 - val_loss: 1.2142 - val_acc: 0.7300
Prédiction pour les données de test
pred_labels = model.predict(x_test)
pred = []
for label in pred_labels:
    idx = label.argmax()
    pred.append(idx)

from sklearn.metrics import accuracy_score
print(accuracy_score(y_test,pred))

0.7464

Le score acc pour la taille de test était de 0.7464. Ensuite, je vais essayer de l'améliorer en incorporant un auto-encodeur.

Après amélioration

structure du modèle

model_after.png

code modèle

Modèle de classification mnist amélioré


#partie autoencoder
input_img = Input(shape=(784,),name="inp1")
x= Dense(256, activation="relu")(input_img)
x = Dense(128,activation="relu")(x)
encoded = Dense(128, activation="relu")(x)

z = Dense(128, activation="relu")(encoded)
decoded = Dense(784, activation="sigmoid",name="decoded")(z)

#Reçoit la sortie de la couche intermédiaire de l'auto-encodeur et se couple complètement
p2 = Dense(128,activation="relu")(encoded)
p2 = Dense(64,activation="relu")(p2)

#Modèle cnn cible à comparer, la structure est la même qu'avant amélioration
inp = Input(shape=(28,28,1),name="inp2")
p3 = Conv2D(32,2,2,padding="same")(inp)
p3 = Conv2D(16,2,2,padding="same")(p3)
p3 = MaxPooling2D(2,2,padding="same")(p3)
p3 = Conv2D(8,2,2,padding="same")(p3)
p3 = MaxPooling2D(2,2,padding="same")(p3)
p3 = Conv2D(8,2,2,padding="same")(p3)
p3 = MaxPooling2D(2,2,padding="same")(p3)
p3 = Flatten()(p3)
p3 = Dense(128,activation="relu")(p3)
p3 = Dense(64,activation="relu")(p3)

p = Add()([p2,p3])
p = Dense(32,activation="relu")(p)
predictor = Dense(10,activation="softmax",name="predictor")(p)
Façon de penser

Il y avait beaucoup de choses sur le Web qui entraînaient l'auto-encodeur séparément et utilisaient la sortie de l'encodeur comme fonction pour améliorer la précision du modèle.

Je l'ai créé avec cette idée.

prétraitement des données

Le prétraitement ne modifie que la structure de la séquence et ne la gonfle pas. Avant l'amélioration, la mnist chargée pourrait être entrée dans la même taille, mais lors de la saisie dans l'autoencoder, elle sera aplatie. De plus, comme il y a deux couches d'entrée, préparez-en deux. De même, pour l'étiquette, préparez deux étiquettes de classification pour la classification et la même image que l'image d'entrée pour l'autoencoder.

x_train_1 = x_train.reshape(len(x_train),784,1)
x_train_2 = x_train.reshape(len(x_train),28,28,1)

x_val_1 = x_val.reshape(len(x_val),784,1)
x_val_2 = x_val.reshape(len(x_val),28,28,1)

Spécifiez x et y au moment de l'ajustement comme suit.

Les conditions sont les mêmes qu'avant l'amélioration.

Apprentissage
Epoch 1/10000
100/100 [==============================] - 0s 5ms/step - loss: 1.5771 - decoded_loss: 0.0945 - predictor_loss: 1.4826 - predictor_acc: 0.5038 - val_loss: 1.1179 - val_decoded_loss: 0.0599 - val_predictor_loss: 1.0580 - val_predictor_acc: 0.6600
Epoch 2/10000
100/100 [==============================] - 0s 3ms/step - loss: 0.6398 - decoded_loss: 0.0569 - predictor_loss: 0.5829 - predictor_acc: 0.8200 - val_loss: 0.8113 - val_decoded_loss: 0.0530 - val_predictor_loss: 0.7583 - val_predictor_acc: 0.7650
Epoch 3/10000
100/100 [==============================] - 0s 3ms/step - loss: 0.4338 - decoded_loss: 0.0524 - predictor_loss: 0.3814 - predictor_acc: 0.8700 - val_loss: 0.7595 - val_decoded_loss: 0.0507 - val_predictor_loss: 0.7088 - val_predictor_acc: 0.7500
Epoch 4/10000
100/100 [==============================] - 0s 3ms/step - loss: 0.3216 - decoded_loss: 0.0505 - predictor_loss: 0.2710 - predictor_acc: 0.9225 - val_loss: 0.5286 - val_decoded_loss: 0.0489 - val_predictor_loss: 0.4797 - val_predictor_acc: 0.8250
Epoch 5/10000
100/100 [==============================] - 0s 3ms/step - loss: 0.2043 - decoded_loss: 0.0491 - predictor_loss: 0.1551 - predictor_acc: 0.9588 - val_loss: 0.4416 - val_decoded_loss: 0.0473 - val_predictor_loss: 0.3943 - val_predictor_acc: 0.8600
Epoch 6/10000
100/100 [==============================] - 0s 3ms/step - loss: 0.1560 - decoded_loss: 0.0477 - predictor_loss: 0.1083 - predictor_acc: 0.9650 - val_loss: 0.6524 - val_decoded_loss: 0.0464 - val_predictor_loss: 0.6061 - val_predictor_acc: 0.8350
Epoch 7/10000
100/100 [==============================] - 0s 3ms/step - loss: 0.1374 - decoded_loss: 0.0463 - predictor_loss: 0.0911 - predictor_acc: 0.9737 - val_loss: 0.6657 - val_decoded_loss: 0.0461 - val_predictor_loss: 0.6197 - val_predictor_acc: 0.8450
Epoch 8/10000
100/100 [==============================] - 0s 3ms/step - loss: 0.1535 - decoded_loss: 0.0456 - predictor_loss: 0.1079 - predictor_acc: 0.9675 - val_loss: 0.5291 - val_decoded_loss: 0.0432 - val_predictor_loss: 0.4860 - val_predictor_acc: 0.8600
Epoch 9/10000
100/100 [==============================] - 0s 3ms/step - loss: 0.1218 - decoded_loss: 0.0440 - predictor_loss: 0.0779 - predictor_acc: 0.9737 - val_loss: 0.7133 - val_decoded_loss: 0.0428 - val_predictor_loss: 0.6705 - val_predictor_acc: 0.8600
Epoch 10/10000
100/100 [==============================] - 0s 3ms/step - loss: 0.0800 - decoded_loss: 0.0428 - predictor_loss: 0.0372 - predictor_acc: 0.9900 - val_loss: 0.6788 - val_decoded_loss: 0.0414 - val_predictor_loss: 0.6374 - val_predictor_acc: 0.8550
Epoch 11/10000
100/100 [==============================] - 0s 3ms/step - loss: 0.0590 - decoded_loss: 0.0409 - predictor_loss: 0.0181 - predictor_acc: 0.9962 - val_loss: 0.4702 - val_decoded_loss: 0.0396 - val_predictor_loss: 0.4306 - val_predictor_acc: 0.8850
Epoch 12/10000
100/100 [==============================] - 0s 3ms/step - loss: 0.0586 - decoded_loss: 0.0398 - predictor_loss: 0.0188 - predictor_acc: 0.9962 - val_loss: 0.5544 - val_decoded_loss: 0.0392 - val_predictor_loss: 0.5152 - val_predictor_acc: 0.8600
Epoch 13/10000
100/100 [==============================] - 0s 3ms/step - loss: 0.0398 - decoded_loss: 0.0383 - predictor_loss: 0.0014 - predictor_acc: 1.0000 - val_loss: 0.5413 - val_decoded_loss: 0.0376 - val_predictor_loss: 0.5037 - val_predictor_acc: 0.8800
Epoch 14/10000
100/100 [==============================] - 0s 3ms/step - loss: 0.0376 - decoded_loss: 0.0371 - predictor_loss: 5.6022e-04 - predictor_acc: 1.0000 - val_loss: 0.5456 - val_decoded_loss: 0.0371 - val_predictor_loss: 0.5085 - val_predictor_acc: 0.8750
Epoch 15/10000
100/100 [==============================] - 0s 3ms/step - loss: 0.0362 - decoded_loss: 0.0359 - predictor_loss: 3.1317e-04 - predictor_acc: 1.0000 - val_loss: 0.5563 - val_decoded_loss: 0.0361 - val_predictor_loss: 0.5202 - val_predictor_acc: 0.8700
Prédiction pour les données de test
pred_img ,pred_labels = model.predict({"inp1":x_test_1,"inp2":x_test_2})

pred = []
for label in pred_labels:
    idx = label.argmax()
    pred.append(idx)

from sklearn.metrics import accuracy_score
print(accuracy_score(y_test,pred))

0.9055
encoder la sortie de l'auto-encodeur


#Sortie auto-encodeur
for i in range(5):
    fig , ax = plt.subplots()
    x_test = x_test.reshape(len(x_test),28,28)
    ax.imshow(x_test[i])
    
    fig , ax = plt.subplots()
    pred_img = pred_img.reshape(len(pred_img),28,28)
    ax.imshow(pred_img[i])

    plt.show()

ダウンロード.pngダウンロード(1).png ダウンロード (2).pngダウンロード(3).png ダウンロード (6).pngダウンロード(7).png ダウンロード (8).pngダウンロード(9).png ダウンロード (4).pngダウンロード(5).png

Le score acc pour les données de test était de 0,9055. Il semble que l'autoencodeur lui-même puisse être reproduit d'une manière ou d'une autre (très subtilement). Cependant, la reproduction de l'autoencodeur lui-même peut être mieux reproduite sans attacher le modèle cnn (bien que je ne le décrirai pas cette fois).

Résumé

J'ai résumé les deux scores acc.

Une amélioration d'environ 0,2 de la précision a été observée avant l'amélioration. En ajoutant un autoencoder, on peut dire que mnist peut améliorer la précision (en fonction de la tâche).

dernier

J'ai utilisé un modèle qui n'utilise pas la normalisation bacth cette fois, mais je pense que vous pouvez voir une meilleure précision en ajoutant une couche de normalisation par lots. De plus, cette fois, nous avons constaté une amélioration de la précision avec mnist, mais lorsque nous traitons d'images avec une grande quantité d'informations telles que cifar-10, je pense que nous ne saurons pas si nous améliorerons la précision ou non.

Recommended Posts

Tout en conservant la structure du modèle de classification d'image (mnist), attachez un auto-encodeur pour améliorer la précision de bout en bout. [tensorflow, keras, mnist, autoencder]
[TensorFlow / Keras] La route pour assembler un RNN de votre structure préférée
10 méthodes pour améliorer la précision de BERT
Challenge classification des images par TensorFlow2 + Keras 3 ~ Visualiser les données MNIST ~
Essayez d'améliorer la précision de l'estimation du nombre de Twitter