File size: 3,773 Bytes
59b54d3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import os
import pandas as pd
import torch
from sklearn.model_selection import train_test_split
from transformers import (
    AutoTokenizer, 
    AutoModelForSequenceClassification, 
    TrainingArguments, 
    Trainer,
    DataCollatorWithPadding
)
from datasets import Dataset

# 1. Configuration (Updated for Kaggle)
# Change DATA_PATH to point to your uploaded dataset in Kaggle Inputs
DATA_PATH = "/kaggle/input/goemotions-mapped/goemotions_mapped.csv" 
MODEL_NAME = "distilbert-base-uncased"
OUTPUT_DIR = "./sentiment_model_trained"
LOG_DIR = "./logs"

# Label mapping (Must match the Mood Music Hub system)
EMOTION_MAP = {
    'Neutral': 0,
    'Happy': 1,
    'Sad': 2,
    'Angry': 3,
    'Fearful': 4
}
ID_TO_EMOTION = {v: k for k, v in EMOTION_MAP.items()}

def train():
    print(f">>> πŸš€ Starting Kaggle Training Pipeline for {MODEL_NAME}...")
    
    # Check for GPU
    device = "cuda" if torch.cuda.is_available() else "cpu"
    print(f">>> πŸ’» Training Device: {device.upper()}")

    # 2. Load and Prepare Data
    if not os.path.exists(DATA_PATH):
        print(f"!!! Error: Dataset not found at {DATA_PATH}. Make sure to add the CSV to Kaggle Inputs.")
        return

    df = pd.read_csv(DATA_PATH)
    print(f">>> πŸ“Š Dataset loaded: {len(df)} rows.")

    df['label'] = df['emotion'].map(EMOTION_MAP)
    df = df.dropna(subset=['label'])
    df['label'] = df['label'].astype(int)

    # Split data (85% Train, 15% Eval)
    train_df, val_df = train_test_split(df, test_size=0.15, random_state=42, stratify=df['label'])
    
    train_dataset = Dataset.from_pandas(train_df)
    val_dataset = Dataset.from_pandas(val_df)

    # 3. Tokenization
    tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME)

    def tokenize_func(examples):
        return tokenizer(examples['text'], truncation=True, padding=True, max_length=128)

    print(">>> πŸ”€ Tokenizing dataset...")
    train_dataset = train_dataset.map(tokenize_func, batched=True)
    val_dataset = val_dataset.map(tokenize_func, batched=True)

    # 4. Model Initialization
    model = AutoModelForSequenceClassification.from_pretrained(
        MODEL_NAME, 
        num_labels=len(EMOTION_MAP),
        id2label=ID_TO_EMOTION,
        label2id=EMOTION_MAP
    ).to(device)

    # 5. Training Arguments (Optimized for Kaggle GPU)
    training_args = TrainingArguments(
        output_dir="./results",
        num_train_epochs=3,
        per_device_train_batch_size=16 if device == "cuda" else 8,
        per_device_eval_batch_size=16 if device == "cuda" else 8,
        warmup_steps=500,
        weight_decay=0.01,
        logging_dir=LOG_DIR,
        logging_steps=50,
        eval_strategy="epoch",
        save_strategy="epoch",
        load_best_model_at_end=True,
        metric_for_best_model="eval_loss",
        fp16=True if device == "cuda" else False, # Mixed precision for faster GPU training
        report_to="none"
    )

    data_collator = DataCollatorWithPadding(tokenizer=tokenizer)

    # 6. Trainer API
    trainer = Trainer(
        model=model,
        args=training_args,
        train_dataset=train_dataset,
        eval_dataset=val_dataset,
        tokenizer=tokenizer,
        data_collator=data_collator
    )

    # 7. Execute Training
    print(">>> πŸ‹οΈ Training model...")
    trainer.train()

    # 8. Save Final Model
    print(f">>> πŸ’Ύ Saving best model to {OUTPUT_DIR}...")
    trainer.save_model(OUTPUT_DIR)
    tokenizer.save_pretrained(OUTPUT_DIR)
    
    # 9. ZIP the output (Easy to download from Kaggle)
    import shutil
    shutil.make_archive("sentiment_model_ready", 'zip', OUTPUT_DIR)
    print(">>> βœ… ZIP Archive created: sentiment_model_ready.zip")
    print(">>> πŸŽ‰ Training Complete!")

if __name__ == "__main__":
    train()