andefined commited on
Commit
2acb489
·
verified ·
1 Parent(s): fd55846

Upload fine_tune_classifier.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. fine_tune_classifier.py +166 -0
fine_tune_classifier.py ADDED
@@ -0,0 +1,166 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # fine_tune_classifier.py
2
+ import os
3
+ import pandas as pd
4
+
5
+ from datasets import Dataset, DatasetDict, ClassLabel
6
+ from transformers import AutoTokenizer, AutoModelForSequenceClassification, Trainer, TrainingArguments
7
+ from sklearn.metrics import accuracy_score, f1_score
8
+
9
+ import torch
10
+
11
+ # --- 1. Configuration ---
12
+ DATA_FILE = "df.csv"
13
+
14
+ MODEL_NAME = "mediawatch-el-climate"
15
+ MODEL_CHECKPOINT = os.getenv("MODEL_CHECKPOINT", "cvcio/roberta-el-news")
16
+ OUTPUT_DIR = MODEL_NAME + "/" + MODEL_CHECKPOINT.replace("/", "-") + "-finetuned"
17
+
18
+ NUM_EPOCHS = 4
19
+ BATCH_SIZE = 64
20
+
21
+ # --- 2. Load and Prepare the Dataset ---
22
+ print("Step 2: Loading and preparing the dataset...")
23
+
24
+ # Load your data from the CSV file
25
+ df = pd.read_csv(DATA_FILE)
26
+
27
+ # Ensure the columns are named 'text' and 'label'
28
+ df = df.rename(columns={'text': 'text', 'label': 'label'})
29
+ df = df.dropna(subset=['text', 'label']).reset_index(drop=True)
30
+
31
+ # Convert the pandas DataFrame to a Hugging Face Dataset
32
+ dataset = Dataset.from_pandas(df)
33
+
34
+ # Get the list of unique labels
35
+ unique_labels = df['label'].unique().tolist()
36
+
37
+ # Create label-to-ID and ID-to-label mappings
38
+ label2id = {label: i for i, label in enumerate(unique_labels)}
39
+ id2label = {i: label for i, label in enumerate(unique_labels)}
40
+
41
+ num_labels = len(unique_labels)
42
+ print(f"Found {num_labels} unique labels: {unique_labels}")
43
+
44
+ # Create a ClassLabel feature to map string labels to integer IDs
45
+ class_label_feature = ClassLabel(names=unique_labels)
46
+
47
+ # Map string labels to integer IDs
48
+ def map_labels(example):
49
+ example['label'] = class_label_feature.str2int(example['label'])
50
+ return example
51
+
52
+
53
+ dataset = dataset.map(map_labels, batched=True)
54
+ dataset = dataset.class_encode_column("label")
55
+
56
+ # Split the dataset into training (80%) and testing (20%) sets
57
+ train_test_split = dataset.train_test_split(test_size=0.2) ## , stratify_by_column="label")
58
+
59
+ # Create a DatasetDict
60
+ raw_datasets = DatasetDict({
61
+ 'train': train_test_split['train'],
62
+ 'test': train_test_split['test']
63
+ })
64
+
65
+ print("Dataset prepared and split.")
66
+ print(raw_datasets)
67
+
68
+
69
+ # --- 3. Tokenization ---
70
+ print("\nStep 3: Tokenizing the text data...")
71
+
72
+ # Load the tokenizer associated with the pre-trained model
73
+ tokenizer = AutoTokenizer.from_pretrained(MODEL_CHECKPOINT,model_max_length=512)
74
+
75
+ # Create a function to tokenize the text
76
+ def tokenize_function(examples):
77
+ return tokenizer(examples["text"], padding="max_length", truncation=True)
78
+
79
+ # Apply the tokenization to the entire dataset
80
+ tokenized_datasets = raw_datasets.map(tokenize_function, batched=True)
81
+
82
+ print("Tokenization complete.")
83
+
84
+ # --- 4. Model Training ---
85
+ print("\nStep 4: Setting up and training the model...")
86
+
87
+ # Load the pre-trained model, configured for our number of labels
88
+ model = AutoModelForSequenceClassification.from_pretrained(
89
+ MODEL_CHECKPOINT,
90
+ num_labels=num_labels,
91
+ id2label=id2label, # Pass the mappings to the model
92
+ label2id=label2id,
93
+ max_length=512,
94
+ )
95
+
96
+ # Define a function to compute metrics during evaluation
97
+ def compute_metrics(eval_pred):
98
+ logits, labels = eval_pred
99
+ predictions = logits.argmax(axis=-1)
100
+ return {
101
+ "accuracy": accuracy_score(labels, predictions),
102
+ "f1_weighted": f1_score(labels, predictions, average="weighted"),
103
+ }
104
+
105
+ # Define the training arguments
106
+ training_args = TrainingArguments(
107
+ output_dir=OUTPUT_DIR,
108
+ num_train_epochs=NUM_EPOCHS,
109
+ per_device_train_batch_size=BATCH_SIZE,
110
+ per_device_eval_batch_size=BATCH_SIZE,
111
+ warmup_steps=50,
112
+ weight_decay=0.01,
113
+ logging_dir='./logs',
114
+ logging_steps=10,
115
+ eval_strategy="epoch", # Evaluate at the end of each epoch
116
+ save_strategy="epoch", # Save the model at the end of each epoch
117
+ load_best_model_at_end=True, # Load the best model found during training
118
+ )
119
+
120
+ # Create the Trainer instance
121
+ trainer = Trainer(
122
+ model=model,
123
+ args=training_args,
124
+ train_dataset=tokenized_datasets["train"],
125
+ eval_dataset=tokenized_datasets["test"],
126
+ compute_metrics=compute_metrics,
127
+ tokenizer=tokenizer,
128
+ )
129
+
130
+ # Start the training
131
+ print("Starting training...")
132
+ trainer.train()
133
+ print("Training finished.")
134
+
135
+ # Save the final model and tokenizer
136
+ trainer.save_model(OUTPUT_DIR)
137
+ print(f"Model saved to {OUTPUT_DIR}")
138
+
139
+
140
+ # --- 5. Example Prediction ---
141
+ print("\nStep 5: Running an example prediction...")
142
+
143
+ # # The trainer saves the label mapping in the model's config
144
+ # id2label = model.config.id2label
145
+
146
+ # Text to classify
147
+ new_text = "Λειψυδρία: Σε ανησυχητικό επίπεδο η στάθμη του νερού σε Πηνειό και Μόρνο – Καμπανάκι ΕΥΔΑΠ για τα αποθέματα : Έχουμε λιγότερο από τα μισά του 2019"
148
+
149
+ # Tokenize the new text
150
+ inputs = tokenizer(new_text, return_tensors="pt")
151
+
152
+ # Move inputs to the same device as the model
153
+ device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
154
+ model.to(device)
155
+ inputs = {k: v.to(device) for k, v in inputs.items()}
156
+
157
+ # Get predictions
158
+ with torch.no_grad():
159
+ logits = model(**inputs).logits
160
+
161
+ # Find the label with the highest probability
162
+ predicted_class_id = logits.argmax().item()
163
+ predicted_label = id2label[predicted_class_id]
164
+
165
+ print(f"\nText: '{new_text}'")
166
+ print(f"Predicted Label: {predicted_label}")