Skip to content
Back to skills

Per Patient Slice Maxpool Aggregation

ASecurity

Aggregate per-slice CNN predictions into a single patient-level injury score by mean-pooling across TTA copies first, then max-pooling across slices — the worst-slice wins, which matches the medical reality that one bad slice is enough to grade the patient

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

Works with

  • cli

Security analysis

A100/100

Scanned September 12, 2026

npx -y skills add wenmin-wu/ds-skills --skill per-patient-slice-maxpool-aggregation --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Per Patient Slice Maxpool Aggregation?

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

Security grade badge for Per Patient Slice Maxpool Aggregation
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/wenmin-wu-per-patient-slice-maxpool-aggregation/badge)](https://www.skillsdirectory.com/skills/wenmin-wu-per-patient-slice-maxpool-aggregation)

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-patient-slice-maxpool-aggregation
description: Aggregate per-slice CNN predictions into a single patient-level injury score by mean-pooling across TTA copies first, then max-pooling across slices — the worst-slice wins, which matches the medical reality that one bad slice is enough to grade the patient
---

## Overview

For per-patient binary or grade tasks (injury yes/no, severity 0-2-3) where the label depends on *whether the worst slice is bad*, average-pooling across slices washes out the signal: a single high-confidence injury slice gets diluted by 50 healthy ones. The right reduction is max across slices — but only after you've already averaged across TTA / multi-model copies, otherwise you collapse the noise floor. The order matters: `mean(TTA) → max(slices)` is the right composition; `max(everything)` overstates probability and `mean(everything)` understates it.

## Quick Start

```python
import numpy as np

def aggregate_patient(slice_preds, n_tta):
    """
    slice_preds: (n_tta * n_slices, n_outputs) raw model outputs
    Returns: (n_outputs,) patient-level score
    """
    n_slices = slice_preds.shape[0] // n_tta
    pred = slice_preds.reshape(n_tta, n_slices, -1)
    pred = pred.mean(axis=0)              # 1. average TTA copies per slice
    pred = pred.max(axis=0)               # 2. worst slice across the volume
    return pred

patient_scores = np.zeros((len(patient_ids), 11), dtype='float32')
for i, pid in enumerate(patient_ids):
    pdf = test_df.query('patient_id == @pid')
    raw = model.predict(build_dataset(pdf.image_path.tolist()))
    raw = np.concatenate(raw, axis=-1)    # multi-head → flat
    patient_scores[i] = aggregate_patient(raw, n_tta=4)
```

## Workflow

1. Run inference on every slice with N TTA copies (flips, rotations) → `(N * S, C)` predictions
2. Reshape to `(N, S, C)` and average over the TTA axis to denoise per-slice scores
3. Take the max over the slice axis to elevate the worst slice's score to the patient level
4. For multi-head outputs (binary + multi-class), apply this aggregation per head, then concatenate
5. Optionally clip the final scores to `[0.01, 0.99]` if the metric penalizes log-loss extremes

## Key Decisions

- **Mean-then-max, not max-then-mean**: max-then-mean averages already-saturated 1.0s and produces an unstable score; mean-then-max averages noise first then takes a clean argmax.
- **vs. attention pooling**: attention is better in theory but needs training-time supervision; mean→max is zero-parameter and competitive on injury-detection tasks.
- **Don't pool across organs**: the max is per-organ-head; pooling across organs would let a torn liver mask a healthy bowel.
- **Per-series, then per-patient**: if a patient has multiple CT series, max within each series, then *mean* across series — different series are independent observations of the same patient.
- **Stride sampling earlier**: sampling every Nth slice before the model is fine; max-pooling is robust to undersampling as long as N < typical organ-span-in-slices.

## References

- [KerasCV starter notebook (Infer)](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…