1import json
2import numpy as np
3import os
4import pickle
5from IPython.display import clear_output
6import pandas as pd
7import tensorflow as tf
8import transformers
9from datasets import load_dataset
10from sklearn.metrics import confusion_matrix, classification_report
11from sklearn.model_selection import train_test_split
12from transformers import DistilBertTokenizer, TFDistilBertForSequenceClassification
13import warnings
14
15# Silence all warnings
16warnings.filterwarnings("ignore")
17
18
19# Try to create a directory named "models"
20try:
21 os.makedirs("models")
22except:
23 # If the directory already exists or if there's an error, do nothing (pass)
24 pass
25
26# Try to create a directory named "results"
27try:
28 os.makedirs("results")
29except:
30 # If the directory already exists or if there's an error, do nothing (pass)
31 pass
32
33# Try to create a directory named "history"
34try:
35 os.makedirs("history")
36except:
37 # If the directory already exists or if there's an error, do nothing (pass)
38 pass
39
40
41# Flag to determine if existing models and histories should be overwritten
42overwrite = True
43
44# Load dataset for the first fold
45data = load_dataset("raicrits/fever_folds", data_files="folds_en/1.json")['train']
46test = data['test'][0]
47val_set = data['val'][0]
48train_set = data['train'][0]
49
50# Define paths for model, results, and history
51model_path = 'models/DistilFEVERen_weights_0.h5'
52results_path = "results/DistilFEVERen_0.json"
53history_path = 'history/DistilFEVERen_0.pickle'
54
55# Load the tokenizer
56tokenizer = DistilBertTokenizer.from_pretrained('distilbert-base-multilingual-cased')
57
58# Preprocess the data
59test_encodings = tokenizer(test['text'], test['claim'], truncation=True, padding=True, max_length=256, return_tensors='tf')
60test_labels = tf.convert_to_tensor(test['label'])
61
62train_encodings = tokenizer(train_set['text'], train_set['claim'], truncation=True, padding=True, return_tensors='tf')
63val_encodings = tokenizer(val_set['text'], val_set['claim'], truncation=True, padding=True, return_tensors='tf')
64
65train_labels = tf.convert_to_tensor(train_set['label'])
66val_labels = tf.convert_to_tensor(val_set['label'])
67
68# Check if the model and history already exist for the first fold
69if not overwrite and os.path.exists(model_path):
70 print("Model and history already exist for fold {}. Loading...".format(0))
71 model = TFDistilBertForSequenceClassification.from_pretrained('distilbert-base-multilingual-cased', num_labels=3)
72 model.load_weights(model_path)
73 # with open(history_path, 'rb') as file_pi:
74 # history = pickle.load(file_pi)
75else:
76 # Create a new model and define loss, optimizer, and callbacks
77 model = TFDistilBertForSequenceClassification.from_pretrained('distilbert-base-multilingual-cased', num_labels=3)
78 loss = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True)
79 optimizer = tf.keras.optimizers.Adam(learning_rate=5e-5)
80 model.compile(optimizer=optimizer, loss=loss, metrics=['accuracy'])
81 model_checkpoint = tf.keras.callbacks.ModelCheckpoint(
82 model_path,
83 monitor='val_loss',
84 save_best_only=True,
85 mode='min',
86 save_weights_only=True
87 )
88 early_stopping = tf.keras.callbacks.EarlyStopping(
89 monitor='val_loss',
90 patience=1,
91 mode='min',
92 restore_best_weights=True
93 )
94
95 # Train the model for the first fold
96 clear_output(wait=True)
97 history = model.fit(
98 [train_encodings['input_ids'], train_encodings['attention_mask']], train_labels,
99 validation_data=([val_encodings['input_ids'], val_encodings['attention_mask']], val_labels),
100 batch_size=10,
101 epochs=100,
102 callbacks=[early_stopping, model_checkpoint]
103 )
104
105 # Save the training history
106 with open(history_path, 'wb') as file_pi:
107 pickle.dump(history.history, file_pi)