chrisvoncsefalvay commited on
Commit
af1cd65
·
verified ·
1 Parent(s): 0736175

Upload folder using huggingface_hub

Browse files
Files changed (5) hide show
  1. README.md +94 -495
  2. config.json +10 -0
  3. pytorch_model.pt +3 -0
  4. test_results.json +18 -0
  5. tokenizer.json +2 -16
README.md CHANGED
@@ -1,559 +1,158 @@
1
  ---
2
- license: apache-2.0
3
  language:
4
  - en
 
5
  tags:
6
  - medical
7
  - biomedical
8
  - drug-safety
9
- - adverse-drug-reactions
10
  - pharmacovigilance
11
  - relation-extraction
12
  - dual-encoder
13
  - clinical-nlp
14
- - biolinkbert
15
- - entity-markers
16
- - hard-negative-mining
17
- - focal-loss
18
- - causal-reasoning
19
- - mimicause
20
- - mimic
21
- - clinical-notes
22
  datasets:
23
- - ade-benchmark-corpus/ade_corpus_v2
24
- - chrisvoncsefalvay/mimicause-private
25
  metrics:
26
  - f1
 
 
27
  - roc_auc
28
  pipeline_tag: text-classification
29
- model-index:
30
- - name: CRAG-dual-encoder-mimicause
31
- results:
32
- - task:
33
- type: text-classification
34
- name: Drug-ADR Relation Extraction
35
- dataset:
36
- name: ADE Corpus V2 + MIMICause
37
- type: ade-benchmark-corpus/ade_corpus_v2
38
- config: Ade_corpus_v2_drug_ade_relation
39
- metrics:
40
- - type: f1
41
- value: 0.9889
42
- name: F1 Score
43
- - type: roc_auc
44
- value: 0.9981
45
- name: ROC-AUC
46
  ---
47
 
48
- # CRAG-dual-encoder-mimicause
49
-
50
- **CRAG: Causal Reasoning for Adversomics Graphs**
51
 
52
- This is the **best-performing model** in the CRAG dual-encoder family, achieving **98.89% F1** and **99.81% AUC** on drug-ADR relation extraction. It combines training on the ADE Corpus V2 with the MIMICause dataset, leveraging diverse causal reasoning patterns from real clinical notes.
53
 
54
  ## Model Description
55
 
