suitch commited on
Commit
0c0131f
·
verified ·
1 Parent(s): c169091

Upload RadBERT German CTRate multi-label classifier

Browse files
README.md ADDED
@@ -0,0 +1,145 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ language:
3
+ - de
4
+ license: mit
5
+ library_name: transformers
6
+ pipeline_tag: text-classification
7
+ tags:
8
+ - radiology
9
+ - medical-imaging
10
+ - chest-ct
11
+ - multi-label-classification
12
+ - radbert
13
+ - german
14
+ - ctrate
15
+ base_model: zhihets/RadBERT-RoBERTa-Base
16
+ ---
17
+
18
+ # RadBERT German CTRate Classifier
19
+
20
+ A **RadBERT**-based multi-label classifier for predicting 18 pathology labels from **German-language** radiology reports.
21
+ The training data consists of German-translated reports from the [CTRate](https://huggingface.co/datasets/ibrahimhamamci/CT-RATE) dataset, translated using Qwen 2.5 9B.
22
+
23
+ ## Model Details
24
+
25
+ | Property | Value |
26
+ |---|---|
27
+ | **Base model** | RadBERT (RoBERTa-base architecture, pre-trained on radiology text) |
28
+ | **Task** | Multi-label text classification (18 labels) |
29
+ | **Language** | German (`de`) |
30
+ | **Framework** | 🤗 Transformers + PyTorch |
31
+ | **Problem type** | `multi_label_classification` |
32
+
33
+ ## Labels (18 pathologies)
34
+
35
+ | ID | Label |
36
+ |----|-------|
37
+ | 0 | Medical material |
38
+ | 1 | Arterial wall calcification |
39
+ | 2 | Cardiomegaly |
40
+ | 3 | Pericardial effusion |
41
+ | 4 | Coronary artery wall calcification |
42
+ | 5 | Hiatal hernia |
43
+ | 6 | Lymphadenopathy |
44
+ | 7 | Emphysema |
45
+ | 8 | Atelectasis |
46
+ | 9 | Lung nodule |
47
+ | 10 | Lung opacity |
48
+ | 11 | Pulmonary fibrotic sequela |
49
+ | 12 | Pleural effusion |
50
+ | 13 | Mosaic attenuation pattern |
51
+ | 14 | Peribronchial thickening |
52
+ | 15 | Consolidation |
53
+ | 16 | Bronchiectasis |
54
+ | 17 | Interlobular septal thickening |
55
+
56
+ ## Quick Start
57
+
58
+ ### Installation
59
+
60
+ ```bash
61
+ pip install transformers torch
62
+ ```
63
+
64
+ ### Loading the model
65
+
66
+ ```python
67
+ from transformers import AutoTokenizer, AutoConfig
68
+ from modeling_radbert import RadBertForSequenceClassification
69
+ import torch
70
+
71
+ repo_id = "suitch/radbert-german-ctrate-classifier"
72
+
73
+ # Download the custom model class (or copy modeling_radbert.py locally)
74
+ from huggingface_hub import hf_hub_download
75
+ import sys, os
76
+
77
+ modeling_path = hf_hub_download(repo_id=repo_id, filename="modeling_radbert.py")
78
+ sys.path.insert(0, os.path.dirname(modeling_path))
79
+
80
+ # Load config, model, and tokenizer
81
+ config = AutoConfig.from_pretrained(repo_id)
82
+ model = RadBertForSequenceClassification.from_pretrained(repo_id, config=config)
83
+ tokenizer = AutoTokenizer.from_pretrained(repo_id)
84
+
85
+ model.eval()
86
+ ```
87
+
88
+ ### Inference example
89
+
90
+ ```python
91
+ text = "Das Herz ist leicht vergrößert. Es zeigt sich ein kleiner Pleuraerguss links."
92
+
93
+ inputs = tokenizer(text, return_tensors="pt", truncation=True, padding=True, max_length=512)
94
+
95
+ with torch.no_grad():
96
+ logits = model(**inputs)
97
+
98
+ probabilities = torch.sigmoid(logits).squeeze()
99
+ threshold = 0.5
100
+ predicted_labels = [
101
+ config.id2label[i] for i, p in enumerate(probabilities) if p >= threshold
102
+ ]
103
+
104
+ print("Predicted labels:", predicted_labels)
105
+ print("Probabilities:")
106
+ for i, p in enumerate(probabilities):
107
+ print(f" {config.id2label[i]}: {p:.4f}")
108
+ ```
109
+
110
+ ## Training Details
111
+
112
+ - **Base checkpoint**: RadBERT (RoBERTa-base weights pre-trained on radiology corpora)
113
+ - **Training data**: German translations of CTRate radiology reports (translated with Qwen 2.5 9B)
114
+ - **Classification head**: Linear layer on top of the `[CLS]` / pooler output
115
+ - **Loss**: Binary Cross-Entropy with Logits (per-label sigmoid)
116
+
117
+ ## Limitations
118
+
119
+ - This model is trained for **label inference from report text only** — it does **not** process images.
120
+ - It should **not** be treated as a clinical decision support system.
121
+ - Performance is limited by the quality of the machine-translated training data.
122
+
123
+ ## Citation
124
+
125
+ If you use this model, please cite the CTRate dataset and RadBERT:
126
+
127
+ ```bibtex
128
+ @article{hamamci2024ctrate,
129
+ title={CT-RATE: A Large-Scale Computed Tomography Report-Image Dataset for AI in Radiology},
130
+ author={Hamamci, Ibrahim Ethem and others},
131
+ journal={arXiv preprint},
132
+ year={2024}
133
+ }
134
+
135
+ @article{yan2022radbert,
136
+ title={RadBERT: Adapting Transformer-based Language Models to Radiology},
137
+ author={Yan, Di and others},
138
+ journal={Radiology: Artificial Intelligence},
139
+ year={2022}
140
+ }
141
+ ```
142
+
143
+ ## License
144
+
145
+ MIT
config.json ADDED
@@ -0,0 +1,71 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "architectures": [
3
+ "RadBertForSequenceClassification"
4
+ ],
5
+ "attention_probs_dropout_prob": 0.1,
6
+ "auto_map": {
7
+ "AutoModelForSequenceClassification": "modeling_radbert.RadBertForSequenceClassification"
8
+ },
9
+ "bos_token_id": 0,
10
+ "classifier_dropout": null,
11
+ "dtype": "float32",
12
+ "eos_token_id": 2,
13
+ "gradient_checkpointing": false,
14
+ "hidden_act": "gelu",
15
+ "hidden_dropout_prob": 0.1,
16
+ "hidden_size": 768,
17
+ "id2label": {
18
+ "0": "Medical material",
19
+ "1": "Arterial wall calcification",
20
+ "2": "Cardiomegaly",
21
+ "3": "Pericardial effusion",
22
+ "4": "Coronary artery wall calcification",
23
+ "5": "Hiatal hernia",
24
+ "6": "Lymphadenopathy",
25
+ "7": "Emphysema",
26
+ "8": "Atelectasis",
27
+ "9": "Lung nodule",
28
+ "10": "Lung opacity",
29
+ "11": "Pulmonary fibrotic sequela",
30
+ "12": "Pleural effusion",
31
+ "13": "Mosaic attenuation pattern",
32
+ "14": "Peribronchial thickening",
33
+ "15": "Consolidation",
34
+ "16": "Bronchiectasis",
35
+ "17": "Interlobular septal thickening"
36
+ },
37
+ "initializer_range": 0.02,
38
+ "intermediate_size": 3072,
39
+ "label2id": {
40
+ "Arterial wall calcification": 1,
41
+ "Atelectasis": 8,
42
+ "Bronchiectasis": 16,
43
+ "Cardiomegaly": 2,
44
+ "Consolidation": 15,
45
+ "Coronary artery wall calcification": 4,
46
+ "Emphysema": 7,
47
+ "Hiatal hernia": 5,
48
+ "Interlobular septal thickening": 17,
49
+ "Lung nodule": 9,
50
+ "Lung opacity": 10,
51
+ "Lymphadenopathy": 6,
52
+ "Medical material": 0,
53
+ "Mosaic attenuation pattern": 13,
54
+ "Peribronchial thickening": 14,
55
+ "Pericardial effusion": 3,
56
+ "Pleural effusion": 12,
57
+ "Pulmonary fibrotic sequela": 11
58
+ },
59
+ "layer_norm_eps": 1e-05,
60
+ "max_position_embeddings": 514,
61
+ "model_type": "roberta",
62
+ "num_attention_heads": 12,
63
+ "num_hidden_layers": 12,
64
+ "pad_token_id": 1,
65
+ "position_embedding_type": "absolute",
66
+ "problem_type": "multi_label_classification",
67
+ "transformers_version": "4.57.6",
68
+ "type_vocab_size": 1,
69
+ "use_cache": true,
70
+ "vocab_size": 50265
71
+ }
export_metadata.json ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "base_model": "/vol/ideadata/ac54awik/Medical_report_evaluation/radbert_local",
3
+ "checkpoint": "classifier_training/classifier_de/RadBertClassifier_best.pth",
4
+ "labels": [
5
+ "Medical material",
6
+ "Arterial wall calcification",
7
+ "Cardiomegaly",
8
+ "Pericardial effusion",
9
+ "Coronary artery wall calcification",
10
+ "Hiatal hernia",
11
+ "Lymphadenopathy",
12
+ "Emphysema",
13
+ "Atelectasis",
14
+ "Lung nodule",
15
+ "Lung opacity",
16
+ "Pulmonary fibrotic sequela",
17
+ "Pleural effusion",
18
+ "Mosaic attenuation pattern",
19
+ "Peribronchial thickening",
20
+ "Consolidation",
21
+ "Bronchiectasis",
22
+ "Interlobular septal thickening"
23
+ ],
24
+ "tokenizer_source": "/vol/ideadata/ac54awik/Medical_report_evaluation/radbert_local"
25
+ }
merges.txt ADDED
The diff for this file is too large to render. See raw diff
 
