0
$\begingroup$

I'm trying to do SMILES chemical representation prediction from a large dataset (Around 5M Samples) to teach it do predict another downstream task. The model's part responsible for generating the data is a decoder embedding layer that roughly looks like this:

self.decoder_embedding = nn.Embedding(len(tokenizer), hidden_size)
decoder_layer = nn.TransformerDecoderLayer(
    d_model=hidden_size,
    nhead=heads,
    dim_feedforward=hidden_size,
    dropout=dropout,
    batch_first=True,
    norm_first=True
)
self.decoder = nn.TransformerDecoder(decoder_layer, num_layers=2)
self.smiles_generation_head = nn.Linear(hidden_size, 125)

The inputs to the model includes smiles_tokens which have been randomly masked of shape [batch_size, 125] and a padding attention mask. The output is simply pretext_predictions of shape [batch_size, 125].

def mask_tokens(inputs, tokenizer, mask_prob=0.15):
    masked_inputs = inputs.clone()
    mask_token_id = tokenizer.mask_token_id

    # Mask a random selection of tokens
    random_mask = torch.rand(masked_inputs.shape) < mask_prob
    masked_inputs[random_mask] = mask_token_id

    return masked_inputs

masked_smiles_tokens = mask_tokens(non_share_smiles_tokens, tokenizer)

smiles_tokens = model(masked_smiles_tokens, *features)

When this is passed into the loss function, it starts at an incredibly high loss value (roughly 10K and above). When the batch size is increased, the loss value also doubles and sometimes triples to around 30K or above.

smiles_tokens = nn.ConstantPad1d(
    (0, 125 - smiles_tokens.shape[1]),
    0
)(smiles_tokens).float()
padding_mask = smiles_tokens != 0
loss = loss_fn(
    pretext_predictions[padding_mask],
    smiles_tokens[padding_mask],
)

This is the loss function definition:

def loss_fn(inputs, targets):
    ce_criterion = nn.CrossEntropyLoss(reduction='mean')
    ce_loss = ce_criterion(inputs, targets)
    return ce_loss

What is causing this high loss value? I tired normalizing my input features apart from the SMILES token indices and that doesn't seem to solve the issue. I noticed that when I create random tensors like this:

import torch
import torch.nn as nn
import random

# Example tensors (replace with your actual data)
predictions = torch.randn(16, 50).softmax(dim=1)
targets = torch.randint(0, 100, (16, 50)).float()
mask = torch.randint(0, 2, (16, 50))

# Create the loss function
loss_fn = nn.CrossEntropyLoss() 

# Calculate the loss
loss = loss_fn(predictions[mask], targets[mask])

print(loss)

It also result in huge loss values.

tensor(9981.9561)

My ultimate aim is a BCE task and the loss from BCE is very small (0 to 1) compared to the CE loss. This makes it difficult to asses whether the model is making any progress. What should I do? Do I simply just find another loss function? NLLLoss also doesn't seem to being doing well but CE Loss uses that under the hood so I'm guessing it stems from that?

Note: pretext_predictions are logits, and smiles_tokens are indices for the tokenizer vocabulary of size 37. The learning rate is 1e-3 using Adam and model size is only 5M parameters.

$\endgroup$

0

You must log in to answer this question.

Browse other questions tagged .