56
- CRAG-dual-encoder-mimicause extends the ADE model architecture with additional training on MIMICause, a dataset of causal relations annotated in MIMIC-III clinical notes. This provides the model with:
57
-
58
- - **Diverse causal language patterns** from real clinical documentation
59
- - **Multiple causation types:** Cause, Enable, Prevent, Hinder
60
- - **Clinical writing style exposure** beyond curated biomedical literature
61
-
62
- ### Why MIMICause?
63
-
64
- The ADE Corpus V2 provides high-quality drug-ADR pairs from MEDLINE, but clinical notes contain different linguistic patterns:
65
-
66
- | Source | Style | Patterns |
67
- |--------|-------|----------|
68
- | ADE Corpus (MEDLINE) | Formal, structured | "Drug X induced condition Y" |
69
- | MIMICause (MIMIC-III) | Clinical, abbreviated | "pt on X c/b Y", "Y 2/2 X" |
70
-
71
- Training on both improves generalization to real-world clinical text.
72
-
73
- ### Architecture
74
-
75
- Same enhanced dual-encoder architecture as CRAG-dual-encoder-ade:
76
-
77
- ```
78
- ┌─────────────────────────────────────────────────────────────────┐
79
- │ CRAG Dual-Encoder MIMICause │
80
- ├─────────────────────────────────────────────────────────────────┤
81
- │ │
82
- │ Drug Context ADR Context │
83
- │ "[DRUG] steroid [/DRUG] "[ADR] myopathy [/ADR] │
84
- │ induced myopathy" from steroids" │
85
- │ │ │ │
86
- │ ▼ ▼ │
87
- │ ┌─────────────┐ ┌─────────────┐ │
88
- │ │ BioLinkBERT │ │ BioLinkBERT │ │
89
- │ │ Drug │ │ ADR │ │
90
- │ │ Encoder │ │ Encoder │ │
91
- │ └──────┬──────┘ └──────┬──────┘ │
92
- │ │ │ │
93
- │ ▼ ▼ │
94
- │ ┌─────────────┐ ┌─────────────┐ │
95
- │ │ Attention │ │ Attention │ │
96
- │ │ Pooling │ │ Pooling │ │
97
- │ └──────┬──────┘ └──────┬──────┘ │
98
- │ │ │ │
99
- │ ▼ ▼ │
100
- │ ┌─────────────┐ ┌─────────────┐ │
101
- │ │ Projection │ │ Projection │ │
102
- │ │ 768 → 256 │ │ 768 → 256 │ │
103
- │ └──────┬──────┘ └──────┬──────┘ │
104
- │ │ │ │
105
- │ └──────────┬──────────────────┘ │
106
- │ ▼ │
107
- │ ┌──────────────┐ │
108
- │ │ Bilinear │ │
109
- │ │ + Concat │ │
110
- │ └──────┬───────┘ │
111
- │ ▼ │
112
- │ ┌──────────────┐ │
113
- │ │ Classifier │ │
114
- │ │ 512→256→1 │ │
115
- │ └──────┬───────┘ │
116
- │ ▼ │
117
- │ P(causal) │
118
- └─────────────────────────────────────────────────────────────────┘
119
- ```
120
-
121
- ### Model Specifications
122
-
123
- - **Base Model:** `michiyasunaga/BioLinkBERT-base`
124
- - **Hidden Dimension:** 768
125
- - **Fusion Dimension:** 256
126
- - **Attention Heads:** 4
127
- - **Total Parameters:** 238,667,009
128
- - **Special Tokens:** `[DRUG]`, `[/DRUG]`, `[ADR]`, `[/ADR]`
129
-
130
- ## Training Data
131
-
132
- ### Combined Dataset
133
-
134
- | Dataset | Split | Examples | Source |
135
- |---------|-------|----------|--------|
136
- | ADE Corpus V2 | Train | 13,642 | MEDLINE case reports |
137
- | ADE Corpus V2 | Val | 2,047 | MEDLINE case reports |
138
- | MIMICause | Train | 2,281 | MIMIC-III clinical notes |
139
- | MIMICause | Val | 403 | MIMIC-III clinical notes |
140
- | **Combined** | **Train** | **15,923** | - |
141
-
142
- ### MIMICause Label Mapping
143
-
144
- MIMICause provides nuanced causal annotations that were mapped to binary labels:
145
-
146
- | MIMICause Label | Mapped To | Rationale |
147
- |-----------------|-----------|-----------|
148
- | Cause(E1,E2) | Positive | Direct causation |
149
- | Cause(E2,E1) | Positive | Direct causation (reversed) |
150
- | Enable(E1,E2) | Positive | Enabling = contributing cause |
151
- | Enable(E2,E1) | Positive | Enabling (reversed) |
152
- | Prevent(E1,E2) | Negative | Opposite of causation |
153
- | Prevent(E2,E1) | Negative | Opposite (reversed) |
154
- | Hinder(E1,E2) | Negative | Partial prevention |
155
- | Hinder(E2,E1) | Negative | Partial prevention (reversed) |
156
- | Other | Negative | No causal relationship |
157
-
158
- ### Entity Classification in MIMICause
159
-
160
- MIMICause annotates generic entities (E1, E2). Drug entities were identified using:
161
-
162
- 1. **Lexicon matching:** Common drug names (aspirin, morphine, etc.)
163
- 2. **Suffix patterns:** -ine, -ol, -mab, -pril, -statin, etc.
164
- 3. **Default assignment:** When ambiguous, E1 = drug, E2 = ADR
165
 
166
- ## Training Procedure
167
-
168
- ### Phase 1: Contrastive Pre-training (5 epochs)
169
-
170
- ```python
171
- CONFIG = {
172
- "temperature": 0.07,
173
- "hard_negative_ratio": 0.5,
174
- "batch_size": 16,
175
- "gradient_accumulation_steps": 4,
176
- "max_length": 256, # Longer for clinical notes
177
- }
178
- ```
179
-
180
- - InfoNCE loss with hard negative mining
181
- - Combined ADE + MIMICause training data
182
- - Learns unified embedding space for both data sources
183
-
184
- ### Phase 2: Classification Fine-tuning (8 epochs)
185
-
186
- ```python
187
- CONFIG = {
188
- "learning_rate": 2e-5,
189
- "warmup_ratio": 0.1,
190
- "layerwise_lr_decay": 0.9,
191
- "focal_gamma": 2.0,
192
- "focal_alpha": 0.75,
193
- "weight_decay": 0.01,
194
- }
195
- ```
196
 
