Вопрос или проблема
Я использую этот набор данных для обучения своей модели: https://www.kaggle.com/datasets/sankalpsrivastava26/capital-alphabets-28×28
Я хочу предсказать цифры, строчную и заглавную рукопись, поэтому после изменения формы и нормализации это моя модель:
model = tf.keras.models.Sequential([
tf.keras.layers.Conv2D(32, (3,3), activation='relu', input_shape=(32, 32, 1)),
tf.keras.layers.MaxPooling2D(2, 2),
tf.keras.layers.Conv2D(64, (3,3), activation='relu'),
tf.keras.layers.MaxPooling2D(2,2),
tf.keras.layers.Conv2D(128, (3,3), activation='relu'),
tf.keras.layers.MaxPooling2D(2,2),
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(512, activation='relu'),
tf.keras.layers.Dense(62, activation='softmax')
])
и мои обратные вызовы:
tensorboard_callback = tf.keras.callbacks.TensorBoard(log_dir=log_dir, histogram_freq=1)
reduce_lr = tf.keras.callbacks.ReduceLROnPlateau(monitor="val_loss", factor=0.2,
patience=5, min_lr=0.001)
es = tf.keras.callbacks.EarlyStopping(monitor = "val_accuracy", restore_best_weights=True, mode="max", patience = 15, verbose = 1)
model_cp = tf.keras.callbacks.ModelCheckpoint(filepath="best_model2.weights.h5", monitor = "val_accuracy", save_best_only = True, verbose = 1, save_weights_only=True)
и обучение:
adam_optimizer = tf.keras.optimizers.Adam(learning_rate=0.001)
model.compile(loss="categorical_crossentropy", optimizer=adam_optimizer, metrics=['accuracy'])
result = model.fit(
trainX, trainY,
validation_data=(testX, testY),
epochs=1000,
steps_per_epoch=len(trainX)//32,
callbacks=[tensorboard_callback, es, model_cp],
verbose=1
)
но val_accuracy и accuracy не увеличиваются, также loss и val_loss значения не уменьшаются.
Я тестировал:
**epochs= 32, 100, 200**
,
Также я использовал генератор вот так:
generator = ImageDataGenerator(
featurewise_center=False,
featurewise_std_normalization=False,
rotation_range=20,
width_shift_range=0.2,
height_shift_range=0.2,
shear_range=0.3,
zoom_range=0.08,
horizontal_flip=True)
test_gen = ImageDataGenerator()
train_generator = generator.flow(trainX, trainY, batch_size=32, shuffle=True)
test_generator = test_gen.flow(testX, testY, batch_size=32)
adam_optimizer = tf.keras.optimizers.Adam(learning_rate=0.001)
model.compile(loss="categorical_crossentropy", optimizer=adam_optimizer, metrics=['accuracy'])
result = model.fit(
train_generator,
trainX, trainY,
validation_data=test_generator,
validation_data=(testX, testY),
epochs=100,
validation_steps=len(testX)//32,
steps_per_epoch=len(trainX)//32,
verbose=1,
callbacks=[reduce_lr, tensorboard_callback, es, model_cp],
)
эти изменения привели к плохому результату, я новичок и не знаю, что делать дальше.
# Подтвержденные размеры
print("Shape of concatenated trainX:", trainX.shape)
print("Shape of concatenated trainY:", trainY.shape)
print("Shape of concatenated testX:", testX.shape)
print("Shape of concatenated testY:", testY.shape)
Shape of concatenated trainX: (487227, 32, 32)
Shape of concatenated trainY: (487227, 62)
Shape of concatenated testX: (155489, 32, 32)
Shape of concatenated testY: (155489, 62)
Epoch 1: val_accuracy improved from -inf to 0.80699, saving model to best_model2.weights.h5
15225/15225 ━━━━━━━━━━━━━━━━━━━━ 136s 9ms/step - accuracy: 0.7509 - loss: 0.8253 - val_accuracy: 0.8070 - val_loss: 0.5859
Epoch 2/1000
14763/15225 ━━━━━━━━━━━━━━━━━━━━ 4s 9ms/step - accuracy: 0.8191 - loss: 0.5483
Epoch 2: val_accuracy improved from 0.80699 to 0.81478, saving model to best_model2.weights.h5
15225/15225 ━━━━━━━━━━━━━━━━━━━━ 145s 10ms/step - accuracy: 0.8191 - loss: 0.5482 - val_accuracy: 0.8148 - val_loss: 0.5643
Epoch 3/1000
14763/15225 ━━━━━━━━━━━━━━━━━━━━ 3s 9ms/step - accuracy: 0.8287 - loss: 0.5159
Epoch 3: val_accuracy improved from 0.81478 to 0.81694, saving model to best_model2.weights.h5
15225/15225 ━━━━━━━━━━━━━━━━━━━━ 141s 9ms/step - accuracy: 0.8287 - loss: 0.5161 - val_accuracy: 0.8169 - val_loss: 0.5574
Epoch 4/1000
14760/15225 ━━━━━━━━━━━━━━━━━━━━ 4s 9ms/step - accuracy: 0.8328 - loss: 0.4986
Epoch 4: val_accuracy improved from 0.81694 to 0.82024, saving model to best_model2.weights.h5
15225/15225 ━━━━━━━━━━━━━━━━━━━━ 144s 9ms/step - accuracy: 0.8327 - loss: 0.4987 - val_accuracy: 0.8202 - val_loss: 0.5510
Epoch 5/1000
14761/15225 ━━━━━━━━━━━━━━━━━━━━ 3s 8ms/step - accuracy: 0.8363 - loss: 0.4852
Epoch 5: val_accuracy did not improve from 0.82024
15225/15225 ━━━━━━━━━━━━━━━━━━━━ 134s 9ms/step - accuracy: 0.8362 - loss: 0.4854 - val_accuracy: 0.8197 - val_loss: 0.5709
Epoch 6/1000
14759/15225 ━━━━━━━━━━━━━━━━━━━━ 3s 8ms/step - accuracy: 0.8382 - loss: 0.4786
Epoch 6: val_accuracy did not improve from 0.82024
15225/15225 ━━━━━━━━━━━━━━━━━━━━ 137s 9ms/step - accuracy: 0.8381 - loss: 0.4788 - val_accuracy: 0.8162 - val_loss: 0.5658
Epoch 7/1000
14761/15225 ━━━━━━━━━━━━━━━━━━━━ 3s 9ms/step - accuracy: 0.8411 - loss: 0.4684
Epoch 7: val_accuracy did not improve from 0.82024
15225/15225 ━━━━━━━━━━━━━━━━━━━━ 139s 9ms/step - accuracy: 0.8411 - loss: 0.4686 - val_accuracy: 0.8145 - val_loss: 0.5823
Epoch 8/1000
14760/15225 ━━━━━━━━━━━━━━━━━━━━ 3s 8ms/step - accuracy: 0.8439 - loss: 0.4600
Epoch 8: val_accuracy did not improve from 0.82024
15225/15225 ━━━━━━━━━━━━━━━━━━━━ 138s 9ms/step - accuracy: 0.8438 - loss: 0.4603 - val_accuracy: 0.8159 - val_loss: 0.5786
Epoch 9/1000
14760/15225 ━━━━━━━━━━━━━━━━━━━━ 3s 9ms/step - accuracy: 0.8438 - loss: 0.4576
2024-10-27 17:06:58.858730: I tensorflow/core/framework/local_rendezvous.cc:404] Local rendezvous is aborting with status: OUT_OF_RANGE: End of sequence
[[{{node IteratorGetNext}}]]
Epoch 9: val_accuracy did not improve from 0.82024
15225/15225 ━━━━━━━━━━━━━━━━━━━━ 138s 9ms/step - accuracy: 0.8438 - loss: 0.4577 - val_accuracy: 0.8132 - val_loss: 0.5921
Epoch 10/1000
14759/15225 ━━━━━━━━━━━━━━━━━━━━ 3s 9ms/step - accuracy: 0.8464 - loss: 0.4476
Epoch 10: val_accuracy did not improve from 0.82024
15225/15225 ━━━━━━━━━━━━━━━━━━━━ 139s 9ms/step - accuracy: 0.8463 - loss: 0.4479 - val_accuracy: 0.8142 - val_loss: 0.6027
Epoch 11/1000
14762/15225 ━━━━━━━━━━━━━━━━━━━━ 3s 8ms/step - accuracy: 0.8498 - loss: 0.4392
Epoch 11: val_accuracy did not improve from 0.82024
15225/15225 ━━━━━━━━━━━━━━━━━━━━ 135s 9ms/step - accuracy: 0.8497 - loss: 0.4395 - val_accuracy: 0.8099 - val_loss: 0.6066
Epoch 12/1000
14765/15225 ━━━━━━━━━━━━━━━━━━━━ 3s 8ms/step - accuracy: 0.8505 - loss: 0.4373
Epoch 12: val_accuracy did not improve from 0.82024
15225/15225 ━━━━━━━━━━━━━━━━━━━━ 134s 9ms/step - accuracy: 0.8505 - loss: 0.4376 - val_accuracy: 0.8112 - val_loss: 0.6194
Epoch 13/1000
14760/15225 ━━━━━━━━━━━━━━━━━━━━ 3s 9ms/step - accuracy: 0.8508 - loss: 0.4342
Epoch 13: val_accuracy did not improve from 0.82024
15225/15225 ━━━━━━━━━━━━━━━━━━━━ 140s 9ms/step - accuracy: 0.8508 - loss: 0.4345 - val_accuracy: 0.8129 - val_loss: 0.6261
Я также пробовал это:
model = tf.keras.models.Sequential([
tf.keras.layers.Conv2D(32, (3,3), activation='relu', input_shape=(32, 32, 1)),
tf.keras.layers.MaxPooling2D(2, 2),
tf.keras.layers.BatchNormalization(),
tf.keras.layers.Conv2D(64, (3,3), activation='relu'),
tf.keras.layers.MaxPooling2D(2, 2),
tf.keras.layers.BatchNormalization(),
tf.keras.layers.Conv2D(128, (3,3), activation='relu'),
tf.keras.layers.MaxPooling2D(2, 2),
tf.keras.layers.BatchNormalization(),
tf.keras.layers.Flatten(),
# Скрытый слой с 512 нейронами
tf.keras.layers.Dense(512, activation='relu'),
tf.keras.layers.Dropout(0.3),
tf.keras.layers.Dense(62, activation='softmax')
])
и генератор:
train_generator = ImageDataGenerator(
featurewise_center=True,
featurewise_std_normalization=True,
rotation_range=20,
width_shift_range=0.2,
height_shift_range=0.2,
shear_range=0.3,
zoom_range=0.08,
horizontal_flip=True
)
train_generator.fit(trainX)
test_generator = ImageDataGenerator(
featurewise_center=True,
featurewise_std_normalization=True
)
test_generator.mean = train_generator.mean
test_generator.std = train_generator.std
train_data_gen = train_generator.flow(trainX, trainY, batch_size=32, shuffle=True)
test_data_gen = test_generator.flow(testX, testY, batch_size=32)
adam_optimizer = tf.keras.optimizers.Adam(learning_rate=0.001)
model.compile(loss="categorical_crossentropy", optimizer=adam_optimizer, metrics=['accuracy'])
result = model.fit(
train_data_gen,
validation_data=test_data_gen,
epochs=1000,
steps_per_epoch=len(trainX)//32,
callbacks=[tensorboard_callback, es, model_cp],
verbose=1
)
и результат https://pastebin.ubuntu.com/p/4pM4RwWR8X/
Ответ или решение
Увеличение точности и снижение потерь в модели сверточной нейронной сети (CNN) может быть достигнуто с помощью ряда подходов и улучшений. Рассмотрим ключевые моменты, которые могут помочь вам в вашем проекте.
1. Улучшение архитектуры модели
-
Добавление дополнительных слоев и фильтров: Вы можете попробовать увеличить количество слоев и число фильтров в существующих слоях. Например, добавьте дополнительные сверточные и подвыборочные (max pooling) слои. Проверьте, как они влияют на производительность:
model = tf.keras.models.Sequential([ tf.keras.layers.Conv2D(64, (3,3), activation='relu', input_shape=(32, 32, 1)), tf.keras.layers.MaxPooling2D(2, 2), tf.keras.layers.Conv2D(128, (3,3), activation='relu'), tf.keras.layers.MaxPooling2D(2,2), tf.keras.layers.Conv2D(256, (3,3), activation='relu'), tf.keras.layers.MaxPooling2D(2,2), tf.keras.layers.Flatten(), tf.keras.layers.Dense(512, activation='relu'), tf.keras.layers.Dropout(0.5), # Добавление дропаута tf.keras.layers.Dense(62, activation='softmax') ])
-
Использование схемы с остаточными связями (Residual connections): Это может помочь избежать деградации производительности при добавлении большего количества слоев.
2. Повышение надежности данных и их аугментация
-
Аугментация данных: Убедитесь, что ваши аугментации применяются правильно. Вы уже используете
ImageDataGenerator
, но попробуйте настроить параметры аугментации (например, увеличитьrotation_range
,width_shift_range
и т.д.), чтобы ваши данные были более разнообразными.generator = ImageDataGenerator( rotation_range=30, width_shift_range=0.2, height_shift_range=0.2, shear_range=0.2, zoom_range=0.2, horizontal_flip=True, fill_mode='nearest' )
-
Перепроверка нормализации данных: Это критически важно для CNN. Убедитесь, что ваши данные правильно нормализованы до диапазона [0, 1] или [-1, 1].
3. Оптимизация функций обучения
-
Пробуйте разные оптимизаторы и параметры обучения: Вы используете
Adam
с фиксированной learning rate. Попробуйте адаптивные схемы обучения, такие какReduceLROnPlateau
, и разные инициализации весов.adam_optimizer = tf.keras.optimizers.Adam(learning_rate=0.0001) # Попробуйте меньшую learning rate
-
Измените функцию потерь на
sparse_categorical_crossentropy
: Если метки в формате целых чисел, это может помочь.
4. Использование регуляризации
-
Регуляризация Dropout: Убедитесь, что вы внедрили слои Dropout, чтобы снизить переобучение. Добавьте их после полносвязных слоев.
-
Раннее прекращение обучения: Подходит, если вы видите, что модель начинает переобучаться. Вы уже используете это, но проверьте настройки
patience
.
5. Исправление потока данных
- Правильная реализация генераторов: В ваших примерах есть несоответствия в использовании генератора и передачи данных в метод
fit
. Убедитесь, что используете их корректно.
Заключение
Учитывая ваши текущие проблемы с моделью, рекомендую вам последовательно пробовать каждое из вышеуказанных решений и наблюдать за тем, как они влияют на производительность модели. Процесс настройки конволюционных нейронных сетей требует терпения и экспериментов. Не спешите с выводами, но по мере получения результатов корректируйте направление ваших усилий. Удачи вам!