ziffir commited on
Commit
f198920
·
verified ·
1 Parent(s): c422187

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +73 -344
app.py CHANGED
@@ -1,376 +1,105 @@
1
- # app.py - Orta Ölçek Jeo-Referanslama
2
- import torch
3
- import torch.nn as nn
4
- from transformers import AutoModel, AutoImageProcessor
5
- from datasets import load_dataset
6
- import torchvision.transforms as transforms
7
  from PIL import Image
8
  import numpy as np
9
- import gradio as gr
10
- import matplotlib.pyplot as plt
11
- import folium
12
- import tempfile
13
- import os
14
- from tqdm import tqdm
15
  import json
16
 
17
- class MediumScaleGeoSystem:
18
  def __init__(self):
19
- self.device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
20
- print(f"Cihaz: {self.device}")
21
-
22
- # Hafif model - DINOv2-small
23
- self.model_name = "facebook/dinov2-small"
24
- self.processor = AutoImageProcessor.from_pretrained(self.model_name)
25
- self.backbone = AutoModel.from_pretrained(self.model_name).to(self.device)
26
-
27
- # Regression head
28
- self.regressor = nn.Sequential(
29
- nn.Linear(384, 256), # small model 384 feature
30
- nn.ReLU(),
31
- nn.Dropout(0.2),
32
- nn.Linear(256, 128),
33
- nn.ReLU(),
34
- nn.Linear(128, 2) # lat, lon
35
- ).to(self.device)
36
-
37
- self.transform = transforms.Compose([
38
- transforms.Resize((224, 224)),
39
- transforms.ToTensor(),
40
- transforms.Normalize(mean=[0.485, 0.456, 0.406],
41
- std=[0.229, 0.224, 0.225])
42
- ])
43
-
44
- # Dataset cache - sadece küçük kısmı
45
- self.dataset = None
46
- self.load_medium_dataset()
47
 
48
- def load_medium_dataset(self, num_samples=2000):
49
- """Orta ölçekte dataset yükle (1-2GB)"""
50
  try:
51
- print(f"{num_samples} örnek yükleniyor...")
52
- self.dataset = load_dataset(
53
- "allenai/s2-naip",
54
- split=f"train[:{num_samples}]",
55
- streaming=False # Küçük olduğu için memory'de tut
56
- )
57
- print(f"Dataset yüklendi: {len(self.dataset)} örnek")
58
 
59
- # Dataset istatistikleri
60
- self.analyze_dataset()
61
 
62
- except Exception as e:
63
- print(f"Dataset yükleme hatası: {e}")
64
- self.dataset = None
65
-
66
- def analyze_dataset(self):
67
- """Dataset analizi"""
68
- if self.dataset is None:
69
- return
70
-
71
- print("\n=== Dataset Analizi ===")
72
- print(f"Toplam örnek: {len(self.dataset)}")
73
-
74
- # Koordinat istatistikleri
75
- lats, lons = [], []
76
- for i in range(min(100, len(self.dataset))):
77
- sample = self.dataset[i]
78
- if 'lat' in sample and 'lon' in sample:
79
- lats.append(sample['lat'])
80
- lons.append(sample['lon'])
81
-
82
- if lats:
83
- print(f"Enlem aralığı: {min(lats):.2f} - {max(lats):.2f}")
84
- print(f"Boylam aralığı: {min(lons):.2f} - {max(lons):.2f}")
85
- print(f"Koordinatlı örnek: {len(lats)}")
86
-
87
- def prepare_training_data(self, num_samples=1000):
88
- """Eğitim verisi hazırla"""
89
- if self.dataset is None:
90
- return None, None
91
 
92
- images = []
93
- coordinates = []
94
-
95
- print("Eğitim verisi hazırlanıyor...")
96
- for i in tqdm(range(min(num_samples, len(self.dataset)))):
97
- sample = self.dataset[i]
98
 
