1import os
2import time
3import torch
4import torch.nn as nn
5from torchvision import transforms
6from PIL import Image
7import matplotlib.pyplot as plt
8from thop import profile
9import numpy as np
10from datetime import datetime
11import warnings
12from sklearn.metrics import average_precision_score
13warnings.filterwarnings("ignore", category=FutureWarning)
14warnings.filterwarnings("ignore", category=UserWarning)
15from transformers import T5Tokenizer, T5ForConditionalGeneration
16
17
18class SimpleCNN(nn.Module):
19 def __init__(self, model_type='c', num_classes=6): # Model tipine göre "model_type" değişkeni "f, c, q" olarak değiştirilebilir. / The ‘model_type’ variable can be changed to ‘f, c, q’ according to the model type.
20 super(SimpleCNN, self).__init__()
21 self.num_classes = num_classes
22 if model_type == 'f':
23 self.conv1 = nn.Conv2d(3, 16, kernel_size=3, stride=1, padding=1)
24 self.conv2 = nn.Conv2d(16, 32, kernel_size=3, stride=1, padding=1)
25 self.conv3 = nn.Conv2d(32, 64, kernel_size=3, stride=1, padding=1)
26 self.fc1 = nn.Linear(64 * 28 * 28, 256)
27 self.dropout = nn.Dropout(0.5)
28 elif model_type == 'c':
29 self.conv1 = nn.Conv2d(3, 32, kernel_size=3, stride=1, padding=1)
30 self.conv2 = nn.Conv2d(32, 64, kernel_size=3, stride=1, padding=1)
31 self.conv3 = nn.Conv2d(64, 128, kernel_size=3, stride=1, padding=1)
32 self.fc1 = nn.Linear(128 * 28 * 28, 512)
33 self.dropout = nn.Dropout(0.5)
34 elif model_type == 'q':
35 self.conv1 = nn.Conv2d(3, 64, kernel_size=3, stride=1, padding=1)
36 self.conv2 = nn.Conv2d(64, 128, kernel_size=3, stride=1, padding=1)
37 self.conv3 = nn.Conv2d(128, 256, kernel_size=3, stride=1, padding=1)
38 self.conv4 = nn.Conv2d(256, 512, kernel_size=3, stride=1, padding=1)
39 self.fc1 = nn.Linear(512 * 14 * 14, 1024)
40 self.dropout = nn.Dropout(0.5)
41
42 self.fc2 = nn.Linear(self.fc1.out_features, num_classes)
43 self.relu = nn.ReLU()
44 self.pool = nn.MaxPool2d(kernel_size=2, stride=2, padding=0)
45
46 def forward(self, x):
47 x = self.pool(self.relu(self.conv1(x)))
48 x = self.pool(self.relu(self.conv2(x)))
49 x = self.pool(self.relu(self.conv3(x)))
50 if hasattr(self, 'conv4'):
51 x = self.pool(self.relu(self.conv4(x)))
52 x = x.view(x.size(0), -1)
53 x = self.relu(self.fc1(x))
54 x = self.dropout(x)
55 x = self.fc2(x)
56 return x
57
58
59def predict_image(model: nn.Module, image_path: str, transform, device):
60 img = Image.open(image_path).convert('RGB')
61 inp = transform(img).unsqueeze(0).to(device)
62 model.eval()
63 with torch.no_grad():
64 out = model(inp)
65 prob = torch.nn.functional.softmax(out, dim=1)
66 pred = prob.argmax(dim=1).item()
67 conf = prob[0, pred].item() * 100
68 return pred, conf, inp, prob
69
70
71def calculate_performance_metrics(model: nn.Module, device, input_size=(1, 3, 224, 224)):
72 model.to(device)
73 x = torch.randn(input_size).to(device)
74 flops, params = profile(model, inputs=(x,), verbose=False)
75 cpu_start = time.time()
76 _ = model(x)
77 cpu_time = (time.time() - cpu_start) * 1000
78 return {
79 'size_pixels': input_size[-1],
80 'speed_cpu_b1': cpu_time,
81 'speed_cpu_b32': cpu_time / 10,
82 'speed_v100_b1': cpu_time / 2,
83 'params_million': params / 1e6,
84 'flops_billion': flops / 1e9
85 }
86
87
88def load_tbai_model(model_dir: str, device):
89 tokenizer = T5Tokenizer.from_pretrained(model_dir)
90 model = T5ForConditionalGeneration.from_pretrained(model_dir).to(device)
91 model.eval()
92 return tokenizer, model
93
94
95def generate_comment_turkce(tokenizer, model, sinif_adi: str, device, max_length: int = 64) -> str:
96 input_text = f"Sınıf: {sinif_adi}"
97 inputs = tokenizer(
98 input_text,
99 return_tensors="pt",
100 padding="longest",
101 truncation=True,
102 max_length=32
103 ).to(device)
104
105 out_ids = model.generate(
106 **inputs,
107 max_length=max_length,
108 do_sample=True,
109 top_k=50,
110 top_p=0.95,
111 no_repeat_ngram_size=2,
112 early_stopping=True
113 )
114 comment = tokenizer.decode(out_ids[0], skip_special_tokens=True)
115 return comment
116
117
118def save_monitoring_log(predicted_class, confidence, comment_text,
119 metrics, class_names, image_path, ap_scores=None, map_score=None,
120 log_path='monitoring_log.txt'):
121 os.makedirs(os.path.dirname(log_path) or '.', exist_ok=True)
122 timestamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
123 img_name = os.path.basename(image_path)
124
125 log = f"""
126===== Model Monitoring Log =====
127Timestamp: {timestamp}
128Image: {img_name}
129Predicted Class: {class_names[predicted_class]}
130Confidence: {confidence:.2f}%
131Comment: {comment_text}
132
133-- Performance Metrics --
134Params (M): {metrics['params_million']:.2f}
135FLOPs (B): {metrics['flops_billion']:.2f}
136Image Size: {metrics['size_pixels']}x{metrics['size_pixels']}
137CPU Time b1 (ms): {metrics['speed_cpu_b1']:.2f}
138V100 Time b1 (ms): {metrics['speed_v100_b1']:.2f}
139V100 Time b32 (ms): {metrics['speed_cpu_b32']:.2f}
140
141-- AP/mAP Metrics --"""
142
143 if ap_scores is not None and map_score is not None:
144 log += f"\nmAP: {map_score:.4f}"
145 for i, (class_name, ap) in enumerate(zip(class_names, ap_scores)):
146 log += f"\nAP_{class_name}: {ap:.4f}"
147 else:
148 log += "\nAP/mAP: Not calculated (single image)"
149
150 log += "\n================================\n"
151
152 with open(log_path, 'a', encoding='utf-8') as f:
153 f.write(log)
154
155
156def main():
157 device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
158 print(device)
159 transform = transforms.Compose([
160 transforms.Resize((224, 224)),
161 transforms.ToTensor(),
162 transforms.Normalize([0.485, 0.456, 0.406],
163 [0.229, 0.224, 0.225])
164 ])
165
166 class_names = [
167 'Alzheimer Disease',
168 'Mild Alzheimer Risk',
169 'Moderate Alzheimer Risk',
170 'Very Mild Alzheimer Risk',
171 'No Risk',
172 'Parkinson Disease'
173 ]
174
175 model = SimpleCNN(model_type='c', num_classes=len(class_names)).to(device) # Model tipine göre "model_type" değişkeni "f, c, q" olarak değiştirilebilir. / The ‘model_type’ variable can be changed to ‘f, c, q’ according to the model type.
176 model_path = 'Vbai/model/file/path'
177 try:
178 model.load_state_dict(torch.load(model_path, map_location=device))
179 except Exception as e:
180 print(f"Görüntü modeli yükleme hatası: {e}")
181 return
182
183 metrics = calculate_performance_metrics(model, device)
184
185 tbai_model_dir = "Tbai/model/dir/path"
186 tokenizer, tbai_model = load_tbai_model(tbai_model_dir, device)
187
188 en2tr = {
189 'Alzheimer Disease': 'Alzheimer Hastalığı',
190 'Mild Alzheimer Risk': 'Hafif Alzheimer Riski',
191 'Moderate Alzheimer Risk': 'Orta Düzey Alzheimer Riski',
192 'Very Mild Alzheimer Risk': 'Çok Hafif Alzheimer Riski',
193 'No Risk': 'Risk Yok',
194 'Parkinson Disease': 'Parkinson Hastalığı'
195 }
196
197 image_path = 'test/images/path'
198
199
200 pred_class_idx, confidence, inp_tensor, predicted_probs = predict_image(model, image_path, transform, device)
201 predicted_class_name = class_names[pred_class_idx]
202
203 print(f"Prediction: {predicted_class_name} ({confidence:.2f}%)")
204 print(f"Confidence: {confidence:.2f}%")
205 print(f"Params (M): {metrics['params_million']:.2f}")
206 print(f"FLOPs (B): {metrics['flops_billion']:.2f}")
207 print(f"Image Size: {metrics['size_pixels']}x{metrics['size_pixels']}")
208 print(f"CPU Time b1 (ms): {metrics['speed_cpu_b1']:.2f}")
209 print(f"V100 Time b1 (ms): {metrics['speed_v100_b1']:.2f}")
210 print(f"V100 Time b32 (ms): {metrics['speed_cpu_b32']:.2f}")
211
212 tr_class_name = en2tr.get(predicted_class_name, predicted_class_name)
213 try:
214 comment_text = generate_comment_turkce(tokenizer, tbai_model, tr_class_name, device)
215 except Exception as e:
216 print(f"Yorum üretme hatası: {e}")
217 comment_text = "Yorum üretilemedi."
218
219 print(f"\nComment (Tbai-DPA 1.0): {comment_text}")
220
221 save_monitoring_log(
222 pred_class_idx, confidence, comment_text,
223 metrics, class_names, image_path)
224
225 img_show = inp_tensor.squeeze(0).permute(1, 2, 0).cpu().numpy()
226 mean = np.array([0.485, 0.456, 0.406])
227 std = np.array([0.229, 0.224, 0.225])
228 img_show = img_show * std + mean
229 img_show_clipped = np.clip(img_show, 0.0, 1.0)
230
231 plt.imshow(img_show_clipped)
232 plt.title(f'{predicted_class_name} — {confidence:.2f}%')
233 plt.axis('off')
234 plt.show()
235
236
237if __name__ == '__main__':
238 main()