jarpalucas commited on
Commit
8c6aef7
·
verified ·
1 Parent(s): 15607c7

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +161 -89
app.py CHANGED
@@ -8,67 +8,128 @@ import pickle
8
  import os
9
  os.environ['TF_ENABLE_ONEDNN_OPTS'] = '0'
10
 
 
 
 
 
 
11
  # Intentar importar TensorFlow con manejo de errores
12
  try:
13
- from tensorflow.keras.models import load_model
14
- TENSORFLOW_AVAILABLE = True
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
15
  except ImportError as e:
16
- print(f"TensorFlow no disponible: {e}")
17
  TENSORFLOW_AVAILABLE = False
18
- # Usar una alternativa
19
- from sklearn.ensemble import RandomForestClassifier
20
- import joblib
21
 
22
  # Cargar modelo y artefactos
23
  def load_resources():
24
  """Carga el modelo y todos los artefactos necesarios"""
25
  try:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
26
  if TENSORFLOW_AVAILABLE:
27
- model = load_model("modulo_tabular.h5")
28
- print("✅ Modelo TensorFlow cargado exitosamente")
29
- else:
30
- # Si TensorFlow falla, intentar cargar con joblib
31
  try:
32
- model = joblib.load("modulo_tabular.h5")
33
- print("✅ Modelo cargado con joblib")
34
- except:
35
- # Crear un modelo dummy para pruebas
36
- print("⚠️ Usando modelo dummy para demostración")
37
- model = None
38
-
39
- with open("scaler.pkl", "rb") as f:
40
- scaler = pickle.load(f)
41
- print("✅ Scaler cargado")
42
-
43
- with open("label_encoder.pkl", "rb") as f:
44
- label_encoder = pickle.load(f)
45
- print("✅ Label encoder cargado")
46
-
47
- with open("feature_stats.json", "r") as f:
48
- feature_stats = json.load(f)
49
- print("✅ Feature stats cargado")
50
-
 
 
 
 
 
 
 
51
  return model, scaler, label_encoder, feature_stats
52
 
53
  except Exception as e:
54
- print(f"❌ Error cargando recursos: {str(e)}")
55
- # Crear objetos dummy para que la app funcione
56
- feature_stats = {
57
- "feature_columns": [
58
- "koi_period", "koi_duration", "koi_depth", "koi_prad",
59
- "koi_srad", "koi_teq", "koi_steff", "koi_slogg",
60
- "koi_smet", "koi_kepmag", "koi_model_snr", "koi_num_transits"
61
- ],
62
- "train_medians": {
63
- "koi_period": 10.0, "koi_duration": 5.0, "koi_depth": 1000.0,
64
- "koi_prad": 2.0, "koi_srad": 1.0, "koi_teq": 1000.0,
65
- "koi_steff": 6000.0, "koi_slogg": 4.5, "koi_smet": 0.0,
66
- "koi_kepmag": 12.0, "koi_model_snr": 10.0, "koi_num_transits": 3.0
67
- }
 
 
68
  }
69
- return None, None, None, feature_stats
70
 
71
  # Cargar recursos al inicio
 
72
  model, scaler, label_encoder, feature_stats = load_resources()
73
 
74
  if feature_stats:
@@ -78,6 +139,11 @@ else:
78
  feature_columns = []
79
  train_medians = {}
80
 
 
 
 
 
 
81
  BASE = "https://exoplanetarchive.ipac.caltech.edu/cgi-bin/nstedAPI/nph-nstedAPI"
82
 
83
  def first_present(candidates, cols_set):
@@ -91,16 +157,38 @@ def first_present(candidates, cols_set):
91
  return found[0]
92
  return None
93
 
94
- def predict_dummy():
95
- """Función de predicción dummy para cuando el modelo no está disponible"""
96
- return "🔧 El modelo no está disponible actualmente. Por favor, verifica que los archivos del modelo estén correctamente cargados."
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
97
 
98
  def predict_toi_realtime():
99
  """Obtiene y predice objetos TOI en tiempo real"""
100
  try:
