Ejemplo n.º 1
0
def plot_physics_model():
    distance = np.linspace(10, 1600)

    train_dataset, valid_dataset, test_dataset = dataset_factory()

    num_features = train_dataset.features.shape[1] + 1
    image_size = [256, 256]
    out_channels = [120, 60, 12, 6, 1]
    channels = 3
    rsrp_mu = train_dataset.target_mu
    rsrp_std = train_dataset.target_std
    model = SkynetModel(channels,
                        num_features,
                        image_size,
                        out_channels,
                        rsrp_mu=rsrp_mu,
                        rsrp_std=rsrp_std)

    P_811 = model.PhysicsModel(distance, torch.tensor(0.811), offset=18)
    P_811_unnorm = P_811.numpy() * rsrp_std + rsrp_mu
    P_2630 = model.PhysicsModel(distance, torch.tensor(2.630), offset=0)
    P_2630_unnorm = P_2630.numpy() * rsrp_std + rsrp_mu

    mse_2630, mse_2630_norm = model.MSE_physicsmodel(train_dataset.distances,
                                                     train_dataset.targets)
    print("MSE of 2630 MHz {}".format(mse_2630.numpy()))
    print("MSE of 2630 MHz {} (normalized)".format(mse_2630_norm.numpy()))

    with plt.style.context('seaborn'):
        fig = plt.figure(figsize=(6, 4))
        plt.plot(
            train_dataset.distances[train_dataset.features[:, 7] == 1] * 1000,
            train_dataset.targets_unnorm[train_dataset.features[:, 7] == 1],
            'o',
            label='Measurements 2630 MHz',
            markersize=3)
        plt.plot(
            train_dataset.distances[train_dataset.features[:, 7] != 1] * 1000,
            train_dataset.targets_unnorm[train_dataset.features[:, 7] != 1],
            'o',
            label='Measurements 811 MHz',
            markersize=3)

        plt.plot(distance.numpy(), P_811_unnorm[0, :], label='UMa 811 MHz')
        plt.plot(distance.numpy(), P_2630_unnorm[0, :], label='UMa 2630 MHz')
        plt.xlabel('Distance [m]')
        plt.ylabel('RSRP [dBm]')
        plt.legend()
        plt.savefig("plots/rsrp_uma_measurements.eps")
        plt.show()
        plt.tight_layout()
Ejemplo n.º 2
0
def run(args):

    args.cuda = not args.no_cuda and torch.cuda.is_available()

    if args.cuda:
        torch.cuda.empty_cache()

    torch.manual_seed(args.seed)
    if args.cuda:
        print('CUDA enabled')
        torch.cuda.manual_seed(args.seed)

    if not args.model_mode == 'features-only':
        args.use_images = True
        print("Using images.")
    else:
        args.use_images = False

    if args.no_data_augment:
        transform = False
    else:
        transform = True
        print("Using data augmentation")

    num_workers = 4

    # Load data
    train_dataset, test_dataset = dataset_factory(
        use_images=args.use_images,
        transform=transform,
        data_augment_angle=args.data_augmentation_angle
    )  # No image folder means loading from hdf5 file
    train_loader = torch.utils.data.DataLoader(train_dataset,
                                               batch_size=args.batch_size,
                                               shuffle=True,
                                               num_workers=num_workers,
                                               drop_last=True)
    test_loader = torch.utils.data.DataLoader(test_dataset,
                                              batch_size=args.batch_size,
                                              num_workers=num_workers,
                                              drop_last=False,
                                              shuffle=False)

    # Instansiate model
    args.num_features = train_dataset.features.shape[1] + 1
    args.image_size = [256, 256]
    args.out_channels = [int(args.out_channels_l1), 100, 50, 25, 12, 1]
    args.kernel_size = [(5, 5), (3, 3), (3, 3), (3, 3), (2, 2), (2, 2)]
    args.nn_layers = [200, 200]
    args.channels = 1

    rsrp_mu = train_dataset.target_mu
    rsrp_std = train_dataset.target_std

    model = SkynetModel(args, rsrp_mu=rsrp_mu, rsrp_std=rsrp_std)
    if args.cuda:
        model.cuda()

    # Define loss function, optimizer and LR scheduler
    criterion = nn.MSELoss()
    optimizer = optim.Adam(model.parameters(),
                           lr=args.lr,
                           weight_decay=args.weight_decay)
    scheduler_model = lr_scheduler.ReduceLROnPlateau(optimizer, patience=5)

    # Training loop
    train_loss = []
    test_loss = []

    def train(epoch):
        # Called by the loop
        trainloss = 0
        with tqdm(total=len(train_loader)) as pbar:
            for idx, (feature, image, target, dist) in enumerate(train_loader):
                if args.cuda:
                    image = image.cuda()
                    feature = feature.cuda()
                    target = target.cuda()
                    dist = dist.cuda()

                optimizer.zero_grad()

                output, sum_output = model(feature, image, dist)

                loss = criterion(sum_output, target)
                loss.backward()
                trainloss += loss.item()
                optimizer.step()
                pbar.update(1)

            train_loss.append(trainloss / idx)

        pbar.close()

    def test(epoch):
        # Called by the loop
        testloss = 0
        with torch.no_grad():
            with tqdm(total=len(test_loader)) as pbar:
                for idx, (feature, image, target,
                          dist) in enumerate(test_loader):
                    if args.cuda:
                        image = image.cuda()
                        feature = feature.cuda()
                        target = target.cuda()
                        dist = dist.cuda()

                    output, sum_output = model(feature, image, dist)

                    loss = criterion(sum_output, target)
                    testloss += loss.item()
                    pbar.update(1)

                test_loss.append(testloss / idx)
            pbar.close()

    for epoch in range(args.epochs):
        model.train()
        train(epoch)
        model.eval()
        test(epoch)
        scheduler_model.step(test_loss[-1])
        print("Epoch: {}, train_loss: {}, test_loss: {}".format(
            epoch, train_loss[-1], test_loss[-1]))

        if optimizer.param_groups[0]['lr'] < 1e-7:
            print('Learning rate too low. Early stopping.')
            break

    exp = Experiment('file', config=args.__dict__, root_folder='exps/')
    results_dict = dict()
    results_dict['train_loss'] = train_loss
    results_dict['test_loss'] = test_loss
    exp.results = results_dict
    exp.save()

    torch.save(
        model.state_dict(), exp.root_folder +
        '/models/{}_model_{:.3f}.pt'.format(exp.id, test_loss[-1]))
