Проблема, с которой я столкнулся, заключается в том, что я получил точность ниже 10% за 10 эпох. Мне понадобится помощь в улучшении моей модели.
Я работаю над проектом классификации изображений, чтобы классифицировать изображения животных по 90 различным категориям с использованием EfficientNetB0 и стратифицированной перекрестной проверки K-Fold. Набор данных взят из Kaggle: https://www.kaggle.com/datasets/iamsour ... ataset-90- Different-animals/data.
Я подготовил данные загрузку, увеличение данных и создание собственного генератора данных, но я все равно получил низкую точность для моей модели EfficientNetB0.
# Define paths
data_dir = 'E:/Kaggle/AnimalDataset/animals/animals'
categories = [
'antelope', 'badger', 'bat', 'bear', 'bee', 'beetle', 'bison', 'boar', 'butterfly', 'cat',
'caterpillar', 'chimpanzee', 'cockroach', 'cow', 'coyote', 'crab', 'crow', 'deer', 'dog', 'dolphin',
'donkey', 'dragonfly', 'duck', 'eagle', 'elephant', 'flamingo', 'fly', 'fox', 'goat', 'goldfish',
'goose', 'gorilla', 'grasshopper', 'hamster', 'hare', 'hedgehog', 'hippopotamus', 'hornbill', 'horse',
'hummingbird', 'hyena', 'jellyfish', 'kangaroo', 'koala', 'ladybugs', 'leopard', 'lion', 'lizard',
'lobster', 'mosquito', 'moth', 'mouse', 'octopus', 'okapi', 'orangutan', 'otter', 'owl', 'ox', 'oyster',
'panda', 'parrot', 'pelecaniformes', 'penguin', 'pig', 'pigeon', 'porcupine', 'possum', 'raccoon', 'rat',
'reindeer', 'rhinoceros', 'sandpiper', 'seahorse', 'seal', 'shark', 'sheep', 'snake', 'sparrow', 'squid',
'squirrel', 'starfish', 'swan', 'tiger', 'turkey', 'turtle', 'whale', 'wolf', 'wombat', 'woodpecker', 'zebra'
]
# Hyperparameters
input_shape = (224, 224, 3)
num_classes = len(categories)
batch_size = 12
num_folds = 5
# Load the data and labels
data = []
labels = []
for category in categories:
category_path = os.path.join(data_dir, category)
if os.path.exists(category_path):
images = os.listdir(category_path)
for image in images:
data.append(os.path.join(category_path, image))
labels.append(category)
# Convert labels to numeric
label_to_index = {label: idx for idx, label in enumerate(categories)}
numeric_labels = [label_to_index[label] for label in labels]
# Data augmentation functions
def augment_image(image):
# Horizontal flip
if np.random.rand() < 0.5:
image = cv2.flip(image, 1)
# Rotation
angle = np.random.uniform(-10, 10)
h, w = image.shape[:2]
M = cv2.getRotationMatrix2D((w // 2, h // 2), angle, 1)
image = cv2.warpAffine(image, M, (w, h), borderMode=cv2.BORDER_REFLECT_101)
# Zoom
scale = np.random.uniform(0.9, 1.1)
new_h, new_w = int(h * scale), int(w * scale)
if scale < 1.0:
top = (h - new_h) // 2
bottom = h - new_h - top
left = (w - new_w) // 2
right = w - new_w - left
image = cv2.copyMakeBorder(cv2.resize(image, (new_w, new_h)), top, bottom, left, right, cv2.BORDER_REFLECT_101)
else:
image = cv2.resize(image, (w, h))
# Contrast adjustment
pil_img = Image.fromarray(image)
enhancer = ImageEnhance.Contrast(pil_img)
factor = np.random.uniform(0.85, 1.15)
image = np.array(enhancer.enhance(factor))
return image.astype(np.uint8)
class AugmentedImageDataGenerator(Sequence):
def __init__(self, image_paths, labels, batch_size, input_shape, num_classes, augment=False):
self.image_paths = image_paths
self.labels = labels
self.batch_size = batch_size
self.input_shape = input_shape
self.num_classes = num_classes
self.augment = augment
self.on_epoch_end()
def __len__(self):
return int(np.ceil(len(self.image_paths) / self.batch_size))
def __getitem__(self, index):
batch_image_paths = self.image_paths[index * self.batch_size:(index + 1) * self.batch_size]
batch_labels = self.labels[index * self.batch_size:(index + 1) * self.batch_size]
images = np.empty((len(batch_image_paths), *self.input_shape), dtype=np.float32)
labels = np.empty((len(batch_image_paths), self.num_classes), dtype=np.float32)
for i, (image_path, label) in enumerate(zip(batch_image_paths, batch_labels)):
image = Image.open(image_path).resize(self.input_shape[:2])
image = np.array(image).astype(np.uint8) # Ensure the data type is uint8
if self.augment:
image = augment_image(image)
image = image / 255.0 # Normalize to [0, 1]
images = image.astype(np.float32) # Ensure the data type is float32
labels = tf.keras.utils.to_categorical(label, num_classes=self.num_classes)
return images, labels
def on_epoch_end(self):
self.indices = np.arange(len(self.image_paths))
np.random.shuffle(self.indices)
self.image_paths = [self.image_paths for i in self.indices]
self.labels = [self.labels for i in self.indices]
# Perform Stratified K-Fold Cross Validation
skf = StratifiedKFold(n_splits=num_folds, shuffle=True, random_state=42)
fold_accuracies = []
for fold, (train_idx, test_idx) in enumerate(skf.split(data, numeric_labels)):
print(f"Training fold {fold+1}/{num_folds}...")
# Split data into training and testing
train_data = [data for i in train_idx]
train_labels = [numeric_labels for i in train_idx]
test_data = [data for i in test_idx]
test_labels = [numeric_labels for i in test_idx]
# Create data generators
train_generator = AugmentedImageDataGenerator(
train_data,
train_labels,
batch_size=batch_size,
input_shape=input_shape,
num_classes=num_classes,
augment=False # Initially without augmentation
)
test_generator = AugmentedImageDataGenerator(
test_data,
test_labels,
batch_size=batch_size,
input_shape=input_shape,
num_classes=num_classes,
augment=False
)
# Load the EfficientNetB0 model
base_model = EfficientNetB0(weights='imagenet', include_top=False, input_shape=input_shape)
# Add new top layers
x = base_model.output
x = GlobalAveragePooling2D()(x)
outputs = Dense(num_classes, activation='softmax')(x)
# Create the model
model = Model(inputs=base_model.input, outputs=outputs)
# Freeze all layers in the base model
for layer in base_model.layers:
layer.trainable = False
# Compile the model
model.compile(
optimizer=Adam(learning_rate=1e-5),
loss='categorical_crossentropy',
metrics=['accuracy']
)
# Callbacks
early_stopping = EarlyStopping(monitor='val_loss', patience=5, restore_best_weights=True)
reduce_lr = ReduceLROnPlateau(monitor='val_loss', factor=0.2, patience=3, min_lr=1e-6)
# Train the model
history = model.fit(
train_generator,
epochs=30, # Adjusted number of epochs
validation_data=test_generator,
callbacks=[early_stopping, reduce_lr]
)
# Unfreeze some layers of the base model
for layer in base_model.layers[-40:]: # Unfreeze more layers
layer.trainable = True
# Re-compile the model with a lower learning rate
model.compile(
optimizer=Adam(learning_rate=1e-6), # Lower learning rate
loss='categorical_crossentropy',
metrics=['accuracy']
)
# Continue training the model with augmentation
train_generator.augment = True
# Continue training the model
history_fine = model.fit(
train_generator,
epochs=20, # Adjusted number of epochs
validation_data=test_generator,
callbacks=[early_stopping, reduce_lr]
)
# Evaluate the model
loss, accuracy = model.evaluate(test_generator)
print(f"Fold {fold+1} test accuracy: {accuracy}")
fold_accuracies.append(accuracy)
# Calculate the average accuracy across all folds
average_accuracy = np.mean(fold_accuracies)
print(f"Average test accuracy: {average_accuracy}")
Результат, который я получил
Training fold 1/5...
Epoch 1/30
360/360 ━━━━━━━━━━━━━━━━━━━━ 99s 254ms/step - accuracy: 0.0124 - loss: 4.5010 - val_accuracy: 0.0111 - val_loss: 4.5007 - learning_rate: 1.0000e-05
Epoch 2/30
360/360 ━━━━━━━━━━━━━━━━━━━━ 93s 256ms/step - accuracy: 0.0146 - loss: 4.5006 - val_accuracy: 0.0111 - val_loss: 4.5006 - learning_rate: 1.0000e-05
Epoch 3/30
360/360 ━━━━━━━━━━━━━━━━━━━━ 90s 248ms/step - accuracy: 0.0121 - loss: 4.5012 - val_accuracy: 0.0111 - val_loss: 4.5005 - learning_rate: 1.0000e-05
Epoch 4/30
360/360 ━━━━━━━━━━━━━━━━━━━━ 90s 247ms/step - accuracy: 0.0120 - loss: 4.5015 - val_accuracy: 0.0111 - val_loss: 4.5004 - learning_rate: 1.0000e-05
Epoch 5/30
360/360 ━━━━━━━━━━━━━━━━━━━━ 92s 254ms/step - accuracy: 0.0078 - loss: 4.5015 - val_accuracy: 0.0111 - val_loss: 4.5004 - learning_rate: 1.0000e-05
Epoch 6/30
360/360 ━━━━━━━━━━━━━━━━━━━━ 92s 253ms/step - accuracy: 0.0116 - loss: 4.5007 - val_accuracy: 0.0111 - val_loss: 4.5003 - learning_rate: 1.0000e-05
Epoch 7/30
360/360 ━━━━━━━━━━━━━━━━━━━━ 95s 261ms/step - accuracy: 0.0144 - loss: 4.5006 - val_accuracy: 0.0111 - val_loss: 4.5003 - learning_rate: 1.0000e-05
Epoch 8/30
360/360 ━━━━━━━━━━━━━━━━━━━━ 91s 251ms/step - accuracy: 0.0086 - loss: 4.5018 - val_accuracy: 0.0111 - val_loss: 4.5002 - learning_rate: 1.0000e-05
Epoch 9/30
360/360 ━━━━━━━━━━━━━━━━━━━━ 89s 245ms/step - accuracy: 0.0122 - loss: 4.5004 - val_accuracy: 0.0111 - val_loss: 4.5002 - learning_rate: 1.0000e-05
Epoch 10/30
360/360 ━━━━━━━━━━━━━━━━━━━━ 91s 251ms/step - accuracy: 0.0103 - loss: 4.5010 - val_accuracy: 0.0111 - val_loss: 4.5001 - learning_rate: 1.0000e-05
Epoch 11/30
360/360 ━━━━━━━━━━━━━━━━━━━━ 86s 237ms/step - accuracy: 0.0086 - loss: 4.5002 - val_accuracy: 0.0111 - val_loss: 4.5001 - learning_rate: 1.0000e-05
Epoch 12/30
37/360 ━━━━━━━━━━━━━━━━━━━━ 1:02 195ms/step - accuracy: 0.0147 - loss: 4.4990
Подробнее здесь: https://stackoverflow.com/questions/786 ... sification
Как повысить точность модели EfficientNetB0 для классификации животных ⇐ Python
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение
-
-
Рассчитайте точность, полноту, точность и сбалансированную точность из матрицы путаницы.
Anonymous » » в форуме Python - 0 Ответы
- 38 Просмотры
-
Последнее сообщение Anonymous
-