Hello, I want to classificate isolated music notes.
My dataset has the shape: input[252, seq_len], target[88, seq_len]
Dataset is normalized.
How seq_len is different for each note, I had to create my custom collate_fn:
def music_collate_fn(batch):
data = np.zeros((252 , 0), dtype=np.float)
target = np.zeros((88,0), dtype=np.int)
for item in batch:
data = np.concatenate((data, item[0]), axis=1)
target = np.concatenate((target, item[1]), axis = 1)
#to tensor
data = torch.from_numpy(data).float()
target = torch.from_numpy(target).float()
#Transpose
data = data.t()
target = target.t()
#Cuda
data = data.to(device)
target = target.to(device)
return data, target
The target is a binary classification. I have 88 musical notes. If a note is the number 0, I have 1 in the row 0 As many times as input data represents the note 0. If the note is the number 77, I have a 1 in the row 77. I think I am in the correct way. For example, target of note 0 before concatenate is like:
trainSet[0][1]
array([[1, 1, 1, ..., 1, 1, 1],
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
...,
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0]])
I am trying to calculate loss in my program:
Train code:
mlp = rn.MLP(input_dim, hidden_dim, output_dim).to(device)
optimizer = torch.optim.SGD(mlp.parameters(), lr = 0.001, momentum=0.5)
def train(model, train_loader, optimizer, criterion):
model.train()
temp_loss = []
i = 0
for batch_idx, (input,target) in enumerate(train_loader):
outputs = model(input)
loss = criterion(outputs, target)
temp_loss.append(loss.item())
optimizer.zero_grad() #Gradientes a cero
loss.backward() #Back propagation
optimizer.step() #Actualizar parámetros.
i +=1
if(i % 5):
print('----------TRAIN--------------PERDIDA: ', loss)
print("Loss: {}".format(np.mean(temp_loss)))
return temp_loss
The test code is:
def test( model, test_loader, optimizer, criterion):
model.eval()
test_loss = 0
correct = 0
temp_loss = []
i=0
with torch.no_grad():
for data, target in test_loader:
outputs = model(data)
loss = criterion(outputs, target)
temp_loss.append(loss.item())
if(i == 3):
print('\n----------TEST--------------\nPERDIDA: ', loss.item())
i = 0
pred = outputs.data.max(1, keepdim=True)[1]
target = target.data.max(1,keepdim = True)[1]
correct += pred.eq(target).sum()
i += 1
print('\nTest set: Avg. loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format(
loss, correct, target.shape[0],
correct / target.shape[0]))
return temp_loss
I am trying to calculate accuracy, but prediction is always a low value, like 0,0001%. So the model never learn.
Furthermore, I am ussing F.binary_cross_entropy instead nn.BCELoss, because is the only way to have results. If I use nn.CrossEntropyLoss, the problem returned is:
File "<ipython-input-9-5c699a4fd8ff>", line 1, in <module>
losses += train(mlp, train_loader, optimizer, criterion)
File "<ipython-input-7-072d93cf4aa0>", line 9, in train
loss = criterion(outputs, target)
File "C:\ProgramData\Anaconda3\lib\site-packages\torch\nn\modules\loss.py", line 898, in __init__
super(CrossEntropyLoss, self).__init__(weight, size_average, reduce, reduction)
File "C:\ProgramData\Anaconda3\lib\site-packages\torch\nn\modules\loss.py", line 23, in __init__
super(_WeightedLoss, self).__init__(size_average, reduce, reduction)
File "C:\ProgramData\Anaconda3\lib\site-packages\torch\nn\modules\loss.py", line 16, in __init__
self.reduction = _Reduction.legacy_get_string(size_average, reduce)
File "C:\ProgramData\Anaconda3\lib\site-packages\torch\nn\_reduction.py", line 42, in legacy_get_string
if size_average and reduce:
RuntimeError: bool value of Tensor with more than one value is ambiguous