# FCN
A dense per-pixel classifier that replaces a detector's fully connected layers with convolutions, so it outputs a full-resolution class map instead of boxes. LibreYOLO ships it for semantic segmentation only.
Tasks: Semantic segmentation. Install: pip install libreyolo.
Verified against LibreYOLO v1.5.0.

## Install

FCN needs no optional extra. Everything it imports is in the base install.

```bash
pip install libreyolo
```

## Predict

Weights download from Hugging Face on first use and are cached locally.

**Python**

```python
from libreyolo import LibreYOLO, SAMPLE_IMAGE

model = LibreYOLO("LibreFCNr50.pt")
result = model(SAMPLE_IMAGE, save=True)

mask = result.semantic_mask
print(mask.data.shape)   # (H, W) class ids
print(mask.classes)      # sorted class ids present in the image
```

**CLI**

```bash
libreyolo predict model=LibreFCNr50.pt source=https://raw.githubusercontent.com/LibreYOLO/libreyolo/release/libreyolo/assets/parkour.jpg save=True
```

Semantic segmentation returns one class id per pixel, not boxes, so
`result.semantic_mask` carries a `(H, W)` array on `.data` and the list of
class ids present in the image on `.classes`. `conf`, `iou` and `max_det` are
accepted for API parity but have no effect: the model assigns a class to every
pixel by argmax, with no confidence threshold or NMS step. See
[prediction](/docs/predict) for sources, streaming and result handling.

## Variants

Two ResNet depths, both at a fixed 520 px input. The library's inference graph
is torchvision's dilated-ResNet FCN, not the original paper's VGG-based FCN-8s
network with skip connections.

LibreYOLO does not train FCN: `train()` raises `NotImplementedError` for this
family, which the [support tier](/docs/models) above marks as inference only.
The two published checkpoints are torchvision's own COCO-trained weights,
converted for LibreYOLO's loader.

## Validate

`val()` returns `metrics/mIoU` and `metrics/pixel_accuracy`, measured against
any dataset in the format you trained on.

**Python**

```python
from libreyolo import LibreYOLO

model = LibreYOLO("LibreFCNr50.pt")
metrics = model.val(data="my-dataset.yaml")

print(metrics["metrics/mIoU"])
print(metrics["metrics/pixel_accuracy"])
```

**CLI**

```bash
libreyolo val model=LibreFCNr50.pt data=my-dataset.yaml
```

## Export

| Task | ONNX | TorchScript | ExecuTorch | TensorRT | OpenVINO | Paddle | MNN | RKNN | ncnn | TFLite | CoreML | Core AI |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| Semantic segmentation | yes | yes |  | yes | yes |  |  |  |  |  |  |  |

A "yes" means the export is supported. An empty cell means the exporter refuses that combination.

An exported artifact loads back through `LibreYOLO()` on its file suffix, so a
`.onnx` or `.engine` file behaves like a checkpoint and returns the same
`Results`. [Export](/docs/export) lists the arguments every format accepts.

**Python**

```python
from libreyolo import LibreYOLO

model = LibreYOLO("LibreFCNr50.pt")
model.export(format="onnx")
model.export(format="tensorrt", half=True)
```

**CLI**

```bash
libreyolo export model=LibreFCNr50.pt format=onnx
libreyolo export model=LibreFCNr50.pt format=tensorrt half=True
```

**Use the exported file**

```python
from libreyolo import LibreYOLO, SAMPLE_IMAGE

# The factory routes on the file suffix, so an exported artifact loads
# like any checkpoint and returns the same Results object.
model = LibreYOLO("LibreFCNr50.onnx")
result = model(SAMPLE_IMAGE)

print(result.semantic_mask.data.shape)
```

## Checkpoints

Every published weight file for this family.

| File | Input (px) | Task | Weights license |
| --- | --- | --- | --- |
| `LibreFCNr50.pt` | 520 | Semantic segmentation | bsd-3-clause |
| `LibreFCNr101.pt` | 520 | Semantic segmentation | bsd-3-clause |

## Licensing

Check the license on the Hugging Face repository of the specific weights you download. That repository is authoritative and licenses are not always uniform across a family. This is a description of the licenses involved, not legal advice.

- Original work: FCN, PyTorch
- Upstream license: BSD-3-Clause
- Upstream source: https://github.com/pytorch/vision
- LibreYOLO code: BSD-3-Clause
- Weights: BSD-3-Clause, republished at https://huggingface.co/LibreYOLO
- Interpretation: BSD-3-Clause is a permissive license, so this code and these weights can be used in commercial and closed-source products. It asks you to keep the copyright notice, license text and a non-endorsement clause with any copy you redistribute. LibreYOLO's inference graph is torchvision's dilated-ResNet FCN, not the original VGG-based FCN-8s skip-fusion network from the paper. The two published checkpoints are torchvision's official COCO-trained weights; their separate LibreYOLO Hugging Face mirrors carry BSD-3-Clause on an implied basis disclosed by torchvision rather than an explicit checkpoint-specific grant, and torchvision's own documentation notes that pretrained-model terms can depend on the training data, leaving that determination to the user.


## FCN architecture

- r50: [SVG](/diagrams/models/fcn/r50-semantic.svg), [interactive diagram](/diagrams/models/fcn/r50-semantic.html)
- r101: [SVG](/diagrams/models/fcn/r101-semantic.svg), [interactive diagram](/diagrams/models/fcn/r101-semantic.html)
- Shared r50/r101 topology: [SVG](/diagrams/models/fcn/family.svg), [interactive diagram](/diagrams/models/fcn/family.html)
