def train(model, train_loader, eval_loader, num_epochs, output, opt, wd):
    utils.create_dir(output)
    if (opt == 'Adadelta'):
        optim = torch.optim.Adadelta(model.parameters(), rho=0.95, eps=1e-06, weight_decay=wd)
    elif (opt == 'RMSprop'):
        optim = torch.optim.RMSprop(model.parameters(), lr=0.01, alpha=0.99, eps=1e-08, weight_decay=wd, momentum=0, centered=False)
    elif (opt == 'Adam'):
        optim = torch.optim.Adam(model.parameters(), lr=0.001, betas=(0.9, 0.999), eps=1e-08, weight_decay=wd)
    else:
        optim = torch.optim.Adamax(model.parameters(), weight_decay=wd)
    logger = utils.Logger(os.path.join(output, 'log.txt'))
    best_eval_score = 0
    for epoch in range(num_epochs):
        total_loss = 0
        train_score = 0
        t = time.time()
        correct = 0
        for (i, (v, b, q, a)) in enumerate(train_loader):
            v = Variable(v).cuda()
            b = Variable(b).cuda()
            q = Variable(q).cuda()
            a = Variable(a).cuda()
            pred = model(v, b, q, a)
            loss = instance_bce_with_logits(pred, a)
            loss.backward()
            nn.utils.clip_grad_norm(model.parameters(), 0.25)
            optim.step()
            optim.zero_grad()
            batch_score = compute_score_with_logits(pred, a.data).sum()
            total_loss += (loss.data[0] * v.size(0))
            train_score += batch_score
        total_loss /= len(train_loader.dataset)
        train_score = ((100 * train_score) / len(train_loader.dataset))
        model.train(False)
        (eval_score, bound, V_loss) = evaluate(model, eval_loader)
        model.train(True)
        logger.write(('epoch %d, time: %.2f' % (epoch, (time.time() - t))))
        logger.write(('\ttrain_loss: %.3f, score: %.3f' % (total_loss, train_score)))
        logger.write(('\teval loss: %.3f, score: %.3f (%.3f)' % (V_loss, (100 * eval_score), (100 * bound))))
        if (eval_score > best_eval_score):
            model_path = os.path.join(output, 'model.pth')
            torch.save(model.state_dict(), model_path)
            best_eval_score = eval_score
def train(model, train_loader, eval_loader, num_epochs, output, opt, wd):
    utils.create_dir(output)
    if (opt == 'Adadelta'):
        optim = torch.optim.Adadelta(model.parameters(), rho=0.95, eps=1e-06, weight_decay=wd)
    elif (opt == 'RMSprop'):
        optim = torch.optim.RMSprop(model.parameters(), lr=0.01, alpha=0.99, eps=1e-08, weight_decay=wd, momentum=0, centered=False)
    elif (opt == 'Adam'):
        optim = torch.optim.Adam(model.parameters(), lr=0.001, betas=(0.9, 0.999), eps=1e-08, weight_decay=wd)
    else:
        optim = torch.optim.Adamax(model.parameters(), weight_decay=wd)
    logger = utils.Logger(os.path.join(output, 'log.txt'))
    best_eval_score = 0
    for epoch in range(num_epochs):
        total_loss = 0
        train_score = 0
        t = time.time()
        correct = 0
        for (i, (v, b, q, a)) in enumerate(train_loader):
            v = Variable(v).cuda()
            b = Variable(b).cuda()
            q = Variable(q).cuda()
            a = Variable(a).cuda()
            pred = model(v, b, q, a)
            loss = instance_bce_with_logits(pred, a)
            loss.backward()
            nn.utils.clip_grad_norm(model.parameters(), 0.25)
            optim.step()
            optim.zero_grad()
            batch_score = compute_score_with_logits(pred, a.data).sum()
            total_loss += (loss.data[0] * v.size(0))
            train_score += batch_score
        total_loss /= len(train_loader.dataset)
        train_score = ((100 * train_score) / len(train_loader.dataset))
        model.train(False)
        (eval_score, bound, V_loss) = evaluate(model, eval_loader)
        model.train(True)
        logger.write(('epoch %d, time: %.2f' % (epoch, (time.time() - t))))
        logger.write(('\ttrain_loss: %.3f, score: %.3f' % (total_loss, train_score)))
        logger.write(('\teval loss: %.3f, score: %.3f (%.3f)' % (V_loss, (100 * eval_score), (100 * bound))))
        if (eval_score > best_eval_score):
            model_path = os.path.join(output, 'model.pth')
            torch.save(model.state_dict(), model_path)
            best_eval_score = eval_score