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.
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()
#Setzen Sie den Pixelwert auf 0~Normalisieren Sie zwischen 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)]
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'])])
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())
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.
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.
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.