Skip to content
Back to skills

Per Organ Multihead Sigmoid Softmax

ASecurity

Single CNN backbone with one shallow Dense neck per organ and mixed sigmoid (binary) + softmax (multi-class severity) heads, trained with a dict of losses so each organ is calibrated independently while sharing visual features

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

Security analysis

A100/100

Scanned September 12, 2026

npx -y skills add wenmin-wu/ds-skills --skill per-organ-multihead-sigmoid-softmax --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Per Organ Multihead Sigmoid Softmax?

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

Security grade badge for Per Organ Multihead Sigmoid Softmax
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/wenmin-wu-per-organ-multihead-sigmoid-softmax/badge)](https://www.skillsdirectory.com/skills/wenmin-wu-per-organ-multihead-sigmoid-softmax)

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-per-organ-multihead-sigmoid-softmax
description: Single CNN backbone with one shallow Dense neck per organ and mixed sigmoid (binary) + softmax (multi-class severity) heads, trained with a dict of losses so each organ is calibrated independently while sharing visual features
---

## Overview

Multi-organ trauma classification has a heterogeneous label structure: some organs are binary (injured / not), others have ordered severity grades (healthy / low / high). The naive answer — one big sigmoid head with all classes flattened — destroys the mutual exclusivity inside each grade group and trains every label to compete with every other label. The right structure is one shared backbone, a tiny per-organ "neck" Dense layer, and a head whose activation matches the label semantics: sigmoid for binary organs, softmax for severity-graded ones. Keras `compile(loss={...})` accepts a dict mapping head names to losses, so each head gets its correct loss without hand-rolling.

## Quick Start

```python
from tensorflow.keras.layers import GlobalAveragePooling2D, Dense
from tensorflow.keras.models import Model
from tensorflow.keras.losses import BinaryCrossentropy, CategoricalCrossentropy

x = GlobalAveragePooling2D()(backbone.output)

necks = {n: Dense(32, activation='silu', name=f'{n}_neck')(x)
         for n in ['bowel', 'extra', 'liver', 'kidney', 'spleen']}

outs = [
    Dense(1, activation='sigmoid', name='bowel')(necks['bowel']),
    Dense(1, activation='sigmoid', name='extra')(necks['extra']),
    Dense(3, activation='softmax', name='liver')(necks['liver']),
    Dense(3, activation='softmax', name='kidney')(necks['kidney']),
    Dense(3, activation='softmax', name='spleen')(necks['spleen']),
]

model = Model(backbone.inputs, outs)
model.compile(
    optimizer='adam',
    loss={
        'bowel':  BinaryCrossentropy(label_smoothing=0.05),
        'extra':  BinaryCrossentropy(label_smoothing=0.05),
        'liver':  CategoricalCrossentropy(label_smoothing=0.05),
        'kidney': CategoricalCrossentropy(label_smoothing=0.05),
        'spleen': CategoricalCrossentropy(label_smoothing=0.05),
    },
)
```

## Workflow

1. Pick the smallest "neck" width that still trains (32 is usually plenty) — smaller necks force the backbone to do the work
2. Use sigmoid heads for binary organs and softmax heads for ordered/multi-class organs in the same model
3. Pass a dict to `compile(loss=...)` matching the head names — Keras auto-routes per-output losses
4. Apply uniform `label_smoothing=0.05` across all heads to prevent any one organ from collapsing onto a 0/1 saturated prediction
5. At inference, concatenate head outputs in the order the submission expects (use `cv-multihead-softmax-to-flat-submission` patterns)

## Key Decisions

- **Per-organ neck, not shared head**: a shared head forces every organ to use the same projection of backbone features and underperforms on rare classes.
- **Sigmoid + softmax in the same model**: forcing everything to sigmoid breaks softmax's mutual-exclusivity guarantee for severity grades; forcing to softmax breaks the binary semantics.
- **`silu` over `relu` in the neck**: smoother gradients on a tiny 32-unit layer; the difference is small but consistently positive.
- **Label smoothing = 0.05, not 0.1**: medical labels are clean enough that aggressive smoothing hurts; 0.05 is the sweet spot for log-loss metrics.
- **Don't share weights between necks**: the whole point is per-organ specialization on a shared visual representation.

## References

- [RSNA-ATD: CNN [TPU][Train]](https://www.kaggle.com/competitions/rsna-2023-abdominal-trauma-detection)

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…