File size: 3,023 Bytes
db8c322
 
aa8d5ee
 
 
a425514
aa8d5ee
 
a425514
aa8d5ee
 
 
ee4d02f
 
 
 
db8c322
aa8d5ee
 
 
 
 
db8c322
aa8d5ee
db8c322
 
aa8d5ee
 
 
 
 
db8c322
aa8d5ee
db8c322
 
aa8d5ee
a425514
db8c322
aa8d5ee
 
 
 
 
 
db8c322
aa8d5ee
 
 
 
 
 
 
db8c322
aa8d5ee
 
 
 
db8c322
aa8d5ee
 
db8c322
 
aa8d5ee
 
 
 
 
 
 
db8c322
aa8d5ee
 
 
 
 
 
 
db8c322
aa8d5ee
 
 
 
 
 
db8c322
aa8d5ee
 
 
 
 
 
 
db8c322
aa8d5ee
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
import os
import numpy as np
import tensorflow as tf
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.applications import EfficientNetV2B1
from tensorflow.keras.models import Model
from tensorflow.keras.layers import Dense, Dropout, GlobalAveragePooling2D
from tensorflow.keras.callbacks import EarlyStopping, ModelCheckpoint, ReduceLROnPlateau
from tensorflow.keras.optimizers import Adam
from sklearn.utils.class_weight import compute_class_weight

# ==================== Paths ====================
# Define paths
base_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '../'))
train_dir = os.path.join(base_dir, 'combine_dataset/train')
val_dir = os.path.join(base_dir, 'combine_dataset/test')

# ==================== Parameters ====================
img_size = (192, 192)  # Recommended for EfficientNetV2B1
batch_size = 32
epochs = 30
num_classes = 7

# ==================== Data Augmentation ====================
train_datagen = ImageDataGenerator(
    rescale=1./255,
    rotation_range=10,
    zoom_range=0.1,
    width_shift_range=0.05,
    height_shift_range=0.05,
    brightness_range=[0.9, 1.1],
    horizontal_flip=True,
    fill_mode='nearest'
)

val_datagen = ImageDataGenerator(rescale=1./255)

train_generator = train_datagen.flow_from_directory(
    train_dir,
    target_size=img_size,
    batch_size=batch_size,
    class_mode='categorical',
    shuffle=True
)

val_generator = val_datagen.flow_from_directory(
    val_dir,
    target_size=img_size,
    batch_size=batch_size,
    class_mode='categorical',
    shuffle=False
)

# ==================== Compute Class Weights ====================
labels = train_generator.classes
class_weights = compute_class_weight(class_weight='balanced', classes=np.unique(labels), y=labels)
class_weights = dict(enumerate(class_weights))

# ==================== Build Model ====================
base_model = EfficientNetV2B1(include_top=False, input_shape=(192, 192, 3), weights='imagenet')
x = base_model.output
x = GlobalAveragePooling2D()(x)
x = Dropout(0.4)(x)
output = Dense(num_classes, activation='softmax')(x)
model = Model(inputs=base_model.input, outputs=output)

# ==================== Compile Model ====================
optimizer = Adam(learning_rate=1e-5)
model.compile(optimizer=optimizer, loss='categorical_crossentropy', metrics=['accuracy'])

# ==================== Callbacks ====================
checkpoint = ModelCheckpoint(
    "/content/emotion_model.keras",
    monitor='val_accuracy',
    save_best_only=True,
    verbose=1
)

early_stop = EarlyStopping(
    monitor='val_loss',
    patience=7,
    restore_best_weights=True,
    verbose=1
)

lr_schedule = ReduceLROnPlateau(
    monitor='val_loss',
    factor=0.5,
    patience=3,
    verbose=1,
    min_lr=1e-6
)

# ==================== Train Model ====================
model.fit(
    train_generator,
    validation_data=val_generator,
    epochs=epochs,
    callbacks=[checkpoint, early_stop, lr_schedule],
    class_weight=class_weights
)