Ejemplo n.º 3
0
        ImageList(
            root=args.image_root_path, fileList=args.image_validate_list,
            transform=transforms.Compose(
                [transforms.Resize(
                     size=(args.crop_size, args.crop_size)),
                 transforms.ToTensor(), 
                 ])
            ),
        batch_size=args.validate_batch_size, shuffle=False, **kwargs
        )
'''

test_path = '/home/leolau/pytorch/data'  #just for test, when parameter confirm this might delete
dataset_f = dataset_factory(args.dataset,
                            args.batch_size,
                            args.validate_batch_size,
                            kwargs,
                            root_path=test_path)
train_loader = dataset_f.train_loader
validate_loader = dataset_f.validate_loader

optimizer = optim.SGD(filter(lambda p: p.requires_grad, model.parameters()),
                      lr=args.lr,
                      weight_decay=args.weight_decay,
                      momentum=args.momentum,
                      nesterov=True)
# optimizer = optim.Adam(
#    filter(
#        lambda p: p.requires_grad,
#        model.parameters()),
#    lr=args.lr,
Ejemplo n.º 4
0
def run(args):
    cuda = not args.no_cuda and torch.cuda.is_available()

    if cuda:
        torch.cuda.empty_cache()

    torch.manual_seed(args.seed)
    if cuda:
        print('CUDA enabled')
        torch.cuda.manual_seed(args.seed)

    # Load data

    # Load experiment

    exp_root_path = args.exp_folder + "/"

    exp = load_experiment(args.name, root_path=exp_root_path)
    name = args.name
    args = edict(exp.config)
    args.name = name
    args.cuda = cuda
    args.data_augmentation_angle = 20
    # compatibility
    if not 'offset_811' in args:
        args.offset_811 = 18

    if not 'offset_2630' in args:
        args.offset_2630 = 0

    train_dataset, test_dataset = dataset_factory(
        use_images=args.use_images,
        use_hdf5=True,
        transform=True,
        data_augment_angle=args.data_augmentation_angle)
    train_loader = torch.utils.data.DataLoader(train_dataset,
                                               batch_size=args.batch_size,
                                               shuffle=True,
                                               num_workers=0,
                                               drop_last=True)
    test_loader = torch.utils.data.DataLoader(test_dataset,
                                              batch_size=args.batch_size,
                                              num_workers=0,
                                              drop_last=False,
                                              shuffle=False)
    print(len(test_loader))

    rsrp_mu = train_dataset.target_mu
    rsrp_std = train_dataset.target_std

    model = SkynetModel(args, rsrp_mu=rsrp_mu, rsrp_std=rsrp_std)

    if args.cuda:
        model.cuda()

    # Find model name
    list_of_files = os.listdir('{}models/'.format(
        exp_root_path))  #list of files in the current directory
    for each_file in list_of_files:
        if each_file.startswith(args.name):
            name = each_file

    model.load_state_dict(torch.load('{}models/{}'.format(exp_root_path,
                                                          name)))
    model.eval()
    criterion = nn.MSELoss()
    MSE_loss_batch = 0
    with torch.no_grad():
        for idx, (feature, image, target, dist) in enumerate(test_loader):
            if args.cuda:
                image = image.cuda()
                feature = feature.cuda()
                target = target.cuda()
                dist = dist.cuda()

            correction_, sum_output_ = model(feature, image, dist)
            P = model.predict_physicals_model(feature, dist)

            MSE_loss_batch += criterion(sum_output_, target)
            try:
                p = torch.cat([p, P], 0)
            except:
                p = P

            try:
                correction = torch.cat([correction, correction_], 0)
            except:
                correction = correction_

            try:
                sum_output = torch.cat([sum_output, sum_output_], 0)
            except:
                sum_output = sum_output_

            try:
                features = torch.cat([features, feature], 0)
            except:
                features = feature

    # Check if folder with name in results exist
    results_folder_path = 'results/{}'.format(args.name)
    if not os.path.exists(results_folder_path):
        os.mkdir(results_folder_path)

    # Store predictions
    np.save(results_folder_path + "/correction.npy", correction)
    np.save(results_folder_path + "/sum_output.npy", sum_output)
    np.save(results_folder_path + "/pathloss_model.npy", P)
def run(args):
    cuda = not args.no_cuda and torch.cuda.is_available()


    

    if cuda:
        torch.cuda.empty_cache()

    torch.manual_seed(args.seed)
    if cuda:
        print('CUDA enabled')
        torch.cuda.manual_seed(args.seed)


    # Load data

    # Load experiment

    exp_root_path = args.exp_folder+"/"

    exp = load_experiment(args.name, root_path = exp_root_path)
    name = args.name
    args = edict(exp.config)
    args.name = name
    args.cuda = cuda
    args.data_augmentation_angle = 20
    
    # compatibility 
    if not 'offset_811' in args:
        args.offset_811 = 18
    
    if not 'offset_2630' in args:
        args.offset_2630 = 0
    
    train_dataset, test_dataset = dataset_factory(use_images=args.use_images, transform=True, data_augment_angle=args.data_augmentation_angle)
    train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=args.batch_size, shuffle=True, num_workers=0, drop_last=True)
    test_loader = torch.utils.data.DataLoader(test_dataset, batch_size=args.batch_size, num_workers=0, drop_last=False, shuffle=False)
    print(len(test_loader))


    rsrp_mu = train_dataset.target_mu
    rsrp_std = train_dataset.target_std
   

    model = SkynetModel(args, rsrp_mu = rsrp_mu, rsrp_std = rsrp_std)
 
    if args.cuda:
        model.cuda()

    # Find model name
    list_of_files = os.listdir('{}models/'.format(exp_root_path)) #list of files in the current directory
    for each_file in list_of_files:
        if each_file.startswith(args.name):  
            name = each_file

    print(name)
            

    model.load_state_dict(torch.load('{}models/{}'.format(exp_root_path, name)))
    model.eval()
    criterion = nn.MSELoss()
    MSE_loss_batch = 0
    with torch.no_grad():
        for idx, (feature, image, target, dist) in enumerate(test_loader):
            if args.cuda:
                image = image.cuda()
                feature = feature.cuda()
                target = target.cuda()
                dist = dist.cuda()
            I = image
            for block in model.ImageModel.blocks:
                I = block(I)
                print(I.shape)
Ejemplo n.º 6
0
def run(args):
    opt = DotDict(args)
    torch.manual_seed(opt.seed)

    if opt.cuda:
        device = torch.device('cuda:0')
        torch.cuda.empty_cache()
    else:
        device = torch.device('cpu')

    batch_size = opt.batch_size

    ##### DATA LOADERS

    train, test = dataset_factory(opt.datadir,
                                  opt.dataset,
                                  opt.T,
                                  data_augment=opt.data_augment)
    trainloader = torch.utils.data.DataLoader(train,
                                              batch_size=batch_size,
                                              shuffle=True,
                                              num_workers=0)
    testloader = torch.utils.data.DataLoader(test,
                                             batch_size=batch_size,
                                             shuffle=True,
                                             num_workers=0)

    feature_dim = train.chunks_inputs[:, :, :, :].shape

    opt.channels = feature_dim[1]
    x_dim = feature_dim[2]
    t_dim = feature_dim[3]
    z_dim = opt.hidden_dim

    ##### MODEL SETUP
    print('Setting up model')
    model = DataImputator(opt.channels,
                          opt.hidden_dim,
                          x_dim,
                          t_dim,
                          dropout=opt.dropout)
    model.to(device)
    summary(model, input_size=feature_dim[1:])

    criterion = nn.MSELoss()
    optimizer = optim.Adam(model.parameters(),
                           lr=opt.learning_rate,
                           weight_decay=opt.weight_decay)
    scheduler_model = lr_scheduler.ReduceLROnPlateau(optimizer, patience=50)

    print('Testing forward pass:'******'train_loss', avg_trainloss, epoch)
            writer.add_scalar('test_loss', avg_testloss, epoch)
            t.set_postfix(loss=avg_trainloss,
                          testloss=avg_testloss,
                          epoch=epoch,
                          avg_elapsed=elapsed / batch_idx,
                          lr=optimizer.param_groups[0]['lr'])
            scheduler_model.step(testloss / len(testloader))
            # if epoch % 1 == 0:
            #     plt.clf()

            #     err = torch.abs(h[0,0,:,:]- h_tilde[0,0,:,:]).cpu().detach().numpy()
            #     ax = plt.subplot(151)
            #     ax.contour(g_tilde[0,0,:,:].cpu().detach().numpy(), levels=100)
            #     ax.set_xlabel('# SRS sequence')
            #     ax.set_ylabel('Subcarrier')
            #     ax.set_title("Input sequences Real $\hat{g}$")
            #     ax = plt.subplot(152)
            #     ax.contourf(h_tilde[0,0,:,:].cpu().detach().numpy())
            #     ax.set_xlabel('# SRS sequence')
            #     ax.set_ylabel('Subcarrier')
            #     ax.set_title("Predicted channel Real $\widetilde{h}$")
            #     ax = plt.subplot(153)
            #     ax.contourf(h[0,0,:,:].cpu().detach().numpy())
            #     ax.set_xlabel('# SRS sequence')
            #     ax.set_ylabel('Subcarrier')
            #     ax.set_title("True channel Real $h$")

            #     ax = plt.subplot(154)
            #     ax.plot(h_tilde[0,0,:,-1].cpu().detach().numpy(),'b-', label='Predicted')
            #     ax.plot(h[0,0,:,-1].cpu().detach().numpy(),'-o',label='True')
            #     ax.plot(g_tilde[0,0,:,-1].cpu().detach().numpy(),'o',label='Input')
            #     ax.set_xlabel('Subcarrier')
            #     ax.set_ylabel('Real(h[t])')
            #     ax.set_title("h[t] prediction and input")
            #     ax.legend()

            #     ax = plt.subplot(155)
            #     err_contour = ax.contourf(err)
            #     ax.set_title('Absolute error')
            #     ax.set_xlabel('# SRS sequence')
            #ax.set_ylabel('Subcarrier')
            #plt.colorbar(err_contour)

            #plt.tight_layout()

            #writer.add_figure('predicted',fig, epoch)

            #plt.savefig(opt.draw_folder+'\{}.png'.format(epoch))
        if optimizer.param_groups[0]['lr'] < 1e-7:
            break

    exp = Experiment('file', config=dict(opt), root_folder='exps/')
    results_dict = dict()
    results_dict['train_loss'] = train_loss
    results_dict['test_loss'] = test_loss
    exp.results = results_dict
    exp.save()

    torch.save(model, exp.root_folder + '/models/{}_model.pt'.format(exp.id))
Ejemplo n.º 7
0
def run(args):
    cuda = not args.no_cuda and torch.cuda.is_available()

    if cuda:
        torch.cuda.empty_cache()

    torch.manual_seed(args.seed)
    if cuda:
        print('CUDA enabled')
        torch.cuda.manual_seed(args.seed)

    # Load data

    # Load experiment

    exp_root_path = args.exp_folder + "/"

    exp = load_experiment(args.name, root_path=exp_root_path)
    name = args.name
    args = edict(exp.config)
    args.name = name
    args.cuda = cuda
    args.data_augmentation_angle = 20

    # compatibility
    if not 'offset_811' in args:
        args.offset_811 = 18

    if not 'offset_2630' in args:
        args.offset_2630 = 0

    train_dataset, test_dataset = dataset_factory(
        use_images=args.use_images,
        transform=True,
        data_augment_angle=args.data_augmentation_angle)
    train_loader = torch.utils.data.DataLoader(train_dataset,
                                               batch_size=args.batch_size,
                                               shuffle=True,
                                               num_workers=0,
                                               drop_last=True)
    test_loader = torch.utils.data.DataLoader(test_dataset,
                                              batch_size=args.batch_size,
                                              num_workers=0,
                                              drop_last=False,
                                              shuffle=False)
    print(len(test_loader))

    rsrp_mu = train_dataset.target_mu
    rsrp_std = train_dataset.target_std

    model = SkynetModel(args, rsrp_mu=rsrp_mu, rsrp_std=rsrp_std)

    if args.cuda:
        model.cuda()

    # Find model name
    list_of_files = os.listdir('{}models/'.format(
        exp_root_path))  #list of files in the current directory
    for each_file in list_of_files:
        if each_file.startswith(args.name):
            name = each_file

    print(name)

    model.load_state_dict(torch.load('{}models/{}'.format(exp_root_path,
                                                          name)))
    model.eval()
    criterion = nn.MSELoss()
    MSE_loss_batch = 0
    with torch.no_grad():
        for idx, (feature, image, target, dist) in enumerate(test_loader):
            if args.cuda:
                image = image.cuda()
                feature = feature.cuda()
                target = target.cuda()
                dist = dist.cuda()

            correction_, sum_output_ = model(feature, image, dist)
            P = model.predict_physicals_model(feature, dist)

            MSE_loss_batch += criterion(sum_output_, target)
            try:
                p = torch.cat([p, P], 0)
            except:
                p = P

            try:
                correction = torch.cat([correction, correction_], 0)
            except:
                correction = correction_

            try:
                sum_output = torch.cat([sum_output, sum_output_], 0)
            except:
                sum_output = sum_output_

            try:
                features = torch.cat([features, feature], 0)
            except:
                features = feature

    correction_unnorm = (correction * model.rsrp_std)

    def correct_hist_plot(correction_unnorm, features):
        fig = plt.figure(figsize=(7, 3))
        sns.set_style('darkgrid')
        sns.distplot(correction_unnorm[features[:, 7] == 1].cpu().numpy(),
                     label='2630 MHz')
        sns.distplot(correction_unnorm[features[:, 7] != 1].cpu().numpy(),
                     label='811 MHz')
        plt.xlabel('RSRP correction [dB]')
        plt.ylabel('Frequency')
        plt.legend()
        plt.savefig('results/rsrp_correction_hist_{}.eps'.format(args.name))
        plt.savefig('results/rsrp_correction_hist_{}.png'.format(args.name))
        plt.show()

    def cdf_hist_plot(target, predicted, theoretical, mhz):
        fig = plt.figure(figsize=(5, 5))
        sns.set_style('darkgrid')
        sns.distplot(target,
                     hist_kws=dict(cumulative=True),
                     kde_kws=dict(cumulative=True),
                     label='Target')
        sns.distplot(predicted,
                     hist_kws=dict(cumulative=True),
                     kde_kws=dict(cumulative=True),
                     label='Predicted')
        #sns.distplot(theoretical, hist_kws=dict(cumulative=True), kde_kws=dict(cumulative=True), label='38.901 UMa')
        plt.legend()
        plt.xlabel('RSRP [dBm]')
        plt.tight_layout()
        plt.savefig('results/cdf_{}_{}mhz.eps'.format(args.name, mhz))
        plt.savefig('results/cdf_{}_{}mhz.png'.format(args.name, mhz))
        plt.show()

    def hist_plot(target, predicted, theoretical, mhz):
        fig = plt.figure(figsize=(5, 5))
        sns.set_style('darkgrid')
        sns.distplot(target, label='Target')
        sns.distplot(predicted, label='Predicted')
        #sns.distplot(theoretical, label='38.901 UMa')
        plt.xlabel('RSRP [dBm]')
        plt.legend()
        plt.tight_layout()
        plt.savefig('results/hist_{}_{}mhz.eps'.format(args.name, mhz))
        plt.show()

    #cdf_hist_plot(test_dataset.targets, p.cpu().numpy())

    # correction_hist_plot(correction_unnorm, features)

    # Compute RMSE for model and pathloss model

    print('Test MSE batch norm {}'.format(MSE_loss_batch / idx))
    MSE_loss_model = criterion(sum_output.cpu(),
                               torch.from_numpy(test_dataset.targets).float())
    print('Test MSE norm {}'.format(MSE_loss_model.item()))
    RMSE_model = np.sqrt(MSE_loss_model.item()) * model.rsrp_std.numpy()
    print('Test RMSE unnorm {}'.format(RMSE_model))

    MSE_pathloss_model = criterion(
        p.cpu(),
        torch.from_numpy(test_dataset.targets).float())
    print("Pathloss model MSE {}".format(MSE_pathloss_model.item()))
    RMSE_pathloss = np.sqrt(MSE_pathloss_model.item()) * model.rsrp_std.numpy()
    print("Pathloss model RMSE {}".format(RMSE_pathloss))

    # Save JSON with evaluation results
    results = dict()
    results['RMSE_unnorm'] = RMSE_model
    results['MSE_loss'] = MSE_loss_model.item()
    results['MSE_pathloss_model'] = MSE_pathloss_model.item()
    results['RMSE_pathloss'] = RMSE_pathloss

    idx_811mhz = test_dataset.get_811Mhz_idx()
    idx_2630mhz = test_dataset.get_2630Mhz_idx()
    MSE_loss_811mhz = criterion(
        sum_output[idx_811mhz].cpu(),
        torch.from_numpy(test_dataset.targets[idx_811mhz]).float())
    MSE_loss_2630mhz = criterion(
        sum_output[idx_2630mhz].cpu(),
        torch.from_numpy(test_dataset.targets[idx_2630mhz]).float())
    print("MSE Loss at 811 MHz: {}".format(MSE_loss_811mhz))
    print("MSE Loss at 2630 MHz: {}".format(MSE_loss_2630mhz))
    RMSE_811 = np.sqrt(MSE_loss_811mhz.item()) * model.rsrp_std.numpy()
    RMSE_2630 = np.sqrt(MSE_loss_2630mhz.item()) * model.rsrp_std.numpy()
    print("RMSE 811 MHz {}".format(RMSE_811))
    print("RMSE 2630 MHz {}".format(RMSE_2630))
    results['RMSE_811'] = RMSE_811
    results['RMSE_2630'] = RMSE_2630

    MSE_pathloss_811 = criterion(
        p[idx_811mhz].cpu(),
        torch.from_numpy(test_dataset.targets[idx_811mhz]).float())
    MSE_pathloss_2630 = criterion(
        p[idx_2630mhz].cpu(),
        torch.from_numpy(test_dataset.targets[idx_2630mhz]).float())
    RMSE_pathloss_811 = np.sqrt(
        MSE_pathloss_811.item()) * model.rsrp_std.numpy()
    RMSE_pathloss_2630 = np.sqrt(
        MSE_pathloss_2630.item()) * model.rsrp_std.numpy()
    results['RMSE_pathloss_811'] = RMSE_pathloss_811
    results['RMSE_pathloss_2630'] = RMSE_pathloss_2630

    plt.rcParams.update({'font.size': 18})
    pred_811_unnorm = (sum_output[idx_811mhz].cpu().numpy() *
                       test_dataset.target_std) + test_dataset.target_mu
    pred_2630_unnorm = (sum_output[idx_2630mhz].cpu().numpy() *
                        test_dataset.target_std) + test_dataset.target_mu
    uma_811_unnorm = (p[idx_811mhz].cpu().numpy() *
                      test_dataset.target_std) + test_dataset.target_mu
    uma_2630_unnorm = (p[idx_2630mhz].cpu().numpy() *
                       test_dataset.target_std) + test_dataset.target_mu
    cdf_hist_plot(test_dataset.targets_unnorm[idx_811mhz], pred_811_unnorm,
                  uma_811_unnorm, '811')
    cdf_hist_plot(test_dataset.targets_unnorm[idx_2630mhz], pred_2630_unnorm,
                  uma_2630_unnorm, '2630')
    hist_plot(test_dataset.targets_unnorm[idx_811mhz], pred_811_unnorm,
              uma_811_unnorm, '811')
    hist_plot(test_dataset.targets_unnorm[idx_2630mhz], pred_2630_unnorm,
              uma_2630_unnorm, '2630')

    results_file_name = args.name + "_results.json"

    with open('results/evaluations/{}'.format(results_file_name),
              'w') as output:
        json.dump(results, output)
def run(args):

    
    exp_root_path = "exps/"

    exp = load_experiment(args.name, root_path = exp_root_path)
    name = args.name
    args = edict(exp.config)

    #args = DotDict(parameters)
    torch.manual_seed(args.seed)

    if args.cuda:
        device = torch.device('cuda:0')
        torch.cuda.empty_cache()
    else:
        device = torch.device('cpu')

    print(device)

    batch_size = args.batch_size
   


    # Load dataset
    train, test = dataset_factory(args.datadir, args.dataset, args.T, data_augment=False)
    trainloader = torch.utils.data.DataLoader(train, batch_size=batch_size, shuffle=True, num_workers=0)
    testloader = torch.utils.data.DataLoader(test, batch_size=batch_size, shuffle=True, num_workers=0)

    feature_dim = train.chunks_inputs.shape[1:4]
    args.channels = feature_dim[0]
    args.subcarriers = feature_dim[1]


    # Load Model
    imputator = torch.load(exp_root_path+"models/"+name+"_model.pt")
    imputator = imputator.to(device)
    imputator.eval()
    #summary(imputator, input_size=(feature_dim))
    criterion = nn.MSELoss()

    # Set SNR range
    SNRdB = [40]

    N_sc = args.subcarriers # Total number of available subcarriers
    Totsym_subframe = N_sc*14 # Total number of OFDM symbols per subframe
    max_oh = ((N_sc/2)/Totsym_subframe)*100
    
    print("Max OH if only 1 OFDM symbol per subframe is used: {}".format(max_oh))
    randommask = Mask(args.T, args.subcarriers, 'subcarriers',  mask_type='random', period=2)
    sequentialmask = Mask(args.T, args.subcarriers, 'subcarriers', mask_type='sequential', period=2)
    iterrange = 100
    # Set overhead range
    #oh_range = np.linspace(5, 5) # Percent
    oh_range = np.linspace(2, 6, 10)
    results_random = np.empty((len(testloader), len(SNRdB), len(oh_range)))
    results_uncertainty = np.empty((len(testloader), len(SNRdB), len(oh_range)))
    results_sequential = np.empty((len(testloader), len(SNRdB), len(oh_range)))
    results_srs = np.empty((len(testloader), len(SNRdB), len(oh_range)))
    for batch_idx, (g_tilde, h) in enumerate(testloader):
        if batch_idx == iterrange:
            break

        torch.cuda.manual_seed(batch_idx+int(args.seed))
        h_noise = h.to(device)
        h = h.to(device)
        g_tilde = g_tilde.to(device)
        #h_noise = h
        np.random.seed(batch_idx + int(args.seed))

        #loader = iter(testloader)
        print("Batch {}/{}".format(batch_idx, len(testloader)))
        #g_hat, h = loader.next() # Get next batch
        for snridx, SNR in enumerate(SNRdB):
            print("SNR: {}/{}".format(snridx, len(SNRdB)))

            #h_noise = add_awgn(h, SNR)


            for ohidx, oh in enumerate(oh_range):
                print("OH: {}/{}".format(ohidx, len(oh_range)))


                ###########################
                # Actual SRS sequence
                ###########################
                imputator = imputator.eval()
                predicted_srs = imputator(g_tilde)
                mseloss_srs = criterion(predicted_srs, h)
                results_srs[batch_idx, snridx, ohidx] = mseloss_srs.item()
                predicted_srs = predicted_srs.detach()
                g_tilde = g_tilde.detach()

                ############################
                # Sequential sequence
                ############################
                imputator = imputator.eval()
                masked_input_sequential = sequentialmask.mask_input(h_noise, oh)
                masked_input_sequential = masked_input_sequential.to(device)
                predicted_sequential = imputator(masked_input_sequential)
                mseloss_sequential = criterion(predicted_sequential, h)
                results_sequential[batch_idx, snridx, ohidx] = mseloss_sequential.item()
                masked_input_sequential = masked_input_sequential.detach()
                predicted_sequential = predicted_sequential.detach()

                #plot_grid(masked_input_sequential, predicted, h, 'Sequential')
                
                #############################
                # Randomly placed sequences
                #############################
                imputator = imputator.eval()
                masked_input_random = randommask.mask_input(h_noise, oh)
                masked_input_random = masked_input_random.to(device)
                predicted_random = imputator(masked_input_random)
                mseloss_random = criterion(predicted_random, h)
                results_random[batch_idx, snridx, ohidx] = mseloss_random.item()

                #plot_grid(masked_input_random, predicted, h, 'Random')

                # clear variables
                #h = h.detach()
                masked_input_random = masked_input_random.detach()
                predicted_random = predicted_random.detach()


                #############################
                # Uncertainty
                #############################

                # Place first sequence randomly
                masked_random_start = randommask.mask_input(h_noise, oh, num_sequences=1) # Place first randomly
                masked_random_start = masked_random_start.to(device)

                # Place the next sequences based on uncertainty
                subframes_remaining =  int(np.floor(h_noise.shape[3]/randommask.period)*randommask.period) # Round down
                subframes_to_sample = np.arange(9, subframes_remaining, step=10)
                imputator = imputator.eval()
                with torch.no_grad():
                    predicted_mc, std = imputator.MC(masked_random_start, num_samples = 100)

                predicted_mc = predicted_mc.to(device).detach()
                std = std.to(device).detach()



                for subframe in subframes_to_sample:

                    # Find subcarrier with maximum uncertanity
                    std_pow = torch.pow(std,2)  # Mean over std in real and imag
                    std_mean = torch.mean(std,dim=1)
                    max_sc = torch.argmax(std_mean[:,:,subframe], dim=1)
                    #max_std = torch.max(std[:,:,subframe], dim=1)
                    #sorted_peaks = torch.argsort(std[:,:,subframe], dim=1, descending=True)

                    # fig = plt.figure(figsize=(10, 8))
                    # plt.subplot(1,2,1)
                    # plt.plot(std_pow[0,0,subframe,:].cpu().detach().numpy())
                    # plt.subplot(1,2,2)
                    # plt.plot(std_pow[0,1,subframe,:].cpu().detach().numpy())
                    # plt.show()

                    # Find sequence_length on either side
                    # Loop for all batches
                    masked_random_start = masked_random_start.to(device)
                    for sc in range(h_noise.shape[0]):
                        sequence = randommask.find_span_peak(max_sc[sc].cpu())

                        #sequence = randommask.select_peaks(sorted_peaks[sc])

                        masked_random_start[sc,:,sequence,subframe] = h_noise[sc,:,sequence,subframe] # Set new sequence

                    # Predict using newly set sequence
                    masked_random_start = masked_random_start.to(device)
                    imputator = imputator.eval()
                    with torch.no_grad():
                        predicted_mc, std = imputator.MC(masked_random_start, num_samples = 100)

                    performance_after = criterion(predicted_mc.to(device), h.to(device))
                    std = std.to(device).detach()
                    predicted_mc = predicted_mc.to(device).detach()
                    masked_random_start = masked_random_start.to(device).detach()
                    torch.cuda.empty_cache()


                    #fig = plt.figure(figsize=(8,8))
                    #ax = plt.subplot(1,2,1)
                    #pp = ax.imshow(std[0,0,:,:].to(device).detach().numpy(), aspect='auto')
                    #ax = plt.subplot(1,2,2)
                    #pp = ax.imshow(masked_random_start[0,0,:,:].to(device).detach().numpy(), aspect='auto')
                    #plt.show()

                #plot_grid(masked_random_start, predicted, h, 'Uncertainty')
                results_uncertainty[batch_idx, snridx, ohidx] = performance_after.item()
                #plot_sequences(masked_input_sequential, masked_input_random, masked_random_start, std, ['Sequential', 'Random', 'Uncertainty', 'std'])
                #plot_sequences(predicted_sequential, predicted_random, predicted_mc, h, ['Sequential', 'Random', 'Uncertainty', 'True'])
                print("MSE random: {}".format(results_random[batch_idx, snridx, ohidx]))
                print("MSE sequential: {}".format(results_sequential[batch_idx, snridx, ohidx]))
                print("MSE uncertainty {}".format(results_uncertainty[batch_idx, snridx, ohidx]))
                print("MSE SRS {}".format(results_srs[batch_idx, snridx, ohidx]))
                #print("Total number of symbols with {}% OH : {}".format(oh, N_sym_pilots))
                #print("MSE with {}% OH;  SNR: {} = {}".format(oh, SNR, mseloss.item()))

    with plt.style.context('seaborn'):
        fig = plt.figure()
        plt.plot(oh_range, np.mean(results_uncertainty[:,0,:],axis=0),'-o', label='Uncertainty scheme')
        plt.plot(oh_range, np.mean(results_random[:, 0, :], axis=0), '-o', label='Random scheme')
        plt.plot(oh_range, np.mean(results_sequential[:, 0, :], axis=0), '-o', label='Sequential scheme')
        plt.plot(oh_range, np.mean(results_srs[:, 0, :], axis=0), '-o', label='Actual SRS')
        plt.xlabel('Overhead [%]')
        plt.ylabel('MSE')
        plt.legend()
        plt.savefig(args.results_folder+'/oh_SNR{}.eps'.format(name))
        plt.savefig(args.results_folder+'/oh_SNR{}.png'.format(name))
        plt.show()

    np.save(args.results_folder+'/results_uncertainty_{}.npy'.format(name), results_uncertainty)
    np.save(args.results_folder+'/results_random_{}.npy'.format(name), results_random)
    np.save(args.results_folder+'/results_sequential_{}.npy'.format(name), results_sequential)