So, I'm having a problem with the validation of a model, in particular, I'm trying a linear readoff (a logistic regression attached to a middle layer of a neural network)
In particular, if I train the linear-readoff on the training set, and evaluate on the validation set, i get I higher accuracy than training it in the validation set, and evaluating in the validation set
However, to me this makes little sense, as theoretically speaking, the loss of the log-regression is convex, thus the accuracy training it on the validation set itself, should be the best one
the code that I'm using to validate it is the following, and I can't see why this is happening:
# val set forward
val_data_ = []
val_targets_ = []
for k,val_data in enumerate(tqdm(val_dataloader, desc="val epoch")):
val_img = val_data[0].to(device)
idx = val_data[2]
output = torch.zeros((val_img.size(0), ))
for i in range(len(sex_target)):
output[i] = 0 if idx[i] in some_set else 1
val_output_batch = classifier(val_feature_batch)
val_data_.append(val_feature_batch.cpu().detach().numpy())
val_targets_.append(output.cpu().detach().numpy())
# train set forward
data_ = []
targets_ = []
with torch.no_grad():
for m,data in enumerate(tqdm(train_dataloader, desc="train for val epoch")):
img = data[0].to(device)
output = torch.zeros((img.size(0), ))
for i in range(len(sex_target)):
output[i] = 0 if idx[i] in some_other_set else 1
data_.append(model(img))
targets_.append(output)
data_ = np.concatenate([el.cpu().numpy() for el in data_], axis=0).astype(float)
targets_ = np.concatenate([el.cpu().numpy() for el in targets_], axis=0).astype(float)
val_data_ = np.concatenate(val_data_, axis=0).astype(float)
val_targets_ = np.concatenate(val_targets_, axis=0).astype(float)
val_clf = LogisticRegression(solver="newton-cholesky").fit(val_data_, val_targets_)
train_clf = LogisticRegression(solver="newton-cholesky").fit(data_, targets_)
val_fair_from_train = balanced_accuracy_score(val_targets_, train_clf.predict(val_data_))
val_fair_from_val = balanced_accuracy_score(val_targets_, val_clf.predict(val_data_))
# val_fair_from_train is most of the times higher than val_fair_from_val