197
- - Focal loss for hard example mining
198
- - Cosine learning rate schedule
199
- - Layer-wise learning rate decay (0.9× per layer)
200
 
201
  ## Performance
202
 
203
- ### Final Metrics
204
 
205
- | Metric | Value |
206
  |--------|-------|
207
- | **F1 Score** | 98.89% |
208
- | **ROC-AUC** | 99.81% |
209
- | **Optimal Threshold** | 0.70 |
210
-
211
- ### Training Progression
212
-
213
- | Epoch | Train Loss | Train F1 | Val F1 | Val AUC |
214
- |-------|------------|----------|--------|---------|
215
- | 1 | 0.1842 | 93.21% | 94.56% | 98.12% |
216
- | 2 | 0.0523 | 96.34% | 97.23% | 99.34% |
217
- | 4 | 0.0187 | 97.89% | 98.12% | 99.78% |
218
- | 8 | 0.0059 | 98.23% | **98.89%** | **99.81%** |
219
-
220
- ### Comparison with CRAG Family
221
 
222
- | Model | F1 | AUC | Δ F1 vs Base |
223
- |-------|-----|-----|--------------|
224
- | CRAG-dual-encoder-base | 88.3% | - | - |
225
- | CRAG-dual-encoder-ade | 97.5% | 99.1% | +9.2% |
226
- | **CRAG-dual-encoder-mimicause** | **98.89%** | **99.81%** | **+10.59%** |
227
 
228
- ### MIMICause Contribution
229
-
230
- Training on the additional 2,281 MIMICause examples improved:
231
- - **F1:** 97.5% 98.89% (+1.39 percentage points)
232
- - **AUC:** 99.1% 99.81% (+0.71 percentage points)
233
-
234
- The MIMICause data provides complementary signal through:
235
- - Clinical language patterns different from MEDLINE
236
- - Exposure to causal reasoning beyond simple drug-ADR pairs
237
- - Real-world clinical documentation style
238
 
239
  ## Usage
240
 
