dejanai commited on
Commit
8e1fac4
·
verified ·
1 Parent(s): 5731a0d

7-level sentiment classifier on gemma-3-270m

Browse files
Files changed (7) hide show
  1. .gitattributes +1 -0
  2. NOTICE +1 -0
  3. README.md +96 -0
  4. config.json +80 -0
  5. model.safetensors +3 -0
  6. tokenizer.json +3 -0
  7. tokenizer_config.json +24 -0
.gitattributes CHANGED
@@ -33,3 +33,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ tokenizer.json filter=lfs diff=lfs merge=lfs -text
NOTICE ADDED
@@ -0,0 +1 @@
 
 
1
+ Gemma is provided under and subject to the Gemma Terms of Use found at ai.google.dev/gemma/terms
README.md ADDED
@@ -0,0 +1,96 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ license: gemma
3
+ base_model: google/gemma-3-270m
4
+ pipeline_tag: text-classification
5
+ language:
6
+ - en
7
+ tags:
8
+ - sentiment-analysis
9
+ - text-classification
10
+ - gemma3
11
+ - synthetic-data
12
+ metrics:
13
+ - accuracy
14
+ - f1
15
+ ---
16
+
17
+ # Gemma 3 270M: 7-level sentiment classifier
18
+
19
+ A fine-tune of [google/gemma-3-270m](https://huggingface.co/google/gemma-3-270m) (the base model, not the instruct version) with a classification head. It sorts a short piece of text (a sentence, heading, bullet point, or table row) into one of seven sentiment levels:
20
+
21
+ | id | label |
22
+ |---|---|
23
+ | 0 | very positive |
24
+ | 1 | positive |
25
+ | 2 | somewhat positive |
26
+ | 3 | neutral |
27
+ | 4 | somewhat negative |
28
+ | 5 | negative |
29
+ | 6 | very negative |
30
+
31
+ ## Results
32
+
33
+ On a held-out test set of 8,749 segments (from documents never seen in training):
34
+
35
+ | Metric | Score |
36
+ |---|---|
37
+ | Exact label | **84.0%** |
38
+ | Exact or one level off | **95.2%** |
39
+ | Macro-F1 | 0.833 |
40
+
41
+ | Label | F1 |
42
+ |---|---|
43
+ | very positive | 0.88 |
44
+ | positive | 0.80 |
45
+ | somewhat positive | 0.88 |
46
+ | neutral | 0.90 |
47
+ | somewhat negative | 0.70 |
48
+ | negative | 0.79 |
49
+ | very negative | 0.89 |
50
+
51
+ Most errors are one level off. The hardest boundary is "somewhat negative" versus "negative".
52
+
53
+ **Important:** the test set is synthetic and was labelled by the same process as the training data (see below). These scores measure agreement with that labelling. The model has not yet been evaluated on human-labelled, real-world text.
54
+
55
+ ## Usage
56
+
57
+ ```python
58
+ from transformers import pipeline
59
+
60
+ clf = pipeline("text-classification", model="dejanai/sentiment-classifier")
61
+ clf("Delivery took three weeks and nobody answered my emails.")
62
+ # [{'label': 'negative', 'score': 0.88}]
63
+ ```
64
+
65
+ Classify one sentence or short segment at a time. For a whole document, split it into sentences, headings, bullet points, and table rows first, and classify each. Inputs are truncated at 128 tokens.
66
+
67
+ ## Training data
68
+
69
+ About 83,000 labelled segments from 2,782 synthetic documents, made in three steps:
70
+
71
+ 1. **Writer:** Gemini 3.8 Flash wrote complete documents in 26 content formats (blog posts, product reviews, tweet threads, meeting notes, technical papers, press releases, support chats, YouTube and podcast transcripts, FAQ pages, and more). Topics were seeded mainly from products, services, brands, and invented people, with some general topics (parenting, politics, health, everyday life). People in the documents are fictional.
72
+ 2. **Segmenter:** a Python script split each document into its natural units, keeping structure: headings, bullet points, table rows, metadata lines (bylines, dates), code lines, and sentences.
73
+ 3. **Labeller:** a separate Gemini 3.8 Flash call labelled every segment, reading it in the context of the whole document.
74
+
75
+ Most documents mix tones; a further set was written with one dominant tone, to bring every non-neutral label up to about 10,900 segments. Neutral has about 17,800. Overused names and phrases were replaced with varied alternatives.
76
+
77
+ Splits are by document (80/10/10), so no document has segments in both training and test.
78
+
79
+ ## Training procedure
80
+
81
+ - Base: `google/gemma-3-270m`, `Gemma3TextForSequenceClassification` head, 7 labels
82
+ - Input embedding frozen; all other weights trained
83
+ - AdamW, learning rate 2e-5 with one-cycle schedule over 1.5 epochs, batch size 32, max length 128, bf16 autocast
84
+ - Cross-entropy weighted by inverse label frequency
85
+ - Validation every 100 steps; early stopping with patience 5. Stopped at step 2,600; the released checkpoint (lowest validation loss) is from step 2,100.
86
+
87
+ ## Limitations
88
+
89
+ - Trained and tested only on synthetic, model-written English text. Real reviews, social posts, and informal writing may score lower.
90
+ - Labels come from one model (Gemini 3.8 Flash), so its judgement and biases about sentiment strength are built in.
91
+ - Each segment is classified on its own. A sentence whose tone depends on what came before (for example "And yet…") may be misread.
92
+ - Neighbouring levels, especially "somewhat negative" and "negative", are often confused.
93
+
94
+ ## License
95
+
96
+ This model is a derivative of Gemma and is provided under and subject to the [Gemma Terms of Use](https://ai.google.dev/gemma/terms). Use must also follow the [Gemma Prohibited Use Policy](https://ai.google.dev/gemma/prohibited_use_policy).
config.json ADDED
@@ -0,0 +1,80 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "_sliding_window_pattern": 6,
3
+ "architectures": [
4
+ "Gemma3TextForSequenceClassification"
5
+ ],
6
+ "attention_bias": false,
7
+ "attention_dropout": 0.0,
8
+ "attn_logit_softcapping": null,
9
+ "bos_token_id": 2,
10
+ "dtype": "bfloat16",
11
+ "eos_token_id": 1,
12
+ "final_logit_softcapping": null,
13
+ "head_dim": 256,
14
+ "hidden_activation": "gelu_pytorch_tanh",
15
+ "hidden_size": 640,
16
+ "id2label": {
17
+ "0": "very positive",
18
+ "1": "positive",
19
+ "2": "somewhat positive",
20
+ "3": "neutral",
21
+ "4": "somewhat negative",
22
+ "5": "negative",
23
+ "6": "very negative"
24
+ },
25
+ "initializer_range": 0.02,
26
+ "intermediate_size": 2048,
27
+ "label2id": {
28
+ "very positive": 0,
29
+ "positive": 1,
30
+ "somewhat positive": 2,
31
+ "neutral": 3,
32
+ "somewhat negative": 4,
33
+ "negative": 5,
34
+ "very negative": 6
35
+ },
36
+ "layer_types": [
37
+ "sliding_attention",
38
+ "sliding_attention",
39
+ "sliding_attention",
40
+ "sliding_attention",
41
+ "sliding_attention",
42
+ "full_attention",
43
+ "sliding_attention",
44
+ "sliding_attention",
45
+ "sliding_attention",
46
+ "sliding_attention",
47
+ "sliding_attention",
48
+ "full_attention",
49
+ "sliding_attention",
50
+ "sliding_attention",
51
+ "sliding_attention",
52
+ "sliding_attention",
53
+ "sliding_attention",
54
+ "full_attention"
55
+ ],
56
+ "max_position_embeddings": 32768,
57
+ "model_type": "gemma3_text",
58
+ "num_attention_heads": 4,
59
+ "num_hidden_layers": 18,
60
+ "num_key_value_heads": 1,
61
+ "pad_token_id": 0,
62
+ "query_pre_attn_scalar": 256,
63
+ "rms_norm_eps": 1e-06,
64
+ "rope_parameters": {
65
+ "full_attention": {
66
+ "rope_theta": 1000000.0,
67
+ "rope_type": "default"
68
+ },
69
+ "sliding_attention": {
70
+ "rope_theta": 10000.0,
71
+ "rope_type": "default"
72
+ }
73
+ },
74
+ "sliding_window": 512,
75
+ "tie_word_embeddings": true,
76
+ "transformers_version": "5.5.0",
77
+ "use_bidirectional_attention": false,
78
+ "use_cache": true,
79
+ "vocab_size": 262144
80
+ }
model.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:f78047aff96b53e4675d97f3a0def8482a4ce7fb3d15df04cd7340a6a76c8ac4
3
+ size 536232096
tokenizer.json ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:ea32934d51349dfadb7bd02697c64fb740160bcc7a472c2aaca1f9d2df4768f7
3
+ size 33384819
tokenizer_config.json ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "backend": "tokenizers",
3
+ "boi_token": "<start_of_image>",
4
+ "bos_token": "<bos>",
5
+ "clean_up_tokenization_spaces": false,
6
+ "eoi_token": "<end_of_image>",
7
+ "eos_token": "<eos>",
8
+ "image_token": "<image_soft_token>",
9
+ "is_local": false,
10
+ "mask_token": "<mask>",
11
+ "model_max_length": 1000000000000000019884624838656,
12
+ "model_specific_special_tokens": {
13
+ "boi_token": "<start_of_image>",
14
+ "eoi_token": "<end_of_image>",
15
+ "image_token": "<image_soft_token>"
16
+ },
17
+ "pad_token": "<pad>",
18
+ "padding_side": "left",
19
+ "sp_model_kwargs": null,
20
+ "spaces_between_special_tokens": false,
21
+ "tokenizer_class": "GemmaTokenizer",
22
+ "unk_token": "<unk>",
23
+ "use_default_system_prompt": false
24
+ }