Why LungCT-NET Stacks Four Networks Instead of Trusting One

Analysis by the aitrendblend editorial team · 13 minute read
Lung Cancer Transfer Learning Ensemble Learning Explainable AI
 LungCT-NET: Illustration of four transfer learning networks feeding into a stacking ensemble for lung nodule classification from CT scans
Four different networks look at the same nodule and disagree slightly. That disagreement, it turns out, is useful.
A single deep learning model asked to sort lung nodules into benign or malignant will usually get most of them right and quietly get a worrying number wrong in ways nobody can explain. A team spanning Jahangirnagar University in Bangladesh, King Saud University in Saudi Arabia, and Charles Sturt University in Australia built a system that instead asks four different networks to weigh in, feeds their disagreements into a second layer of tree based classifiers, and then opens the whole thing up with SHAP so a radiologist can see which parts of the scan actually swayed the decision.
This article explains published research. It is not medical advice, diagnosis or treatment. LungCT-NET was tested on a public research dataset and has not been validated in a clinical trial or approved for diagnostic use. Anyone concerned about a lung CT finding should speak with a radiologist or physician rather than rely on this summary.

Key points

  • LungCT-NET reconfigures seven pretrained networks for binary lung nodule classification, then picks the four strongest, VGG-16, VGG-19, MobileNet-V2 and EfficientNet-B0, as base models for a second stage ensemble.
  • That second stage stacks three tree based classifiers, Decision Tree, Extra Trees and Random Forest, and combines their outputs with a Logistic Regression meta model.
  • On the LIDC IDRI dataset, the full system reached 98.99 percent accuracy, precision, recall and F1 score, with an AUC of 98.15 percent, well above any of its seven individual component networks.
  • An ablation study shows the ensemble does not lean on its most accurate solo model. Removing MobileNet-V2, a comparatively lightweight network, hurt the ensemble more than removing the deeper VGG-19.
  • SHAP explanations are applied both to the individual transfer learning models and to the tree based base learners, giving two separate layers of interpretability rather than one.
  • Despite combining four networks, the ensemble’s prediction speed of two seconds per scan matched the fastest single lightweight model tested, MobileNet-V2.

The diagnostic problem this is trying to solve

Lung cancer kills more people worldwide than any other cancer, and the reason is timing more than treatment. A lung nodule found early, while it is still small and localized, is a very different clinical situation from one found after it has already invaded surrounding tissue. Low dose CT screening catches nodules earlier than a chest X ray, which is part of why it has been shown to cut lung cancer mortality by around a fifth in trial populations. But catching a nodule is only step one. Someone still has to decide whether it is benign or malignant, and that decision has historically required a radiologist to weigh subtle differences in texture, shape and density, differences that are genuinely hard to see consistently, even for experienced readers.

The authors frame their motivation around two separate failures of prior automated approaches. The first is data scarcity. Deep learning models are hungry for labeled examples, and annotated lung CT data is expensive to produce and restricted by patient privacy, which is exactly why transfer learning, reusing a network already trained on millions of general images, has become the default workaround in this field. The second failure is opacity. Even when a deep model performs well, a black box prediction is a hard sell to a radiologist who is professionally and legally accountable for a diagnosis. LungCT-NET tries to address both problems at once, leaning on transfer learning to cope with limited data and layering SHAP throughout the pipeline to make the reasoning visible.

Where the field already stood

The literature review inside the paper is worth pausing on because it maps out just how crowded this specific benchmark has become. Working from the same LIDC IDRI dataset, prior groups have tried VGG based capsule networks reaching 98.61 percent accuracy, weighted VGG networks around 93 percent, ResNet variants in the low nineties, and a federated learning system paired with a capsule network claiming 99.69 percent accuracy, though the authors note that result lacked proper output interpretation. Ensemble approaches specifically had already shown promise. One prior study combined three transfer learning models with a custom weight allocation scheme based on F1 and ROC AUC scores and reported 97.23 percent accuracy. The gap LungCT-NET is aiming at is not raw accuracy so much as combining a strong ensemble with genuine, multi layered explainability, which fewer of the cited studies attempted together.

How LungCT-NET is actually built

The pipeline runs in two distinct stages, and understanding why the second stage exists is the key to understanding the whole paper.

Stage one, seven reconfigured networks compete