241
- ### Loading the Model
242
-
243
  ```python
244
  import torch
245
- import torch.nn as nn
246
- from transformers import AutoTokenizer, AutoModel
247
-
248
- class AttentionPooling(nn.Module):
249
- def __init__(self, hidden_dim=768, num_heads=4):
250
- super().__init__()
251
- self.attention = nn.MultiheadAttention(hidden_dim, num_heads, batch_first=True)
252
- self.query = nn.Parameter(torch.randn(1, 1, hidden_dim))
253
-
254
- def forward(self, hidden_states, attention_mask):
255
- batch_size = hidden_states.size(0)
256
- query = self.query.expand(batch_size, -1, -1)
257
- key_padding_mask = ~attention_mask.bool()
258
- pooled, _ = self.attention(query, hidden_states, hidden_states,
259
- key_padding_mask=key_padding_mask)
260
- return pooled.squeeze(1)
261
-
262
- class CRAGDualEncoder(nn.Module):
263
- def __init__(self, model_name="michiyasunaga/BioLinkBERT-base",
264
- hidden_dim=768, fusion_dim=256, dropout=0.1):
265
- super().__init__()
266
-
267
- # Dual encoders
268
- self.drug_encoder = AutoModel.from_pretrained(model_name)
269
- self.adr_encoder = AutoModel.from_pretrained(model_name)
270
-
271
- # Attention pooling
272
- self.drug_pooler = AttentionPooling(hidden_dim)
273
- self.adr_pooler = AttentionPooling(hidden_dim)
274
-
275
- # Projection heads
276
- self.drug_projection = nn.Sequential(
277
- nn.Linear(hidden_dim, fusion_dim),
278
- nn.LayerNorm(fusion_dim),
279
- nn.GELU(),
280
- nn.Dropout(dropout),
281
- nn.Linear(fusion_dim, fusion_dim),
282
- )
283
- self.adr_projection = nn.Sequential(
284
- nn.Linear(hidden_dim, fusion_dim),
285
- nn.LayerNorm(fusion_dim),
286
- nn.GELU(),
287
- nn.Dropout(dropout),
288
- nn.Linear(fusion_dim, fusion_dim),
289
- )
290
-
291
- # Fusion and classification
292
- self.bilinear = nn.Bilinear(fusion_dim, fusion_dim, fusion_dim)
293
- self.fusion_norm = nn.LayerNorm(fusion_dim)
294
- self.classifier = nn.Sequential(
295
- nn.Linear(fusion_dim * 2, fusion_dim),
296
- nn.LayerNorm(fusion_dim),
297
- nn.GELU(),
298
- nn.Dropout(dropout),
299
- nn.Linear(fusion_dim, fusion_dim // 2),
300
- nn.GELU(),
301
- nn.Dropout(dropout),
302
- nn.Linear(fusion_dim // 2, 1),
303
- )
304
-
305
- def encode_drug(self, input_ids, attention_mask):
306
- outputs = self.drug_encoder(input_ids=input_ids, attention_mask=attention_mask)
307
- pooled = self.drug_pooler(outputs.last_hidden_state, attention_mask)
308
- return self.drug_projection(pooled)
309
-
310
- def encode_adr(self, input_ids, attention_mask):
311
- outputs = self.adr_encoder(input_ids=input_ids, attention_mask=attention_mask)
312
- pooled = self.adr_pooler(outputs.last_hidden_state, attention_mask)
313
- return self.adr_projection(pooled)
314
-
315
- def forward(self, drug_input_ids, drug_attention_mask, adr_input_ids, adr_attention_mask):
316
- drug_repr = self.encode_drug(drug_input_ids, drug_attention_mask)
317
- adr_repr = self.encode_adr(adr_input_ids, adr_attention_mask)
318
-
319
- bilinear_out = self.bilinear(drug_repr, adr_repr)
320
- bilinear_out = self.fusion_norm(bilinear_out)
321
- combined = torch.cat([bilinear_out, drug_repr + adr_repr], dim=-1)
322
-
323
- return self.classifier(combined)
324
 
325
- # Load model
326
- tokenizer = AutoTokenizer.from_pretrained("chrisvoncsefalvay/CRAG-dual-encoder-mimicause")
327
- model = CRAGDualEncoder()
328
 
329
- # Load weights
330
  from huggingface_hub import hf_hub_download
331
- weights_path = hf_hub_download(
332
- repo_id="chrisvoncsefalvay/CRAG-dual-encoder-mimicause",
333
- filename="pytorch_model.bin"
334
- )
335
- model.load_state_dict(torch.load(weights_path, map_location="cpu"))
336
- model.eval()
337
- ```
338
 
339
- ### Inference
 
 
340
 
341
- ```python
342
- def predict_causal_relationship(model, tokenizer, text, drug, adr, threshold=0.70):
343
- """
344
- Predict if a drug-ADR pair has a causal relationship.
345
-
346
- Args:
347
- model: Loaded CRAGDualEncoder
348
- tokenizer: Loaded tokenizer
349
- text: Clinical text containing both entities
350
- drug: Drug entity string
351
- adr: ADR entity string
352
- threshold: Classification threshold (default 0.70)
353
-
354
- Returns:
355
- dict with probability and prediction
356
- """
357
- # Create marked contexts
358
- drug_context = text.replace(drug, f"[DRUG] {drug} [/DRUG]", 1)
359
- adr_context = text.replace(adr, f"[ADR] {adr} [/ADR]", 1)
360
-
361
- # Tokenize
362
- drug_enc = tokenizer(
363
- drug_context,
364
- max_length=256,
365
- padding="max_length",
366
- truncation=True,
367
- return_tensors="pt"
368
- )
369
- adr_enc = tokenizer(
370
- adr_context,
371
- max_length=256,
372
- padding="max_length",
373
- truncation=True,
374
- return_tensors="pt"
375
- )
376
-
377
- # Predict
378
- with torch.no_grad():
379
- logit = model(
380
- drug_enc["input_ids"],
381
- drug_enc["attention_mask"],
382
- adr_enc["input_ids"],
383
- adr_enc["attention_mask"]
384
- )
385
- prob = torch.sigmoid(logit).item()
386
-
387
- return {
388
- "probability": prob,
389
- "is_causal": prob >= threshold,
390
- "confidence": abs(prob - 0.5) * 2 # 0 = uncertain, 1 = confident
391
- }
392
-
393
- # Example: Clinical note from MIMIC-style text
394
- result = predict_causal_relationship(
395
- model, tokenizer,
396
- text="Steroid myopathy: Patient had a history of steroid induced myopathy and had presented with an ongoing steroid taper.",
397
- drug="steroid",
398
- adr="myopathy"
399
- )
400
- print(f"Probability: {result['probability']:.3f}")
401
- print(f"Is Causal: {result['is_causal']}")
402
- print(f"Confidence: {result['confidence']:.3f}")
403
- # Output:
404
- # Probability: 0.967
405
- # Is Causal: True
406
- # Confidence: 0.934
407
  ```
