Views
No views yet
| Model | Held-out AUC |
|---|---|
| Existing circular "emotion" dim (177-dim model trained on Claude scores) | 0.557 |
| Frozen-embedding probe (sentence-transformer + linear head) | 0.637 |
| This model — DistilBERT end-to-end on bridge labels | 0.678 |
model.pt — full state-dict: DistilBERT encoder + mean-pool + Linear(hidden→1) head.metrics.json — final held-out AUC + baseline comparison.AutoModelForSequenceClassification.from_pretrained directly. Load like this:1import torch
2from transformers import AutoTokenizer, AutoModel
3
4class AffectNet(torch.nn.Module):
5 def __init__(self):
6 super().__init__()
7 self.enc = AutoModel.from_pretrained("distilbert-base-uncased")
8 self.head = torch.nn.Linear(self.enc.config.hidden_size, 1)
9 def forward(self, ids, mask):
10 h = self.enc(input_ids=ids, attention_mask=mask).last_hidden_state
11 m = mask.unsqueeze(-1).float()
12 pooled = (h * m).sum(1) / m.sum(1).clamp(min=1e-6)
13 return self.head(pooled).squeeze(1)
14
15tok = AutoTokenizer.from_pretrained("distilbert-base-uncased")
16model = AffectNet()
17model.load_state_dict(torch.load("model.pt", map_location="cpu"))
18model.eval()
19
20text = "I can't bear this any longer."
21enc = tok(text, padding="max_length", truncation=True, max_length=48, return_tensors="pt")
22with torch.no_grad():
23 valence = torch.sigmoid(model(enc["input_ids"], enc["attention_mask"]))[0].item()
24print(valence) # ~1.0 = negative/distressed affect, ~0.0 = positivecorpus/booknlp_output/):
for each character quote, the narration window (±7 tokens around the quote) was
scanned for emotion supersense spans (verb.emotion, noun.feeling) and
manner adverbs anchored to a speech verb ("said bitterly"). Quotes mapped
to net-negative vs net-positive author affect → 17,749 neg / 16,375 pos
balanced labels (29,852 total used, 23,881 train / 5,971 test).distilbert-base-uncased (~66M params).Dropout-free Linear(hidden_size, 1) over mean-pooled token embeddings.BCEWithLogitsLoss on binary affect-valence.