[PYTHON] Hyper Parameter Tuning 2

Einführung

Letztes Mal habe ich ein Modell für die handschriftliche Zeichenerkennung in CNN erstellt und Hyperparameter mithilfe der Rastersuche angepasst. Daraus haben wir gelernt, wie man ein hochgenaues Modell mit den Werten Aktivierung, Optimierer, Epoche und Batch-Größe erhält. Dieses Mal möchte ich das Filterattribut von CNN überprüfen.

Bibliothek importieren

from tensorflow.keras.datasets import mnist
from tensorflow.keras.models import Model
from tensorflow.keras.layers import Activation, Conv2D, Dense, Flatten, MaxPooling2D, Reshape, Input
from tensorflow.keras.callbacks import EarlyStopping, ModelCheckpoint
from sklearn.metrics import accuracy_score
from collections import OrderedDict
import pandas as pd
import os

Datenaufbereitung

(X_train, y_train), (X_test, y_test) = mnist.load_data()

#Setzen Sie den Pixelwert auf 0~Normalisieren Sie zwischen 1
X_train = X_train / 255.0
X_test = X_test / 255.0

Modell erstellen

class CNNModel:
    def __init__(self, hid_dim_0=32, hid_dim_1=64):
        self.input = Input(shape=(28, 28), name='Input')
        self.reshape = Reshape(target_shape=(28, 28, 1), name='Reshape')
        self.layers = OrderedDict()
        self.layers['conv_0'] = Conv2D(hid_dim_0, (3, 3), strides=(1, 1), name='Conv_0')
        self.layers['pool_0'] = MaxPooling2D((2, 2), strides=(1, 1), name='Pool_0')
        self.layers['conv_1'] = Conv2D(hid_dim_1, (3, 3), strides=(1, 1), name='Conv_1')
        self.layers['pool_1'] = MaxPooling2D((2, 2), strides=(1, 1), name='Pool_1')
        self.layers['flatten'] = Flatten()
        self.layers['dense_0'] = Dense(256, activation='relu')
        self.layers['dense_1'] = Dense(128, activation='relu')
        self.layers['dense_2'] = Dense(64, activation='relu')
        self.last = Dense(10, activation='softmax', name='last')

    def build(self):
        x = self.input
        z = self.reshape(x)
        for layer in self.layers.values():
            z = layer(z)
        p = self.last(z)

        model = Model(inputs=x, outputs=p)

        return model

Stellen Sie mehrere CNN-Filterwerte ein (16, 32, 64, 128)

dim_hidden_layers = [2**i for i in range(4, 8)]

Vergleichen und speichern Sie die Ergebnisse in der Tabelle

Die Anzahl der Parameter und die Genauigkeit (korrekte Antwortrate) werden in einer Variablen namens "df_accuracy" gespeichert.

df_accuracy = pd.DataFrame()

for hid_dim_0 in dim_hidden_layres:
    for hid_dim_1 in dim_hidden_layres:
        print('========', 'hid_dim_0:', hid_dim_0, '; hid_dim_1:', hid_dim_1, '========')
        model = CNNModel(hid_dim_0=hid_dim_0, hid_dim_1=hid_dim_1)
        model = model.build()
        model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['acc'])
        callbacks = [
            EarlyStopping(patience=3),
            ModelCheckpoint(filepath=os.path.join('models', 'CNN', 'model_{}_{}.h5'.format(hid_dim_0, hid_dim_1)), save_best_only=True),
        ]
        n_param = model.count_params()
        model.fit(x=X_train, y=y_train, batch_size=64, epochs=20, callbacks=callbacks, validation_split=0.1)
        acc = accuracy_score(y_test, model.predict(X_test).argmax(axis=-1))
        
        df_accuracy = pd.concat([df_accuracy, pd.DataFrame([[hid_dim_0, hid_dim_1, n_param, acc]], columns=['hid_dim_0', 'hid_dim_1', 'n_param', 'accuracy'])])

Überprüfen Sie das Ergebnis

display(df_accuracy.set_index(['hid_dim_0', 'hid_dim_1'])[['n_param']].unstack())
display(df_accuracy.set_index(['hid_dim_0', 'hid_dim_1'])[['accuracy']].unstack())

スクリーンショット 2020-09-11 14.16.30.png

Es scheint, dass es keinen großen Unterschied zwischen ihnen gibt, aber ich fand, dass die Kombination von "128" und "64" das genaueste Modell ist.

Stellen Sie das erhaltene Ergebnis ein und überprüfen Sie die Generalisierungsleistung

model = CNNModel(hid_dim_0=128, hid_dim_1=64)
model = model.build()
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['acc'])

history = model.fit(x=X_train, y=y_train, batch_size=64, epochs=20, callbacks=callbacks, validation_split=0.1)

print(model.evaluate(X_test, y_test)) # [0.09829007089138031, 0.9854999780654907]

Daher haben wir ein Modell mit einer Genauigkeit von ca. 98,5%. Es ist ein gutes Modell mit hoher Genauigkeit.

abschließend

Bei dieser Überprüfung ist das Ergebnis, dass es keinen großen Unterschied im Filterwert gibt, aber ich frage mich, was in anderen Fällen passiert. Nächstes Mal möchte ich die Tiefe der Schichten untersuchen. Vielen Dank für das Lesen bis zum Ende.

Recommended Posts

Hyper-Parameter-Tuning
Hyper Parameter Tuning 2
Was ist Hyperparameter-Tuning?
Random Forest (Klassifizierung) und Hyperparameter-Tuning