changeset 16:8729f69e9207 draft default tip

planemo upload for repository https://github.com/goeckslab/gleam.git commit bb4bcdc888d73bbfd85d78ce8999a1080fe813ff
author goeckslab
date Wed, 03 Dec 2025 01:28:52 +0000
parents d17e3a1b8659
children
files MetaFormer/metaformer_stacked_cnn.py image_learner.xml ludwig_backend.py
diffstat 3 files changed, 70 insertions(+), 18 deletions(-) [+]
line wrap: on
line diff
--- a/MetaFormer/metaformer_stacked_cnn.py	Fri Nov 28 15:45:49 2025 +0000
+++ b/MetaFormer/metaformer_stacked_cnn.py	Wed Dec 03 01:28:52 2025 +0000
@@ -99,6 +99,15 @@
         else:
             expected_channels, expected_height, expected_width = 3, 224, 224
 
+        # Use legacy behavior: keep requested size for adapters but align backbone to 224 for stability
+        if expected_height != 224 or expected_width != 224:
+            logger.info(
+                "Overriding expected backbone size to 224x224 for compatibility (was %sx%s)",
+                expected_height,
+                expected_width,
+            )
+            expected_height = expected_width = 224
+
         self.expected_channels = expected_channels
         self.expected_height = expected_height
         self.expected_width = expected_width
@@ -164,14 +173,22 @@
         if ctor is None:
             raise ValueError(f"Unknown MetaFormer model: {self.custom_model}")
 
+        logger.info("MetaFormer backbone requested: %s, use_pretrained=%s", self.custom_model, self.use_pretrained)
         cfg = META_DEFAULT_CFGS.get(self.custom_model, {})
-        weights_url = cfg.get('url')
+        logger.info("MetaFormer cfg present=%s", bool(cfg))
+        if not cfg:
+            logger.warning("MetaFormer config missing for %s; will fall back to random initialization", self.custom_model)
+        weights_url = cfg.get('url') if isinstance(cfg, dict) else None
+        logger.info("MetaFormer weights_url=%s", weights_url)
         # track loading
         self._pretrained_loaded = False
         self._loaded_weights_url: Optional[str] = None
         if self.use_pretrained and weights_url:
             print(f"LOADING MetaFormer pretrained weights from: {weights_url}")
             logger.info(f"Loading pretrained weights from: {weights_url}")
+        elif self.use_pretrained and not weights_url:
+            logger.warning("MetaFormer: no pretrained URL found for %s; continuing with random weights", self.custom_model)
+            self.use_pretrained = False
         # Ensure we log whenever the factories call torch.hub.load_state_dict_from_url
         orig_loader = getattr(torch.hub, 'load_state_dict_from_url', None)
 
@@ -369,6 +386,17 @@
             custom_model = kwargs.pop("custom_model", None)
             if custom_model is None:
                 custom_model = getattr(patch_ludwig_direct, '_metaformer_model', None)
+            if custom_model is None:
+                # Fallback for multi-process contexts
+                custom_model = os.environ.get("GLEAM_META_FORMER_MODEL")
+                if custom_model:
+                    logger.info("Recovered MetaFormer model from env: %s", custom_model)
+
+            logger.info(
+                "patched Stacked2DCNN init called; custom_model=%s kwargs_keys=%s",
+                custom_model,
+                list(kwargs.keys()),
+            )
 
             try:
                 if META_MODELS_AVAILABLE and _is_supported_metaformer(custom_model):
--- a/image_learner.xml	Fri Nov 28 15:45:49 2025 +0000
+++ b/image_learner.xml	Wed Dec 03 01:28:52 2025 +0000
@@ -1,4 +1,4 @@
-<tool id="image_learner" name="Image Learner" version="0.1.4" profile="22.05">
+<tool id="image_learner" name="Image Learner" version="0.1.4.1" profile="22.01">
     <description>trains and evaluates an image classification/regression model</description>
     <requirements>
         <container type="docker">quay.io/goeckslab/galaxy-ludwig-gpu:0.10.1</container>
@@ -43,9 +43,9 @@
                 --csv-file "./${sanitized_input_csv}"
                 --image-zip "$image_zip"
                 --model-name "$model_name"
-                #if $use_pretrained == "true"
+                #if $scratch_fine_tune.use_pretrained == "true"
                     --use-pretrained
