Whats the equivalent of tf.nn.softmax_cross_entropy_with_logits in pytorch?
I was trying to replicate a code ,which was written in tensorflow ,with pytorch. I came across a loss function in tensorflow, softmax_cross_entropy_with_logits.I was looking for an equivalent of it in pytorch and i found torch.nn.MultiLabelSoftMarginLoss,though im not quite sure it is the right function.Also i dont know how to measure the accuracy of my model when i use this loss function and no relu layer at the end of the network here is my code :


# GRADED FUNCTION: compute_cost 

def compute_cost(Z3, Y):

    loss = torch.nn.MultiLabelSoftMarginLoss()    
    return loss(Z3,Y)


def model(net,X_train, y_train, X_test, y_test, learning_rate = 0.009,
          num_epochs = 100, minibatch_size = 64, print_cost = True):

    optimizer = torch.optim.Adam(net.parameters(), lr=learning_rate)
    optimizer.zero_grad()

    total_train_acc=0

    for epoch in range(num_epochs):
        for i, data in enumerate(train_loader, 0):
            running_loss = 0.0

            inputs, labels = data

            inputs, labels = Variable(inputs), Variable(labels)

            Z3 = net(inputs)

            # Cost function
            cost = compute_cost(Z3, labels)

            # Backpropagation: Define the optimizer. 
            # Use an AdamOptimizer that minimizes the cost.

            cost.backward()
            optimizer.step()             

            running_loss += cost.item()

            # Measuring the accuracy of minibatch
            acc = (labels==Z3).sum()
            total_train_acc += acc.item()
            #Print every 10th batch of an epoch
            if epoch%1 == 0:
            print("Cost after epoch {} : 
            {:.3f}".format(epoch,running_loss/len(train_loader)))


Use torch.nn.CrossEntropyLoss(). It combines both softmax and cross-entropy. From documentation:


  This criterion combines nn.LogSoftmax() and nn.NLLLoss() in one single class.


Example: 

# define loss function
loss_fn = torch.nn.CrossEntropyLoss(reduction='mean')

# during training
for (x, y) in train_loader:
    model.train()
    y_pred = model(x) # your input `torch.FloatTensor`
    loss_val = loss_fn(y_pred, y)
    print(loss_val.item()) # prints numpy value

    optimizer.zero_grad()
    loss_val.backward()
    optimizer.step()


Make sure that the types of x and y are correct. Usually the conversion is done like this: loss_fn(y_pred.type(torch.FloatTensor), y.type(torch.LongTensor)).

To measure accuracy you can define a custom function:

def compute_accuracy(y_pred, y):
   if list(y_pred.size()) != list(y.size()):
      raise ValueError('Inputs have different shapes.',
                       list(y_pred.size()), 'and', list(y.size()))

  result = [1 if y1==y2 else 0 for y1, y2 in zip(y_pred, y)]

  return sum(result) / len(result)


And use both like this:

model.train()
y_pred = model(x)

loss_val = loss_fn(y_pred.type(torch.FloatTensor), y.type(torch.LongTensor))
_, y_pred = torch.max(y_pred, 1)
accuracy_val = compute_accuracy(y_pred, y)
print(loss_val.item()) # print loss value
print(accuracy_val) # print accuracy value
# update step e.t.c


If your input data is one-hot encoded you can convert it to regular encoding before you use loss_fn:

_, targets = y.max(dim=1)
y_pred = model(x)
loss_val = loss_fn(y_pred, targets)