modeling_radbert.py ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ import torch.nn as nn
3
+ from transformers import RobertaModel, RobertaConfig, PreTrainedModel
4
+
5
+
6
+ class RadBertForSequenceClassification(PreTrainedModel):
7
+ config_class = RobertaConfig
8
+ base_model_prefix = "model"
9
+
10
+ def __init__(self, config):
11
+ super().__init__(config)
12
+ num_labels = getattr(config, "num_labels", 2)
13
+ self.model = RobertaModel(config)
14
+ self.classifier = nn.Linear(config.hidden_size, num_labels)
15
+ self.post_init()
16
+
17
+ def forward(
18
+ self,
19
+ input_ids=None,
20
+ attention_mask=None,
21
+ token_type_ids=None,
22
+ **kwargs,
23
+ ):
24
+ outputs = self.model(
25
+ input_ids=input_ids,
26
+ attention_mask=attention_mask,
27
+ token_type_ids=token_type_ids,
28
+ **kwargs,
29
+ )
30
+
31
+ pooled_output = outputs.pooler_output
32
+ if pooled_output is None:
33
+ pooled_output = outputs.last_hidden_state[:, 0]
34
+
35
+ return self.classifier(pooled_output)
pytorch_model.bin ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:ed6c293735a097bb023a10c7a5bcb1c2cc395bdac5fbedba902f341143f3359b
3
+ size 498704519
special_tokens_map.json ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "bos_token": {
3
+ "content": "<s>",
4
+ "lstrip": false,
5
+ "normalized": true,
6
+ "rstrip": false,
7
+ "single_word": false
8
+ },
9
+ "cls_token": {
10
+ "content": "<s>",
11
+ "lstrip": false,
12
+ "normalized": true,
13
+ "rstrip": false,
14
+ "single_word": false
15
+ },
16
+ "eos_token": {
17
+ "content": "</s>",
18
+ "lstrip": false,
19
+ "normalized": true,
20
+ "rstrip": false,
21
+ "single_word": false
22
+ },
23
+ "mask_token": {
24
+ "content": "<mask>",
25
+ "lstrip": true,
26
+ "normalized": true,
27
+ "rstrip": false,
28
+ "single_word": false
29
+ },
30
+ "pad_token": {
31
+ "content": "<pad>",
32
+ "lstrip": false,
33
+ "normalized": true,
34
+ "rstrip": false,
35
+ "single_word": false
36
+ },
37
+ "sep_token": {
38
+ "content": "</s>",
39
+ "lstrip": false,
40
+ "normalized": true,
41
+ "rstrip": false,
42
+ "single_word": false
43
+ },
44
+ "unk_token": {
45
+ "content": "<unk>",
46
+ "lstrip": false,
47
+ "normalized": true,
48
+ "rstrip": false,
49
+ "single_word": false
50
+ }
51
+ }
tokenizer.json ADDED
The diff for this file is too large to render. See raw diff
 
