I’m trying to create a textual classifier. The goal is to categorize different sentences of a wikipedia page into a set of classes. I have 4 different classes which I named “other”,“eats”,“habitat” and “lifespan”. I was wondering how these labels can be turned into integers. I have a word to index dictionary that maps each word in my training wikipedia text to a unique index. Should I encode the labels with the same word to index dictionary or can I just label them 0,1,2,3( which is what I’m currently doing) . The problem I’m facing with this scheme is that my loss becomes NAN after an epoch. I’m not sure if the labeling is the problem it’s just a hunch. Please tell me if I am going wrong anywhere else.
I believe just labelling them 0,1,2,3 is the typical approach.
What do you use for the last model layer, and what loss function do you use?
In the literature models for classification typically use a softmax layer as the last layer together with cross-entropy loss. In PyTorch this can be achieved in two ways.
Use nn.LogSoftmax for the last layer together with nn.NLLLoss. But, in this case you must transform your target values into one-hot format. Label 0 would be represented by the vector [1,0,0,0], label 1 would be represented by [0,1,0,0], etc…
Simply use nn.CrossEntropyLoss without the nn.LogSoftmax layer and provide target values as 0, 1, 2, 3.
If that is correct, then the next thing to try is to reduce the learning rate. Though that might simply delay the loss becoming NaN.
If that fails then I wouldn’t know what to suggest without seeing any code.
def __init__(self):
super(CNN,self).__init__()
self.voacb_size=5304
self.batch_size=1
self.num_filters=3
self.word_embed=torch.load("word2vec.pkl")
self.in_channel=1
self.filter_sizes=[1,2,3]
self.embedding_length=200
self.number_classes=4
self.embed = nn.Embedding(self.voacb_size + 1, self.embedding_length)
#self.embed.weight.data.copy_(torch.from_numpy(self.word_embed.weight.data))
#self.embed.weight.requires_grad=False
self.conv1=nn.ModuleList([nn.Conv2d(in_channels=self.in_channel,out_channels=self.num_filters,kernel_size=(x,self.embedding_length)) for x in self.filter_sizes])
self.dropout=nn.Dropout(p=0.5)
self.fc=nn.Linear(self.num_filters*len(self.filter_sizes),self.number_classes)
def forward(self,input_x):
x = self.embed(input_x)
x=x.unsqueeze(1)
x = [F.relu(conv(x)).squeeze(3) for conv in self.conv1]
x = [F.max_pool1d(i, i.size(2)).squeeze(2) for i in x]
x = torch.cat(x, 1)
x = self.dropout(x) # (batch_size,len(kernel_sizes)*num_kernels)
logit = self.fc(x) # (batch_size, num_aspects)
return logit
This is what I’m doing I believe that I am using the cross_entropy loss as my loss function. The loss function is defined in my train function. Please let me know if you want to have a look at it.
I can’t see anything obviously wrong with it. Assuming your input data is properly cleaned, then I guess there must be some latent numerical instability in your model, though I can’t see where.
What would I need to do in cleaning the data, my vocabulary is pretty small and I have a corresponding unique index for each word. Is there anything else that I need to be doing? Also, the surprising thing is that the loss grows from 500 to a really big value in 3 epochs and then starts returning NaN.