15import matplotlib.pyplot
as plt
17import sklearn.metrics
as skl
19from matplotlib
import use
22print(
"Loading dataframes...")
23data_dir = ROOT.gROOT.GetTutorialDir().Data() +
"/machine_learning/data/"
24df_train =
ROOT.RDataFrame(
"tree", data_dir +
"ml_dataloader_Higgs_Classification_train.root")
25df_val =
ROOT.RDataFrame(
"tree", data_dir +
"ml_dataloader_Higgs_Classification_val.root")
26df_test =
ROOT.RDataFrame(
"tree", data_dir +
"ml_dataloader_Higgs_Classification_test.root")
30class Classifier(nn.Module):
34 hidden_layers: list[int],
36 use_dropout: bool =
False,
37 use_batchnorm: bool =
True,
44 for out_dim
in hidden_layers:
45 block = [nn.Linear(in_dim, out_dim)]
48 block.append(nn.BatchNorm1d(out_dim))
50 block.append(nn.ReLU())
53 block.append(nn.Dropout(p))
55 layers.append(nn.Sequential(*block))
58 self.hidden = nn.Sequential(*layers)
59 self.output_layer = nn.Linear(in_dim, 1)
63 x = self.output_layer(x)
64 return torch.sigmoid(x)
68batches_in_memory = 1000
70columns = [
"m4l",
"good_lep",
"goodlep_E",
"goodlep_eta",
"goodlep_phi",
"goodlep_pt",
"goodlep_type",
"isHiggsRef"]
72max_vec_sizes = {
"good_lep": 4,
"goodlep_E": 4,
"goodlep_eta": 4,
"goodlep_phi": 4,
"goodlep_pt": 4,
"goodlep_type": 4}
77print(
"Normalizing data...")
78for var
in columns[:-1]:
80 mean = df_train.Mean(var).GetValue()
81 stddev = df_train.StdDev(var).GetValue()
82 df_train = df_train.Redefine(var, f
"({var} - {mean}) / {stddev}")
85 df_val = df_val.Redefine(var, f
"({var} - {mean}) / {stddev}")
86 df_test = df_test.Redefine(var, f
"({var} - {mean}) / {stddev}")
91 for i
in range(max_vec_sizes[var]):
92 scalar_column = f
"{var}_{i}"
93 df_train = df_train.Define(scalar_column, f
"{var}[{i}]")
94 means.append(df_train.Mean(scalar_column).GetValue())
95 stddevs.append(df_train.StdDev(scalar_column).GetValue())
98 for i
in range(
len(stddevs)):
101 expr =
", ".join(f
"(({var}[{i}] - {means[i]}) / {stddevs[i]})" for i
in range(max_vec_sizes[var]))
102 df_train = df_train.Redefine(var, f
"ROOT::RVec<double>{{{expr}}}")
105 df_val = df_val.Redefine(var, f
"ROOT::RVec<double>{{{expr}}}")
106 df_test = df_test.Redefine(var, f
"ROOT::RVec<double>{{{expr}}}")
108print(
"Creating dataloaders...")
109train = ROOT.Experimental.ML.RDataLoader(
111 batch_size=batch_size,
112 batches_in_memory=batches_in_memory,
113 drop_remainder=drop_remainder,
116 max_vec_sizes=max_vec_sizes,
120val = ROOT.Experimental.ML.RDataLoader(
122 batch_size=batch_size,
123 batches_in_memory=batches_in_memory,
124 drop_remainder=drop_remainder,
127 max_vec_sizes=max_vec_sizes,
131test = ROOT.Experimental.ML.RDataLoader(
133 batch_size=batch_size,
134 batches_in_memory=batches_in_memory,
135 drop_remainder=drop_remainder,
138 max_vec_sizes=max_vec_sizes,
145num_features =
sum(max_vec_sizes.values()) +
len([0
for i
in train.train_columns
if i
not in max_vec_sizes])
147torch.manual_seed(set_seed)
148hidden_layers = [60, 60]
149model = Classifier(num_features=num_features, hidden_layers=hidden_layers, p=0.2, use_dropout=
False)
150loss_fn = nn.BCELoss()
151optimizer = torch.optim.SGD(model.parameters(), lr=0.01, momentum=0.9)
154def print_epoch_summary(epoch: int, val_loss: float, val_accuracy: float):
155 print(f
"Epoch {epoch} summary ==> Validation loss: {val_loss:.2f}; Validation accuracy: {val_accuracy:.2f}")
159last_val_losses = [float(
"inf")] * 6
162print(
"Starting training...")
163for epoch
in range(epochs):
167 for i, (x_train, y_train)
in enumerate(train.as_torch()):
168 outputs = model(x_train)
169 loss = loss_fn(outputs, y_train)
171 optimizer.zero_grad()
181 with torch.no_grad():
182 for j, (x_val, y_val)
in enumerate(val.as_torch()):
183 outputs = model(x_val)
184 loss = loss_fn(outputs, y_val)
185 val_loss += loss.item()
187 preds = (outputs > 0.5).float()
188 val_correct += (preds == y_val).
sum().item()
189 val_total += y_val.size(0)
191 avg_val_loss = val_loss / (j + 1)
192 avg_val_losses.append(avg_val_loss)
193 val_accuracy = val_correct / val_total
196 print_epoch_summary(epoch + 1, val_loss, val_accuracy)
197 del last_val_losses[0]
198 last_val_losses.append(avg_val_loss)
200 if min(last_val_losses[-3:]) > max(last_val_losses[:3]):
201 print(f
"Validation loss has not improved for 6 epochs, stopping training after {epoch + 1} epochs.")
214 for j, (x_test, y_test)
in enumerate(test.as_torch()):
215 outputs = model(x_test)
216 loss = loss_fn(outputs, y_test)
217 test_loss += loss.item()
218 test_preds += outputs.tolist()
219 test_true += y_test.tolist()
221 preds = (outputs > 0.5).float()
222 test_correct += (preds == y_test).
sum().item()
223 test_total += y_test.size(0)
225avg_test_loss = test_loss / (j + 1)
226test_accuracy = test_correct / test_total
228print(f
"Testing Loss: {avg_test_loss:.4f} Accuracy: {test_accuracy:.4f}\n")
235ax.plot([i
for i
in range(epochs)], avg_val_losses)
236plt.title(
"Loss curve")
238plt.ylabel(
"Validation loss")
239plt.savefig(
"loss_curve")
240print(
"Loss curve saved to loss_curve.png")
242fpr, tpr, thresholds = skl.roc_curve(test_true, test_preds)
245ax.plot(fpr[:-1], tpr[:-1])
246plt.title(
"ROC curve")
247plt.xlabel(
"False positive rate")
248plt.ylabel(
"True positive rate")
249plt.savefig(
"ROC_curve")
250print(
"ROC curve saved to ROC_curve.png")
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t UChar_t len
ROOT's RDataFrame offers a modern, high-level interface for analysis of data stored in TTree ,...
A "std::vector"-like collection of values implementing handy operation to analyse them.
static uint64_t sum(uint64_t i)