Я воспроизвожу результаты исследовательской работы для проекта ML. Статья посвящена распознаванию пальмовых вен с использованием CNN. Он обучает 3 CNN на разных наборах данных вен ладоней, одним из которых является набор данных FYODB.
Я использую Keras для обучения своих моделей с нуля, и хотя AlexNet показывает хорошие результаты с точностью тестов более 95%, по какой-то причине VGG16 и VGG19 не могут НИКАКОГО обучения во время тренировки. Их точность в каждую эпоху не достигает даже 0,1.
Я поделюсь кодом, который использую для построения и обучения модели. Обратите внимание, что в статье, которую я воспроизвожу, намеренно уменьшено количество фильтров на слой CONV2D для сокращения времени обучения (хотя я пробовал и с исходной архитектурой, результаты те же).
Некоторые ключевые константы:
< ul>
[*]Количество классов: 160
[*]Количество выборок в наборе данных: 6400
[*]Train-Val Split: 80- 20
[*]Разделение Train-Test: 80–20.
[*]Общее количество изображений для обучения, тестирования и проверки: 4096, 1024, 1280.
[*]Форма изображения: (224, 224, 3)
Вот код, который у меня есть для сборки и обучения. Я также попробовал перенос обучения с предварительно обученными весами VGG16, и это действительно сработало отлично, с точностью теста более 95%.
data_augmentation = keras.Sequential(
[
layers.RandomFlip("horizontal"),
layers.RandomRotation(0.1),
layers.RandomZoom(0.1),
layers.RandomContrast(0.1),
layers.RandomTranslation(0.1, 0.1),
layers.RandomHeight(0.1),
layers.RandomWidth(0.1),
]
)
def make_vgg16_model(input_shape, num_classes):
inputs = keras.Input(shape=input_shape)
# Block 1
x = data_augmentation(inputs)
x = layers.Rescaling(1.0 / 255)(inputs)
x = layers.Conv2D(32, (3, 3), activation='relu', padding='same')(inputs)
x = layers.Conv2D(32, (3, 3), activation='relu', padding='same')(x)
x = layers.MaxPooling2D((2, 2), strides=(2, 2))(x)
# Block 2
x = layers.Conv2D(64, (3, 3), activation='relu', padding='same')(x)
x = layers.Conv2D(64, (3, 3), activation='relu', padding='same')(x)
x = layers.MaxPooling2D((2, 2), strides=(2, 2))(x)
# Block 3
x = layers.Conv2D(96, (3, 3), activation='relu', padding='same')(x)
x = layers.Conv2D(96, (3, 3), activation='relu', padding='same')(x)
x = layers.Conv2D(96, (3, 3), activation='relu', padding='same')(x)
x = layers.MaxPooling2D((2, 2), strides=(2, 2))(x)
# Block 4
x = layers.Conv2D(128, (3, 3), activation='relu', padding='same')(x)
x = layers.Conv2D(128, (3, 3), activation='relu', padding='same')(x)
x = layers.Conv2D(128, (3, 3), activation='relu', padding='same')(x)
x = layers.MaxPooling2D((2, 2), strides=(2, 2))(x)
# Block 5
x = layers.Conv2D(128, (3, 3), activation='relu', padding='same')(x)
x = layers.Conv2D(128, (3, 3), activation='relu', padding='same')(x)
x = layers.Conv2D(128, (3, 3), activation='relu', padding='same')(x)
x = layers.MaxPooling2D((2, 2), strides=(2, 2))(x)
# Flatten and Fully Connected Layers
x = layers.Flatten()(x)
x = layers.Dense(4096, activation='relu')(x)
x = layers.Dropout(0.5)(x)
x = layers.Dense(4096, activation='relu')(x)
x = layers.Dropout(0.5)(x)
outputs = layers.Dense(num_classes, activation='softmax')(x)
return keras.Model(inputs, outputs)
from tqdm import tqdm
num_epochs = 30
models = {
"AlexNet": make_alexnet_model(input_shape=image_size, num_classes=num_classes),
"VGG16": make_vgg16_model(input_shape=image_size, num_classes=num_classes),
"VGG19": make_vgg19_model(input_shape=image_size, num_classes=num_classes),
}
model_histories = {}
for name, model in models.items():
print(f'\x1b[34mTraining {name} Model...\x1b[0m')
model.compile(
optimizer=keras.optimizers.Adam(1e-3),
loss="sparse_categorical_crossentropy",
metrics=["accuracy"],
)
start = time.time()
# Wrap model.fit with tqdm for a progress bar
progress_bar = tqdm(total=num_epochs, position=0, leave=True)
history = model.fit(
train_dataset,
epochs=num_epochs,
validation_data=val_dataset,
verbose=1,
callbacks=[
tf.keras.callbacks.LambdaCallback(on_epoch_end=lambda epoch, logs: progress_bar.update(1)),
]
)
progress_bar.close()
model_histories[name] = history
end = time.time()
print(f'Finished training {name} in {end-start:.2f}s\n')
Пример вывода:
Epoch 14/30
128/128 [==============================] - ETA: 0s - loss: 5.0713 - accuracy: 0.0054
47%|████▋ | 14/30 [05:35
Подробнее здесь: https://stackoverflow.com/questions/775 ... et-perform