408
 
409
- ### Batch Processing
410
 
411
- ```python
412
- def batch_predict(model, tokenizer, pairs, batch_size=32):
413
- """
414
- Predict for multiple drug-ADR pairs efficiently.
415
-
416
- Args:
417
- pairs: List of (text, drug, adr) tuples
418
-
419
- Returns:
420
- List of probability scores
421
- """
422
- results = []
423
-
424
- for i in range(0, len(pairs), batch_size):
425
- batch = pairs[i:i+batch_size]
426
-
427
- drug_texts = [p[0].replace(p[1], f"[DRUG] {p[1]} [/DRUG]", 1) for p in batch]
428
- adr_texts = [p[0].replace(p[2], f"[ADR] {p[2]} [/ADR]", 1) for p in batch]
429
-
430
- drug_enc = tokenizer(drug_texts, max_length=256, padding=True,
431
- truncation=True, return_tensors="pt")
432
- adr_enc = tokenizer(adr_texts, max_length=256, padding=True,
433
- truncation=True, return_tensors="pt")
434
-
435
- with torch.no_grad():
436
- logits = model(
437
- drug_enc["input_ids"],
438
- drug_enc["attention_mask"],
439
- adr_enc["input_ids"],
440
- adr_enc["attention_mask"]
441
- )
442
- probs = torch.sigmoid(logits).squeeze(-1).tolist()
443
- results.extend(probs)
444
-
445
- return results
446
  ```
 
 
 
 
 
 
 
 
 
 
447
 
448
- ## Intended Uses
 
449
 
450
- ### Primary Applications
451
 
452
- 1. **Clinical Pharmacovigilance**
453
- - Real-time ADR detection in EHR systems
454
- - Screening clinical notes for safety signals
455
- - Supporting adverse event reporting (FAERS, EudraVigilance)
456
 
457
- 2. **Drug Safety Knowledge Graphs**
458
- - Automated edge extraction for drug-ADR graphs
459
- - Causal graph construction for pharmacovigilance
460
- - Integration with existing drug databases (DrugBank, SIDER)
 
461
 
462
- 3. **Literature Mining**
463
- - Systematic review automation
464
- - Case report screening
465
- - Meta-analysis support
466
 
467
- 4. **Regulatory Applications**
468
- - Pre-submission safety signal detection
469
- - Post-market surveillance
470
- - Label update recommendations
 
 
 
471
 
472
- ### Recommended Threshold Selection
473
 
474
- | Use Case | Threshold | Precision | Recall | F1 |
475
- |----------|-----------|-----------|--------|-----|
476
- | High-sensitivity screening | 0.50 | 95.1% | 99.2% | 97.1% |
477
- | Balanced (default) | 0.70 | 98.5% | 98.9% | 98.7% |
478
- | High-precision extraction | 0.85 | 99.5% | 96.8% | 98.1% |
479
 
480
  ## Limitations
481
 
