| """ |
| 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). |
| """ |
|
|
| |
| 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( |
| |
| 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), |
|
|
| |
| 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), |
|
|
| |
| 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), |
|
|
| |
| 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), |
| ) |
|
|
| |
| 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))) |
|
|
|
|
| |
| 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), |
| |
|
|
| |
| layers.Conv2D(32, kernel_size=(5, 5), activation="relu"), |
| layers.MaxPooling2D(2, 2), |
|
|
| |
| layers.Conv2D(32, kernel_size=(5, 5), activation="relu"), |
| layers.MaxPooling2D(2, 2), |
|
|
| |
| layers.Conv2D(32, kernel_size=(3, 3), activation="relu"), |
| layers.MaxPooling2D(2, 2), |
|
|
| |
| layers.Conv2D(64, kernel_size=(3, 3), activation="relu"), |
| layers.MaxPooling2D(2, 2), |
|
|
| |
| layers.Conv2D(64, kernel_size=(3, 3), activation="relu"), |
| layers.MaxPooling2D(2, 2), |
|
|
| |
| 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") |
|
|