99
- try:
100
- # Sentinel-2 görüntüsünü kullan
101
- img = sample['sentinel']
102
- if img.mode != 'RGB':
103
- img = img.convert('RGB')
104
-
105
- img_tensor = self.transform(img)
106
- images.append(img_tensor)
107
-
108
- # Koordinatları normalize et
109
- lat = sample.get('lat', 0.0)
110
- lon = sample.get('lon', 0.0)
111
-
112
- # Normalize: [-90,90] -> [-1,1], [-180,180] -> [-1,1]
113
- lat_norm = lat / 90.0
114
- lon_norm = lon / 180.0
115
-
116
- coordinates.append([lat_norm, lon_norm])
117
-
118
- except Exception as e:
119
- continue
120
-
121
- if len(images) == 0:
122
- return None, None
123
-
124
- images_tensor = torch.stack(images)
125
- coords_tensor = torch.tensor(coordinates, dtype=torch.float32)
126
-
127
- print(f"Eğitim verisi: {len(images_tensor)} örnek")
128
- return images_tensor, coords_tensor
129
-
130
- def train(self, epochs=3, batch_size=16, learning_rate=1e-4):
131
- """Model eğitimi"""
132
- if self.dataset is None:
133
- return {"error": "Dataset yüklenemedi"}
134
-
135
- # Eğitim verisini hazırla
136
- images, coords = self.prepare_training_data(800) # 800 örnekle eğit
137
- if images is None:
138
- return {"error": "Eğitim verisi hazırlanamadı"}
139
-
140
- # Optimizer
141
- optimizer = torch.optim.AdamW(
142
- list(self.regressor.parameters()) + list(self.backbone.parameters()),
143
- lr=learning_rate,
144
- weight_decay=1e-4
145
- )
146
- criterion = nn.MSELoss()
147
-
148
- losses = []
149
- self.backbone.train()
150
- self.regressor.train()
151
-
152
- print("Model eğitimi başlıyor...")
153
- for epoch in range(epochs):
154
- epoch_loss = 0
155
- num_batches = 0
156
-
157
- for i in range(0, len(images), batch_size):
158
- batch_images = images[i:i+batch_size].to(self.device)
159
- batch_coords = coords[i:i+batch_size].to(self.device)
160
-
161
- # Forward pass
162
- optimizer.zero_grad()
163
-
164
- # Özellik çıkarımı
165
- features = self.backbone(batch_images).last_hidden_state
166
- features = features.mean(dim=1)
167
-
168
- # Tahmin
169
- pred_coords = self.regressor(features)
170
- loss = criterion(pred_coords, batch_coords)
171
-
172
- # Backward pass
173
- loss.backward()
174
- optimizer.step()
175
-
176
- epoch_loss += loss.item()
177
- num_batches += 1
178
-
179
- avg_loss = epoch_loss / num_batches if num_batches > 0 else 0
180
- losses.append(avg_loss)
181
- print(f"Epoch {epoch+1}/{epochs}, Loss: {avg_loss:.6f}")
182
-
183
- # Modeli kaydet
184
- self.save_model()
185
- return {"success": True, "final_loss": avg_loss, "losses": losses}
186
-
187
- def predict(self, image):
188
- """Görüntüden koordinat tahmini"""
189
- try:
190
- # Görüntüyü işle
191
- if isinstance(image, str):
192
- image = Image.open(image).convert('RGB')
193
- elif isinstance(image, np.ndarray):
194
- image = Image.fromarray(image.astype('uint8')).convert('RGB')
195
-
196
- image_tensor = self.transform(image).unsqueeze(0).to(self.device)
197
-
198
- with torch.no_grad():
199
- self.backbone.eval()
200
- self.regressor.eval()
201
-
202
- # Özellik çıkarımı
203
- features = self.backbone(image_tensor).last_hidden_state
204
- features = features.mean(dim=1)
205
-
206
- # Tahmin
207
- pred_coords = self.regressor(features)
208
- pred_coords = pred_coords.cpu().numpy()[0]
209
-
210
- # Gerçek koordinatlara dönüştür
211
- lat = pred_coords[0] * 90.0
212
- lon = pred_coords[1] * 180.0
213
-
214
- # Basit güven skoru
215
- confidence = max(0.1, 1.0 - (abs(pred_coords[0]) + abs(pred_coords[1])) / 2)
216
-
217
- result = {
218
- 'latitude': round(lat, 4),
219
- 'longitude': round(lon, 4),
220
- 'confidence': round(confidence, 2),
221
- 'model': 'DINOv2-small',
222
- 'dataset_samples': len(self.dataset) if self.dataset else 0
223
- }
224
-
225
- return result
226
-
227
  except Exception as e:
228
  return {'error': str(e)}
229
-
230
- def save_model(self):
231
- """Modeli kaydet"""
232
- try:
233
- torch.save({
234
- 'regressor_state_dict': self.regressor.state_dict(),
235
- 'backbone_state_dict': self.backbone.state_dict(),
236
- }, 'medium_geo_model.pth')
237
- print("Model kaydedildi: medium_geo_model.pth")
238
- except Exception as e:
239
- print(f"Model kaydetme hatası: {e}")
240
-
241
- def create_map(self, lat, lon):
242
- """Harita oluştur"""
243
- try:
244
- m = folium.Map(location=[lat, lon], zoom_start=10)
245
- folium.Marker(
246
- [lat, lon],
247
- popup=f'Tahmin: {lat}, {lon}',
248
- tooltip='Tahmin Edilen Konum'
249
- ).add_to(m)
250
-
251
- with tempfile.NamedTemporaryFile(suffix='.html', delete=False) as tmp:
252
- m.save(tmp.name)
253
- return tmp.name
254
- except Exception as e:
255
- print(f"Harita oluşturma hatası: {e}")
256
- return None
257
 