482
- 1. **English Only:** Not validated on non-English clinical text
483
- 2. **Binary Output:** Does not distinguish causation types or severity
484
- 3. **Entity Detection Required:** Assumes drug and ADR entities are pre-identified
485
- 4. **Training Data Scope:**
486
- - ADE Corpus: MEDLINE case reports
487
- - MIMICause: US ICU clinical notes (MIMIC-III)
488
- - May not generalize to other clinical settings or countries
489
- 5. **Temporal Reasoning:** Does not explicitly model temporal relationships
490
-
491
- ## Ethical Considerations
492
-
493
- ### Clinical Deployment
494
-
495
- - **Human-in-the-Loop:** Always require expert review for clinical decisions
496
- - **Confidence Communication:** Surface probability scores, not just binary predictions
497
- - **Error Analysis:** Monitor for systematic biases in drug or ADR categories
498
-
499
- ### Bias Considerations
500
-
501
- - Training data reflects US clinical practice and MEDLINE publication patterns
502
- - Common drugs/ADRs better represented than rare ones
503
- - May underperform on pediatric, geriatric, or specialty populations
504
-
505
- ### Privacy
506
-
507
- - Model does not retain patient information
508
- - MIMICause derived from de-identified MIMIC-III data
509
- - No personal health information in model weights
510
-
511
- ## Technical Specifications
512
-
513
- | Specification | Value |
514
- |---------------|-------|
515
- | Framework | PyTorch 2.0+ |
516
- | Base Model | BioLinkBERT-base |
517
- | Model Size | 955 MB |
518
- | Vocabulary Size | 30,522 + 4 special tokens |
519
- | Max Sequence Length | 256 tokens |
520
- | Inference Speed (GPU) | ~85 pairs/second |
521
- | Inference Speed (CPU) | ~5 pairs/second |
522
- | GPU Memory (inference) | ~2 GB |
523
- | Training Hardware | NVIDIA A10G |
524
- | Training Time | ~90 minutes |
525
 
526
  ## Citation
527
 
 
 
528
  ```bibtex
529
- @misc{crag-dual-encoder-mimicause-2024,
530
- title={CRAG: Causal Reasoning for Adversomics Graphs - Dual-Encoder Enhanced with Clinical Causal Reasoning},
531
- author={von Csefalvay, Chris},
532
- year={2024},
533
- publisher={Hugging Face},
534
- url={https://huggingface.co/chrisvoncsefalvay/CRAG-dual-encoder-mimicause}
535
  }
536
  ```
537
 
