File size: 6,449 Bytes
d39182d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9302829
d39182d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
f0ee541
 
 
 
 
d39182d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
f0ee541
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
---
library_name: onnx
pipeline_tag: image-classification
tags:
- onnx
- onnxruntime
- image-classification
- multi-label-classification
- efficientnet
- social-comparison
- on-device
- browser
- mobile
license: other
model-index:
- name: safesocial-trigger-classifier
  results:
  - task:
      type: image-classification
    dataset:
      name: primary Instagram-domain merged test (teacher-labeled)
      type: teacher-agreement
    metrics:
    - type: micro f1
      value: 0.6817
    - type: macro f1
      value: 0.5126
    - type: exact match
      value: 0.2952
    - type: label accuracy
      value: 0.8684
  - task:
      type: image-classification
    dataset:
      name: Karpathy COCO 500-image OOD holdout (teacher-labeled)
      type: teacher-agreement
    metrics:
    - type: micro f1
      value: 0.6526
    - type: macro f1
      value: 0.3466
    - type: exact match
      value: 0.5480
    - type: label accuracy
      value: 0.9176
---

# SafeSocial Trigger Classifier 

SafeSocial is integrated into [WebBrain](https://webbrain.one) as an on-device, privacy-preserving visual moderation and wellbeing layer that automatically detects and mitigates sensitive social-comparison triggers across user feeds before content is rendered.

![SafeSocial Demo](safesocial-unicef-readme.gif)

Compact on-device multi-label image classifier that detects Instagram-style
social-comparison triggers. Intended as a privacy-preserving, user-controlled
filtering aid — **not** a diagnostic tool, moderation authority, or measure of
human validity.

> All metrics below are **student-teacher agreement** against the Qwen teacher
> (`qwen3.6-35b-a3b`), not human-ground-truth accuracy. A human-verified
> evaluation set is still the main missing piece before making strong
> real-world claims.

## Files

- `model.onnx` — deployment model, opset 17, input `pixel_values` (NCHW float32), output `probabilities` (sigmoid multi-label)
- `safesocial-model.json` — machine-readable manifest: labels, per-label thresholds, preprocessing, checkpoint provenance, train/val metrics

SHA-256 of `model.onnx` at release: `fd37c1cd4aafa2bc318b7d29725fa6be3931d09cc1723bb30be3ee819ee22933`

## Labels (10, core taxonomy)

`romance_jealousy`, `social_fomo`, `luxury_status`, `travel_lifestyle`,
`body_beauty_comparison`, `achievement_status`, `social_proof_popularity`,
`exclusivity_access`, `none`, `uncertain`

Two labels from the earlier broad taxonomy were removed before this run and are
**not** predicted by this checkpoint: `envy` (too subjective / visually
underdetermined) and `financial_fomo` (too rare in the image sample).

## Performance (tuned per-label thresholds)

Primary merged test (core + Kaggle partial, unchanged benchmark split):

| metric | value |
| --- | ---: |
| micro F1 | 0.6817 |
| macro F1 | 0.5126 |
| exact match | 0.2952 |
| label accuracy | 0.8684 |

Separate Karpathy COCO 500-image OOD holdout:

| metric | value |
| --- | ---: |
| micro F1 | 0.6526 |
| macro F1 | 0.3466 |
| exact match | 0.5480 |
| label accuracy | 0.9176 |

Report the two domains separately. Do not mix COCO numbers into the primary
Instagram-domain benchmark.

## Thresholds (tuned on validation split, shipped in `safesocial-model.json`)

| label | threshold |
| --- | ---: |
| romance_jealousy | 0.75 |
| social_fomo | 0.80 |
| luxury_status | 0.45 |
| travel_lifestyle | 0.70 |
| body_beauty_comparison | 0.35 |
| achievement_status | 0.90 |
| social_proof_popularity | 0.60 |
| exclusivity_access | 0.60 |
| none | 0.75 |
| uncertain | 1.00 |

These thresholds need human review before product claims, especially for rare
labels.

## Preprocessing

- `image_size`: 224, `resize`: 256, center crop
- color: RGB, layout NCHW
- normalize with ImageNet mean `[0.485, 0.456, 0.406]`, std `[0.229, 0.224, 0.225]`
- input name: `pixel_values`, output name: `probabilities`

## Training

- backbone: `timm/tf_efficientnet_lite0` (feature dim 1280, trained end to end)
- teacher: `qwen3.6-35b-a3b` via local vLLM, core reduced taxonomy
- data: core `kkcosmos/instagram-images-with-captions` (19,991 valid rows) + partial `prithvijaunjale/instagram-images-with-captions` (2,641 rows) = 22,632 merged rows, plus capped ~20% Karpathy COCO auxiliary (4,500 train rows), 20 epochs
- this checkpoint is the aux20 20-epoch EfficientNet-Lite0 run from `paper/core_20k_findings.md`

## Quick use (Python + onnxruntime)

```python
import json
import numpy as np
import onnxruntime as ort
from PIL import Image

manifest = json.load(open("safesocial-model.json"))
labels = manifest["labels"]
thresholds = manifest["label_thresholds"]

img = Image.open("photo.jpg").convert("RGB")
img = img.resize((256, 256))
w, h = img.size
img = img.crop(((w-224)//2, (h-224)//2, (w+224)//2, (h+224)//2))
x = np.asarray(img, dtype=np.float32) / 255.0
mean = np.array([0.485, 0.456, 0.406], np.float32)
std = np.array([0.229, 0.224, 0.225], np.float32)
x = (x - mean) / std
x = np.transpose(x, (2, 0, 1))[None]

sess = ort.InferenceSession("model.onnx", providers=["CPUExecutionProvider"])
probs = sess.run(None, {"pixel_values": x})[0][0]
print({l: float(p) for l, p in zip(labels, probs)})
print([l for l, p in zip(labels, probs) if p >= thresholds[l]])
```

Browser: ONNX Runtime Web (WebGPU/WASM). Mobile: ONNX Runtime React Native via
an Expo development build (Expo Go cannot run the native path); mock scores are
only a fallback. See the source repo `browser_extension/` and `mobile_app/`
prototypes.

## Limitations / data caveat

- Teacher-labeled test data measures agreement with the teacher, not human validity.
- `uncertain` had ~zero support in test splits.
- Public Instagram-style datasets often have unclear scraping/licensing histories: fine for exploratory research, but product training should prefer opt-in, licensed, or synthetic imagery.
- COCO/Flickr data is auxiliary out-of-domain robustness data, not primary benchmark evidence.
- Do not redistribute source Instagram/Kaggle/HF image files unless the source license explicitly allows it.
- No LICENSE file ships in the source repo at release time; confirm rights before commercial use.

## Source

Experiment details: `paper/core_20k_findings.md` in the SafeSocial repo. Model
export: `image_classifier/export_deployment_bundle.py`.


## License

This project is released under a **Private** license. For commercial licensing, integration inquiries, or permissions, please contact **WebBrain**.