Seven ImageNet pretrained backbones, MobileNet-V2, DenseNet-121, InceptionNet-V3, EfficientNet-B0, VGG-16, VGG-19 and ResNet152-V2, each have their original classification heads stripped off and replaced with a lighter set of layers built for this specific binary task. Every backbone keeps its pretrained convolutional layers frozen, which means only the new head, typically a global average pooling layer, a couple of dense layers, and dropout at a 50 percent rate, actually updates during training. This is a fairly standard transfer learning move, and its main payoff is that training stays fast and the model is less likely to overfit on a dataset that, once split for training, only contains a few thousand images per class.

Each of these seven models is trained and evaluated independently on identical CT preprocessing, and their solo performance varies a lot. VGG-19 and VGG-16 come out on top individually, both landing around 95 percent accuracy on the held out test set, while ResNet152-V2 trails badly at 75.9 percent despite being the deepest network in the group. That gap alone is a useful reminder that depth is not destiny in transfer learning, since how well a frozen backbone’s pretrained features happen to transfer to grayscale medical texture patterns matters more than raw parameter count.

Stage two, four survivors get stacked

Rather than simply picking the single best performing network, the authors keep the top four, VGG-16, VGG-19, MobileNet-V2 and EfficientNet-B0, and treat their predictions as input features for a second, entirely separate machine learning layer. The reasoning given for this specific quartet is architectural diversity as much as accuracy. VGG-19’s extra depth captures more abstract, high level structure, VGG-16 focuses on finer local detail, MobileNet-V2’s inverted residual blocks extract efficient local features with far fewer parameters, and EfficientNet-B0’s compound scaling balances low and high level feature extraction. The paper reports they also tried ensembles of three models, which underperformed, and ensembles of more than four, which added computational cost for only a marginal accuracy gain, landing on four as the practical sweet spot.

The stacking layer itself uses three tree based classifiers as base learners, Decision Tree, Extra Trees and Random Forest, feeding into a Logistic Regression meta classifier. Each tree based classifier plays a distinct role in the authors’ framing. The Decision Tree is a simple, interpretable baseline that draws sharp decision boundaries but tends to overfit on its own. Random Forest counters that overfitting by bagging many trees over bootstrapped samples and random feature subsets. Extra Trees pushes randomness further still by randomizing split thresholds too, adding diversity that Random Forest alone does not fully provide. Feeding all three into a Logistic Regression meta model lets that final layer learn how much to trust each tree based classifier’s opinion, rather than averaging them blindly.

The interesting design choice is not any single network. It is refusing to let the strongest individual model, VGG-19, be the final word, and instead making four models argue it out through a second machine learning layer.Reading of the paper’s architecture, not a direct quote from the authors

Getting the CT images ready

Before any of this, every scan goes through a nine step preprocessing pipeline built to isolate just the lung tissue and strip out everything else in the frame. Normalization using mean and standard deviation comes first, followed by extreme value handling that replaces outlier pixels with the mean of the central region. Median filtering smooths the image, and anisotropic diffusion follows to reduce noise while still preserving edges, which matters because a nodule’s edge sharpness is itself a diagnostic clue. K-means clustering then finds a threshold to separate lung tissue from everything else, producing a binary mask that erosion and dilation clean up by closing small gaps. Labeling connects the resulting regions, and a final filtering step based on size and position keeps only the plausible lung regions before that mask gets multiplied back onto the original image, leaving a scan with everything but the lungs blacked out. Every processed image is then resized to 224 by 224 pixels with three channels to match what the pretrained backbones expect.

The dataset and how it was split

All of this runs on LIDC IDRI, a public thoracic CT archive covering 1018 patients with radiologist annotated nodules. Malignancy in the dataset is scored on a scale, and the authors set the cutoff at a score of three, anything below counts as benign and anything at or above counts as malignant. Even after that binarization, the classes are notably imbalanced toward malignant examples.

SplitBenign imagesMalignant images
Training2,0286,877
Validation6982,086
Test5481,679

The overall data was split 80 percent training and 20 percent testing first, and then a five fold stratified cross validation was run only within that 80 percent training portion, carving out roughly 64 percent for actual training and 16 percent for validation across folds while keeping the original test set completely untouched until final evaluation. That is a reasonable way to guard against a model quietly memorizing quirks of a single validation split, though it is worth flagging that the benign class stays outnumbered by roughly three to one throughout, which is exactly the kind of imbalance that can inflate accuracy figures if a model leans toward predicting the majority class. The paper’s own reported recall and specificity numbers, discussed below, are the figures worth checking against that concern rather than accuracy alone.

