zeynepbkn01 commited on
Commit
8386b75
·
verified ·
1 Parent(s): b8fb7a6

Upload create_model.py

Browse files
Files changed (1) hide show
  1. create_model.py +292 -0
create_model.py ADDED
@@ -0,0 +1,292 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ import torch.nn as nn
3
+ from fastai.learner import load_learner
4
+ from safetensors.torch import save_file
5
+ import os
6
+ from PIL import Image
7
+ import numpy as np
8
+
9
+ print("FastAI modelden safetensors modeli oluşturma")
10
+
11
+ # FastAI AdaptiveConcatPool2d sınıfını tanımla
12
+ class AdaptiveConcatPool2d(nn.Module):
13
+ def __init__(self, size=None):
14
+ super().__init__()
15
+ self.ap = nn.AdaptiveAvgPool2d(1)
16
+ self.mp = nn.AdaptiveMaxPool2d(1)
17
+
18
+ def forward(self, x):
19
+ return torch.cat([self.mp(x), self.ap(x)], 1)
20
+
21
+ # Flatten katmanı
22
+ class Flatten(nn.Module):
23
+ def __init__(self):
24
+ super().__init__()
25
+
26
+ def forward(self, x):
27
+ return x.view(x.size(0), -1)
28
+
29
+ # BasicBlock sınıfını tanımla (ResNet34'ten)
30
+ class BasicBlock(nn.Module):
31
+ expansion = 1
32
+
33
+ def __init__(self, inplanes, planes, stride=1, downsample=None):
34
+ super(BasicBlock, self).__init__()
35
+ self.conv1 = nn.Conv2d(inplanes, planes, kernel_size=3, stride=stride, padding=1, bias=False)
36
+ self.bn1 = nn.BatchNorm2d(planes)
37
+ self.relu = nn.ReLU(inplace=True)
38
+ self.conv2 = nn.Conv2d(planes, planes, kernel_size=3, stride=1, padding=1, bias=False)
39
+ self.bn2 = nn.BatchNorm2d(planes)
40
+ self.downsample = downsample
41
+
42
+ def forward(self, x):
43
+ identity = x
44
+
45
+ out = self.conv1(x)
46
+ out = self.bn1(out)
47
+ out = self.relu(out)
48
+
49
+ out = self.conv2(out)
50
+ out = self.bn2(out)
51
+
52
+ if self.downsample is not None:
53
+ identity = self.downsample(x)
54
+
55
+ out += identity
56
+ out = self.relu(out)
57
+
58
+ return out
59
+
60
+ # Tam ResNet34 + FastAI özelleştirmesi
61
+ class EmotionResnet34(nn.Module):
62
+ def __init__(self, num_classes=5):
63
+ super(EmotionResnet34, self).__init__()
64
+
65
+ # İlk katman - ResNet34'ün birinci katmanı
66
+ self.backbone = nn.Sequential(
67
+ nn.Conv2d(3, 64, kernel_size=7, stride=2, padding=3, bias=False),
68
+ nn.BatchNorm2d(64),
69
+ nn.ReLU(inplace=True),
70
+ nn.MaxPool2d(kernel_size=3, stride=2, padding=1)
71
+ )
72
+
73
+ # Layer1 - 3 BasicBlock
74
+ self.layer1 = self._make_layer(64, 64, 3)
75
+
76
+ # Layer2 - 4 BasicBlock
77
+ self.layer2 = self._make_layer(64, 128, 4, stride=2)
78
+
79
+ # Layer3 - 6 BasicBlock
80
+ self.layer3 = self._make_layer(128, 256, 6, stride=2)
81
+
82
+ # Layer4 - 3 BasicBlock
83
+ self.layer4 = self._make_layer(256, 512, 3, stride=2)
84
+
85
+ # FastAI baş kısmı
86
+ self.head = nn.Sequential(
87
+ AdaptiveConcatPool2d(),
88
+ Flatten(),
89
+ nn.BatchNorm1d(1024),
90
+ nn.Dropout(p=0.25),
91
+ nn.Linear(1024, 512, bias=False),
92
+ nn.ReLU(inplace=True),
93
+ nn.BatchNorm1d(512),
94
+ nn.Dropout(p=0.5),
95
+ nn.Linear(512, num_classes, bias=False)
96
+ )
97
+
98
+ def _make_layer(self, inplanes, planes, blocks, stride=1):
99
+ downsample = None
100
+ if stride != 1 or inplanes != planes:
101
+ downsample = nn.Sequential(
102
+ nn.Conv2d(inplanes, planes, kernel_size=1, stride=stride, bias=False),
103
+ nn.BatchNorm2d(planes)
104
+ )
105
+
106
+ layers = []
107
+ layers.append(BasicBlock(inplanes, planes, stride, downsample))
108
+
109
+ for _ in range(1, blocks):
110
+ layers.append(BasicBlock(planes, planes))
111
+
112
+ return nn.Sequential(*layers)
113
+
114
+ def forward(self, x):
115
+ x = self.backbone(x)
116
+ x = self.layer1(x)
117
+ x = self.layer2(x)
118
+ x = self.layer3(x)
119
+ x = self.layer4(x)
120
+ x = self.head(x)
121
+ return x
122
+
123
+ try:
124
+ # Model sınıflarını yükle
125
+ emotions = ["Angry", "Happy", "Neutral", "Sad", "Surprise"]
126
+
127
+ # FastAI modelini yükle
128
+ print("\n1. FastAI modelini yüklüyorum...")
129
+ pkl_path = 'optimized_emotion_classifier.pkl'
130
+ learn = load_learner(pkl_path)
131
+ fastai_model = learn.model
132
+ print("FastAI model yüklendi!")
133
+
134
+ # State dict'i alalım
135
+ fastai_state_dict = fastai_model.state_dict()
136
+
137
+ # Bizim modelimizi oluştur
138
+ print("\n2. PyTorch modelini oluşturuyorum...")
139
+ pytorch_model = EmotionResnet34(len(emotions))
140
+
141
+ # Katman isimlerini eşleştirmek için bir mappping oluştur
142
+ # Bu mapping, originaldeki katmanları bizim modelimizdeki karşılıklarına eşleştirir
143
+ mapping = {}
144
+
145
+ # Tüm katman isimlerini özelleştirelim
146
+ print("\n3. Katman isimlerini eşleştiriyorum...")
147
+
148
+ # Birinci katman (backbone)
149
+ mapping['0.0.weight'] = 'backbone.0.weight'
150
+ mapping['0.1.weight'] = 'backbone.1.weight'
151
+ mapping['0.1.bias'] = 'backbone.1.bias'
152
+ mapping['0.1.running_mean'] = 'backbone.1.running_mean'
153
+ mapping['0.1.running_var'] = 'backbone.1.running_var'
154
+
155
+ # Layer1 (ilk ResNet katmanı)
156
+ for i in range(3): # 3 BasicBlock
157
+ # Her bir BasicBlock için
158
+ for j in ['conv1.weight', 'bn1.weight', 'bn1.bias', 'bn1.running_mean', 'bn1.running_var',
159
+ 'conv2.weight', 'bn2.weight', 'bn2.bias', 'bn2.running_mean', 'bn2.running_var']:
160
+ mapping[f'0.4.{i}.{j}'] = f'layer1.{i}.{j}'
161
+
162
+ # Layer2 (ikinci ResNet katmanı)
163
+ for i in range(4): # 4 BasicBlock
164
+ for j in ['conv1.weight', 'bn1.weight', 'bn1.bias', 'bn1.running_mean', 'bn1.running_var',
165
+ 'conv2.weight', 'bn2.weight', 'bn2.bias', 'bn2.running_mean', 'bn2.running_var']:
166
+ mapping[f'0.5.{i}.{j}'] = f'layer2.{i}.{j}'
167
+
168
+ # Downsample
169
+ if i == 0:
170
+ mapping['0.5.0.downsample.0.weight'] = 'layer2.0.downsample.0.weight'
171
+ mapping['0.5.0.downsample.1.weight'] = 'layer2.0.downsample.1.weight'
172
+ mapping['0.5.0.downsample.1.bias'] = 'layer2.0.downsample.1.bias'
173
+ mapping['0.5.0.downsample.1.running_mean'] = 'layer2.0.downsample.1.running_mean'
174
+ mapping['0.5.0.downsample.1.running_var'] = 'layer2.0.downsample.1.running_var'
175
+
176
+ # Layer3 (üçüncü ResNet katmanı)
177
+ for i in range(6): # 6 BasicBlock
178
+ for j in ['conv1.weight', 'bn1.weight', 'bn1.bias', 'bn1.running_mean', 'bn1.running_var',
179
+ 'conv2.weight', 'bn2.weight', 'bn2.bias', 'bn2.running_mean', 'bn2.running_var']:
180
+ mapping[f'0.6.{i}.{j}'] = f'layer3.{i}.{j}'
181
+
182
+ # Downsample
183
+ if i == 0:
184
+ mapping['0.6.0.downsample.0.weight'] = 'layer3.0.downsample.0.weight'
185
+ mapping['0.6.0.downsample.1.weight'] = 'layer3.0.downsample.1.weight'
186
+ mapping['0.6.0.downsample.1.bias'] = 'layer3.0.downsample.1.bias'
187
+ mapping['0.6.0.downsample.1.running_mean'] = 'layer3.0.downsample.1.running_mean'
188
+ mapping['0.6.0.downsample.1.running_var'] = 'layer3.0.downsample.1.running_var'
189
+
190
+ # Layer4 (dördüncü ResNet katmanı)
191
+ for i in range(3): # 3 BasicBlock
192
+ for j in ['conv1.weight', 'bn1.weight', 'bn1.bias', 'bn1.running_mean', 'bn1.running_var',
193
+ 'conv2.weight', 'bn2.weight', 'bn2.bias', 'bn2.running_mean', 'bn2.running_var']:
194
+ mapping[f'0.7.{i}.{j}'] = f'layer4.{i}.{j}'
195
+
196
+ # Downsample
197
+ if i == 0:
198
+ mapping['0.7.0.downsample.0.weight'] = 'layer4.0.downsample.0.weight'
199
+ mapping['0.7.0.downsample.1.weight'] = 'layer4.0.downsample.1.weight'
200
+ mapping['0.7.0.downsample.1.bias'] = 'layer4.0.downsample.1.bias'
201
+ mapping['0.7.0.downsample.1.running_mean'] = 'layer4.0.downsample.1.running_mean'
202
+ mapping['0.7.0.downsample.1.running_var'] = 'layer4.0.downsample.1.running_var'
203
+
204
+ # Baş kısmı (head)
205
+ mapping['1.2.weight'] = 'head.2.weight'
206
+ mapping['1.2.bias'] = 'head.2.bias'
207
+ mapping['1.2.running_mean'] = 'head.2.running_mean'
208
+ mapping['1.2.running_var'] = 'head.2.running_var'
209
+ mapping['1.4.weight'] = 'head.4.weight'
210
+ mapping['1.6.weight'] = 'head.6.weight'
211
+ mapping['1.6.bias'] = 'head.6.bias'
212
+ mapping['1.6.running_mean'] = 'head.6.running_mean'
213
+ mapping['1.6.running_var'] = 'head.6.running_var'
214
+ mapping['1.8.weight'] = 'head.8.weight'
215
+
216
+ # Ağırlıkları eşleştir
217
+ print("\n4. Ağırlıkları PyTorch modeline aktarıyorum...")
218
+ pytorch_state_dict = {}
219
+ warnings = []
220
+
221
+ for orig_key in fastai_state_dict:
222
+ if orig_key in mapping:
223
+ new_key = mapping[orig_key]
224
+ pytorch_state_dict[new_key] = fastai_state_dict[orig_key]
225
+ else:
226
+ # num_batches_tracked gibi bazı parametreleri yok sayabiliriz
227
+ if not 'num_batches_tracked' in orig_key:
228
+ warnings.append(f"Eşleştirilemeyen anahtar: {orig_key}")
229
+
230
+ # Modelimize yükle
231
+ try:
232
+ pytorch_model.load_state_dict(pytorch_state_dict, strict=False)
233
+ print("Model ağırlıkları başarıyla yüklendi!")
234
+ except Exception as e:
235
+ print(f"Model yüklenirken hata: {e}")
236
+
237
+ if warnings:
238
+ print(f"{len(warnings)} anahtar eşleştirilemedi (önemli olmayabilir)")
239
+
240
+ # Modeli safetensors olarak kaydet
241
+ print("\n5. Modeli safetensors formatında kaydediyorum...")
242
+
243
+ output_path = "emotion_resnet34.safetensors"
244
+ save_file(pytorch_model.state_dict(), output_path)
245
+ print(f"Model başarıyla kaydedildi: {output_path}")
246
+
247
+ # Test bir tahmin yapalım
248
+ print("\n6. Test tahmin yapıyorum...")
249
+ pytorch_model.eval()
250
+
251
+ # Basit bir test görüntüsü oluştur
252
+ def create_test_image():
253
+ img = np.zeros((48, 48), dtype=np.uint8)
254
+ img[10:30, 10:30] = 255 # Beyaz kare
255
+ return Image.fromarray(img).convert('RGB')
256
+
257
+ # Görüntü işleme
258
+ from torchvision import transforms
259
+ transform = transforms.Compose([
260
+ transforms.Resize((224, 224)),
261
+ transforms.ToTensor(),
262
+ transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
263
+ ])
264
+
265
+ test_img = create_test_image()
266
+ input_tensor = transform(test_img).unsqueeze(0)
267
+
268
+ # Tahmin
269
+ with torch.no_grad():
270
+ output = pytorch_model(input_tensor)
271
+ probs = torch.nn.functional.softmax(output, dim=1)[0]
272
+
273
+ # En yüksek olasılık
274
+ _, predicted = torch.max(output, 1)
275
+ emotion = emotions[predicted.item()]
276
+
277
+ print(f"Tahmin Edilen Duygu: {emotion}")
278
+ for i, prob in enumerate(probs):
279
+ print(f"{emotions[i]}: {prob:.6f}")
280
+
281
+ # Model sınıflarını da metin dosyasına kaydet
282
+ with open('model_classes.txt', 'w') as f:
283
+ for emotion in emotions:
284
+ f.write(f"{emotion}\n")
285
+ print("\nModel sınıfları kaydedildi: model_classes.txt")
286
+
287
+ print("\nİşlem tamamlandı!")
288
+
289
+ except Exception as e:
290
+ print(f"Hata: {e}")
291
+ import traceback
292
+ traceback.print_exc()