コード例 #1
0
def evaluate(data_loader, model, criterion, args):

    with torch.no_grad():

        model.eval()
        meter = VOCMApMetric(class_names=("normal", "smoke", "call"))
        total_loss, correct, total, tp, fp, tn, fn = 0, 0, 0, 0, 0, 0, 0

        for data in data_loader:
            image = data["image"].cuda()
            label = data["label"].cuda()

            if args.model == "wsdan":
                y_pred_raw, feature_matrix, attention_map = model(image)
                with torch.no_grad():
                    crop_images = batch_augment(image,
                                                attention_map[:, :1, :, :],
                                                mode='crop',
                                                theta=(0.4, 0.6),
                                                padding_ratio=0.1)
                y_pred_crop, _, _ = model(crop_images)
                loss = (criterion(y_pred_raw, label) +
                        criterion(y_pred_crop, label)) / 2
                predict = (y_pred_raw + y_pred_crop) / 2

            else:
                predict = model(image)
                loss = criterion(predict, label)

            predict = softmax(predict, dim=-1)
            pred_labels = torch.argmax(predict, dim=-1)
            pred_bboxes = torch.ones((pred_labels.size(0), 1, 4))
            gt_bboxes = torch.ones((pred_labels.size(0), 1, 4))
            meter.update(pred_bboxes.cpu().numpy(),
                         pred_labels.cpu().numpy(),
                         predict.cpu().numpy(),
                         gt_bboxes.cpu().numpy(),
                         label.cpu().numpy())

            _, predict = predict.max(1)
            total_loss += loss
            total += label.size(0)
            correct += predict.eq(label).sum().item()
            tp += torch.sum(predict & label)
            fp += torch.sum(predict & (1 - label))
            tn += torch.sum((1 - predict) & (1 - label))
            fn += torch.sum((1 - predict) & label)

        loss = total_loss / len(data_loader)
        acc = float(correct) / float(total)
        precision = (float(tp) + 1e-6) / (float(tp + fp) + 1e-3)
        recall = (float(tp) + 1e-6) / (float(tp + fn) + 1e-3)
        m_ap_normal, m_ap_smoke, m_ap_calling, m_ap = meter.get()[1]
        print("mAP = %.3f, mAP_n = %.3f, mAP_s = %.3f, mAP_c = %.3f, "
              "loss = %.3f, acc = %.3f, p = %.3f, r = %.3f"
              "" % (m_ap, m_ap_normal, m_ap_smoke, m_ap_calling, loss, acc,
                    precision, recall))

    return m_ap, acc, precision, recall, loss
コード例 #2
0
def test(data_loader, model, ckp_path, args):

    with torch.no_grad():

        optimizer = torch.optim.Adagrad(model.parameters())
        model = load_model(model, optimizer, ckp_path)
        model.eval()

        outputs = []
        idx_to_name = ['normal', 'smoking', 'calling']

        for i, data in tqdm(enumerate(data_loader), total=len(data_loader)):

            image = data["image"].cuda()
            name = data["name"]

            if args.model == "wsdan":
                y_pred_raw, _, attention_map = model(image)
                with torch.no_grad():
                    crop_images = batch_augment(image,
                                                attention_map[:, :1, :, :],
                                                mode='crop',
                                                theta=(0.4, 0.6),
                                                padding_ratio=0.1)
                y_pred_crop, _, _ = model(crop_images)
                output = (y_pred_raw + y_pred_crop) / 2

            else:
                output = model(image)
            output = softmax(output, dim=-1)

            for j in range(image.size(0)):

                idx = torch.argmax(output[j, :])
                category = idx_to_name[idx]
                score = output[j, idx]

                outputs.append({
                    "category": category,
                    "image_name": name[j],
                    "score": round(float(score), 5)
                })

    outputs.sort(key=lambda x: int(x['image_name'].split('.')[0]))
    with open("./log/result.json", "w+") as f:
        json.dump(outputs, f, indent=4)

    print("Done.")
    return 0