What the results actually show

The headline numbers are strong by any standard. LungCT-NET’s full stacked ensemble reached 98.99 percent accuracy, 98.99 percent precision, 98.99 percent recall, 98.998 percent F1 score, and an AUC of 98.15 percent on the held out test set, with a five fold cross validated foundation underneath those figures.

ModelAccuracyPrecisionRecallF1 scoreAUC
ResNet152-V275.9%75.9%99.3%86.1%71.9%
InceptionNet-V387.1%86.7%97.8%91.9%93.4%
DenseNet-12182.3%82.0%97.8%89.2%86.9%
EfficientNet-B090.4%92.4%95.1%93.7%94.0%
MobileNet-V290.4%96.7%90.3%93.4%96.2%
VGG-1695.1%95.8%97.7%96.7%97.6%
VGG-1995.2%95.4%98.3%96.9%97.1%
LungCT-NET (full ensemble)98.99%98.99%98.99%98.998%98.15%

What stands out is not just that the ensemble beats every individual network, that is close to the expected outcome for any well built stacking approach, but the size of the gap. The ensemble clears its best individual component, VGG-19, by close to four points of accuracy, which is a substantial jump for a benchmark this heavily studied. Error based metrics tell the same story from a different angle. The ensemble’s mean absolute error sits at just over 1 percent, compared to double digit error rates for ResNet152-V2, DenseNet-121 and InceptionNet-V3, and its false positive rate of 3.4 percent is a fraction of the 45 to 94 percent range some of the weaker individual networks post on that same metric, though those extremely high false positive figures for the weakest models likely reflect how those specific networks skew toward predicting malignant given the class imbalance in the data.

Takeaway. Stacking did not just average out noise between similar models. It closed a gap between the ensemble and its strongest single component that individual hyperparameter tuning of that one component probably could not have closed on its own.

The ablation study is where the real insight sits

Removing pieces one at a time is the most informative part of this paper, because it tests whether the ensemble’s four chosen networks and three tree classifiers are all pulling their weight, or whether some of them are just along for the ride.

On the transfer learning side, pulling MobileNet-V2 out of the ensemble caused the largest accuracy drop, down to 98.069 percent, a 0.93 point fall. Removing VGG-19, despite it being individually the second strongest performer of the seven networks tested solo, caused the smallest drop, down to 98.41 percent, just a 0.58 point fall. That is a genuinely counterintuitive result. The model that looks least impressive on its own, a comparatively lightweight, efficiency focused network, turns out to matter more to the ensemble’s final decision than one of its most individually accurate members. The likely explanation, and the paper gestures at this without fully spelling it out, is that MobileNet-V2’s different architectural approach, inverted residuals and depthwise separable convolutions, produces predictions that disagree with the VGG family in informative ways, giving the stacking layer more to work with. A model that is individually accurate but architecturally similar to another already in the ensemble adds less new information than a model that sees the data differently.

On the tree classifier side, removing Decision Tree hurt the most, dropping accuracy to 97.835 percent, a 1.17 point fall, the single largest drop recorded in the entire ablation study. Removing Random Forest, despite it carrying the highest SHAP importance score among the three tree classifiers in a separate analysis, had the smallest impact, a 0.91 point fall to 98.087 percent. Again the pattern favors diversity of decision style over individual strength. Decision Tree’s simple, sharp boundaries apparently contribute something to the ensemble that Random Forest’s more sophisticated bagging does not fully replicate, even though Random Forest looks stronger by itself.

Takeaway. When choosing base learners for a stacking ensemble, this paper’s ablation results argue for prioritizing how differently a model tends to be wrong over how accurate it is in isolation. The weakest component by individual metrics was, in both stages of this pipeline, the hardest one to remove.

Speed did not get sacrificed for accuracy

A four model ensemble sounds like it should be slower than any single network, and in terms of total compute it is. But the reported prediction speed per scan for the full LungCT-NET pipeline was 2 seconds, tied with MobileNet-V2 alone for the fastest of any model tested, and dramatically faster than the heaviest individual networks, ResNet152-V2 at 15 seconds and VGG-19 at 14 seconds. The explanation is architectural. The four base networks in the ensemble can run in parallel, and the tree based stacking layer sitting on top of their outputs is computationally cheap compared to a deep convolutional forward pass. For anyone weighing whether an ensemble is practical for near real time screening triage, this is a meaningfully reassuring data point, though it is worth noting the reported figure is a per scan prediction time in the authors’ cloud computing environment, Kaggle’s dual T4 GPU setup, and would vary on different hardware.

