Skip to content
Back to skills

Cnn Metadata Fusion Head

ASecurity

Fuse CNN image features with a small tabular MLP branch via concat before a final classifier, training both branches end-to-end

  • 61 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added September 12, 2026
developmentpythongo

Security analysis

A100/100

Scanned September 12, 2026

npx -y skills add wenmin-wu/ds-skills --skill cnn-metadata-fusion-head --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Cnn Metadata Fusion Head?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Cnn Metadata Fusion Head
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/wenmin-wu-cnn-metadata-fusion-head/badge)](https://www.skillsdirectory.com/skills/wenmin-wu-cnn-metadata-fusion-head)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: cv-cnn-metadata-fusion-head
description: Fuse CNN image features with a small tabular MLP branch via concat before a final classifier, training both branches end-to-end
---

## Overview

Many image-classification tasks ship with tabular metadata (patient age, sex, anatomic site, device model) that is independently predictive. The cleanest way to use both is a two-branch network: a CNN processes the image, a small MLP processes normalized tabular features, and the two feature vectors are concatenated before the final classifier. Everything trains end-to-end with a single loss. Reported lift on SIIM-ISIC Melanoma: ~0.5-1 AUC point over image-only baselines, and the tabular branch is tiny (~0.1M params).

## Quick Start

```python
import torch
import torch.nn as nn
from efficientnet_pytorch import EfficientNet

class ImageMetaNet(nn.Module):
    def __init__(self, n_meta_features, arch='efficientnet-b0'):
        super().__init__()
        self.cnn = EfficientNet.from_pretrained(arch)
        self.cnn._fc = nn.Linear(self.cnn._fc.in_features, 500)

        self.meta = nn.Sequential(
            nn.Linear(n_meta_features, 500),
            nn.BatchNorm1d(500), nn.ReLU(), nn.Dropout(0.2),
            nn.Linear(500, 250),
            nn.BatchNorm1d(250), nn.ReLU(), nn.Dropout(0.2),
        )
        self.classifier = nn.Linear(750, 1)   # 500 + 250 concat

    def forward(self, inputs):
        x, meta = inputs            # x: image, meta: (B, n_meta_features)
        img_feat = self.cnn(x)
        meta_feat = self.meta(meta)
        fused = torch.cat((img_feat, meta_feat), dim=1)
        return self.classifier(fused)
```

## Workflow

1. Normalize tabular features (standardize continuous, one-hot or embed categorical) in the dataset
2. Dataset `__getitem__` returns a tuple `(image_tensor, meta_tensor, label)`
3. Forward takes a tuple `(x, meta)` and runs both branches in parallel
4. Concatenate on the feature axis, not the batch axis
5. Train with one loss on the classifier output — no separate tabular loss needed

## Key Decisions

- **Meta branch width ~ image feature width / 2**: equal widths drown out the image branch; too small and the meta branch collapses.
- **BN + Dropout on the meta path**: prevents the small MLP from overfitting the low-dim tabular input.
- **Concat, not add**: addition requires same dims and imposes an untrained alignment.
- **vs. separate models + late blending**: end-to-end fusion learns which features help, blending requires hand-tuned weights and loses interaction terms.

## References

- [Melanoma. Pytorch starter. EfficientNet](https://www.kaggle.com/code/nroman/melanoma-pytorch-starter-efficientnet)

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…