コード例 #3
0
ファイル: eval.py プロジェクト: oahzxl/DianSmokeCall
def evaluate(test_loader_, epoch_, model_):
    model_.eval()
    test_loss, correct, total, tp, fp, tn, fn = 0, 0, 0, 0, 0, 0, 0
    criterion = torch.nn.CrossEntropyLoss()

    # print(len(test_loader))
    for data_ in tqdm(test_loader_):
        try:
            image_ = data_["image"].cuda()
            label_ = data_["label"].cuda()
        except OSError:
            # print("OSError of image. ")
            continue

        y_pred_raw, _, attention_map = model_(image_)
        crop_images = batch_augment(image_,
                                    attention_map,
                                    mode='crop',
                                    theta=0.1,
                                    padding_ratio=0.05)
        y_pred_crop, _, _ = model_(crop_images)
        y_pred = (y_pred_raw + y_pred_crop) / 2.

        loss_ = criterion(y_pred, label_)
        test_loss += loss_.item()

        _, predict = y_pred.max(1)
        total += label_.size(0)
        correct += predict.eq(label_).sum().item()
        tp += torch.sum(predict & label_)
        fp += torch.sum(predict & (1 - label_))
        tn += torch.sum((1 - predict) & (1 - label_))
        fn += torch.sum((1 - predict) & label_)
    acc = 100. * correct / total
    precision = 100.0 * tp / float(tp + fp)
    recall = 100.0 * tp / float(tp + fn)
    print(
        "==> [evaluate] epoch {}, loss = {}, acc = {}, precision = {}, recall = {}"
        .format(epoch_, test_loss, acc, precision, recall))
    return acc, precision, recall
コード例 #4
0
def evl(model, train_loader, eval_loader, args):

    with torch.no_grad():

        optimizer = torch.optim.Adagrad(model.parameters())
        model = load_model(model, optimizer, args.ckp_path)
        model.eval()
        criterion = torch.nn.CrossEntropyLoss()
        meter = VOCMApMetric(class_names=("normal", "smoke", "call"))
        total_loss, correct, total, tp, fp, tn, fn = 0, 0, 0, 0, 0, 0, 0
        bad_true = []
        bad_false = []

        for data_loader in [train_loader, eval_loader]:
            for data in data_loader:
                image = data["image"].cuda()
                label = data["label"].cuda()
                name = data["name"]

                if args.model == "wsdan":
                    y_pred_raw, feature_matrix, attention_map = model(image)
                    with torch.no_grad():
                        crop_images = batch_augment(image,
                                                    attention_map[:, :1, :, :],
                                                    mode='crop',
                                                    theta=(0.4, 0.6),
                                                    padding_ratio=0.1)
                    y_pred_crop, _, _ = model(crop_images)
                    loss = (criterion(y_pred_raw, label) +
                            criterion(y_pred_crop, label)) / 2
                    predict = (y_pred_raw + y_pred_crop) / 2
                else:
                    predict = model(image)
                    loss = criterion(predict, label)

                predict = softmax(predict, dim=-1)
                pred_labels = torch.argmax(predict, dim=-1)
                pred_bboxes = torch.ones((pred_labels.size(0), 1, 4))
                gt_bboxes = torch.ones((pred_labels.size(0), 1, 4))
                meter.update(pred_bboxes.cpu().numpy(),
                             pred_labels.cpu().numpy(),
                             predict.cpu().numpy(),
                             gt_bboxes.cpu().numpy(),
                             label.cpu().numpy())

                score = predict
                _, predict = predict.max(1)

                for j in range(predict.size(0)):
                    if predict[j] == label[j]:
                        bad_true.append((name[j], score[j,
                                                        predict[j]], label[j]))
                    else:
                        bad_false.append(
                            (name[j], score[j, predict[j]], label[j]))

                total_loss += loss
                total += label.size(0)
                correct += predict.eq(label).sum().item()
                tp += torch.sum(predict & label)
                fp += torch.sum(predict & (1 - label))
                tn += torch.sum((1 - predict) & (1 - label))
                fn += torch.sum((1 - predict) & label)

            loss = total_loss / len(data_loader)
            acc = float(correct) / float(total)
            precision = (float(tp) + 1e-6) / (float(tp + fp) + 1e-3)
            recall = (float(tp) + 1e-6) / (float(tp + fn) + 1e-3)
            m_ap_normal, m_ap_smoke, m_ap_calling, m_ap = meter.get()[1]
            print("mAP = %.3f, mAP_n = %.3f, mAP_s = %.3f, mAP_c = %.3f, "
                  "loss = %.3f, acc = %.3f, p = %.3f, r = %.3f"
                  "" % (m_ap, m_ap_normal, m_ap_smoke, m_ap_calling, loss, acc,
                        precision, recall))

    return m_ap, acc, precision, recall, loss