What SHAP actually revealed

The explainability analysis runs at two separate levels, which is a more thorough approach than most comparable papers attempt. At the level of the four transfer learning models, mean absolute SHAP values showed VGG-19 exerting the strongest pull on the ensemble’s malignant predictions, around 0.23, with VGG-16 close behind around 0.14 to 0.17. MobileNet-V2 and EfficientNet-B0 showed markedly smaller SHAP contributions, in the range of 0.01 to 0.05, despite MobileNet-V2’s outsized importance in the ablation study above. That is a genuinely interesting tension the paper does not fully resolve, a model can be structurally hard to remove from an ensemble, because it adds unique disagreement signal, while still contributing a small direct SHAP weight to the final prediction, because SHAP is measuring something closer to consistent directional influence than to how much unique information a feature carries.

At the level of the tree based stacking layer itself, Random Forest carried the highest aggregated SHAP importance, above 2.0, with Extra Trees around 1.5 and Decision Tree lowest around 1.2, which again sits in some tension with the ablation finding that removing Decision Tree hurt performance the most. Taken together, these two explainability results suggest SHAP importance and ablation sensitivity are answering genuinely different questions, one about steady influence on the score, the other about what unique information a component supplies that nothing else in the ensemble replaces, and a careful reader should not expect them to always point at the same component.

At the image level, SHAP heatmaps generated with a Gradient Explainer showed VGG-19 and VGG-16 concentrating attention on central regions of each CT slice, consistent with convolutional networks that build up hierarchical features toward the image center, while MobileNet-V2 showed a more dispersed attention pattern reaching toward the image periphery, and EfficientNet-B0 landed somewhere in between, a pattern the authors attribute to its compound scaling approach balancing depth, width and resolution.

Clinical translation gap

It is worth being specific about what separates a 98.99 percent benchmark result from something a hospital could safely deploy. LIDC IDRI, while a respected and widely used public resource, was assembled from a specific set of imaging protocols and institutions, and the paper does not report testing on an independent external dataset collected from a different hospital, scanner vendor, or patient population, the kind of test that would speak most directly to real world generalization. The malignancy label itself is derived from a radiologist assigned score in the dataset’s annotations rather than from confirmed pathology such as a biopsy in every case, which means the ground truth the model is learning to match is itself a clinical judgment call, not an absolute biological fact. And the entire evaluation is retrospective, meaning the model was tested against scans and labels that already existed rather than followed prospectively as new patients came through a screening program, which is the setting where a tool like this would eventually need to prove itself before touching clinical workflow.

Clinical limitations reported or implied in the paper

  • All training, validation and testing data comes from a single public archive, LIDC IDRI, with no external, independently sourced test set to check generalization across different scanners or institutions.
  • The benign class is outnumbered roughly three to one by the malignant class across every data split, and while five fold stratified cross validation helps guard against overfitting to that imbalance, the paper does not report class balanced accuracy or a confusion matrix breakdown for the final stacked ensemble specifically, only for the seven individual base networks.
  • Malignancy ground truth is derived from an annotated score threshold rather than confirmed histopathology for every case, so some label noise relative to a true biopsy confirmed outcome should be assumed.
  • The evaluation is retrospective on existing, already collected scans, not a prospective study following real screening patients, so how the system performs on the kind of borderline or unusual case that a real screening population would eventually produce remains untested.

Where this sits next to the rest of the field

Table 9 in the paper lines LungCT-NET up against a decade or so of prior approaches on the same or closely related datasets, and the comparison is genuinely favorable. Earlier CNN based methods cluster in the 85 to 95 percent accuracy range, hand crafted feature approaches land similarly, and even the strongest prior transfer learning ensemble the authors cite, a combination of three models reported at 97.23 percent accuracy, sits about 1.8 points behind LungCT-NET’s 98.99 percent. That is a meaningful improvement on an extremely well trodden benchmark, and the fact that the authors also improve or match specificity and AUC alongside accuracy suggests the gain is not simply coming from tuning toward the majority class.