101
- # Verificar si el modelo está disponible
102
- if model is None or scaler is None or label_encoder is None:
103
- return predict_dummy()
 
 
 
 
 
104
 
105
  # 1) Traer TOI (TESS Objects of Interest)
106
  where = ("(tfopwg_disp like 'PC' or tfopwg_disp like 'APC') "
@@ -156,17 +244,7 @@ def predict_toi_realtime():
156
 
157
  # 7) Escalar y predecir
158
  X_cases = scaler.transform(cases.values)
159
-
160
- if TENSORFLOW_AVAILABLE:
161
- probs = model.predict(X_cases, verbose=0)
162
- else:
163
- # Si no es TensorFlow, usar predict_proba si está disponible
164
- if hasattr(model, 'predict_proba'):
165
- probs = model.predict_proba(X_cases)
166
- else:
167
- probs = np.random.rand(len(X_cases), 3)
168
- probs = probs / probs.sum(axis=1, keepdims=True)
169
-
170
  pred_idx = np.argmax(probs, axis=1)
171
  pred_labels = label_encoder.inverse_transform(pred_idx)
172
  clases = list(label_encoder.classes_)
@@ -203,30 +281,28 @@ def predict_toi_realtime():
203
  return summary + result_df.to_markdown(index=False)
204
 
205
  except Exception as e:
206
- return f"❌ Error: {str(e)}"
 
 
 
 
207
 
208
  def predict_custom_data(period, duration, depth, prad, srad, teq, steff, slogg, smet, kepmag, snr, num_transits):
209
  """Predice para datos personalizados ingresados manualmente"""
210
  try:
211
  # Verificar si el modelo está disponible
212
- if model is None or scaler is None or label_encoder is None:
213
- return predict_dummy()
 
 
 
214
 
215
  # Crear array con los datos de entrada
216
  input_data = np.array([[period, duration, depth, prad, srad, teq, steff, slogg, smet, kepmag, snr, num_transits]])
217
 
218
  # Escalar y predecir
219
  X_input = scaler.transform(input_data)
220
-
221
- if TENSORFLOW_AVAILABLE:
222
- probs = model.predict(X_input, verbose=0)
223
- else:
224
- if hasattr(model, 'predict_proba'):
225
- probs = model.predict_proba(X_input)
226
- else:
227
- probs = np.random.rand(1, 3)
228
- probs = probs / probs.sum(axis=1, keepdims=True)
229
-
230
  pred_idx = np.argmax(probs, axis=1)
231
  pred_label = label_encoder.inverse_transform(pred_idx)[0]
232
 
@@ -291,8 +367,12 @@ with gr.Blocks(theme=gr.themes.Soft(), title="Eco Finder API - Clasificador de E
291
  )
292
 
293
  with gr.Tab("ℹ️ Información del Modelo"):
 
294
  gr.Markdown(f"""
295
- ## Estado del Modelo: {'✅ Cargado' if model is not None else '❌ No disponible'}
 
 
 
296
 
297
  **Features utilizadas:** {", ".join(feature_columns) if feature_columns else "No disponibles"}
298
 
@@ -301,20 +381,12 @@ with gr.Blocks(theme=gr.themes.Soft(), title="Eco Finder API - Clasificador de E
301
  - 🔍 **CANDIDATE**: Candidato a exoplaneta
302
  - ❌ **FALSE POSITIVE**: Falso positivo
303
 
304
- **Descripción de features:**
305
- - `koi_period`: Período orbital (días)
306
- - `koi_duration`: Duración del tránsito (horas)
307
- - `koi_depth`: Profundidad del tránsito (ppm)
308
- - `koi_prad`: Radio planetario (Radios terrestres)
309
- - `koi_srad`: Radio estelar (Radios solares)
310
- - `koi_teq`: Temperatura de equilibrio (K)
311
- - `koi_steff`: Temperatura efectiva estelar (K)
312
- - `koi_slogg`: Gravedad superficial estelar (log g)
313
- - `koi_smet`: Metalicidad estelar ([Fe/H])
314
- - `koi_kepmag`: Magnitud TESS
315
- - `koi_model_snr`: Relación señal-ruido
316
- - `koi_num_transits`: Número de tránsitos
317
  """)
318
 
 
319
  if __name__ == "__main__":
320
- demo.launch(share=True)
 
8
  import os
9
  os.environ['TF_ENABLE_ONEDNN_OPTS'] = '0'
10
 
11
+ # Configuración para compatibilidad
12
+ os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
13
+
14
+ print("🚀 Iniciando aplicación Eco Finder API...")
15
+
16
  # Intentar importar TensorFlow con manejo de errores
17
  try:
18
+ import tensorflow as tf
19
+ print(f"✅ TensorFlow version: {tf.__version__}")
20
+
21
+ # Intentar diferentes métodos de carga
22
+ try:
23
+ from tensorflow.keras.models import load_model
24
+ TENSORFLOW_AVAILABLE = True
25
+ LOAD_METHOD = "keras"
26
+ except:
27
+ try:
28
+ # Intentar con tf.keras
29
+ from tensorflow import keras
30
+ load_model = keras.models.load_model
31
+ TENSORFLOW_AVAILABLE = True
32
+ LOAD_METHOD = "tf.keras"
33
+ except:
34
+ TENSORFLOW_AVAILABLE = False
35
+ LOAD_METHOD = "none"
36
+
37
  except ImportError as e:
38
+ print(f"TensorFlow no disponible: {e}")
39
  TENSORFLOW_AVAILABLE = False
40
+ LOAD_METHOD = "none"
41
+
42
+ print(f"📊 Estado TensorFlow: {TENSORFLOW_AVAILABLE}, Método: {LOAD_METHOD}")
43
 
44
  # Cargar modelo y artefactos
45
  def load_resources():
46
  """Carga el modelo y todos los artefactos necesarios"""
47
  try:
48
+ model = None
49
+ scaler = None
50
+ label_encoder = None
51
+ feature_stats = None
52
+
53
+ # 1. Cargar feature_stats primero (siempre necesario)
54
+ try:
55
+ with open("feature_stats.json", "r") as f:
56
+ feature_stats = json.load(f)
57
+ print("✅ Feature stats cargado")
58
+ except Exception as e:
59
+ print(f"❌ Error cargando feature_stats: {e}")
60
+ feature_stats = create_default_feature_stats()
61
+
62
+ # 2. Cargar scaler
63
+ try:
64
+ with open("scaler.pkl", "rb") as f:
65
+ scaler = pickle.load(f)
66
+ print("✅ Scaler cargado")
67
+ except Exception as e:
68
+ print(f"❌ Error cargando scaler: {e}")
69
+ scaler = None
70
+
71
+ # 3. Cargar label_encoder
72
+ try:
73
+ with open("label_encoder.pkl", "rb") as f:
74
+ label_encoder = pickle.load(f)
75
+ print("✅ Label encoder cargado")
76
+ except Exception as e:
77
+ print(f"❌ Error cargando label_encoder: {e}")
78
+ label_encoder = None
79
+
80
+ # 4. Intentar cargar el modelo con diferentes métodos
81
  if TENSORFLOW_AVAILABLE:
 
 
 
 
82
  try:
83
+ print("🔄 Intentando cargar modelo con load_model...")
84
+ model = load_model("modulo_tabular.h5")
85
+ print("✅ Modelo cargado con load_model")
86
+ except Exception as e1:
87
+ print(f" Método 1 falló: {e1}")
88
+ try:
89
+ # Intentar cargar solo arquitectura y pesos por separado
90
+ print("🔄 Intentando cargar arquitectura y pesos por separado...")
91
+ from tensorflow.keras.models import Model
92
+ from tensorflow.keras.layers import Input, Dense
93
+
94
+ # Crear arquitectura manualmente (ajusta según tu modelo)
95
+ inputs = Input(shape=(12,))
96
+ x = Dense(64, activation='relu')(inputs)
97
+ x = Dense(32, activation='relu')(x)
98
+ outputs = Dense(3, activation='softmax')(x)
99
+ model = Model(inputs=inputs, outputs=outputs)
100
+ model.load_weights("modulo_tabular.h5")
101
+ print("✅ Modelo cargado con pesos manualmente")
102
+ except Exception as e2:
103
+ print(f"❌ Método 2 falló: {e2}")
104
+ model = None
105
+ else:
106
+ print("⚠️ TensorFlow no disponible, usando modelo dummy")
107
+ model = None
108
+
109
  return model, scaler, label_encoder, feature_stats
110
 
111
  except Exception as e:
112
+ print(f"❌ Error general cargando recursos: {str(e)}")
113
+ return None, None, None, create_default_feature_stats()
114
+
115
+ def create_default_feature_stats():
116
+ """Crea estadísticas por defecto si no se pueden cargar"""
117
+ return {
118
+ "feature_columns": [
119
+ "koi_period", "koi_duration", "koi_depth", "koi_prad",
120
+ "koi_srad", "koi_teq", "koi_steff", "koi_slogg",
121
+ "koi_smet", "koi_kepmag", "koi_model_snr", "koi_num_transits"
122
+ ],
123
+ "train_medians": {
124
+ "koi_period": 10.0, "koi_duration": 5.0, "koi_depth": 1000.0,
125
+ "koi_prad": 2.0, "koi_srad": 1.0, "koi_teq": 1000.0,
126
+ "koi_steff": 6000.0, "koi_slogg": 4.5, "koi_smet": 0.0,
127
+ "koi_kepmag": 12.0, "koi_model_snr": 10.0, "koi_num_transits": 3.0
128
  }
129
+ }
130
 
131
  # Cargar recursos al inicio
132
+ print("🔄 Cargando recursos del modelo...")
133
  model, scaler, label_encoder, feature_stats = load_resources()
134
 
135
  if feature_stats:
 
139
  feature_columns = []
140
  train_medians = {}
141
 
142
+ print(f"📋 Features cargadas: {len(feature_columns)}")
143
+ print(f"🤖 Modelo disponible: {model is not None}")
144
+ print(f"⚖️ Scaler disponible: {scaler is not None}")
145
+ print(f"🏷️ Label encoder disponible: {label_encoder is not None}")
146
+
147
  BASE = "https://exoplanetarchive.ipac.caltech.edu/cgi-bin/nstedAPI/nph-nstedAPI"
148
 
149
  def first_present(candidates, cols_set):
 
157
  return found[0]
158
  return None
159
 
160
+ def create_demo_predictions():
161
+ """Crear predicciones de demostración"""
162
+ demo_data = [
163
+ {
164
+ "TOI": "TOI-1234.01", "Disposición Actual": "PC", "Predicción": "CONFIRMED",
165
+ "P(Confirmado)": "0.875", "P(Candidato)": "0.120", "P(Falso Positivo)": "0.005",
166
+ "Período (días)": "15.234", "Duración (horas)": "4.567", "Radio Planetario (R⊕)": "2.345"
167
+ },
168
+ {
169
+ "TOI": "TOI-5678.01", "Disposición Actual": "APC", "Predicción": "CANDIDATE",
170
+ "P(Confirmado)": "0.345", "P(Candidato)": "0.650", "P(Falso Positivo)": "0.005",
171
+ "Período (días)": "8.912", "Duración (horas)": "3.210", "Radio Planetario (R⊕)": "1.789"
172
+ },
173
+ {
174
+ "TOI": "TOI-9012.01", "Disposición Actual": "PC", "Predicción": "FALSE POSITIVE",
175
+ "P(Confirmado)": "0.050", "P(Candidato)": "0.150", "P(Falso Positivo)": "0.800",
176
+ "Período (días)": "25.678", "Duración (horas)": "6.543", "Radio Planetario (R⊕)": "0.987"
177
+ }
178
+ ]
179
+ return pd.DataFrame(demo_data)
180
 
181
  def predict_toi_realtime():
182
  """Obtiene y predice objetos TOI en tiempo real"""
183
  try:
184
+ # Verificar si los componentes esenciales están disponibles
185
+ if model is None:
186
+ result_df = create_demo_predictions()
187
+ summary = "⚠️ **MODO DEMOSTRACIÓN**: El modelo no está disponible. Mostrando datos de ejemplo.\n\n"
188
+ return summary + result_df.to_markdown(index=False)
189
+
190
+ if scaler is None or label_encoder is None:
191
+ return "❌ Error: Scaler o Label Encoder no disponibles"
192
 
193
  # 1) Traer TOI (TESS Objects of Interest)
194
  where = ("(tfopwg_disp like 'PC' or tfopwg_disp like 'APC') "
 
244
 
245
  # 7) Escalar y predecir
246
  X_cases = scaler.transform(cases.values)
247
+ probs = model.predict(X_cases, verbose=0)
 
 
 
 
 
 
 
 
 
 
248
  pred_idx = np.argmax(probs, axis=1)
249
  pred_labels = label_encoder.inverse_transform(pred_idx)
250
  clases = list(label_encoder.classes_)
 
281
  return summary + result_df.to_markdown(index=False)
282
 
283
  except Exception as e:
284
+ print(f"❌ Error en predicción TOI: {str(e)}")
285
+ # Fallback a datos de demostración
286
+ result_df = create_demo_predictions()
287
+ summary = f"⚠️ **Error en consulta TOI**: {str(e)}\n\nMostrando datos de ejemplo:\n\n"
288
+ return summary + result_df.to_markdown(index=False)
289
 
290
  def predict_custom_data(period, duration, depth, prad, srad, teq, steff, slogg, smet, kepmag, snr, num_transits):
291
  """Predice para datos personalizados ingresados manualmente"""
292
  try:
293
  # Verificar si el modelo está disponible
294
+ if model is None:
295
+ return "⚠️ **MODO DEMOSTRACIÓN**: El modelo no está disponible actualmente. Esta es una predicción de ejemplo.\n\n**Predicción:** CANDIDATE\n\n**Probabilidades:**\n- CONFIRMED: 0.350\n- CANDIDATE: 0.600\n- FALSE POSITIVE: 0.050"
296
+
297
+ if scaler is None or label_encoder is None:
298
+ return "❌ Error: Scaler o Label Encoder no disponibles"
299
 
300
  # Crear array con los datos de entrada
301
  input_data = np.array([[period, duration, depth, prad, srad, teq, steff, slogg, smet, kepmag, snr, num_transits]])
302
 
303
  # Escalar y predecir
304
  X_input = scaler.transform(input_data)
305
+ probs = model.predict(X_input, verbose=0)
 
 
 
 
 
 
 
 
 
306
  pred_idx = np.argmax(probs, axis=1)
307
  pred_label = label_encoder.inverse_transform(pred_idx)[0]
308
 
 
367
  )
368
 
369
  with gr.Tab("ℹ️ Información del Modelo"):
370
+ model_status = "✅ Cargado y funcionando" if model is not None else "⚠️ En modo demostración"
371
  gr.Markdown(f"""
372
+ ## Estado del Modelo: {model_status}
373
+
374
+ **TensorFlow disponible:** {TENSORFLOW_AVAILABLE}
375
+ **Método de carga:** {LOAD_METHOD}
376
 
377
  **Features utilizadas:** {", ".join(feature_columns) if feature_columns else "No disponibles"}
378
 
 
381
  - 🔍 **CANDIDATE**: Candidato a exoplaneta
382
  - ❌ **FALSE POSITIVE**: Falso positivo
383
 
384
+ **Componentes cargados:**
385
+ - Modelo: {'✅' if model is not None else '❌'}
386
+ - Scaler: {'✅' if scaler is not None else '❌'}
387
+ - Label Encoder: {'✅' if label_encoder is not None else '❌'}
 
 
 
 
 
 
 
 
 
388
  """)
389
 
390
+ print("🎉 Aplicación iniciada correctamente!")
391
  if __name__ == "__main__":
392
+ demo.launch(server_name="0.0.0.0", server_port=7860)