La dernière fois, j'ai créé un modèle de reconnaissance de caractères manuscrits dans CNN et réglé les hyperparamètres en utilisant la recherche par grille. À partir de là, nous avons appris comment obtenir un modèle très précis avec les valeurs d'activation, d'optimiseur, d'époque et de batch_size. Cette fois, je voudrais vérifier l'attribut de filtre de CNN.
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
(X_train, y_train), (X_test, y_test) = mnist.load_data()
#Définissez la valeur du pixel sur 0~Normaliser entre 1
X_train = X_train / 255.0
X_test = X_test / 255.0
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
dim_hidden_layers = [2**i for i in range(4, 8)]
Le nombre de paramètres et la précision (taux de réponse correct) sont stockés dans une variable appelée df_accuracy
.
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'])])
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())
Il semble qu'il n'y ait pas beaucoup de différence entre eux, mais j'ai trouvé que la combinaison de «128» et «64» est le modèle le plus précis.
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]
Par conséquent, nous avons un modèle avec une précision d'environ 98,5%. C'est un bon modèle avec une grande précision.
Dans cette vérification, le résultat est qu'il n'y a pas beaucoup de différence dans la valeur du filtre, mais je me demande ce qui se passe dans d'autres cas. La prochaine fois, j'aimerais étudier la profondeur des couches. Merci d'avoir lu jusqu'au bout.