The paper’s own discussion is candid that the improvement stems less from any single architectural innovation and more from the synergistic combination of reconfigured transfer learning models feeding into deliberately diverse tree based classifiers. That is a fair characterization. There is no fundamentally new layer type or training objective introduced here. What is genuinely useful is the empirical work of figuring out which four networks and which three classifiers actually complement each other, backed up by an ablation study rigorous enough to show that the intuitive choice, keep whatever scores highest individually, is not the right way to build the ensemble.

Limitations worth taking seriously

A few things beyond the clinical translation gap deserve a skeptical eye. The paper reports that ensembles of three base networks underperformed and ensembles of more than four added cost for marginal gain, but does not report the specific accuracy figures for those alternative ensemble sizes, so a reader cannot fully judge how close the three and five model alternatives actually came. The SHAP analysis, while genuinely more thorough than most comparable papers, is presented largely as descriptive visualization rather than validated against radiologist judgment. Comparing the SHAP highlighted regions against annotations from practicing radiologists, something the authors themselves flag as future work, would be a meaningfully stronger form of validation than showing that attention concentrates in plausible looking regions. Finally, the reported prediction speed of two seconds is specific to the Kaggle dual T4 GPU environment used for these experiments, and deployment on typical hospital hardware, which is rarely equipped with dedicated GPUs at this scale, would likely look considerably different.

Conclusion

The core achievement here is a carefully engineered two stage ensemble that beats every one of its seven individual components by a wide margin on a heavily benchmarked public dataset, while backing that result up with an unusually thorough ablation study and a two layer explainability analysis. Neither the transfer learning reconfiguration nor the tree based stacking layer is individually novel. What makes LungCT-NET worth reading closely is the empirical discipline behind choosing which four networks and which three classifiers to combine, and the honesty of showing that the intuitive choice would have been wrong.

The conceptual takeaway that travels furthest beyond this specific paper is the disconnect between a component’s solo accuracy and its value inside an ensemble. MobileNet-V2 and Decision Tree, the least individually impressive members of their respective groups, turned out to be the hardest to remove without hurting the whole system. That is a useful, somewhat counterintuitive lesson for anyone building a stacking ensemble in medical imaging or elsewhere, and it argues for testing removal sensitivity rather than assuming your strongest solo performers automatically make the strongest team.

Whether this specific architecture transfers well to other cancer types or imaging modalities is plausible but untested here. The general recipe, reconfigure a handful of diverse pretrained backbones, stack diverse simple classifiers on top of their outputs, and layer SHAP at both stages, does not depend on anything unique to lung tissue or CT imaging, so there is little architectural reason it could not be tried on other binary medical imaging classification problems with similarly scarce labeled data.

The honest remaining limitations, a single source dataset, retrospective evaluation, and SHAP results not yet checked against radiologist annotation, mean the realistic next step is external validation and a closer look at whether the model’s attention actually lines up with what a pathologist or radiologist would flag, not a jump toward clinical deployment. None of that undercuts the technical result. It just means the distance from benchmark to bedside here is the usual one, not a shortcut this paper has already closed.

The authors’ own stated next steps point toward broader CT scan datasets beyond LIDC IDRI, further refined preprocessing and feature optimization, and direct comparison of the SHAP heatmaps against real clinical findings. Each of those would meaningfully strengthen the case for LungCT-NET as something closer to a deployable tool rather than a strong benchmark result, and each is a reasonable, achievable next step rather than a distant aspiration.

Frequently asked questions

What does LungCT-NET actually classify

It performs binary classification of lung nodules seen on CT scans, sorting each nodule into benign or malignant based on the malignancy scoring included in the LIDC IDRI dataset’s annotations.

Why use four networks instead of just the best one

The ablation study shows the ensemble outperforms any single network by a wide margin, and that its most valuable members are not necessarily the most individually accurate ones. MobileNet-V2, a comparatively lightweight model, mattered more to the final ensemble than the deeper VGG-19 despite scoring lower on its own.

How does the stacking ensemble actually combine the four networks’ predictions

The four transfer learning models’ predictions are concatenated and fed as input features into three tree based classifiers, Decision Tree, Extra Trees and Random Forest, whose outputs are then combined by a Logistic Regression meta classifier to produce the final benign or malignant prediction.

Is LungCT-NET ready to be used in a hospital

No. It was evaluated on a single public research dataset without external validation on data from other institutions or scanners, and the evaluation was retrospective rather than tested prospectively on real incoming patients. Clinical use would require substantially more validation than reported here.

