cyberai-1
updat file
7902c8d
Raw
History Blame Contribute Delete
5.6 kB
"""
models/cnn.py
CNN pour images RGB 3 canaux β€” Intel Image Classification (228Γ—228, 6 classes).
RÈGLE DE NORMALISATION :
La normalisation est faite UNIQUEMENT dans utils/prep.py (pipeline de donnΓ©es).
Les modèles reçoivent des images déjà normalisées — il n'y a PAS de couche
Rescaling à l'intérieur des modèles. Cela garantit un comportement identique
entre training, evaluation et production (Flask).
"""
# ── PyTorch ───────────────────────────────────────────────────────────────────
import torch.nn as nn
import torch.nn.functional as F
class CNN_Torch(nn.Module):
"""
CNN PyTorch 4 blocs pour images RGB (3 canaux, 150Γ—150).
EntrΓ©e : (B, 3, 150, 150) β€” normalisΓ©e ImageNet (mean/std)
Sortie : (B, num_classes) β€” logits bruts (CrossEntropyLoss)
Architecture :
Block 1 : Conv(3β†’32)Γ—2 + BN + ReLU + MaxPool(2) 150β†’75
Block 2 : Conv(32β†’64)Γ—2 + BN + ReLU + MaxPool(2) + Drop2d 75β†’37
Block 3 : Conv(64β†’128)Γ—2 + BN + ReLU + MaxPool(2) + Drop2d 37β†’18
Block 4 : Conv(128β†’256)Γ—2+ BN + ReLU + MaxPool(2) + Drop2d 18β†’9
GAP : AdaptiveAvgPool2d(1) β†’(B,256)
Head : Linear(256β†’256) + ReLU + Dropout + Linear(256β†’C)
"""
def __init__(self, num_classes: int = 6):
super().__init__()
self.features = nn.Sequential(
# Block 1 β€” 150Γ—150 β†’ 75Γ—75
nn.Conv2d(3, 32, kernel_size=3, padding=1, bias=False),
nn.BatchNorm2d(32), nn.ReLU(inplace=True),
nn.Conv2d(32, 32, kernel_size=3, padding=1, bias=False),
nn.BatchNorm2d(32), nn.ReLU(inplace=True),
nn.MaxPool2d(2),
# Block 2 β€” 75Γ—75 β†’ 37Γ—37
nn.Conv2d(32, 64, kernel_size=3, padding=1, bias=False),
nn.BatchNorm2d(64), nn.ReLU(inplace=True),
nn.Conv2d(64, 64, kernel_size=3, padding=1, bias=False),
nn.BatchNorm2d(64), nn.ReLU(inplace=True),
nn.MaxPool2d(2), nn.Dropout2d(0.10),
# Block 3 β€” 37Γ—37 β†’ 18Γ—18
nn.Conv2d(64, 128, kernel_size=3, padding=1, bias=False),
nn.BatchNorm2d(128), nn.ReLU(inplace=True),
nn.Conv2d(128, 128, kernel_size=3, padding=1, bias=False),
nn.BatchNorm2d(128), nn.ReLU(inplace=True),
nn.MaxPool2d(2), nn.Dropout2d(0.15),
# Block 4 β€” 18Γ—18 β†’ 9Γ—9
nn.Conv2d(128, 256, kernel_size=3, padding=1, bias=False),
nn.BatchNorm2d(256), nn.ReLU(inplace=True),
nn.Conv2d(256, 256, kernel_size=3, padding=1, bias=False),
nn.BatchNorm2d(256), nn.ReLU(inplace=True),
nn.MaxPool2d(2), nn.Dropout2d(0.20),
)
# (B,256,9,9) β†’ (B,256,1,1) β†’ (B,256)
self.gap = nn.AdaptiveAvgPool2d(1)
self.classifier = nn.Sequential(
nn.Flatten(),
nn.Linear(256, 256),
nn.ReLU(inplace=True),
nn.Dropout(0.30),
nn.Linear(256, num_classes),
)
def forward(self, x):
return self.classifier(self.gap(self.features(x)))
# ── TensorFlow / Keras ────────────────────────────────────────────────────────
def build_cnn_tf(num_classes: int = 6, input_shape: tuple = (228, 228, 3)):
"""
CNN TF reproduisant l'architecture du notebook de rΓ©fΓ©rence hassanraof.
Source : https://www.kaggle.com/code/hassanraof/intel-image-classification
EntrΓ©e : (B, 228, 228, 3) β€” valeurs [0, 1] normalisΓ©es par prep.py
Sortie : (B, num_classes) β€” softmax
Architecture (5 blocs conv) :
Block 1 : Conv(32, 5Γ—5) β†’ ReLU β†’ MaxPool(2,2)
Block 2 : Conv(32, 5Γ—5) β†’ ReLU β†’ MaxPool(2,2)
Block 3 : Conv(32, 3Γ—3) β†’ ReLU β†’ MaxPool(2,2)
Block 4 : Conv(64, 3Γ—3) β†’ ReLU β†’ MaxPool(2,2)
Block 5 : Conv(64, 3Γ—3) β†’ ReLU β†’ MaxPool(2,2)
Head : Flatten β†’ Dense(1024) β†’ Dropout(0.20)
β†’ Dense(124) β†’ Dropout(0.20)
β†’ Dense(num_classes, softmax)
⚠️ PAS de couche Rescaling ici β€” la normalisation est faite dans prep.py.
Ajouter Rescaling ici causerait une double normalisation.
"""
from tensorflow.keras import layers, models
return models.Sequential([
layers.Input(shape=input_shape),
# ← PAS de Rescaling ici
# Block 1
layers.Conv2D(32, kernel_size=(5, 5), activation="relu"),
layers.MaxPooling2D(2, 2),
# Block 2
layers.Conv2D(32, kernel_size=(5, 5), activation="relu"),
layers.MaxPooling2D(2, 2),
# Block 3
layers.Conv2D(32, kernel_size=(3, 3), activation="relu"),
layers.MaxPooling2D(2, 2),
# Block 4
layers.Conv2D(64, kernel_size=(3, 3), activation="relu"),
layers.MaxPooling2D(2, 2),
# Block 5
layers.Conv2D(64, kernel_size=(3, 3), activation="relu"),
layers.MaxPooling2D(2, 2),
# Head
layers.Flatten(),
layers.Dense(1024, activation="relu"),
layers.Dropout(0.20),
layers.Dense(124, activation="relu"),
layers.Dropout(0.20),
layers.Dense(num_classes, activation="softmax"),
], name="CNN_TF_hassanraof")