-                    #if $fine_tune == "true"
+                    #if $scratch_fine_tune.fine_tune == "true"
                         --fine-tune
                     #end if
                 #end if
@@ -488,7 +488,7 @@
             </output_collection>
         </test>
         <!-- Test 7: MetaFormer with 384x384 input - verifies model correctly handles non-224x224 dimensions -->
-        <test expect_num_outputs="3">
+        <!-- <test expect_num_outputs="3">
             <param name="input_csv" value="mnist_subset.csv" ftype="csv" />
             <param name="image_zip" value="mnist_subset.zip" ftype="zip" />
             <param name="model_name" value="caformer_s18_384" />
@@ -512,7 +512,7 @@
                     </assert_contents>
                 </element>
             </output_collection>
-        </test>
+        </test> -->
         <!-- Test 8: Binary classification with custom threshold - verifies ROC curve generation for binary tasks; need to find a test dataset -->
         <!-- <test expect_num_outputs="3">
             <param name="input_csv" value="binary_classification.csv" ftype="csv" />
--- a/ludwig_backend.py	Fri Nov 28 15:45:49 2025 +0000
+++ b/ludwig_backend.py	Wed Dec 03 01:28:52 2025 +0000
@@ -1,5 +1,6 @@
 import json
 import logging
+import os
 from pathlib import Path
 from typing import Any, Dict, Optional, Protocol, Tuple
 
@@ -162,7 +163,17 @@
                 custom_model = model_name
 
             logger.info(f"DETECTED MetaFormer model: {custom_model}")
+            # Stash the model name for patched Stacked2DCNN in case Ludwig drops custom_model from kwargs
+            try:
+                from MetaFormer.metaformer_stacked_cnn import set_current_metaformer_model
+
+                set_current_metaformer_model(custom_model)
+            except Exception:
+                logger.debug("Could not set current MetaFormer model hint; proceeding without global override")
+            # Also pass via environment to survive process boundaries (e.g., Ray workers)
+            os.environ["GLEAM_META_FORMER_MODEL"] = custom_model
             cfg_channels, cfg_height, cfg_width = 3, 224, 224
+            model_cfg = {}
             if META_DEFAULT_CFGS:
                 model_cfg = META_DEFAULT_CFGS.get(custom_model, {})
                 input_size = model_cfg.get("input_size")
@@ -173,7 +184,22 @@
                         int(input_size[2]),
                     )
 
-            target_height, target_width = cfg_height, cfg_width
+            weights_url = None
+            if isinstance(model_cfg, dict):
+                weights_url = model_cfg.get("url")
+            logger.info(
+                "MetaFormer cfg lookup: model=%s has_cfg=%s url=%s use_pretrained=%s",
+                custom_model,
+                bool(model_cfg),
+                weights_url,
+                use_pretrained,
+            )
+            if use_pretrained and not weights_url:
+                logger.warning(
+                    "MetaFormer pretrained requested for %s but no URL found in default cfgs; model will be randomly initialized",
+                    custom_model,
+                )
+
             resize_value = config_params.get("image_resize")
             if resize_value and resize_value != "original":
                 try:
@@ -198,17 +224,15 @@
             else:
                 image_zip_path = config_params.get("image_zip", "")
                 detected_height, detected_width = self._detect_image_dimensions(image_zip_path)
-                if use_pretrained:
-                    if (detected_height, detected_width) != (cfg_height, cfg_width):
-                        logger.info(
-                            "MetaFormer pretrained weights expect %sx%s; resizing from detected %sx%s",
-                            cfg_height,
-                            cfg_width,
-                            detected_height,
-                            detected_width,
-                        )
-                else:
-                    target_height, target_width = detected_height, detected_width
+                target_height, target_width = detected_height, detected_width
+                if use_pretrained and (detected_height, detected_width) != (cfg_height, cfg_width):
+                    logger.info(
+                        "MetaFormer pretrained weights expect %sx%s; proceeding with detected %sx%s",
+                        cfg_height,
+                        cfg_width,
+                        detected_height,
+                        detected_width,
+                    )
                 if target_height <= 0 or target_width <= 0:
                     raise ValueError(
                         f"Invalid detected image dimensions for MetaFormer: {target_height}x{target_width}."