258
- # Gradio Arayüzü
259
- def create_interface():
260
- geo_system = MediumScaleGeoSystem()
261
 
262
- with gr.Blocks(title="🌍 Orta Ölçek Jeo-Referanslama", theme=gr.themes.Soft()) as demo:
263
  gr.Markdown("""
264
- # 🌍 Orta Ölçek Jeo-Referanslama
265
- **S2-NAIP datasetinin 2000 örneği ile AI koordinat tahmini**
266
 
267
- Bu sistem, 5GB'lık S2-NAIP datasetinin küçük bir kısmını kullanarak eğitilmiştir.
268
  """)
269
 
270
- with gr.Tab("🎯 Tekil Tahmin"):
271
- with gr.Row():
272
- with gr.Column():
273
- image_input = gr.Image(
274
- type="filepath",
275
- label="Uydu Görüntüsü Yükle",
276
- height=300
277
- )
278
- predict_btn = gr.Button("📍 Koordinatları Tahmin Et", variant="primary")
279
-
280
- with gr.Column():
281
- output_json = gr.JSON(label="Tahmin Sonuçları")
282
- map_output = gr.HTML(label="Harita Görünümü")
283
-
284
- def process_prediction(image):
285
- result = geo_system.predict(image)
286
- if 'error' not in result:
287
- map_path = geo_system.create_map(result['latitude'], result['longitude'])
288
- if map_path:
289
- with open(map_path, 'r') as f:
290
- map_html = f.read()
291
- os.unlink(map_path)
292
- return result, map_html
293
- return result, "<p>Harita oluşturulamadı</p>"
294
 
295
- predict_btn.click(
296
- fn=process_prediction,
297
- inputs=image_input,
298
- outputs=[output_json, map_output]
299
- )
300
 
301
- with gr.Tab("🛠️ Model Eğitimi"):
302
- with gr.Row():
303
- with gr.Column():
304
- epochs = gr.Slider(1, 10, value=3, label="Epoch Sayısı")
305
- batch_size = gr.Slider(8, 32, value=16, step=8, label="Batch Size")
306
- train_btn = gr.Button("🚀 Modeli Eğit", variant="primary")
307
-
308
- with gr.Column():
309
- train_output = gr.JSON(label="Eğitim Sonuçları")
310
- loss_plot = gr.Plot(label="Kayıp Grafiği")
311
-
312
- def train_model(epochs, batch_size):
313
- result = geo_system.train(epochs=int(epochs), batch_size=int(batch_size))
314
-
315
- if 'losses' in result:
316
- # Kayıp grafiği oluştur
317
- plt.figure(figsize=(10, 6))
318
- plt.plot(result['losses'])
319
- plt.title('Eğitim Kaybı')
320
- plt.xlabel('Epoch')
321
- plt.ylabel('Loss')
322
- plt.grid(True)
323
-
324
- return result, plt
325
-
326
- return result, None
327
-
328
- train_btn.click(
329
- fn=train_model,
330
- inputs=[epochs, batch_size],
331
- outputs=[train_output, loss_plot]
332
- )
333
 
334
- with gr.Tab("📊 Dataset Bilgisi"):
 
335
  gr.Markdown("""
336
- ### S2-NAIP Dataset (Orta Ölçek)
 
 
337
 
338
- **Kullanılan:** 2000 örnek (~1-2GB)
 
 
339
 
340
- **Özellikler:**
341
- - Sentinel-2 (10m çözünürlük) görüntüleri
342
- - NAIP (1m çözünürlük) görüntüleri
343
- - Koordinat metadata'sı
344
- - ABD genelinde çeşitli lokasyonlar
345
 
346
- **Model:** DINOv2-small (Hafif)
347
- - Özellik boyutu: 384
348
- - Giriş çözünürlük: 224x224
349
- - Çıktı: Enlem, Boylam
350
 
351
- **Performans Beklentisi:**
352
- - Eğitim süresi: 5-15 dakika
353
- - Model boyutu: ~150MB
354
- - Tahmin süresi: <1 saniye
355
  """)
356
-
357
- # Dataset istatistikleri
358
- if geo_system.dataset:
359
- gr.Markdown(f"""
360
- **Yüklenen Örnek:** {len(geo_system.dataset)}
361
- """)
362
 
363
- gr.Markdown("""
364
- ---
365
- ⚡ **Not:** Bu orta ölçekli sistem Hugging Face Spaces'te çalışacak şekilde optimize edilmiştir.
366
- """)
 