What does the SHAP analysis add beyond the accuracy numbers

SHAP is applied at two levels, showing which of the four transfer learning models most influences the ensemble’s decisions and, separately, which of the three tree based classifiers carries the most weight in the stacking layer, plus image level heatmaps showing which regions of each CT scan drove individual predictions.

Did every component of the ensemble turn out to be necessary

Yes, according to the ablation study. Removing any one of the four transfer learning models or any one of the three tree based classifiers reduced accuracy, though by different amounts, with MobileNet-V2 and Decision Tree proving the hardest to remove without hurting performance.

Reproducible implementation sketch

The block below is an independent implementation of the two stage pipeline described in the paper, using PyTorch for the four reconfigured transfer learning backbones and scikit learn for the stacking ensemble, matching the paper’s own design choice to pair deep feature extractors with classical tree based meta learners rather than a purely deep stacking layer. It is a starting point for experimentation, not a copy of the authors’ original code, which was not released publicly at the time of writing.

# lungct_net.py
# Independent reproduction of LungCT-NET (Noman et al., Knowledge-Based Systems 2025)
# Four reconfigured transfer learning backbones -> stacking ensemble of tree classifiers

import torch
import torch.nn as nn
import torchvision.models as models
import numpy as np

from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import ExtraTreesClassifier, RandomForestClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import StackingClassifier
from sklearn.model_selection import GridSearchCV
from sklearn.metrics import accuracy_score, precision_recall_fscore_support, roc_auc_score


class ReconfiguredBackbone(nn.Module):
    """Wraps a frozen ImageNet pretrained backbone with a lightweight trainable
    head for binary lung nodule classification, matching the paper's design.
    global average pooling -> dense -> dropout -> dense -> sigmoid."""

    def __init__(self, backbone_name="mobilenet_v2", hidden_dim=128, dropout=0.5):
        super().__init__()
        self.backbone_name = backbone_name

        if backbone_name == "vgg16":
            base = models.vgg16(weights=models.VGG16_Weights.IMAGENET1K_V1)
            self.features = base.features
            feat_dim = 512
        elif backbone_name == "vgg19":
            base = models.vgg19(weights=models.VGG19_Weights.IMAGENET1K_V1)
            self.features = base.features
            feat_dim = 512
        elif backbone_name == "mobilenet_v2":
            base = models.mobilenet_v2(weights=models.MobileNet_V2_Weights.IMAGENET1K_V1)
            self.features = base.features
            feat_dim = 1280
        elif backbone_name == "efficientnet_b0":
            base = models.efficientnet_b0(weights=models.EfficientNet_B0_Weights.IMAGENET1K_V1)
            self.features = base.features
            feat_dim = 1280
        else:
            raise ValueError(f"Unsupported backbone {backbone_name}")

        # freeze the pretrained base, only the head below trains
        for param in self.features.parameters():
            param.requires_grad = False

        self.pool = nn.AdaptiveAvgPool2d(1)
        self.head = nn.Sequential(
            nn.Flatten(),
            nn.Linear(feat_dim, hidden_dim),
            nn.ReLU(),
            nn.Dropout(dropout),
            nn.Linear(hidden_dim, 1),
            nn.Sigmoid(),
        )

    def forward(self, x):
        feats = self.features(x)
        pooled = self.pool(feats)
        return self.head(pooled).squeeze(-1)  # (B,) probability of malignant


def train_backbone(model, train_loader, val_loader, device, epochs=20, lr=1e-4):
    """Trains only the unfrozen head of a reconfigured backbone with binary
    cross entropy, matching the paper's sigmoid output for binary classification."""
    model.to(device)
    optimizer = torch.optim.Adam(
        filter(lambda p: p.requires_grad, model.parameters()), lr=lr
    )
    criterion = nn.BCELoss()

    for epoch in range(epochs):
        model.train()
        for images, labels in train_loader:
            images, labels = images.to(device), labels.float().to(device)
            optimizer.zero_grad()
            probs = model(images)
            loss = criterion(probs, labels)
            loss.backward()
            optimizer.step()

        model.eval()
        correct, total = 0, 0
        with torch.no_grad():
            for images, labels in val_loader:
                images, labels = images.to(device), labels.float().to(device)
                probs = model(images)
                preds = (probs > 0.5).float()
                correct += (preds == labels).sum().item()
                total += labels.size(0)
        print(f"[{model.backbone_name}] epoch {epoch + 1}/{epochs} "
              f"val acc {correct / max(total, 1):.4f}")

    return model


