def train(epoch, loss_vector_train, accuracy_vector_train ,log_interval=1000):
    model.train()
    train_loss, correct = 0, 0
    for batch_idx, (data, target) in enumerate(train_loader):
        if cuda:
            data, target = data.cuda(), target.cuda()
        data, target = Variable(data), Variable(target)
        optimizer.zero_grad()
        output = model(data)
        
        loss = F.nll_loss(output, target, weight=weights.cuda())
        train_loss += loss
        pred = output.data.max(1)[1]
        
        correct += pred.eq(target.data).cpu().sum()
        loss.backward()
        optimizer.step()
        
        if batch_idx % log_interval == 0:
            print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(
            epoch, batch_idx * len(data), len(train_loader.dataset),
            100. * batch_idx / len(train_loader), loss.data[0]))
            
        
    train_loss /= len(train_loader)
    loss_vector_train.append(train_loss)
    accuracy = 100. * correct / len(train_loader.dataset)
    accuracy_vector_train.append(accuracy)
    print(str(train_loss) + " " + str(accuracy))


def validate(loss_vector, accuracy_vector):
    model.eval()
    val_loss, correct = 0, 0
    confusion_matrix = torchnet.meter.ConfusionMeter(4)
    with torch.no_grad():
        for data, target in validation_loader:
            if cuda:
                data, target = data.cuda(), target.cuda()
            data, target = Variable(data), Variable(target)
            output = model(data)
            confusion_matrix.add(output.data, target.data)
            val_loss += F.nll_loss(output, target, weight=weights.cuda()).data[0]
            pred = output.data.max(1)[1] 
            correct += pred.eq(target.data).cpu().sum()

    val_loss /= len(validation_loader)
    loss_vector.append(val_loss)

    accuracy = 100. * correct / len(validation_loader.dataset)
    accuracy_vector.append(accuracy)
    cm = confusion_matrix.conf
    d = np.diag(cm)
    s = np.sum(cm,1)
    mean_class_acc = np.mean(d/s)
    print('\nValidation set: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format(
        val_loss, correct, len(validation_loader.dataset), accuracy))
    
    return mean_class_acc