Я пытаюсь построить модель, похожую на Lenet5, и тренироваться на наборе данных Caltech 101 . Ожидаемая точность этой базовой модели составляет менее 60% . Но моя модель достигает точности 90 +% , что, я подозреваю, не должно быть возможным с Lenet5 для этого набора данных. В следующих фрагментах кода показано, как считываются данные и как определяется моя модель, а затем результаты, которые я получил.
Я использую tf.data для загрузки изображений, как показано на Учебники по тензорным потокам.
# Obtain test(10%) and train size(90%)
test_size = round(0.1 * image_count)
train_size = image_count-test_size
# Take first 10% values as test_data
test_data = labeled_ds.take(test_size)
# Skip first 10%, and keep rest 90% data as train_data
train_data = labeled_ds.skip(test_size)
# Define np arrays to store images and labels (to be passed to the model)
train_images = np.empty((train_size,64,64,3), dtype=np.float32)
train_labels = np.empty((train_size,101,), dtype=np.bool_)
test_images = np.empty((test_size,64,64,3), dtype=np.float32)
test_labels = np.empty((test_size,101,), dtype=np.bool_)
# Iterating over train_data to seperate images and labels
for i,data in enumerate(train_data):
train_images[i] = data[0]
train_labels[i] = data[1]
# Iterating over test_data to seperate images and labels
for i,data in enumerate(test_data):
test_images[i] = data[0]
test_labels[i] = data[1]
# Convert numpy arrays into tensors
# Perform one-hot encoding for labels (False ->0, True -> 1)
train_images = tf.convert_to_tensor(train_images)
train_labels = tf.convert_to_tensor(train_labels, dtype=tf.int32)
test_images = tf.convert_to_tensor(test_images)
test_labels = tf.convert_to_tensor(test_labels, dtype=tf.int32)
Форма данных:
Train images shape: (7809, 64, 64, 3)
Test images shape: (868, 64, 64, 3)
Train labels shape: (7809, 101)
Test labels shape: (868, 101)
Модель Lenet5, которую я определяю:
# Define the Lenet 5 architecture as per the description
model = models.Sequential()
model.add(layers.Conv2D(32, (5, 5), activation='relu', input_shape=(64, 64, 3)))
model.add(layers.MaxPooling2D((4, 4)))
model.add(layers.Conv2D(64, (5, 5), activation='relu'))
model.add(layers.MaxPooling2D((4, 4)))
model.add(layers.Flatten())
model.add(layers.Dense(1024, input_shape=(256,), activation='relu'))
model.add(layers.Dense(84, activation='relu'))
model.add(layers.Dense(101, activation='softmax'))
model.compile(optimizer='adam',loss=tf.keras.losses.CategoricalCrossentropy(), metrics=['accuracy'])
history = model.fit(train_images, train_labels, epochs=20, validation_data=(test_images, test_labels))
Наблюдаемые потери и точность значения:
Train on 7809 samples, validate on 868 samples
Epoch 1/20
7809/7809 [==============================] - 17s 2ms/sample - loss: 3.8387 - accuracy: 0.2018 - val_loss: 3.3969 - val_accuracy: 0.2661
.
.
.
Epoch 19/20
7809/7809 [==============================] - 15s 2ms/sample - loss: 0.1205 - accuracy: 0.9679 - val_loss: 0.5456 - val_accuracy: 0.9136
Epoch 20/20
7809/7809 [==============================] - 15s 2ms/sample - loss: 0.1672 - accuracy: 0.9522 - val_loss: 0.5295 - val_accuracy: 0.9159
Я проверил, чтобы убедиться, что мои данные испытаний отсутствуют в данных поезда.
test_images.numpy() in train_images.numpy()
# Outputs 'False'
Я построил матрицу путаницы, чтобы убедиться, что модель не классифицирует все метки как Неверно.
from sklearn.metrics import confusion_matrix
y_pred = model.predict_classes(test_images)
y_label = []
for i in range(len(y_pred)):
a, = np.where(test_labels[i].numpy()==1)
y_label.append(a[0])
con_mat = tf.math.confusion_matrix(labels=y_label, predictions=y_pred)
'''
Output: con_mat =
array([[2, 0, 0, ..., 0, 0, 0],
[0, 9, 0, ..., 0, 0, 0],
[0, 0, 4, ..., 0, 0, 0],
...,
[0, 0, 0, ..., 5, 0, 0],
[0, 0, 0, ..., 0, 3, 0],
[0, 0, 0, ..., 0, 0, 2]], dtype=int32)
'''
Я понимаю, что, возможно, допустил ошибку или обнаружил потенциальный недостаток, который мог бы привести к высокой точности. Любые выводы будут оценены. Спасибо!