@torch.no_grad()
def get_backbone_predictions(model, loader, device):
    """Runs a trained backbone over a loader and returns its malignancy
    probability for every image, used as a stacking feature downstream."""
    model.eval()
    all_probs, all_labels = [], []
    for images, labels in loader:
        images = images.to(device)
        probs = model(images).cpu().numpy()
        all_probs.append(probs)
        all_labels.append(labels.numpy())
    return np.concatenate(all_probs), np.concatenate(all_labels)


def build_stacking_ensemble():
    """Reproduces the paper's stacking layer, Decision Tree, Extra Trees and
    Random Forest as base learners, Logistic Regression as the meta model,
    with GridSearchCV tuning applied to each base learner beforehand."""
    dt_grid = GridSearchCV(
        DecisionTreeClassifier(random_state=42),
        param_grid={"max_depth": [4, 8, 12, None], "min_samples_leaf": [1, 5, 10]},
        cv=5,
    )
    et_grid = GridSearchCV(
        ExtraTreesClassifier(random_state=42),
        param_grid={"n_estimators": [100, 300], "max_depth": [8, 16, None]},
        cv=5,
    )
    rf_grid = GridSearchCV(
        RandomForestClassifier(random_state=42),
        param_grid={"n_estimators": [100, 300], "max_depth": [8, 16, None]},
        cv=5,
    )

    stacking_model = StackingClassifier(
        estimators=[
            ("decision_tree", dt_grid),
            ("extra_trees", et_grid),
            ("random_forest", rf_grid),
        ],
        final_estimator=LogisticRegression(max_iter=1000),
        cv=5,
        passthrough=False,
    )
    return stacking_model


def evaluate_stack(y_true, y_pred, y_proba):
    """Computes the core metrics the paper reports for the final ensemble."""
    precision, recall, f1, _ = precision_recall_fscore_support(
        y_true, y_pred, average="binary"
    )
    return {
        "accuracy": accuracy_score(y_true, y_pred),
        "precision": precision,
        "recall": recall,
        "f1": f1,
        "auc": roc_auc_score(y_true, y_proba),
    }


def smoke_test():
    """Runs one forward pass through each backbone on random dummy data, and
    fits the stacking ensemble on random dummy backbone predictions, just to
    confirm every shape and interface lines up before real training."""
    device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
    backbone_names = ["vgg16", "vgg19", "mobilenet_v2", "efficientnet_b0"]

    dummy_images = torch.randn(4, 3, 224, 224, device=device)

    all_probs = []
    for name in backbone_names:
        model = ReconfiguredBackbone(backbone_name=name).to(device)
        model.eval()
        with torch.no_grad():
            probs = model(dummy_images).cpu().numpy()
        assert probs.shape == (4,)
        all_probs.append(probs)
        print(f"{name} forward pass ok, sample probs {probs}")

    # stack the four backbones' probabilities as features for the tree ensemble
    X_stack = np.stack(all_probs, axis=1)  # (4 images, 4 backbone predictions)
    y_dummy = np.array([0, 1, 0, 1])

    ensemble = build_stacking_ensemble()
    # a real run needs far more than four samples, this only checks the interface
    try:
        ensemble.fit(X_stack, y_dummy)
        preds = ensemble.predict(X_stack)
        print(f"stacking ensemble smoke test passed, predictions {preds}")
    except Exception as exc:
        print(f"stacking ensemble needs a larger sample to fit properly, {exc}")


if __name__ == "__main__":
    smoke_test()
Academic citation. Noman, M. Z. I., Sati, K., Yousuf, M. A., Aloteibi, S., and Moni, M. A. 2025. LungCT-NET, an explainable transfer learning based robust ensemble model for lung cancer diagnosis. Knowledge-Based Systems, 324, 113854. https://doi.org/10.1016/j.knosys.2025.113854. Published under a CC BY 4.0 license.

This analysis is based on the published paper and an independent evaluation of its claims.

Related reading

1 thought on “Why LungCT-NET Stacks Four Networks Instead of Trusting One”

  1. Pingback: Skin Cancer AI Combats Adversarial Attacks with MDDA - aitrendblend.com

Leave a Comment

Your email address will not be published. Required fields are marked *