コード例 #5
0
def train(model, train_loader, eval_loader, args):

    model.train()
    print("Start training")
    writer = SummaryWriter(log_dir=args.save_path)

    criterion = nn.CrossEntropyLoss()
    # criterion = LabelSmoothCELoss()
    # criterion = WeightedLabelSmoothCELoss(1978, 2168, 1227)

    fc_params = list(map(id, model.fc.parameters()))
    # fc_params += list(map(id, model.ca.parameters()))
    # fc_params += list(map(id, model.sa.parameters()))
    base_params = filter(lambda p: id(p) not in fc_params, model.parameters())
    if args.optim == 'Adam':
        optimizer = optim.Adam([
            {'params': base_params, 'lr': args.lr / 10},
            {'params': model.fc.parameters()},
            # {'params': model.ca.parameters()},
            # {'params': model.sa.parameters()}
            # {'params': model.parameters()}
        ], lr=args.lr)
    elif args.optim == 'SGD':
        optimizer = optim.SGD([{'params': base_params, 'lr': args.lr / 10},
                               {'params': model.fc.parameters()}], lr=args.lr, momentum=0.9)
    else:
        raise ValueError

    if args.sche == 'reduce':
        scheduler = optim.lr_scheduler.ReduceLROnPlateau(optimizer, 'max', factor=args.factor, patience=args.patience)
    elif args.sche == 'cos':
        scheduler = optim.lr_scheduler.CosineAnnealingWarmRestarts(optimizer, T_0=args.t0, T_mult=args.tm)
    elif args.sche == 'None':
        scheduler = None
    else:
        raise ValueError

    global_step, best_map, loss, t_remain, best_loss = 0, 0, 0, 0, 999.0

    for epoch in range(0, args.num_epochs, 1):
        running_loss = 0.0
        t = time.time()

        for i, data in enumerate(tqdm(train_loader)):
            image = data["image"].cuda()
            label = data["label"].cuda()

            optimizer.zero_grad()

            if args.model == "wsdan":
                y_pred_raw, feature_matrix, attention_map = model(image)
                with torch.no_grad():
                    crop_images = batch_augment(image, attention_map[:, :1, :, :], mode='crop', theta=(0.4, 0.6),
                                                padding_ratio=0.1)
                y_pred_crop, _, _ = model(crop_images)
                loss = (criterion(y_pred_raw, label) + criterion(y_pred_crop, label)) / 2
            else:
                predict = model(image)
                loss = criterion(predict, label)
            running_loss += loss.item()

            loss.backward()
            optimizer.step()

            if args.sche == 'cos':
                scheduler.step(epoch + i / len(train_loader))

            if i % args.print_interval == 0 and i != 0:
                batch_time = (time.time() - t) / args.print_interval / args.batch_size
                running_loss = running_loss / args.print_interval
                print("==> [train] epoch = %2d, batch = %4d, global_step = %4d, loss = %.2f, "
                      "time per picture = %.2fs" % (epoch, i, global_step, running_loss, batch_time))
                writer.add_scalar("scalar/loss", running_loss, global_step, time.time())
                running_loss = 0.0
                t = time.time()
            global_step += 1

        print("[train] epoch = %2d, loss = %.4f, lr = %.1e, time per picture = %.2fs, remaining time = %s"
              % (epoch + 1, running_loss / len(train_loader), optimizer.state_dict()['param_groups'][0]['lr'],
                 (time.time() - t) / len(train_loader) / args.batch_size,
                 sec2time((time.time() - t_remain) * (args.num_epochs - epoch - 1)) if t_remain != 0 else '-1'))
        t_remain = time.time()

        print("[eval train] ", end='')
        map_on_train, acc_on_train, precision_on_train, recall_on_train, loss_on_train = evaluate(
            train_loader, model, criterion, args)
        print("[eval valid] ", end='')
        map_on_valid, acc_on_valid, precision_on_valid, recall_on_valid, loss_on_valid = evaluate(
            eval_loader, model, criterion, args)

        if args.sche == 'reduce':
            # scheduler.step(loss_on_valid)  # ReduceLR
            scheduler.step(map_on_valid)  # ReduceLR

        writer.add_scalar("scalar/loss_on_train", loss_on_train, global_step, time.time())
        writer.add_scalar("scalar/loss_on_valid", loss_on_valid, global_step, time.time())
        writer.add_scalar("scalar/mAP_on_train", map_on_train, global_step, time.time())
        writer.add_scalar("scalar/mAP_on_valid", map_on_valid, global_step, time.time())
        writer.add_scalar("scalar/accuracy_on_train", acc_on_train, global_step, time.time())
        writer.add_scalar("scalar/accuracy_on_valid", acc_on_valid, global_step, time.time())
        writer.add_scalar("scalar/precision_on_train", precision_on_train, global_step, time.time())
        writer.add_scalar("scalar/precision_on_valid", precision_on_valid, global_step, time.time())
        writer.add_scalar("scalar/recall_on_train", recall_on_train, global_step, time.time())
        writer.add_scalar("scalar/recall_on_valid", recall_on_valid, global_step, time.time())

        if loss_on_valid < best_loss:
            best_loss = loss_on_valid
            print("==> [best] loss: %.5f" % best_loss)
        if float(loss_on_valid) < 0.16:
            torch.save({
                "model_state_dict": model.state_dict(),
            }, os.path.join(args.save_path, args.model + "_loss_%.5f" % best_loss + ".tar"))

        if map_on_valid > best_map:
            best_map = map_on_valid
            print("==> [best] mAP: %.5f" % best_map)
        if float(map_on_valid) > 0.93:
            torch.save({
                "model_state_dict": model.state_dict(),
            }, os.path.join(args.save_path, args.model + "_mAP_%.5f" % best_map + ".tar"))

    writer.close()
    print("Done.")
