view image_learner.xml @ 15:d17e3a1b8659 draft default tip

planemo upload for repository https://github.com/goeckslab/gleam.git commit bc50fef8acb44aca15d0a1746e6c0c967da5bb17
author goeckslab
date Fri, 28 Nov 2025 15:45:49 +0000
parents 94cd9ac4a9b1
children
line wrap: on
line source

<tool id="image_learner" name="Image Learner" version="0.1.4" profile="22.05">
    <description>trains and evaluates an image classification/regression model</description>
    <requirements>
        <container type="docker">quay.io/goeckslab/galaxy-ludwig-gpu:0.10.1</container>
    </requirements>
    <required_files>
        <include path="constants.py" />
        <include path="html_structure.py" />
        <include path="image_learner_cli.py" />
        <include path="image_workflow.py" />
        <include path="ludwig_backend.py" />
        <include path="metaformer_setup.py" />
        <include path="plotly_plots.py" />
        <include path="split_data.py" />
        <include path="utils.py" />
        <include path="MetaFormer/__init__.py" />
        <include path="MetaFormer/metaformer_models.py" />
        <include path="MetaFormer/metaformer_stacked_cnn.py" />
    </required_files>
    <stdio>
        <exit_code range="137" level="fatal_oom" description="Out of Memory" />
        <exit_code range="1:" level="fatal" description="Error occurred. Please check Tool Standard Error" />
    </stdio>
    <command>
        <![CDATA[
            #import re
            #if $input_csv
            #set $sanitized_input_csv = re.sub('[^\w\-_\.]', '_', $input_csv.element_identifier.strip())
            ln -sf '$input_csv' "./${sanitized_input_csv}";
            #end if

            #if $task_selection.task == "binary"
                #set $selected_validation_metric = $task_selection.validation_metric_binary
            #elif $task_selection.task == "classification"
                #set $selected_validation_metric = $task_selection.validation_metric_multiclass
            #elif $task_selection.task == "regression"
                #set $selected_validation_metric = $task_selection.validation_metric_regression
            #else
                #set $selected_validation_metric = None
            #end if

            python '$__tool_directory__/image_learner_cli.py'
                --csv-file "./${sanitized_input_csv}"
                --image-zip "$image_zip"
                --model-name "$model_name"
                #if $use_pretrained == "true"
                    --use-pretrained
                    #if $fine_tune == "true"
                        --fine-tune
                    #end if
                #end if
                #if $advanced_settings.customize_defaults == "true"
                    #if $advanced_settings.epochs
                        --epochs "$advanced_settings.epochs"
                    #end if
                    #if $advanced_settings.early_stop
                        --early-stop "$advanced_settings.early_stop"
                    #end if
                    #if $advanced_settings.learning_rate_condition.learning_rate_define == "true"
                        --learning-rate "$advanced_settings.learning_rate_condition.learning_rate"
                    #end if
                    #if $advanced_settings.batch_size_condition.batch_size_define == "true"
                        --batch-size "$advanced_settings.batch_size_condition.batch_size"
                    #end if
                    --split-probabilities "$advanced_settings.train_split" "$advanced_settings.val_split" "$advanced_settings.test_split"
                    #if $advanced_settings.threshold
                        --threshold "$advanced_settings.threshold"
                    #end if
                #end if
                #if $augmentation
                    --augmentation "$augmentation"
                #end if
                #if $selected_validation_metric
                    --validation-metric "$selected_validation_metric"
                #end if
                #if $column_override.override_columns == "true"
                    #if $column_override.target_column
                        --target-column "$column_override.target_column"
                    #end if
                    #if $column_override.image_column
                        --image-column "$column_override.image_column"
                    #end if
                #end if
                --image-resize "$image_resize"
                --random-seed "$random_seed"
                --output-dir "." &&

            mkdir -p '$output_model.extra_files_path' &&
            cp -r experiment_run/model/*.json experiment_run/model/model_weights '$output_model.extra_files_path' &&

            echo "Image Learner Classification Experiment is Done!"
        ]]>
    </command>

    <inputs>
        <param name="input_csv" type="data" format="csv" optional="false" label="the metadata csv containing image_path column, label column and optional split column" />
        <param name="image_zip" type="data" format="zip" optional="false" label="Image zip" help="Image zip file containing your image data"/>
        <conditional name="task_selection">
            <param name="task" type="select" label="Task type" help="Pick task to see only metrics Ludwig accepts for that task; Auto lets the tool infer task and metric.">
                <option value="auto" selected="true">Auto (infer and use defaults)</option>
                <option value="binary">Binary Classification</option>
                <option value="classification">Multi-class Classification</option>
                <option value="regression">Regression</option>
            </param>
            <when value="binary">
                <param name="validation_metric_binary" type="select" optional="true" label="Validation metric (binary)" help="Metrics accepted by Ludwig for binary outputs.">
                    <option value="roc_auc" selected="true">ROC-AUC</option>
                    <option value="accuracy">Accuracy</option>
                    <option value="balanced_accuracy">Balanced Accuracy</option>
                    <option value="precision">Precision</option>
                    <option value="recall">Recall</option>
                    <option value="f1">F1</option>
                    <option value="specificity">Specificity</option>
                    <option value="log_loss">Log Loss</option>
                    <option value="loss">Loss</option>
                </param>
            </when>
            <when value="classification">
                <param name="validation_metric_multiclass" type="select" optional="true" label="Validation metric (multi-class)" help="Metrics accepted by Ludwig for multi-class outputs.">
                    <option value="accuracy" selected="true">Accuracy</option>
                    <option value="roc_auc">ROC-AUC</option>
                    <option value="loss">Loss</option>
                    <option value="balanced_accuracy">Balanced Accuracy</option>
                    <option value="precision">Precision</option>
                    <option value="recall">Recall</option>
                    <option value="f1">F1</option>
                    <option value="specificity">Specificity</option>
                    <option value="log_loss">Log Loss</option>
                </param>
            </when>
            <when value="regression">
                <param name="validation_metric_regression" type="select" optional="true" label="Validation metric (regression)" help="Metrics accepted by Ludwig for regression outputs.">
                    <option value="pearson_r" selected="true">Pearson r</option>
                    <option value="mae">MAE</option>
                    <option value="mse">MSE</option>
                    <option value="rmse">RMSE</option>
                    <option value="mape">MAPE</option>
                    <option value="r2">R²</option>
                    <option value="explained_variance">Explained Variance</option>
                    <option value="loss">Loss</option>
                </param>
            </when>
            <when value="auto">
                <!-- No validation metric selection; tool will infer task and metric. -->
            </when>
        </conditional>
        <conditional name="column_override">
            <param name="override_columns" type="select" label="Overwrite label and/or image column names?" help="Select yes to specify custom column names instead of the defaults 'label' and 'image_path'.">
                <option value="false" selected="true">No</option>
                <option value="true">Yes</option>
            </param>
            <when value="true">
                <param name="target_column" type="text" optional="true" label="Target/label column name" help="Overrides the default 'label' column name in the metadata CSV." />
                <param name="image_column" type="text" optional="true" label="Image column name" help="Overrides the default 'image_path' column name in the metadata CSV." />
            </when>
            <when value="false">
                <!-- No additional parameters -->
            </when>
        </conditional>
        <param name="model_name" type="select" optional="false" label="Select a model for your experiment" >

            <option value="resnet18">Resnet18</option>
            <option value="resnet34">Resnet34</option>
            <option value="resnet50">Resnet50</option>
            <option value="resnet101">Resnet101</option>
            <option value="resnet152">Resnet152</option>
            <option value="resnext50_32x4d">Resnext50_32x4d</option>
            <option value="resnext101_32x8d">Resnext101_32x8d</option>
            <option value="resnext101_64x4d">Resnext101_64x4d</option>
            <option value="resnext152_32x8d">Resnext152_32x8d</option>
            <option value="wide_resnet50_2">Wide_resnet50_2</option>
            <option value="wide_resnet101_2">Wide_resnet101_2</option>
            <option value="wide_resnet103_2">Wide_resnet103_2</option>
            <option value="efficientnet_b0">Efficientnet_b0</option>
            <option value="efficientnet_b1">Efficientnet_b1</option>
            <option value="efficientnet_b2">Efficientnet_b2</option>
            <option value="efficientnet_b3">Efficientnet_b3</option>
            <option value="efficientnet_b4">Efficientnet_b4</option>
            <option value="efficientnet_b5">Efficientnet_b5</option>
            <option value="efficientnet_b6">Efficientnet_b6</option>
            <option value="efficientnet_b7">Efficientnet_b7</option>
            <option value="efficientnet_v2_s">Efficientnet_v2_s</option>
            <option value="efficientnet_v2_m">Efficientnet_v2_m</option>
            <option value="efficientnet_v2_l">Efficientnet_v2_l</option>
            <option value="regnet_y_400mf">Regnet_y_400mf</option>
            <option value="regnet_y_800mf">Regnet_y_800mf</option>
            <option value="regnet_y_1_6gf">Regnet_y_1_6gf</option>
            <option value="regnet_y_3_2gf">Regnet_y_3_2gf</option>
            <option value="regnet_y_8gf">Regnet_y_8gf</option>
            <option value="regnet_y_16gf">Regnet_y_16gf</option>
            <option value="regnet_y_32gf">Regnet_y_32gf</option>
            <option value="regnet_y_128gf">Regnet_y_128gf</option>
            <option value="regnet_x_400mf">Regnet_x_400mf</option>
            <option value="regnet_x_800mf">Regnet_x_800mf</option>
            <option value="regnet_x_1_6gf">Regnet_x_1_6gf</option>
            <option value="regnet_x_3_2gf">Regnet_x_3_2gf</option>
            <option value="regnet_x_8gf">Regnet_x_8gf</option>
            <option value="regnet_x_16gf">Regnet_x_16gf</option>
            <option value="regnet_x_32gf">Regnet_x_32gf</option>
            <option value="vgg11">Vgg11</option>
            <option value="vgg11_bn">Vgg11_bn</option>
            <option value="vgg13">Vgg13</option>
            <option value="vgg13_bn">Vgg13_bn</option>
            <option value="vgg16">Vgg16</option>
            <option value="vgg16_bn">Vgg16_bn</option>
            <option value="vgg19">Vgg19</option>
            <option value="vgg19_bn">Vgg19_bn</option>
            <option value="shufflenet_v2_x0_5">Shufflenet_v2_x0_5</option>
            <option value="shufflenet_v2_x1_0">Shufflenet_v2_x1_0</option>
            <option value="shufflenet_v2_x1_5">Shufflenet_v2_x1_5</option>
            <option value="shufflenet_v2_x2_0">Shufflenet_v2_x2_0</option>
            <option value="squeezenet1_0">Squeezenet1_0</option>
            <option value="squeezenet1_1">Squeezenet1_1</option>
            <option value="swin_t">Swin_t</option>
            <option value="swin_s">Swin_s</option>
            <option value="swin_b">Swin_b</option>
            <option value="swin_v2_t">Swin_v2_t</option>
            <option value="swin_v2_s">Swin_v2_s</option>
            <option value="swin_v2_b">Swin_v2_b</option>
            <option value="vit_b_16">Vit_b_16</option>
            <option value="vit_b_32">Vit_b_32</option>
            <option value="vit_l_16">Vit_l_16</option>
            <option value="vit_l_32">Vit_l_32</option>
            <option value="vit_h_14">Vit_h_14</option>
            <option value="convnext_tiny">Convnext_tiny</option>
            <option value="convnext_small">Convnext_small</option>
            <option value="convnext_base">Convnext_base</option>
            <option value="convnext_large">Convnext_large</option>
            <option value="maxvit_t">Maxvit_t</option>
            <option value="alexnet">Alexnet</option>
            <option value="googlenet">Googlenet</option>
            <option value="inception_v3">Inception_v3</option>
            <option value="mobilenet_v2">Mobilenet_v2</option>
            <option value="mobilenet_v3_large">Mobilenet_v3_large</option>
            <option value="mobilenet_v3_small">Mobilenet_v3_small</option>
            <!-- MetaFormer Models -->
            <option value="identityformer_s12">IdentityFormer S12</option>
            <option value="identityformer_s24">IdentityFormer S24</option>
            <option value="identityformer_s36">IdentityFormer S36</option>
            <option value="identityformer_m36">IdentityFormer M36</option>
            <option value="identityformer_m48">IdentityFormer M48</option>
            <option value="randformer_s12">RandFormer S12</option>
            <option value="randformer_s24">RandFormer S24</option>
            <option value="randformer_s36">RandFormer S36</option>
            <option value="randformer_m36">RandFormer M36</option>
            <option value="randformer_m48">RandFormer M48</option>
            <option value="poolformerv2_s12">PoolFormerV2 S12</option>
            <option value="poolformerv2_s24">PoolFormerV2 S24</option>
            <option value="poolformerv2_s36">PoolFormerV2 S36</option>
            <option value="poolformerv2_m36">PoolFormerV2 M36</option>
            <option value="poolformerv2_m48">PoolFormerV2 M48</option>
            <option value="convformer_s18">ConvFormer S18</option>
            <option value="convformer_s18_384">ConvFormer S18 384</option>
            <option value="convformer_s18_in21ft1k">ConvFormer S18 ImageNet21k</option>
            <option value="convformer_s18_384_in21ft1k">ConvFormer S18 384 ImageNet21k</option>
            <option value="convformer_s18_in21k">ConvFormer S18 ImageNet21k Pretrained</option>
            <option value="convformer_s36">ConvFormer S36</option>
            <option value="convformer_s36_384">ConvFormer S36 384</option>
            <option value="convformer_s36_in21ft1k">ConvFormer S36 ImageNet21k</option>
            <option value="convformer_s36_384_in21ft1k">ConvFormer S36 384 ImageNet21k</option>
            <option value="convformer_s36_in21k">ConvFormer S36 ImageNet21k Pretrained</option>
            <option value="convformer_m36">ConvFormer M36</option>
            <option value="convformer_m36_384">ConvFormer M36 384</option>
            <option value="convformer_m36_in21ft1k">ConvFormer M36 ImageNet21k</option>
            <option value="convformer_m36_384_in21ft1k">ConvFormer M36 384 ImageNet21k</option>
            <option value="convformer_m36_in21k">ConvFormer M36 ImageNet21k Pretrained</option>
            <option value="convformer_b36">ConvFormer B36</option>
            <option value="convformer_b36_384">ConvFormer B36 384</option>
            <option value="convformer_b36_in21ft1k">ConvFormer B36 ImageNet21k</option>
            <option value="convformer_b36_384_in21ft1k">ConvFormer B36 384 ImageNet21k</option>
            <option value="convformer_b36_in21k">ConvFormer B36 ImageNet21k Pretrained</option>
            <option value="caformer_s18">CAFormer S18</option>
            <option value="caformer_s18_384">CAFormer S18 384</option>
            <option value="caformer_s18_in21ft1k">CAFormer S18 ImageNet21k</option>
            <option value="caformer_s18_384_in21ft1k">CAFormer S18 384 ImageNet21k</option>
            <option value="caformer_s18_in21k">CAFormer S18 ImageNet21k Pretrained</option>
            <option value="caformer_s36">CAFormer S36</option>
            <option value="caformer_s36_384">CAFormer S36 384</option>
            <option value="caformer_s36_in21ft1k">CAFormer S36 ImageNet21k</option>
            <option value="caformer_s36_384_in21ft1k">CAFormer S36 384 ImageNet21k</option>
            <option value="caformer_s36_in21k">CAFormer S36 ImageNet21k Pretrained</option>
            <option value="caformer_m36">CAFormer M36</option>
            <option value="caformer_m36_384">CAFormer M36 384</option>
            <option value="caformer_m36_in21ft1k">CAFormer M36 ImageNet21k</option>
            <option value="caformer_m36_384_in21ft1k">CAFormer M36 384 ImageNet21k</option>
            <option value="caformer_m36_in21k">CAFormer M36 ImageNet21k Pretrained</option>
            <option value="caformer_b36">CAFormer B36</option>
            <option value="caformer_b36_384">CAFormer B36 384</option>
            <option value="caformer_b36_in21ft1k">CAFormer B36 ImageNet21k</option>
            <option value="caformer_b36_384_in21ft1k">CAFormer B36 384 ImageNet21k</option>
            <option value="caformer_b36_in21k">CAFormer B36 ImageNet21k Pretrained</option>
        </param>

        <conditional name="scratch_fine_tune">
            <param name="use_pretrained" type="select"
                label="Use pretrained weights?"
                help="If select no, the encoder, combiner, and decoder will all be initialized and trained from scratch. (e.g. when your images are very different from ImageNet or no suitable pretrained model exists.)">
                <option value="false">No</option>
                <option value="true" selected="true">Yes</option>
            </param>
            <when value="true">
                <param name="fine_tune" type="select" label="Fine tune the encoder?"
                    help="Whether to fine tune the encoder(combiner and decoder will be fine-tuned anyway)" >
                    <option value="false" >No</option>
                    <option value="true" selected="true">Yes</option>
                </param>
            </when>
            <when value="false">
                <!-- No additional parameters to show if the user selects 'No' -->
            </when>
        </conditional>
        <param name="image_resize"
               type="select"
               label="Image Resize"
               help="Select the size to resize images to. Original size keeps images as-is, while other options resize all images to the specified dimensions.">
            <option value="original" selected="true">Original Size (No Resize)</option>
            <option value="96x96">96x96</option>
            <option value="128x128">128x128</option>
            <option value="160x160">160x160</option>
            <option value="192x192">192x192</option>
            <option value="220x220">220x220</option>
            <option value="224x224">224x224</option>
            <option value="256x256">256x256</option>
            <option value="299x299">299x299</option>
            <option value="320x320">320x320</option>
            <option value="384x384">384x384</option>
            <option value="448x448">448x448</option>
            <option value="512x512">512x512</option>
        </param>
        <param name="augmentation"
               type="select"
               multiple="true"
               display="checkboxes"
               label="Image Augmentation"
               help="Pick any combination of augmentations to apply">
            <option value="random_horizontal_flip">Random Horizontal Flip</option>
            <option value="random_vertical_flip">Random Vertical Flip</option>
            <option value="random_rotate">Random Rotate</option>
            <option value="random_blur">Random Blur</option>
            <option value="random_brightness">Random Brightness</option>
            <option value="random_contrast">Random Contrast</option>
        </param>
        <param argument="random_seed" type="integer" value="42" optional="true" label="Random seed (set for reproducibility)" min="0" max="999999"/>
        <conditional name="advanced_settings">
            <param name="customize_defaults" type="select" label="Customize Default Settings?" help="Select yes if you want to customize the default settings of the experiment.">
                <option value="false" selected="true">No</option>
                <option value="true">Yes</option>
            </param>
            <when value="true">
                <param name="epochs" type="integer" value="10" min="1" max="99999" label="Epochs" help="Total number of full passes through the training dataset. Higher values may improve accuracy but increase training time. Default: 10." />
                <param name="early_stop" type="integer" value="5" min="1" max="99999" label="Early Stop" help="Number of epochs with no improvement after which training will be stopped. Default: 5." />
                <conditional name="learning_rate_condition">
                    <param name="learning_rate_define" type="select" label="Define an initial learning rate?" help="Want to change the initial learning rate from default to a number? See ludwig.ai for more info. Default: No" >
                        <option value="false" selected="true" >No</option>
                        <option value="true">Yes</option>
                    </param>
                    <when value="true">
                        <param name="learning_rate" type="float" value="0.001" min="0.0001" max="1.0" label="Learning Rate" help="Initial learning rate for the optimizer. Default: 0.001." />
                    </when>
                    <when value="false">
                        <!-- No additional parameters to show if the user selects 'No' -->
                    </when>
                </conditional>
                <conditional name="batch_size_condition">
                    <param name="batch_size_define" type="select" label="Define your batch size?" help="Want to change the batch size from auto to a number? See ludwig.ai for more info. Default: No" >
                        <option value="false" selected="true" >No</option>
                        <option value="true">Yes</option>
                    </param>
                    <when value="true">
                        <param name="batch_size" type="integer" value="32" min="1" max="99999" label="Batch Size" help="Number of samples per gradient update. Default: 32." />
                    </when>
                    <when value="false">
                        <!-- No additional parameters to show if the user selects 'No' -->
                    </when>
                </conditional>
                <param name="train_split" type="float"
                        label="Training split proportion (only works if no split column in the metadata csv)"
                        value="0.7"
                        help="Fraction of data for training (e.g., 0.7). train split + val split + test split should = 1"/>
                <param name="val_split"   type="float"
                        label="Validation split proportion (only works if no split column in the metadata csv)"
                        value="0.1"
                        help="Fraction of data for validation (e.g., 0.1). train split + val split + test split should = 1"/>
                <param name="test_split"  type="float"
                        label="Test split proportion (only works if no split column in the metadata csv)"
                        value="0.2"
                        help="Fraction of data for testing (e.g., 0.2) train split + val split + test split should = 1."/>
                <param name="threshold" type="float" value="0.5" min="0.0" max="1.0" optional="true" label="Decision Threshold (binary only)" help="Set the decision threshold for binary classification (0.0–1.0). Only applies when task is binary; default is 0.5." />
            </when>
            <when value="false">
                <!-- No additional parameters to show if the user selects 'No' -->
            </when>
        </conditional>
    </inputs>
    <outputs>
        <data format="ludwig_model" name="output_model" label="${tool.name} trained model on ${on_string}" />
        <data format="html" name="output_report" from_work_dir="image_classification_results_report.html" label="${tool.name} report on ${on_string}" />
        <collection type="list" name="output_pred_csv" label="${tool.name} predictions CSVs/experiment stats/plots on ${on_string}" >
            <discover_datasets pattern="(?P&lt;designation&gt;predictions\.csv)" format="csv" directory="experiment_run" />
            <discover_datasets pattern="(?P&lt;designation&gt;.+)\.json" format="json" directory="experiment_run" />
            <discover_datasets pattern="(?P&lt;designation&gt;.+)\.png" format="png" directory="experiment_run/visualizations/train" />
            <discover_datasets pattern="(?P&lt;designation&gt;.+)\.png" format="png" directory="experiment_run/visualizations/test" />
        </collection>
    </outputs>
    <tests>
        <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="resnet18" />
            <param name="augmentation" value="random_horizontal_flip,random_vertical_flip,random_rotate" />
            <param name="task_selection|task" value="classification" />
            <param name="task_selection|validation_metric_multiclass" value="accuracy" />
            <output name="output_report">
                <assert_contents>
                    <has_text text="Config and Overall Performance Summary" />
                    <has_text text="Training and Validation Results" />
                    <has_text text="Test Results" />
                </assert_contents>
            </output>

            <output_collection name="output_pred_csv" type="list" >
                <element name="predictions.csv" >
                    <assert_contents>
                        <has_n_columns n="1" />
                    </assert_contents>
                </element>
            </output_collection>
        </test>
        <test expect_num_outputs="3">
            <param name="input_csv" value="utkface_labels.csv" ftype="csv" />
            <param name="image_zip" value="age_regression.zip" ftype="zip" />
            <param name="model_name" value="resnet18" />
            <output name="output_report">
                <assert_contents>
                    <has_text text="Config and Overall Performance Summary" />
                    <has_text text="Training and Validation Results" />
                    <has_text text="Test Results" />
                </assert_contents>
            </output>
            <output_collection name="output_pred_csv" type="list" >
                <element name="predictions.csv" >
                    <assert_contents>
                        <has_n_columns n="1" />
                    </assert_contents>
                </element>
            </output_collection>
        </test>
        <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" />
            <output name="output_report">
                <assert_contents>
                    <has_text text="Config and Overall Performance Summary" />
                    <has_text text="Training and Validation Results" />
                    <has_text text="Test Results" />
                </assert_contents>
            </output>

            <output_collection name="output_pred_csv" type="list" >
                <element name="predictions.csv" >
                    <assert_contents>
                        <has_n_columns n="1" />
                    </assert_contents>
                </element>
            </output_collection>
        </test>
        <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="randformer_s12" />
            <param name="advanced_settings|customize_defaults" value="true" />
            <param name="advanced_settings|epochs" value="5" />
            <output name="output_report">
                <assert_contents>
                    <has_text text="Test Performance Summary" />
                    <has_text text="Training and Validation Results" />
                    <has_text text="Test Results" />
                </assert_contents>
            </output>

            <output_collection name="output_pred_csv" type="list" >
                <element name="predictions.csv" >
                    <assert_contents>
                        <has_n_columns n="1" />
                    </assert_contents>
                </element>
            </output_collection>
        </test>
        <!-- Test 7: MetaFormer with 384x384 input - verifies model correctly handles non-224x224 dimensions -->
        <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" />
            <param name="image_resize" value="384x384" />
            <output name="output_report">
                <assert_contents>
                    <has_text text="Config and Overall Performance Summary" />
                    <has_text text="Training and Validation Results" />
                    <has_text text="Test Results" />
                </assert_contents>
            </output>
            <output_collection name="output_pred_csv" type="list" >
                <element name="predictions.csv" >
                    <assert_contents>
                        <has_n_columns n="1" />
                    </assert_contents>
                </element>
                <element name="description" >
                    <assert_contents>
                        <has_text text="384" />
                    </assert_contents>
                </element>
            </output_collection>
        </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" />
            <param name="image_zip" value="binary_images.zip" ftype="zip" />
            <param name="model_name" value="resnet18" />
            <param name="advanced_settings|customize_defaults" value="true" />
            <param name="advanced_settings|threshold" value="0.6" />
            <output name="output_report">
                <assert_contents>
                    <has_text text="Results Summary" />
                    <has_text text="Train/Validation Results" />
                    <has_text text="Test Results" />
                    <has_text text="ROC-AUC Curves" />
                </assert_contents>
            </output>
            <output_collection name="output_pred_csv" type="list" >
                <element name="predictions.csv" >
                    <assert_contents>
                        <has_n_columns n="1" />
                    </assert_contents>
                </element>
                <element name="test_statistics.json" >
                    <assert_contents>
                        <has_text text="roc_auc" />
                    </assert_contents>
                </element>
            </output_collection>
        </test> -->
        <!-- Test 9: PoolFormerV2 model configuration - verifies custom_model parameter persists in config -->
        <!-- Test 10: Multi-class classification with ROC curves - verifies robust ROC-AUC plot generation -->
        <!-- <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="resnet18" />
            <param name="advanced_settings|customize_defaults" value="true" />
            <param name="advanced_settings|epochs" value="3" />
            <output name="output_report">
                <assert_contents>
                    <has_text text="Results Summary" />
                    <has_text text="Train/Validation Results" />
                    <has_text text="Test Results" />
                    <has_text text="ROC-AUC Curves" />
                    <has_text text="Micro-average ROC" />
                </assert_contents>
            </output>
            <output_collection name="output_pred_csv" type="list" >
                <element name="predictions.csv" >
                    <assert_contents>
                        <has_n_columns n="1" />
                    </assert_contents>
                </element>
            </output_collection>
        </test> -->
        <test expect_num_outputs="3">
            <param name="input_csv" value="mnist_subset_binary.csv" ftype="csv" />
            <param name="image_zip" value="mnist_subset.zip" ftype="zip" />
            <param name="model_name" value="resnet18" />
            <param name="advanced_settings|customize_defaults" value="true" />
            <param name="advanced_settings|threshold" value="0.6" />
            <param name="task_selection|task" value="classification" />
            <param name="task_selection|validation_metric_multiclass" value="balanced_accuracy" />
            <output name="output_report">
                <assert_contents>
                    <has_text text="Config and Overall Performance Summary" />
                    <has_text text="Training and Validation Results" />
                    <has_text text="Test Results" />
                    <has_text text="Threshold" />
                    <has_text text="0.60" />
                </assert_contents>
            </output>
            <output_collection name="output_pred_csv" type="list" >
                <element name="predictions.csv" >
                    <assert_contents>
                        <has_n_columns n="1" />
                    </assert_contents>
                </element>
            </output_collection>
        </test>
    </tests>
    <help>
        <![CDATA[
**What it does**
Image Learner for Classification/regression: trains and evaluates a image classification/regression model.
It uses the metadata csv to find the image paths and labels. 
The metadata csv should contain a column with the name 'image_path' and a column with the name 'label'.
Optionally, you can also add a column with the name 'split' to specify which split each row belongs to (train, val, test). 
If you do not provide a split column, the tool will automatically split the data into train, val, and test sets based on the proportions you specify or [0.7, 0.1, 0.2] by default.

**Models Available**
This tool supports a wide range of state-of-the-art image classification models including:
- Traditional CNNs (ResNet, EfficientNet, VGG, etc.)
- Vision Transformers (ViT, Swin Transformer)
- Modern architectures (ConvNeXt, MaxViT)
- MetaFormer family models (IdentityFormer, RandFormer, PoolFormerV2, ConvFormer, CAFormer)

**MetaFormer Models**
The MetaFormer family represents a unified perspective on transformer-like architectures. These models demonstrate that the success of transformers is largely due to their general architecture rather than specific components like attention mechanisms. All MetaFormer models use pretrained weights from Hugging Face and provide explicit confirmation of weight loading.

**If the selected label column has more than 10 unique values, the tool will automatically treat the task as a regression problem and apply appropriate metrics (e.g., MSE, RMSE, R²).**

**Outputs**
The tool will output a trained model in the form of a ludwig_model file,
a report in the form of an HTML file, and a collection of CSV/json/png files containing the predictions, experiment stats and visualizations.
The html report will contain metrics&experiment setup parameters, train&val plots and test plots.

        ]]>
    </help>
    <citations>
            <citation type="bibtex">
@misc{https://doi.org/10.48550/arxiv.1909.07930,
    doi = {10.48550/ARXIV.1909.07930},
    url = {https://arxiv.org/abs/1909.07930},
    author = {Molino, Piero and Dudin, Yaroslav and Miryala, Sai Sumanth},
    title = {Ludwig: a type-based declarative deep learning toolbox},
    publisher = {arXiv},
    year = {2019},
    copyright = {arXiv.org perpetual, non-exclusive license}
}
            </citation>
        </citations>
</tool>