This model is a fine-tuned version of answerdotai/ModernBERT-base for multilabel classification of Motivational Interviewing (MI) behavioral codes. It classifies utterances into three non-mutually-exclusive categories used in behavioral coding of therapeutic conversations.
This model is designed for automated behavioral coding in Motivational Interviewing contexts, predicting three types of MI-consistent and MI-inconsistent behaviors:
Multilabel Classification: Utterances can have multiple labels simultaneously
Therapeutic Context: Specifically trained on Motivational Interviewing conversations
Context-Aware: Includes three preceding utterances for context
Potential Applications
Automated analysis of therapy session transcripts
Training and feedback for MI practitioners
Quality assurance in behavioral health interventions
Research in therapeutic communication patterns
Model Performance
Test Set Metrics
The model was evaluated on a held-out test set of 3,235 coded utterances.
Overall Performance
Metric
Score
Exact Match Accuracy
85.63%
Hamming Loss
0.0579
F1 Macro
86.66%
F1 Micro
92.46%
Precision Macro
86.53%
Precision Micro
93.47%
Recall Macro
86.84%
Recall Micro
91.48%
Exact Match: Percentage of examples where all labels are predicted correctly
Hamming Loss: Average fraction of labels that are incorrectly predicted (lower is better)
Per-Label Performance
Label
F1 Score
Precision
Recall
Accuracy
Adherent
74.29%
74.47%
74.10%
90.26%
Non-Adherent
89.32%
87.34%
91.39%
98.98%
Neutral
96.39%
97.77%
95.04%
93.38%
Class Distribution
The training data exhibits class imbalance, addressed through positive class weighting:
Neutral: Most common (majority class)
Non-Adherent: Moderate frequency
Adherent: Least common (minority class)
Training Details
Training Data
Source: Multilabel behavioral coding dataset from Motivational Interviewing transcripts
Preprocessing:
Excluded utterances marked as "not_coded" (no MI codes assigned)
Included context from three preceding utterances
Stratified splitting to maintain label distribution
Split: 70% train, 15% validation, 15% test
Training Procedure
Hardware:
GPU training with CUDA
Mixed precision (BFloat16) training
Hyperparameters:
Parameter
Value
Learning Rate
6e-5
Batch Size (per device)
12
Gradient Accumulation
2 steps
Effective Batch Size
24
Max Sequence Length
3000 tokens
Epochs
20 (early stopped at epoch 14)
Weight Decay
0.01
Warmup Ratio
0.1
LR Scheduler
Cosine
Optimizer
AdamW
Dropout
0.1
Training Features:
Positive Class Weighting: BCEWithLogitsLoss with computed pos_weights for each label
Early Stopping: Patience of 3 epochs on validation F1 macro
Gradient Checkpointing: Enabled for memory efficiency
Flash Attention 2: For efficient attention computation
Best Model Selection: Based on validation F1 macro score
Loss Function: Binary Cross-Entropy with Logits Loss (BCEWithLogitsLoss) with per-label positive class weights
Model Architecture
The model uses a custom architecture on top of ModernBERT:
1import torch
2from transformers import AutoTokenizer, AutoModel
3import torch.nn as nn
45# Define the model class6classMultiLabelBERTModel(nn.Module):7def__init__(self, model_name, num_labels=3, dropout=0.1):8super().__init__()9 self.bert = AutoModel.from_pretrained(model_name)10 self.dropout = nn.Dropout(dropout)11 self.classifier = nn.Linear(self.bert.config.hidden_size, num_labels)12 self.num_labels = num_labels
1314defforward(self, input_ids, attention_mask):15 outputs = self.bert(input_ids=input_ids, attention_mask=attention_mask)16 pooled_output = outputs.last_hidden_state[:,0,:]# [CLS] token17 pooled_output = self.dropout(pooled_output)18 logits = self.classifier(pooled_output)19return logits
2021# Load model and tokenizer22model_name ="Lekhansh/bc-multilabel-classifier"23tokenizer = AutoTokenizer.from_pretrained(model_name)2425# Initialize model architecture26model = MultiLabelBERTModel(model_name, num_labels=3)2728# Load trained weights29# Note: You'll need to load the weights from the saved model30model.eval()3132# Prepare input33text ="That's a wonderful goal you've set for yourself."34inputs = tokenizer(text, return_tensors="pt", truncation=True, max_length=3000)3536# Get predictions37with torch.no_grad():38 logits = model(inputs['input_ids'], inputs['attention_mask'])39 probs = torch.sigmoid(logits)40 predictions =(probs >0.5).int()4142# Interpret results43labels =['adherent','non_adherent','neutral']44print(f"Text: {text}")45print("\nPredictions:")46for i, label inenumerate(labels):47if predictions[0][i]:48print(f" ✓ {label} (confidence: {probs[0][i]:.2%})")
Batch Prediction with Confidence Scores
python
1defpredict_multilabel(texts, model, tokenizer, threshold=0.5):2"""
3 Predict multiple labels for each text with confidence scores.
45 Args:
6 texts: List of input texts
7 model: The multilabel classification model
8 tokenizer: The tokenizer
9 threshold: Probability threshold for positive prediction (default: 0.5)
1011 Returns:
12 List of dicts with predictions and probabilities
13 """14 inputs = tokenizer(15 texts,16 return_tensors="pt",17 truncation=True,18 max_length=3000,19 padding=True20)2122with torch.no_grad():23 logits = model(inputs['input_ids'], inputs['attention_mask'])24 probs = torch.sigmoid(logits)2526 labels =['adherent','non_adherent','neutral']27 results =[]2829for i inrange(len(texts)):30 predictions =(probs[i]> threshold).int()31 result ={32'text': texts[i],33'labels':{},34'probabilities':{}35}3637for j, label inenumerate(labels):38 result['labels'][label]=bool(predictions[j])39 result['probabilities'][label]=float(probs[i][j])4041 results.append(result)4243return results
4445# Example usage46utterances =[47"I hear you saying that you want to change but you're not sure how.",48"You need to stop making excuses and just do it.",49"How many cigarettes do you smoke per day?"50]5152results = predict_multilabel(utterances, model, tokenizer)53for r in results:54print(f"\nText: {r['text'][:60]}...")55print("Predicted labels:")56for label in['adherent','non_adherent','neutral']:57 status ="✓"if r['labels'][label]else"✗"58 conf = r['probabilities'][label]59print(f" {status}{label}: {conf:.2%}")
Custom Threshold Tuning
python
1# Adjust threshold for precision/recall trade-off2defpredict_with_custom_threshold(text, model, tokenizer, thresholds):3"""
4 Predict with different thresholds for each label.
56 Args:
7 thresholds: Dict with keys 'adherent', 'non_adherent', 'neutral'
8 """9 inputs = tokenizer(text, return_tensors="pt", truncation=True, max_length=3000)1011with torch.no_grad():12 logits = model(inputs['input_ids'], inputs['attention_mask'])13 probs = torch.sigmoid(logits)1415 labels_list =['adherent','non_adherent','neutral']16 predictions ={}1718for i, label inenumerate(labels_list):19 threshold = thresholds.get(label,0.5)20 predictions[label]={21'predicted':bool(probs[0][i]> threshold),22'probability':float(probs[0][i]),23'threshold': threshold
24}2526return predictions
2728# Example: Higher threshold for adherent (higher precision)29custom_thresholds ={30'adherent':0.6,31'non_adherent':0.5,32'neutral':0.533}3435result = predict_with_custom_threshold(36"What are your thoughts on reducing your drinking?",37 model,38 tokenizer,39 custom_thresholds
40)
Limitations and Bias
Limitations
Domain Specificity: Trained on Motivational Interviewing data; may not generalize to other therapeutic modalities
Context Dependency: Performance may vary with utterances lacking proper conversational context
Class Imbalance: Lower performance on "adherent" label due to class imbalance in training data
Multilabel Complexity: Some utterances may have ambiguous or overlapping codes
Context Length: Maximum 3000 tokens; longer texts will be truncated
Language: Trained on English text only
Potential Biases
Training data may reflect biases from the original coding framework and human coders
Performance may vary across different MI contexts (e.g., substance use vs. health behavior change)
Cultural and linguistic variations in therapeutic communication may affect predictions
The model may be more accurate on populations/contexts similar to training data
Recommended Use
Use as a screening tool or preliminary analysis, not as definitive behavioral coding
Validate predictions with human expert review, especially for critical applications
Consider adjusting prediction thresholds based on your use case (precision vs. recall trade-off)
Be aware that multilabel predictions may sometimes conflict with clinical judgment
Parameters: ~110M (inherited from base model + classification head)
Precision: BFloat16
Compute Infrastructure
Training: Single GPU with CUDA
Inference: CPU or GPU compatible
Memory: ~500MB model size
Label Format
python
1# Output format2{3"adherent":0or1,4"non_adherent":0or1,5"neutral":0or16}78# Example: An utterance can have multiple labels9# "I hear that you're struggling, and I believe you can overcome this."10# → adherent=1, non_adherent=0, neutral=0
Environmental Impact
Training was conducted using mixed precision to optimize resource usage. Exact carbon footprint was not measured.
Citation
If you use this model in your research, please cite:
bibtex
1@misc{lekhansh2025bcmultilabel,
2 author = {Lekhansh},
3 title = {Behavioral Coding Multilabel Classifier for Motivational Interviewing},
4 year = {2025},
5 publisher = {HuggingFace},
6 howpublished = {\url{https://huggingface.co/Lekhansh/bc-multilabel-classifier}}
7}
References
For more information on Motivational Interviewing behavioral coding:
Miller, W. R., & Rollnick, S. (2013). Motivational Interviewing: Helping People Change (3rd ed.)
Moyers, T. B., et al. (2016). Motivational Interviewing Treatment Integrity Coding Manual 4.2.1