367
 
368
- return demo
369
 
370
  if __name__ == "__main__":
371
- demo = create_interface()
372
- demo.launch(
373
- server_name="0.0.0.0",
374
- server_port=7860,
375
- share=False
376
- )
 
1
+ import gradio as gr
 
 
 
 
 
2
  from PIL import Image
3
  import numpy as np
4
+ import random
 
 
 
 
 
5
  import json
6
 
7
+ class UltraLightGeoDemo:
8
  def __init__(self):
9
+ self.dataset_info = "S2-NAIP Demo - Gerçek model yüklenmedi"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
 
11
+ def predict_coordinates(self, image):
12
+ """Demo tahmin - model yüklemeden"""
13
  try:
14
+ # Rastgele koordinatlar (demo amaçlı)
15
+ lat = round(random.uniform(36.0, 42.0), 4) # Türkiye
16
+ lon = round(random.uniform(26.0, 45.0), 4)
 
 
 
 
17
 
18
+ # Basit güven skoru
19
+ confidence = round(random.uniform(0.3, 0.9), 2)
20
 
21
+ result = {
22
+ 'latitude': lat,
23
+ 'longitude': lon,
24
+ 'confidence': confidence,
25
+ 'note': 'BU BİR DEMO TAHMİNDİR - Gerçek model eğitilmemiştir',
26
+ 'next_step': 'Gerçek eğitim için Kaggle kullanın: https://kaggle.com'
27
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28
 
29
+ return result
 
 
 
 
 
30
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
  except Exception as e:
32
  return {'error': str(e)}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33
 
34
+ # Gradio arayüzü
35
+ def create_demo_interface():
36
+ demo = UltraLightGeoDemo()
37
 
38
+ with gr.Blocks(title="🌍 Jeo-Referanslama Demo", theme=gr.themes.Soft()) as interface:
39
  gr.Markdown("""
40
+ # 🌍 Jeo-Referanslama DEMO
41
+ **Ultra Hafif Sürüm - Gerçek model olmadan çalışır**
42
 
43
+ *Not: Bu bir demo uygulamasıdır. Gerçek model eğitimi için aşağıdaki Kaggle bağlantısını kullanın.*
44
  """)
45
 
46
+ with gr.Row():
47
+ with gr.Column():
48
+ image_input = gr.Image(
49
+ type="filepath",
50
+ label="Uydu Görüntüsü Yükle",
51
+ height=300
52
+ )
53
+ predict_btn = gr.Button("📍 Demo Tahmin Yap", variant="primary")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
54
 
55
+ with gr.Column():
56
+ output_json = gr.JSON(label="Tahmin Sonuçları")
 
 
 
57
 
58
+ # Kaggle bağlantısı
59
+ gr.Markdown("""
60
+ ---
61
+ ## 🚀 Gerçek Model İçin Kaggle'a Git:
62
+
63
+ **[👉 KAGGLE'DA TAM SİSTEMİ ÇALIŞTIR](https://kaggle.com)**
64
+
65
+ **Kaggle'da yapman gerekenler:**
66
+ 1. Yukarıdaki bağlantıya tıkla
67
+ 2. "Notebooks" "New Notebook"
68
+ 3. "Settings" → "GPU" seç
69
+ 4. Aşağıdaki kodu yapıştır
70
+ """)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
71
 
72
+ # Kaggle kodu
73
+ with gr.Accordion("📋 Kaggle İçin Hazır Kod", open=False):
74
  gr.Markdown("""
75
+ ```python
76
+ # Kaggle'da çalıştıracak tam kod
77
+ !pip install torch transformers datasets torchvision tqdm
78
 
79
+ import torch
80
+ from transformers import AutoModel
81
+ from datasets import load_dataset
82
 
83
+ # TAM S2-NAIP datasetini yükle (5GB)
84
+ dataset = load_dataset("allenai/s2-naip", split="train")
85
+ print(f"Tam dataset: {len(dataset)} örnek")
 
 
86
 
87
+ # GPU kullan
88
+ device = "cuda" if torch.cuda.is_available() else "cpu"
89
+ model = AutoModel.from_pretrained("facebook/dinov2-small").to(device)
 
90
 
91
+ print("Gerçek eğitim başlayabilir!")
92
+ ```
 
 
93
  """)
 
 
 
 
 
 
94
 
95
+ predict_btn.click(
96
+ fn=demo.predict_coordinates,
97
+ inputs=image_input,
98
+ outputs=output_json
99
+ )
100
 
101
+ return interface
102
 
103
  if __name__ == "__main__":
104
+ demo = create_demo_interface()
105
+ demo.launch(server_name="0.0.0.0", server_port=7860)