I’m trying to train a generator model M_gen
whose output serves as input for a classifier model M_cls
. However, M_cls
is also trained with additional data that doesn’t come from M_gen
. To handle this, I combine both datasets into a single DataLoader
. The issue is that M_gen
doesn’t seem to be training properly, the evaluation metric avg_f1
remains the same across all epochs. This is my code to train M_gen
:
while epoch <= num_epochs:
for phase in ['train', 'val']:
print(phase + "-Phase")
if phase == 'train':
model.train() # Set model to training mode
dataloader = train_dataloader
else:
model.eval() # Set model to evaluate mode
dataloader = val_dataloader
generated_data_list = []
for idx, inputs in tqdm(enumerate(dataloader), total=len(dataloader)):
inputs = inputs.to(device).float()
regression_output, classification_output = model(inputs)
generated_data_list.append((regression_output, classification_output))
f1 = main_M_cls.main(seed=2025, generated_data_list=generated_data_list)
loss = torch.tensor(100-(f1*100), requires_grad=True, device=device)
if phase == 'train':
optimizer.zero_grad()
loss.backward()
optimizer.step()
In main_M_cls.main() I merge the samples from M_gen
and the additional data saved in train_dataset
dataset2 = [(x1, y1) for (regression_output, classification_output) in generated_data_list for x1, y1 in zip(regression_output, classification_output)]
train_merged_dataset = ConcatDataset([train_dataset, dataset2])
train_loader = DataLoader(train_merged_dataset, batch_size=batch_size, shuffle=True)
Then I start the training and evaluation of M_cls
:
for epoch in range(3):
train_loss, val_loss = [], []
# Start Training
model.train()
for i, (sample, label) in tqdm(enumerate(train_loader), total=len(train_loader)):
sample = sample.to(device=device)
label = label.to(device=device)
output = model(sample)
loss = criterion(output, label)
optimizer.zero_grad()
loss.backward(retain_graph=True)
optimizer.step()
running_val_loss = 0
# Start Validation
model.eval()
true_labels, pred_labels = [], []
for i, (sample, label) in enumerate(val_loader):
sample = sample.to(device=device, dtype=torch.float)
label = label.to(device=device, dtype=torch.long)
output = model(sample)
loss = criterion(output, label)
true_labels.append(vote_label.detach().cpu().numpy())
pred_labels.append(output.detach().cpu().numpy())
y_true = np.concatenate(true_labels, axis=0)
y_prob = np.concatenate(pred_labels, axis=0)
y_pred = np.argmax(y_prob, axis=1)
val_f1 = f1_score(y_true, y_pred, average='macro') # this function comes from sklearn.metrics
return val_f1
I first thought that the f1-Score might be a problem, because the computation graph might not be able to compute and backpropagate the gradients, since the f1-Score is a Python scaler. However, I also tested my code by using the validation loss instead of f1-Score but still, the model M_gen
is not learning anything, the losses for M_gen
are always the same.
I appreciate any help or suggestions. Thanks in advance!