コード例 #6
0
ファイル: train.py プロジェクト: oahzxl/DianSmokeCall
def train(model, train_loader, eval_loader, cfg):
    model.train()
    print("Start training")
    writer = SummaryWriter(log_dir=cfg.log_path)

    criterion = torch.nn.CrossEntropyLoss()
    optimizer = torch.optim.Adam(model.parameters(),
                                 lr=0.0001,
                                 weight_decay=0.0005,
                                 amsgrad=True)
    current_epoch = 0
    global_step = 0
    loss = 0
    if cfg.load_ckp:
        model, optimizer, current_epoch, global_step, loss = load_model(
            model, optimizer, cfg.ckp_path)

    # feature_center = torch.zeros(2, cfg_.num_attentions * model_.num_features)
    # center_loss = CenterLoss()

    for epoch in range(current_epoch, cfg.NUM_EPOCHS, 1):
        running_loss = 0.0
        t = time()
        for i, data in enumerate(tqdm(train_loader)):
            if i == len(train_loader) - 1:
                break
            try:
                image = data["image"].cuda()
                label = data["label"].cuda()
            except OSError:
                print("OSError of image. ")
                continue
            optimizer.zero_grad()
            y_pred_raw, feature_matrix, attention_map = model(image)
            '''
            # Update Feature Center            
            feature_center_batch = torch.nn.functional.normalize(feature_center[label], dim=-1)
            print(feature_center[label].shape, feature_matrix.detach().shape, feature_center_batch.shape)
            feature_center_batch[label] += cfg.beta * (feature_matrix.detach() - feature_center_batch)
            '''

            # Attention Cropping
            with torch.no_grad():
                crop_images = batch_augment(image,
                                            attention_map[:, :1, :, :],
                                            mode='crop',
                                            theta=(0.4, 0.6),
                                            padding_ratio=0.1)

            # crop images forward
            y_pred_crop, _, _ = model(crop_images)
            '''
            # Attention Dropping
            with torch.no_grad():
                drop_images = batch_augment(image, attention_map[:, 1:, :, :], mode='drop', theta=(0.2, 0.5))

            # drop images forward
            y_pred_drop, _, _ = model(drop_images)
            '''

            loss = criterion(y_pred_raw, label) / 3. + \
                criterion(y_pred_crop, label) / 3
            #   criterion(y_pred_drop, label) / 3. + \
            #   0 center_loss(feature_matrix, feature_center_batch)

            # print(loss)
            loss.backward()
            optimizer.step()

            running_loss += loss.item()
            if i % cfg.print_interval == 0:
                batch_time = time() - t
                print(
                    "==> [train] epoch {}, batch {}, global_step {}. loss for 10 batches: {}, "
                    "time for 10 batches: {}s".format(epoch, i, global_step,
                                                      running_loss,
                                                      batch_time))
                writer.add_scalar("scalar/loss", running_loss, global_step,
                                  time())
                running_loss = 0.0
                t = time()
            global_step += 1
        # TODO add save condition eg. acc

        if epoch % cfg.evaluate_epoch == 0:
            torch.save(
                {
                    "epoch": epoch,
                    "model_state_dict": model.state_dict(),
                    "optimizer_state_dict": optimizer.state_dict(),
                    "global_step": global_step,
                    'loss': loss,
                },
                os.path.join(cfg.save_path,
                             "train_epoch_" + str(epoch) + ".tar"))
            print("==> [eval] on train dataset")
            acc_on_train, precision_on_train, recall_on_train = evaluate(
                train_loader, epoch, model)
            print("==> [eval] on valid dataset")
            acc_on_valid, precision_on_valid, recall_on_valid = evaluate(
                eval_loader, epoch, model)
            writer.add_scalar("scalar/accuracy_on_train", acc_on_train,
                              global_step, time())
            writer.add_scalar("scalar/accuracy_on_valid", acc_on_valid,
                              global_step, time())
            writer.add_scalar("scalar/precision_on_train", precision_on_train,
                              global_step, time())
            writer.add_scalar("scalar/precision_on_valid", precision_on_valid,
                              global_step, time())
            writer.add_scalar("scalar/recall_on_train", recall_on_train,
                              global_step, time())
            writer.add_scalar("scalar/recall_on_valid", recall_on_valid,
                              global_step, time())

    writer.close()
    print("Finish training.")