andreamena commited on
Commit
b16f006
Β·
verified Β·
1 Parent(s): d5b68e1

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +32 -26
app.py CHANGED
@@ -117,15 +117,7 @@ def load_ensemble_models():
117
 
118
  model = PredictModel(num_layers=6, d_model=256, dff=512, num_heads=8, vocab_size=18, a=1, dense_dropout=0.4)
119
  # Dummy call to build graph
120
- # We use dummy tensors to initialize the weights
121
  dummy_x = tf.zeros((1, 512), dtype=tf.int64)
122
- # ... (simplified init) ...
123
- # Actually, simpler to just load weights if we build input correctly.
124
- # But Safe way: Just return the fresh model and load weights during loop if needed?
125
- # No, that's slow. We load weights NOW.
126
-
127
- # NOTE: To load weights, we need to build the model first.
128
- # We will do lazy-loading inside the loop but KEEP the model in memory.
129
  models.append((model, weight_file))
130
 
131
  return models
@@ -162,16 +154,13 @@ def predict_single(payload, linker, peptide):
162
  if not payload or not linker or not peptide:
163
  return "⚠️ Please fill in all fields."
164
 
165
- # For single prediction, we accept the small slowness of loading
166
- # to avoid keeping models in memory forever if not needed.
167
- # OR reuse the logic. Let's reuse logic for consistency.
168
  models = load_ensemble_models()
169
  data = preprocess_input(payload, linker, peptide)
170
 
171
  if data is None: return "Error processing input."
172
 
173
  score = predict_with_loaded_models(models, data)
174
- keras.backend.clear_session() # Clean up after single use
175
 
176
  label = "Active PDC βœ…" if score > 0.5 else "Inactive ❌"
177
  return f"{label}\nConfidence: {score:.2%}"
@@ -197,7 +186,7 @@ def predict_batch(file_obj, progress=gr.Progress()):
197
  if missing:
198
  return None, pd.DataFrame({"Error": [f"Missing columns: {missing}"]})
199
 
200
- # 3. LOAD MODELS ONCE (The Speed Fix)
201
  print("πŸš€ Loading Ensemble Models for Batch Processing...")
202
  models = load_ensemble_models()
203
 
@@ -209,36 +198,52 @@ def predict_batch(file_obj, progress=gr.Progress()):
209
  l_smiles = row[col_map['Linker SMILES']]
210
  peptide = row[col_map['Peptide Sequence']]
211
 
212
- # Preprocess
213
  data = preprocess_input(p_smiles, l_smiles, peptide)
214
 
215
  if data is None:
216
  pred, conf = "Error", 0.0
217
  else:
218
- # Predict using the ALREADY LOADED models
219
  score = predict_with_loaded_models(models, data)
220
  pred = "Active" if score > 0.5 else "Inactive"
221
  conf = score
222
 
223
- results.append([p_smiles, l_smiles, peptide, pred, f"{conf:.4f}"])
 
224
 
225
  # 5. Cleanup
226
  keras.backend.clear_session()
227
 
228
  # 6. Format Outputs
229
- res_df = pd.DataFrame(results, columns=['Payload', 'Linker', 'Peptide', 'Prediction', 'Score'])
 
230
  output_file = "predictions.csv"
231
  res_df.to_csv(output_file, index=False)
232
 
233
  return output_file, res_df
234
 
235
  # --- 7. GRADIO INTERFACE ---