538
- ## References
539
-
540
- - Gurulingappa, H., et al. (2012). Development of a benchmark corpus to support the automatic extraction of drug-related adverse effects from medical case reports. *Journal of Biomedical Informatics*.
541
- - Yasunaga, M., et al. (2022). LinkBERT: Pretraining Language Models with Document Links. *ACL*.
542
- - Khetan, V., et al. (2022). MIMICause: Representation and automatic extraction of causal relation types from clinical notes. *ACL Findings*.
543
- - Johnson, A.E.W., et al. (2016). MIMIC-III, a freely accessible critical care database. *Scientific Data*.
544
-
545
- ## Related Models
546
-
547
- - [CRAG-dual-encoder-base](https://huggingface.co/chrisvoncsefalvay/CRAG-dual-encoder-base) - Baseline PubMedBERT model
548
- - [CRAG-dual-encoder-ade](https://huggingface.co/chrisvoncsefalvay/CRAG-dual-encoder-ade) - Enhanced ADE-only model
549
-
550
- ## Model Card Authors
551
-
552
- Chris von Csefalvay ([@chrisvoncsefalvay](https://huggingface.co/chrisvoncsefalvay))
553
-
554
- ## Model Card Contact
555
 
556
- For questions, issues, or collaboration inquiries:
557
- - Open a discussion on this model's repository
558
- - Email: [email protected]
559
- - GitHub: [@chrisvoncsefalvay](https://github.com/chrisvoncsefalvay)
 
1
  ---
 
2
  language:
3
  - en
4
+ license: apache-2.0
5
  tags:
6
  - medical
7
  - biomedical
8
  - drug-safety
9
+ - adverse-drug-events
10
  - pharmacovigilance
11
  - relation-extraction
12
  - dual-encoder
13
  - clinical-nlp
 
 
 
 
 
 
 
 
14
  datasets:
15
+ - ade_corpus_v2
16
+ - mimicause
17
  metrics:
18
  - f1
19
+ - precision
20
+ - recall
21
  - roc_auc
22
  pipeline_tag: text-classification
23
+ library_name: pytorch
24
+ base_model:
25
+ - michiyasunaga/BioLinkBERT-base
 
 
 
 
 
 
 
 
 
 
 
 
 
 
26
  ---
27
 
28
+ # CRAG: Causal Reasoning for Adversomics Graphs
 
 
29
 
30
+ **CRAG** (Causal Reasoning for Adversomics Graphs) is a dual-encoder model for extracting adverse drug event (ADE) relationships from clinical narratives. It achieves state-of-the-art performance on ADE extraction, significantly outperforming both specialized biomedical language models and large language models.
31
 
32
  ## Model Description
33
 
34
+ CRAG uses a dual-encoder architecture with:
35
+ - **Two separate BioLinkBERT encoders**: One for drug mentions, one for adverse event mentions
36
+ - **Attention pooling**: Multi-head attention mechanism for sequence representation
37
+ - **Bilinear fusion**: Captures complex drug-ADR interactions
38
+ - **Multi-view concatenation**: Combines bilinear output, individual embeddings, and element-wise products
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
39
 
40
+ ### Training Approach
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
41
 
42
+ The model is trained in two phases:
43
+ 1. **Phase 1 - Contrastive Pre-training**: InfoNCE loss with hard negative mining to learn discriminative drug-ADR embeddings
44
+ 2. **Phase 2 - Classification Fine-tuning**: Focal loss to handle class imbalance and refine the classifier
45
 
46
  ## Performance
47
 
48
+ ### Test Set Results
49
 
50
+ | Metric | Score |
51
  |--------|-------|
52
+ | **F1 Score** | 0.9332 |
53
+ | **Precision** | 0.9075 |
54
+ | **Recall** | 0.9603 |
55
+ | **AUC-ROC** | 0.9765 |
 
 
 
 
 
 
 
 
 
 
56
 
57
+ ### Comparison with Baselines
 
 
 
 
58
 
59
+ | Model | F1 Score | AUC-ROC | F1 Improvement |
60
+ |-------|----------|---------|----------------|
61
+ | BioLinkBERT (zero-shot) | 0.215 | 0.523 | - |
62
+ | GPT-4 Turbo | 0.734 | 0.713 | - |
63
+ | Qwen2.5-1.5B-Instruct | 0.714 | 0.728 | - |
64
+ | **CRAG (this model)** | **0.933** | **0.977** | **+27% vs GPT-4** |
 
 
 
 
65
 
66
  ## Usage
67
 
 
 
68
  ```python
69
  import torch
70
+ from transformers import AutoTokenizer
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
71
 
72
+ # Load tokenizer
73
+ tokenizer = AutoTokenizer.from_pretrained("michiyasunaga/BioLinkBERT-base")
74
+ tokenizer.add_special_tokens({'additional_special_tokens': ['[DRUG]', '[/DRUG]', '[ADR]', '[/ADR]']})
75
 
76
+ # Load model
77
  from huggingface_hub import hf_hub_download
78
+ import torch
 
 
 
 
 
 
79
 
80
+ # Download and load the model
81
+ model_path = hf_hub_download(repo_id="chrisvoncsefalvay/CRAG-dual-encoder-mimicause", filename="pytorch_model.pt")
82
+ checkpoint = torch.load(model_path, map_location='cpu')
83
 
84
+ # For inference, see the example notebook in the repository
85
+
86
+ # Example input format:
87
+ drug_context = "The patient developed [DRUG] aspirin [/DRUG] induced gastric bleeding."
88
+ adr_context = "The patient developed aspirin induced [ADR] gastric bleeding [/ADR]."
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
89
  ```
90
 
91
+ ## Model Architecture
92
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
93
  ```
94
+ CRAGDualEncoder(
95
+ (drug_encoder): BioLinkBERT-base (110M params)
96
+ (adr_encoder): BioLinkBERT-base (110M params)
97
+ (drug_pooler): AttentionPooling (4 heads)
98
+ (adr_pooler): AttentionPooling (4 heads)
99
+ (drug_projection): Linear(768 -> 256) + LayerNorm + GELU + Linear
100
+ (adr_projection): Linear(768 -> 256) + LayerNorm + GELU + Linear
101
+ (bilinear): Bilinear(256, 256 -> 256)
102
+ (classifier): Linear(1024 -> 256) + LayerNorm + GELU + Linear(256 -> 128) + GELU + Linear(128 -> 1)
103
+ )
104
 
105
+ Total Parameters: 238,798,081
106
+ ```
107
 
108
+ ## Training Data
109
 
110
+ The model was trained on a combination of:
111
+ - **ADE Corpus v2**: Biomedical literature annotations for drug-adverse event pairs
112
+ - **MIMICause**: Clinical notes from MIMIC-III with causal ADE annotations
 
113
 
114
+ | Split | Samples | Positive | Negative |
115
+ |-------|---------|----------|----------|
116
+ | Train | 12,978 | 6,264 | 6,714 |
117
+ | Validation | 1,667 | 812 | 855 |
118
+ | Test | 1,681 | 807 | 874 |
119
 
120
+ ## Training Configuration
 
 
 
121
 
122
+ | Parameter | Phase 1 (Contrastive) | Phase 2 (Classification) |
123
+ |-----------|----------------------|--------------------------|
124
+ | Epochs | 5 | 8 |
125
+ | Batch Size | 16 | 16 |
126
+ | Learning Rate | 2e-5 | 2e-5 |
127
+ | Loss Function | InfoNCE (τ=0.07) | Focal (γ=2.0, α=0.75) |
128
+ | Hard Negatives | 50% | - |
129
 
130
+ ## Experiment Tracking
131
 
132
+ - **WandB Run**: [68d4wq4u](https://wandb.ai/chrisvoncsefalvay/crag-experiments/runs/68d4wq4u)
133
+ - **Dataset Artifacts**: [HuggingFace Dataset](https://huggingface.co/datasets/chrisvoncsefalvay/crag-experiment-artifacts)
 
 
 
134
 
135
  ## Limitations
136
 
137
+ - Trained primarily on English clinical and biomedical text
138
+ - Requires drug and ADR spans to be pre-identified (not an end-to-end NER+RE model)
139
+ - Performance may vary on drug/ADR pairs not seen during training
140
+ - Best suited for binary relation classification, not relation type classification
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
141
 
142
  ## Citation
143
 
144
+ If you use this model, please cite:
145
+
146
  ```bibtex
147
+ @misc{crag2024,
148
+ author = {von Csefalvay, Chris},
149
+ title = {CRAG: Causal Reasoning for Adversomics Graphs},
150
+ year = {2024},
151
+ publisher = {Hugging Face},
152
+ howpublished = {\url{https://huggingface.co/chrisvoncsefalvay/CRAG-dual-encoder-mimicause}}
153
  }
154
  ```
155
 
156
+ ## License
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
157
 
158
+ Apache 2.0
 
 
 
config.json ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "model": {
3
+ "base_model": "michiyasunaga/BioLinkBERT-base",
4
+ "hidden_dim": 768,
5
+ "fusion_dim": 256,
6
+ "dropout": 0.1,
7
+ "pooling": "attention",
8
+ "attention_heads": 4
9
+ }
10
+ }
pytorch_model.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:38572981c02b8494a10a530410b836f3228484726ed3d9fb0cbeae13b6b492ad
3
+ size 955369379
test_results.json ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "f1": 0.9331727874774233,
3
+ "precision": 0.9074941451990632,
4
+ "recall": 0.9603469640644362,
5
+ "auc": 0.9765410779251344,
6
+ "confusion_matrix": [
7
+ [
8
+ 795,
9
+ 79
10
+ ],
11
+ [
12
+ 32,
13
+ 775
14
+ ]
15
+ ],
16
+ "num_samples": 1681,
17
+ "num_positive": 807
18
+ }
tokenizer.json CHANGED
@@ -1,21 +1,7 @@
1
  {
2
  "version": "1.0",
3
- "truncation": {
4
- "direction": "Right",
5
- "max_length": 256,
6
- "strategy": "LongestFirst",
7
- "stride": 0
8
- },
9
- "padding": {
10
- "strategy": {
11
- "Fixed": 256
12
- },
13
- "direction": "Right",
14
- "pad_to_multiple_of": null,
15
- "pad_id": 0,
16
- "pad_type_id": 0,
17
- "pad_token": "[PAD]"
18
- },
19
  "added_tokens": [
20
  {
21
  "id": 0,
 
1
  {
2
  "version": "1.0",
3
+ "truncation": null,
4
+ "padding": null,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5
  "added_tokens": [
6
  {
7
  "id": 0,