minoruskore commited on
Commit
ba5386d
·
1 Parent(s): 7039fca

Añadir implementación inicial de un modelo de evaluación de precisión con interfaz de usuario en Gradio

Browse files
Files changed (3) hide show
  1. app.py +238 -0
  2. etiquetas.txt +10 -0
  3. requirements.txt +5 -0
app.py ADDED
@@ -0,0 +1,238 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ import torch.nn as nn
3
+ from torchvision import models
4
+ import gradio as gr
5
+ import os
6
+ from torch.utils.data import Dataset, DataLoader
7
+ from torchvision import transforms
8
+ from safetensors.torch import load_model
9
+ from datasets import load_dataset
10
+
11
+
12
+ # modelos
13
+ class Stem(nn.Module):
14
+ def __init__(self):
15
+ super(Stem, self).__init__()
16
+ self.conv = nn.Sequential(
17
+ nn.Conv2d(3, 64, kernel_size=7, stride=2),
18
+ nn.MaxPool2d(kernel_size=3, stride=2),
19
+ )
20
+
21
+ def forward(self, x):
22
+ x = self.conv(x)
23
+ return x
24
+
25
+
26
+ class ResidualBlock(nn.Module):
27
+ def __init__(self, in_channels, out_channels, stride=1):
28
+ super(ResidualBlock, self).__init__()
29
+ self.conv1 = nn.Sequential(
30
+ nn.Conv2d(in_channels, out_channels // 4, stride=1, kernel_size=1),
31
+ nn.BatchNorm2d(out_channels // 4),
32
+ nn.ReLU(inplace=True),
33
+ )
34
+ self.conv2 = nn.Sequential(
35
+ nn.Conv2d(
36
+ out_channels // 4,
37
+ out_channels // 4,
38
+ stride=stride,
39
+ kernel_size=3,
40
+ padding=1,
41
+ ),
42
+ nn.BatchNorm2d(out_channels // 4),
43
+ nn.ReLU(inplace=True),
44
+ )
45
+
46
+ self.conv3 = nn.Sequential(
47
+ nn.Conv2d(out_channels // 4, out_channels, kernel_size=1, stride=1),
48
+ nn.BatchNorm2d(out_channels),
49
+ )
50
+
51
+ self.shortcut = (
52
+ nn.Identity()
53
+ if in_channels == out_channels
54
+ else nn.Sequential(
55
+ nn.Conv2d(in_channels, out_channels, kernel_size=1, stride=stride),
56
+ nn.BatchNorm2d(out_channels),
57
+ )
58
+ )
59
+
60
+ self.relu = nn.ReLU(inplace=True)
61
+
62
+ def forward(self, x):
63
+ identity = self.shortcut(x)
64
+ x = self.conv1(x)
65
+ x = self.conv2(x)
66
+ x = self.conv3(x)
67
+ x += identity
68
+ x = self.relu(x)
69
+ return x
70
+
71
+
72
+ def make_layer(in_channels, out_channels, block, num_blocks):
73
+ layers = []
74
+ for i in range(num_blocks):
75
+ layers.append(block(in_channels, out_channels))
76
+ in_channels = out_channels
77
+
78
+ return layers
79
+
80
+
81
+ class FromZero(nn.Module):
82
+ def __init__(self, num_classes=10):
83
+ super(FromZero, self).__init__()
84
+ self.stem = Stem()
85
+ self.layer1 = nn.Sequential(*make_layer(64, 64, ResidualBlock, 2))
86
+ self.layer2 = nn.Sequential(
87
+ ResidualBlock(64, 128, stride=2), ResidualBlock(128, 128)
88
+ )
89
+ self.layer3 = nn.Sequential(
90
+ ResidualBlock(128, 256, stride=2), ResidualBlock(256, 256)
91
+ )
92
+ self.layer4 = nn.Sequential(
93
+ ResidualBlock(256, 512, stride=2), ResidualBlock(512, 512)
94
+ )
95
+
96
+ self.flatten = nn.Flatten()
97
+ self.avgpool = nn.AdaptiveAvgPool2d((1, 1))
98
+ self.fc = nn.Linear(512, num_classes)
99
+
100
+ def forward(self, x):
101
+ x = self.stem(x)
102
+ x = self.layer1(x)
103
+ x = self.layer2(x)
104
+ x = self.layer3(x)
105
+ x = self.layer4(x)
106
+ x = self.avgpool(x)
107
+ x = self.flatten(x)
108
+ x = self.fc(x)
109
+ return x
110
+
111
+
112
+ class PreTrained(nn.Module):
113
+ def __init__(self, num_classes):
114
+ super().__init__()
115
+ self.model = models.resnet18(
116
+ weights=models.ResNet18_Weights.IMAGENET1K_V1, progress=True
117
+ )
118
+ for param in self.model.parameters():
119
+ param.requires_grad = False
120
+
121
+ self.model.fc = nn.Sequential(
122
+ nn.Linear(self.model.fc.in_features, 512),
123
+ nn.ReLU(inplace=True),
124
+ nn.Linear(512, num_classes),
125
+ )
126
+
127
+ def forward(self, x):
128
+ return self.model(x)
129
+
130
+
131
+ with open("etiquetas.txt", "r") as f:
132
+ etiquetas = f.read().splitlines()[1:]
133
+ num_clases = len(etiquetas)
134
+ codigo = {etiqueta.lower(): i for i, etiqueta in enumerate(etiquetas)}
135
+
136
+
137
+ def codificar_etiqueta(etiqueta):
138
+ return codigo[etiqueta]
139
+
140
+ dataset = load_dataset(
141
+ "minoruskore/elementosparaevaluarclases", split="train"
142
+ )
143
+
144
+
145
+ class imagenDataset(Dataset):
146
+ def __init__(self, dt, transform):
147
+ self.dt = dt
148
+ self.tr = transform
149
+
150
+ def __len__(self):
151
+ return len(self.dt)
152
+
153
+ def __getitem__(self, idx):
154
+ row = self.dt[idx]
155
+ imagen = row["image"].convert("RGB")
156
+ label = row["etiqueta"].lower()
157
+ label = codificar_etiqueta(label)
158
+ imagen = self.tr(imagen)
159
+ return imagen, label
160
+
161
+
162
+ tr = transforms.Compose([transforms.Resize([256, 256]), transforms.ToTensor()])
163
+ test_dataset = imagenDataset(dataset, transform=tr)
164
+ cpus = os.cpu_count()
165
+ test_dataloader = DataLoader(test_dataset, batch_size=500, num_workers=cpus)
166
+
167
+
168
+ def multiclass_accuracy(predictions, labels):
169
+
170
+ # Obtén las clases predichas (la clase con la mayor probabilidad)
171
+ _, predicted_classes = torch.max(predictions, 1)
172
+
173
+ # Compara las clases predichas con las etiquetas verdaderas
174
+ correct_predictions = (predicted_classes == labels).sum().item()
175
+
176
+ # Calcula la precisión
177
+ accuracy = correct_predictions / labels.size(0)
178
+
179
+ return accuracy
180
+
181
+
182
+ def cargar_evaluar_modelo(archivo, tipo_modelo):
183
+ try:
184
+ if tipo_modelo == "tarea_7":
185
+ modelo = FromZero(num_clases)
186
+
187
+ elif tipo_modelo == "tarea_8":
188
+ modelo = PreTrained(num_clases)
189
+
190
+ load_model(modelo, archivo)
191
+ modelo.eval()
192
+ device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
193
+ modelo.to(device)
194
+ accuracy = 0
195
+ with torch.no_grad():
196
+ for imagenes, etiquetas in test_dataloader:
197
+ imagenes = imagenes.to(device)
198
+ etiquetas = etiquetas.to(device)
199
+ predictions = modelo(imagenes)
200
+ accuracy += multiclass_accuracy(predictions, etiquetas)
201
+ accuracy = accuracy / len(test_dataloader)
202
+ return accuracy
203
+ except Exception as e:
204
+ return f"Error: {str(e)}"
205
+
206
+
207
+ def evaluate_interface(model_file, model_type):
208
+ if model_file is None:
209
+ return "Por favor, carga un archivo .safetensor"
210
+
211
+ # Verificamos que el archivo sea .safetensor
212
+ if not model_file.name.endswith(".safetensor"):
213
+ return "Por favor, carga un archivo con extensión .safetensor"
214
+
215
+ # Evaluamos el modelo
216
+ accuracy = cargar_evaluar_modelo(
217
+ model_file.name,
218
+ model_type,
219
+ )
220
+
221
+ if isinstance(accuracy, float):
222
+ return f"Precisión del modelo: {accuracy*100:.2f}%"
223
+ else:
224
+ return accuracy
225
+
226
+
227
+ demo = gr.Interface(
228
+ fn=evaluate_interface,
229
+ inputs=[
230
+ gr.File(label="Archivo del modelo (.safetensor)"),
231
+ gr.Radio(["tarea_7", "tarea_8"], label="Tipo de modelo", value="tarea_7"),
232
+ ],
233
+ outputs=gr.Textbox(label="Resultado", lines=1),
234
+ title="Evaluador de Tareas 7 y 8",
235
+ description="Carga un archivo .safetensor de la tarea 7 o 8 y evalúa su precisión en el conjunto de datos de evaluación.",
236
+ )
237
+
238
+ demo.launch()
etiquetas.txt ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ dummy
2
+ Ilustración
3
+ Mujer joven
4
+ Mujer mayor
5
+ Niña
6
+ Hombre joven
7
+ Hombre mayor
8
+ Niño
9
+ Perro
10
+ Gato
requirements.txt ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ torch
2
+ torchvision
3
+ torchaudio
4
+ safetensors
5
+ torcheval