Spaces:
Sleeping
Sleeping
Commit ·
274df0f
1
Parent(s): 8900a2d
first training
Browse files- __pycache__/model.cpython-310.pyc +0 -0
- data/MNIST/raw/t10k-images-idx3-ubyte +3 -0
- data/MNIST/raw/t10k-images-idx3-ubyte.gz +3 -0
- data/MNIST/raw/t10k-labels-idx1-ubyte +3 -0
- data/MNIST/raw/t10k-labels-idx1-ubyte.gz +3 -0
- data/MNIST/raw/train-images-idx3-ubyte +3 -0
- data/MNIST/raw/train-images-idx3-ubyte.gz +3 -0
- data/MNIST/raw/train-labels-idx1-ubyte +3 -0
- data/MNIST/raw/train-labels-idx1-ubyte.gz +3 -0
- model.py +19 -14
- runs/Movieposter/00003/default/metadata.tsv +3 -0
- runs/Movieposter/00003/default/sprite.png +3 -0
- runs/Movieposter/00003/default/tensors.tsv +3 -0
- runs/Movieposter/events.out.tfevents.1772969768.DESKTOP-5TAQJI5.15764.0 +3 -0
- runs/Movieposter/events.out.tfevents.1772971673.DESKTOP-5TAQJI5.21220.0 +3 -0
- runs/Movieposter/events.out.tfevents.1772972078.DESKTOP-5TAQJI5.8588.0 +3 -0
- runs/Movieposter/projector_config.pbtxt +10 -0
- train.py +144 -0
- weights/movieposter_net.pth +3 -0
__pycache__/model.cpython-310.pyc
ADDED
|
Binary file (1.36 kB). View file
|
|
|
data/MNIST/raw/t10k-images-idx3-ubyte
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:0fa7898d509279e482958e8ce81c8e77db3f2f8254e26661ceb7762c4d494ce7
|
| 3 |
+
size 7840016
|
data/MNIST/raw/t10k-images-idx3-ubyte.gz
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:8d422c7b0a1c1c79245a5bcf07fe86e33eeafee792b84584aec276f5a2dbc4e6
|
| 3 |
+
size 1648877
|
data/MNIST/raw/t10k-labels-idx1-ubyte
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:ff7bcfd416de33731a308c3f266cc351222c34898ecbeaf847f06e48f7ec33f2
|
| 3 |
+
size 10008
|
data/MNIST/raw/t10k-labels-idx1-ubyte.gz
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:f7ae60f92e00ec6debd23a6088c31dbd2371eca3ffa0defaefb259924204aec6
|
| 3 |
+
size 4542
|
data/MNIST/raw/train-images-idx3-ubyte
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:ba891046e6505d7aadcbbe25680a0738ad16aec93bde7f9b65e87a2fc25776db
|
| 3 |
+
size 47040016
|
data/MNIST/raw/train-images-idx3-ubyte.gz
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:440fcabf73cc546fa21475e81ea370265605f56be210a4024d2ca8f203523609
|
| 3 |
+
size 9912422
|
data/MNIST/raw/train-labels-idx1-ubyte
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:65a50cbbf4e906d70832878ad85ccda5333a97f0f4c3dd2ef09a8a9eef7101c5
|
| 3 |
+
size 60008
|
data/MNIST/raw/train-labels-idx1-ubyte.gz
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:3552534a0a558bbed6aed32b30c495cca23d567ec52cac8be1a0730e8010255c
|
| 3 |
+
size 28881
|
model.py
CHANGED
|
@@ -3,29 +3,34 @@ import torch.nn as nn
|
|
| 3 |
import torch.nn.functional as F
|
| 4 |
|
| 5 |
class MovieposterNet(nn.Module):
|
| 6 |
-
def __init__(self):
|
| 7 |
super(MovieposterNet, self).__init__()
|
| 8 |
-
|
| 9 |
-
self.
|
| 10 |
-
self.
|
| 11 |
-
self.
|
| 12 |
-
|
| 13 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 14 |
|
| 15 |
def forward(self, x):
|
| 16 |
-
x = F.relu(self.conv1(x))
|
| 17 |
-
x = self.pool(x)
|
| 18 |
-
x =
|
| 19 |
-
x = self.pool(x)
|
| 20 |
-
x=torch.flatten(x,1)
|
| 21 |
x = F.relu(self.fc1(x))
|
| 22 |
x = F.relu(self.fc2(x))
|
| 23 |
x = self.fc3(x)
|
| 24 |
return x
|
| 25 |
|
| 26 |
-
|
| 27 |
def get_features(self, x):
|
|
|
|
| 28 |
x = self.pool(F.relu(self.conv1(x)))
|
| 29 |
x = self.pool(F.relu(self.conv2(x)))
|
| 30 |
-
x =
|
| 31 |
return x
|
|
|
|
| 3 |
import torch.nn.functional as F
|
| 4 |
|
| 5 |
class MovieposterNet(nn.Module):
|
| 6 |
+
def __init__(self, num_classes=10):
|
| 7 |
super(MovieposterNet, self).__init__()
|
| 8 |
+
# Entrée : 3 canaux (RGB), 8 filtres, noyau 5x5
|
| 9 |
+
self.conv1 = nn.Conv2d(3, 8, 5)
|
| 10 |
+
self.conv2 = nn.Conv2d(8, 16, 5)
|
| 11 |
+
self.pool = nn.MaxPool2d(2, 2)
|
| 12 |
+
|
| 13 |
+
# Calcul des dimensions après convolutions et pooling :
|
| 14 |
+
# Input: (3, 224, 224)
|
| 15 |
+
# Conv1: 224 - 5 + 1 = 220 -> Pool: 110
|
| 16 |
+
# Conv2: 110 - 5 + 1 = 106 -> Pool: 53
|
| 17 |
+
# Taille aplatie : 16 * 53 * 53 = 44944
|
| 18 |
+
self.fc1 = nn.Linear(16 * 53 * 53, 128)
|
| 19 |
+
self.fc2 = nn.Linear(128, 64)
|
| 20 |
+
self.fc3 = nn.Linear(64, num_classes)
|
| 21 |
|
| 22 |
def forward(self, x):
|
| 23 |
+
x = self.pool(F.relu(self.conv1(x)))
|
| 24 |
+
x = self.pool(F.relu(self.conv2(x)))
|
| 25 |
+
x = torch.flatten(x, 1)
|
|
|
|
|
|
|
| 26 |
x = F.relu(self.fc1(x))
|
| 27 |
x = F.relu(self.fc2(x))
|
| 28 |
x = self.fc3(x)
|
| 29 |
return x
|
| 30 |
|
|
|
|
| 31 |
def get_features(self, x):
|
| 32 |
+
# Pour TensorBoard : extraction des caractéristiques avant les couches denses
|
| 33 |
x = self.pool(F.relu(self.conv1(x)))
|
| 34 |
x = self.pool(F.relu(self.conv2(x)))
|
| 35 |
+
x = torch.flatten(x, 1)
|
| 36 |
return x
|
runs/Movieposter/00003/default/metadata.tsv
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:dde9687965705836c2844ef4737cdae31c7c5c22a19aecb5e204e64f68269044
|
| 3 |
+
size 456
|
runs/Movieposter/00003/default/sprite.png
ADDED
|
|
Git LFS Details
|
runs/Movieposter/00003/default/tensors.tsv
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:0b65839a3628693becb0a65a290fb7ae1b291ba33c2e5995a36da7e7a37e3e15
|
| 3 |
+
size 41848595
|
runs/Movieposter/events.out.tfevents.1772969768.DESKTOP-5TAQJI5.15764.0
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:f9cedd73a112b3e6198fe35ca760beafb2f22fe1209aa0f5f767a6c1f0f0c940
|
| 3 |
+
size 239
|
runs/Movieposter/events.out.tfevents.1772971673.DESKTOP-5TAQJI5.21220.0
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:7ed38084b8611ca16178122c6ac4307cdd817d6e51ba9d48f1d5a420f44fcb12
|
| 3 |
+
size 8611
|
runs/Movieposter/events.out.tfevents.1772972078.DESKTOP-5TAQJI5.8588.0
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:0cb8d524bb7d65ce97c42cb1b4bc329da13496f779b0b83e128b008afec80c22
|
| 3 |
+
size 3008529
|
runs/Movieposter/projector_config.pbtxt
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
embeddings {
|
| 2 |
+
tensor_name: "default:00003"
|
| 3 |
+
metadata_path: "00003/default\\metadata.tsv"
|
| 4 |
+
sprite {
|
| 5 |
+
image_path: "00003/default\\sprite.png"
|
| 6 |
+
single_image_dim: 224
|
| 7 |
+
single_image_dim: 224
|
| 8 |
+
}
|
| 9 |
+
tensor_path: "00003/default\\tensors.tsv"
|
| 10 |
+
}
|
train.py
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import argparse
|
| 2 |
+
from statistics import mean
|
| 3 |
+
|
| 4 |
+
import torch
|
| 5 |
+
import torchvision
|
| 6 |
+
import torchvision.transforms as transforms
|
| 7 |
+
import torch.nn as nn
|
| 8 |
+
import torch.nn.functional as F
|
| 9 |
+
import torch.optim as optim
|
| 10 |
+
from tqdm import tqdm
|
| 11 |
+
from torch.utils.tensorboard import SummaryWriter
|
| 12 |
+
from torchvision import datasets
|
| 13 |
+
from torch.utils.data import DataLoader, random_split
|
| 14 |
+
|
| 15 |
+
from model import MovieposterNet
|
| 16 |
+
|
| 17 |
+
# setting device on GPU if available, else CPU
|
| 18 |
+
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
|
| 19 |
+
|
| 20 |
+
def train(net, optimizer, loader, writer,epochs=10):
|
| 21 |
+
criterion = nn.CrossEntropyLoss()
|
| 22 |
+
for epoch in range(epochs):
|
| 23 |
+
running_loss = []
|
| 24 |
+
t = tqdm(loader)
|
| 25 |
+
for x, y in t:
|
| 26 |
+
x, y = x.to(device), y.to(device)
|
| 27 |
+
outputs = net(x)
|
| 28 |
+
loss = criterion(outputs, y)
|
| 29 |
+
running_loss.append(loss.item())
|
| 30 |
+
optimizer.zero_grad()
|
| 31 |
+
loss.backward()
|
| 32 |
+
optimizer.step()
|
| 33 |
+
t.set_description(f'training loss: {mean(running_loss)}')
|
| 34 |
+
writer.add_scalar('training loss', mean(running_loss), epoch)
|
| 35 |
+
|
| 36 |
+
|
| 37 |
+
def test(model, dataloader):
|
| 38 |
+
test_corrects = 0
|
| 39 |
+
total = 0
|
| 40 |
+
with torch.no_grad():
|
| 41 |
+
for x, y in dataloader:
|
| 42 |
+
x = x.to(device)
|
| 43 |
+
y = y.to(device)
|
| 44 |
+
y_hat = model(x).argmax(1)
|
| 45 |
+
test_corrects += y_hat.eq(y).sum().item()
|
| 46 |
+
total += y.size(0)
|
| 47 |
+
return test_corrects / total
|
| 48 |
+
|
| 49 |
+
if __name__=='__main__':
|
| 50 |
+
|
| 51 |
+
parser = argparse.ArgumentParser()
|
| 52 |
+
|
| 53 |
+
parser.add_argument('--exp_name', type=str, default = 'Movieposter', help='experiment name')
|
| 54 |
+
parser.add_argument('--epochs', type=int, default = int(10), help='nb of epochs')
|
| 55 |
+
parser.add_argument('--batch_size', type=int, default = int(64), help='batch size')
|
| 56 |
+
parser.add_argument('--lr', type=float, default = float(1e-3), help='learning rate')
|
| 57 |
+
|
| 58 |
+
|
| 59 |
+
args = parser.parse_args()
|
| 60 |
+
print(args.exp_name)
|
| 61 |
+
exp_name = args.exp_name
|
| 62 |
+
epochs = args.epochs
|
| 63 |
+
batch_size = args.batch_size
|
| 64 |
+
lr = args.lr
|
| 65 |
+
|
| 66 |
+
writer = SummaryWriter(f'runs/Movieposter')
|
| 67 |
+
|
| 68 |
+
# 1. Définition des transformations
|
| 69 |
+
# Les posters sont en couleur (3 canaux) et de tailles variées, contrairement à MNIST.
|
| 70 |
+
transform = transforms.Compose([
|
| 71 |
+
transforms.Resize((224, 224)), # Redimensionnement standard pour les modèles de vision
|
| 72 |
+
transforms.ToTensor(),
|
| 73 |
+
transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5)) # Normalisation sur 3 canaux (RGB)
|
| 74 |
+
])
|
| 75 |
+
|
| 76 |
+
# 2. Chargement du dataset complet
|
| 77 |
+
# Le chemin '../' permet de remonter d'un niveau par rapport au dossier 'projet_AIF'
|
| 78 |
+
data_dir = '../sorted_movie_posters_paligema'
|
| 79 |
+
full_dataset = datasets.ImageFolder(root=data_dir, transform=transform)
|
| 80 |
+
|
| 81 |
+
# 3. Division en train/test (ex: 80% train, 20% test)
|
| 82 |
+
train_size = int(0.8 * len(full_dataset))
|
| 83 |
+
test_size = len(full_dataset) - train_size
|
| 84 |
+
trainset, testset = random_split(full_dataset, [train_size, test_size])
|
| 85 |
+
|
| 86 |
+
# 4. Création des DataLoaders
|
| 87 |
+
trainloader = DataLoader(trainset, batch_size=batch_size, shuffle=True, num_workers=2)
|
| 88 |
+
testloader = DataLoader(testset, batch_size=batch_size, shuffle=False, num_workers=2)
|
| 89 |
+
|
| 90 |
+
# Accès aux classes (genres)
|
| 91 |
+
classes = full_dataset.classes
|
| 92 |
+
print(f"Classes détectées : {classes}")
|
| 93 |
+
|
| 94 |
+
|
| 95 |
+
net =MovieposterNet().to(device)
|
| 96 |
+
|
| 97 |
+
# setting net on device(GPU if available, else CPU)
|
| 98 |
+
net = net.to(device)
|
| 99 |
+
optimizer = optim.SGD(net.parameters(), lr=lr)
|
| 100 |
+
|
| 101 |
+
train(net, optimizer,trainloader, writer, epochs)
|
| 102 |
+
test_acc = test(net,testloader)
|
| 103 |
+
print(f'Test accuracy: {test_acc}')
|
| 104 |
+
|
| 105 |
+
# 1. Gestion du dossier de sauvegarde des poids
|
| 106 |
+
import os
|
| 107 |
+
if not os.path.exists('weights'):
|
| 108 |
+
os.makedirs('weights')
|
| 109 |
+
|
| 110 |
+
torch.save(net.state_dict(), 'weights/movieposter_net.pth')
|
| 111 |
+
|
| 112 |
+
# 2. Récupération d'un échantillon de données pour TensorBoard
|
| 113 |
+
# On utilise le loader pour obtenir des tenseurs déjà transformés
|
| 114 |
+
dataiter = iter(trainloader)
|
| 115 |
+
images, labels = next(dataiter)
|
| 116 |
+
|
| 117 |
+
# On limite à 64 images pour la visualisation et on envoie sur le device
|
| 118 |
+
images = images[:64].to(device)
|
| 119 |
+
labels = labels[:64].to(device)
|
| 120 |
+
|
| 121 |
+
# 3. Enregistrement du graphe du modèle
|
| 122 |
+
# Vérifiez que les dimensions d'entrée du modèle correspondent (ex: 3, 224, 224)
|
| 123 |
+
writer.add_graph(net, images)
|
| 124 |
+
|
| 125 |
+
# 4. Enregistrement d'une grille d'images
|
| 126 |
+
img_grid = torchvision.utils.make_grid(images)
|
| 127 |
+
writer.add_image('movieposter_samples', img_grid)
|
| 128 |
+
|
| 129 |
+
# 5. Projecteur d'embeddings
|
| 130 |
+
# get_features() doit être définie dans MovieposterNet pour retourner l'avant-dernière couche
|
| 131 |
+
with torch.no_grad():
|
| 132 |
+
try:
|
| 133 |
+
embeddings = net.get_features(images)
|
| 134 |
+
# Conversion des indices en noms de classes pour la lisibilité
|
| 135 |
+
metadata = [classes[l] for l in labels]
|
| 136 |
+
writer.add_embedding(embeddings,
|
| 137 |
+
metadata=metadata,
|
| 138 |
+
label_img=images,
|
| 139 |
+
global_step=epochs)
|
| 140 |
+
except AttributeError:
|
| 141 |
+
print("Erreur : La méthode get_features n'est pas définie dans MovieposterNet.")
|
| 142 |
+
|
| 143 |
+
# 6. Fermeture du SummaryWriter
|
| 144 |
+
writer.close()
|
weights/movieposter_net.pth
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:24daa4b8600c1c61c2a05b129871ee80c38b00d582b81991611c2381f45d68c4
|
| 3 |
+
size 23066885
|