236
- with gr.Blocks(title="PDCNet Ensemble Demo") as demo:
237
- gr.Markdown("# πŸ’Š PDCNet Ensemble Predictor")
238
- gr.Markdown("Predict Peptide-Drug Conjugate activity. Upload a file or type manually.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
239
 
240
  with gr.Tabs():
241
  with gr.TabItem("Single Prediction"):
 
242
  with gr.Row():
243
  with gr.Column():
244
  in_payload = gr.Textbox(label="Payload SMILES", placeholder="e.g. COc1cc2c...", lines=2)
@@ -250,19 +255,20 @@ with gr.Blocks(title="PDCNet Ensemble Demo") as demo:
250
  btn_predict.click(predict_single, inputs=[in_payload, in_linker, in_peptide], outputs=out_result)
251
 
252
  with gr.TabItem("Batch Prediction (File)"):
253
- gr.Markdown("Upload a CSV or Excel file.")
254
- with gr.Row():
255
- file_input = gr.File(label="Upload Dataset")
256
- btn_batch = gr.Button("Run Batch Prediction", variant="primary")
 
257
 
258
- # OUTPUTS: Visual Table AND Download File
259
  out_dataframe = gr.Dataframe(label="Results Preview", interactive=False)
260
  file_output = gr.File(label="Download Full Results (.csv)")
261
 
262
  btn_batch.click(
263
  predict_batch,
264
  inputs=file_input,
265
- outputs=[file_output, out_dataframe] # Two outputs now!
266
  )
267
 
268
  demo.launch()
 
117
 
118
  model = PredictModel(num_layers=6, d_model=256, dff=512, num_heads=8, vocab_size=18, a=1, dense_dropout=0.4)
119
  # Dummy call to build graph
 
120
  dummy_x = tf.zeros((1, 512), dtype=tf.int64)
 
 
 
 
 
 
 
121
  models.append((model, weight_file))
122
 
123
  return models
 
154
  if not payload or not linker or not peptide:
155
  return "⚠️ Please fill in all fields."
156
 
 
 
 
157
  models = load_ensemble_models()
158
  data = preprocess_input(payload, linker, peptide)
159
 
160
  if data is None: return "Error processing input."
161
 
162
  score = predict_with_loaded_models(models, data)
163
+ keras.backend.clear_session()
164
 
165
  label = "Active PDC βœ…" if score > 0.5 else "Inactive ❌"
166
  return f"{label}\nConfidence: {score:.2%}"
 
186
  if missing:
187
  return None, pd.DataFrame({"Error": [f"Missing columns: {missing}"]})
188
 
189
+ # 3. LOAD MODELS ONCE
190
  print("πŸš€ Loading Ensemble Models for Batch Processing...")
191
  models = load_ensemble_models()
192
 
 
198
  l_smiles = row[col_map['Linker SMILES']]
199
  peptide = row[col_map['Peptide Sequence']]
200
 
 
201
  data = preprocess_input(p_smiles, l_smiles, peptide)
202
 
203
  if data is None:
204
  pred, conf = "Error", 0.0
205
  else:
 
206
  score = predict_with_loaded_models(models, data)
207
  pred = "Active" if score > 0.5 else "Inactive"
208
  conf = score
209
 
210
+ # UI UPDATE: Put Prediction and Score FIRST
211
+ results.append([pred, f"{conf:.4f}", p_smiles, l_smiles, peptide])
212
 
213
  # 5. Cleanup
214
  keras.backend.clear_session()
215
 
216
  # 6. Format Outputs
217
+ # Columns Reordered here for both display and CSV
218
+ res_df = pd.DataFrame(results, columns=['Prediction', 'Score', 'Payload', 'Linker', 'Peptide'])
219
  output_file = "predictions.csv"
220
  res_df.to_csv(output_file, index=False)
221
 
222
  return output_file, res_df
223
 
224
  # --- 7. GRADIO INTERFACE ---
225
+ # CSS to center the content nicely
226
+ css = """
227
+ .gradio-container {text-align: center;}
228
+ h1 {text-align: center; display: block;}
229
+ p {text-align: center; display: block;}
230
+ """
231
+
232
+ with gr.Blocks(title="PDCNet Ensemble Demo", css=css) as demo:
233
+
234
+ # CENTERED HEADER
235
+ gr.HTML("""
236
+ <div style="text-align: center; max-width: 800px; margin: 0 auto;">
237
+ <h1>πŸ’Š PDCNet Ensemble Predictor</h1>
238
+ <p style="font-size: 1.1em;">
239
+ Predict Peptide-Drug Conjugate activity using Graph Neural Networks + ESM-2 Protein Language Model.
240
+ </p>
241
+ </div>
242
+ """)
243
 
244
  with gr.Tabs():
245
  with gr.TabItem("Single Prediction"):
246
+ # Centering the input area slightly
247
  with gr.Row():
248
  with gr.Column():
249
  in_payload = gr.Textbox(label="Payload SMILES", placeholder="e.g. COc1cc2c...", lines=2)
 
255
  btn_predict.click(predict_single, inputs=[in_payload, in_linker, in_peptide], outputs=out_result)
256
 
257
  with gr.TabItem("Batch Prediction (File)"):
258
+ gr.Markdown("### Upload a CSV or Excel file to process many molecules at once.")
259
+
260
+ # UI UPDATE: Stacked vertically (No gr.Row)
261
+ file_input = gr.File(label="Upload Dataset")
262
+ btn_batch = gr.Button("Run Batch Prediction", variant="primary")
263
 
264
+ # OUTPUTS
265
  out_dataframe = gr.Dataframe(label="Results Preview", interactive=False)
266
  file_output = gr.File(label="Download Full Results (.csv)")
267
 
268
  btn_batch.click(
269
  predict_batch,
270
  inputs=file_input,
271
+ outputs=[file_output, out_dataframe]
272
  )
273
 
274
  demo.launch()