tokenizer_config.json ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "add_prefix_space": false,
3
+ "added_tokens_decoder": {
4
+ "0": {
5
+ "content": "<s>",
6
+ "lstrip": false,
7
+ "normalized": true,
8
+ "rstrip": false,
9
+ "single_word": false,
10
+ "special": true
11
+ },
12
+ "1": {
13
+ "content": "<pad>",
14
+ "lstrip": false,
15
+ "normalized": true,
16
+ "rstrip": false,
17
+ "single_word": false,
18
+ "special": true
19
+ },
20
+ "2": {
21
+ "content": "</s>",
22
+ "lstrip": false,
23
+ "normalized": true,
24
+ "rstrip": false,
25
+ "single_word": false,
26
+ "special": true
27
+ },
28
+ "3": {
29
+ "content": "<unk>",
30
+ "lstrip": false,
31
+ "normalized": true,
32
+ "rstrip": false,
33
+ "single_word": false,
34
+ "special": true
35
+ },
36
+ "50264": {
37
+ "content": "<mask>",
38
+ "lstrip": true,
39
+ "normalized": true,
40
+ "rstrip": false,
41
+ "single_word": false,
42
+ "special": true
43
+ }
44
+ },
45
+ "bos_token": "<s>",
46
+ "clean_up_tokenization_spaces": false,
47
+ "cls_token": "<s>",
48
+ "do_lower_case": true,
49
+ "eos_token": "</s>",
50
+ "errors": "replace",
51
+ "extra_special_tokens": {},
52
+ "mask_token": "<mask>",
53
+ "model_max_length": 512,
54
+ "pad_token": "<pad>",
55
+ "sep_token": "</s>",
56
+ "tokenizer_class": "RobertaTokenizer",
57
+ "trim_offsets": true,
58
+ "unk_token": "<unk>"
59
+ }
vocab.json ADDED
The diff for this file is too large to render. See raw diff