UOMOP

Filter counting of zero padding 본문

DE/Code

Filter counting of zero padding

Happy PinGu 2024. 8. 6. 10:51
import numpy as np
import torch
import torchvision
import torchvision.transforms as transforms

def patch_importance(image, patch_size=2, type='variance', how_many=2, noise_scale=0):
    if isinstance(image, torch.Tensor):
        image = image.numpy()

    H, W = image.shape[-2:]
    extended_patch_size = patch_size + 2 * how_many
    value_map = np.zeros((H // patch_size, W // patch_size))

    for i in range(0, H, patch_size):
        for j in range(0, W, patch_size):
            start_i = max(i - how_many, 0)
            end_i = min(i + patch_size + how_many, H)
            start_j = max(j - how_many, 0)
            end_j = min(j + patch_size + how_many, W)

            extended_patch = image[start_i:end_i, start_j:end_j]

            if type == 'variance':
                value = np.std(extended_patch)
            elif type == 'mean_brightness':
                value = np.mean(extended_patch)
            elif type == 'contrast':
                value = extended_patch.max() - extended_patch.min()
            elif type == 'edge_density':
                dy, dx = np.gradient(extended_patch)
                value = np.sum(np.sqrt(dx ** 2 + dy ** 2))
            elif type == 'color_diversity':
                value = np.std(extended_patch)

            noise = np.random.randn() * noise_scale
            value_map[i // patch_size, j // patch_size] = value + noise

    return value_map

# Define the Gaussian mask function
def PPM(images, patch_size=2, mask_ratio=0.5):
    B, C, H, W = images.shape
    masked_images = images.clone()
    num_patches = (H // patch_size) * (W // patch_size)
    num_masked_patches = int(num_patches * mask_ratio)
    unmasked_counts = []

    center_x, center_y = H // 2, W // 2
    sigma = max(H, W) / 8

    for b in range(B):
        mask = np.zeros((H // patch_size, W // patch_size), dtype=bool)

        # Create a 2D grid of patch coordinates
        x = np.arange(H // patch_size)
        y = np.arange(W // patch_size)
        xv, yv = np.meshgrid(x, y, indexing='ij')

        # Calculate distances from the center
        distances = np.sqrt((xv - center_x // patch_size) ** 2 + (yv - center_y // patch_size) ** 2)

        # Calculate probabilities using a Gaussian distribution
        probabilities = np.exp(-distances ** 2 / (2 * sigma ** 2))
        probabilities /= probabilities.sum()  # Normalize to sum to 1

        # Flatten probabilities and choose patches to mask
        probabilities_flat = probabilities.flatten()
        mask_indices = np.random.choice(num_patches, num_masked_patches, replace=False, p=probabilities_flat)
        mask_indices = np.unravel_index(mask_indices, mask.shape)

        mask[mask_indices] = True

        for i in range(H // patch_size):
            for j in range(W // patch_size):
                if mask[i, j]:
                    masked_images[b, :, i * patch_size:(i + 1) * patch_size, j * patch_size:(j + 1) * patch_size] = 0

        unmasked_counts.append(num_patches - num_masked_patches)

    return masked_images, unmasked_counts

def TopK_mask(images, patch_size=2, mask_ratio=0.5, importance_type='variance', how_many=0, noise_scale=0):
    B, C, H, W = images.shape
    masked_images = images.clone()
    unmasked_counts = []

    mask_ratio = 1 - mask_ratio

    target_unmasked_ratio = 1 - mask_ratio
    num_patches = (H // patch_size) * (W // patch_size)
    target_unmasked_patches = int(num_patches * target_unmasked_ratio)

    for b in range(B):
        unmasked_count = 0
        patch_importance_map = patch_importance(images[b, 0], patch_size, importance_type, how_many, noise_scale)

        # Flatten patch importance map and sort indices by importance
        patch_importance_flat = patch_importance_map.flatten()
        sorted_indices = np.argsort(patch_importance_flat)

        # Create a mask initialized to False
        mask = np.zeros((H // patch_size, W // patch_size), dtype=bool)

        # Mask patches with the lowest importance until the target unmasked patches count is reached
        for idx in sorted_indices:
            if unmasked_count >= target_unmasked_patches:
                break
            mask[np.unravel_index(idx, mask.shape)] = True
            unmasked_count += 1

        # Apply the mask to the images
        for i in range(H // patch_size):
            for j in range(W // patch_size):
                if mask[i, j]:
                    masked_images[b, :, i * patch_size:(i + 1) * patch_size, j * patch_size:(j + 1) * patch_size] = 0

        unmasked_counts.append(unmasked_count)

    return masked_images, unmasked_counts

def chessboard_mask(images, patch_size=2, mask_ratio=0.5, importance_type='variance', how_many=0, noise_scale=0):
    B, C, H, W = images.shape
    masked_images = images.clone()
    unmasked_counts = []

    target_unmasked_ratio = 1 - mask_ratio
    num_patches = (H // patch_size) * (W // patch_size)
    target_unmasked_patches = int(num_patches * target_unmasked_ratio)

    for b in range(B):
        unmasked_count = 0
        patch_importance_map = patch_importance(images[b, 0], patch_size, importance_type, how_many, noise_scale)

        mask = np.zeros((H // patch_size, W // patch_size), dtype=bool)
        for i in range(H // patch_size):
            for j in range(W // patch_size):
                if (i + j) % 2 == 0:
                    mask[i, j] = True

        unmasked_count = np.sum(~mask)

        if mask_ratio < 0.5:
            masked_indices = np.argwhere(mask)
            importances = patch_importance_map[mask]
            sorted_indices = masked_indices[np.argsort(importances)[::-1]]

            for idx in sorted_indices:
                if unmasked_count >= target_unmasked_patches:
                    break
                mask[tuple(idx)] = False
                unmasked_count += 1

        elif mask_ratio > 0.5:
            unmasked_indices = np.argwhere(~mask)
            importances = patch_importance_map[~mask]
            sorted_indices = unmasked_indices[np.argsort(importances)]

            for idx in sorted_indices:
                if unmasked_count <= target_unmasked_patches:
                    break
                mask[tuple(idx)] = True
                unmasked_count -= 1

        for i in range(H // patch_size):
            for j in range(W // patch_size):
                if mask[i, j]:
                    masked_images[b, :, i * patch_size:(i + 1) * patch_size, j * patch_size:(j + 1) * patch_size] = 0

        unmasked_counts.append(unmasked_count)

    return masked_images, unmasked_counts

def random_mask(images, patch_size=2, mask_ratio=0.5):
    B, C, H, W = images.shape
    masked_images = images.clone()
    num_patches = (H // patch_size) * (W // patch_size)
    num_masked_patches = int(num_patches * mask_ratio)
    unmasked_counts = []

    for b in range(B):
        mask = np.zeros((H // patch_size, W // patch_size), dtype=bool)
        mask_indices = np.random.choice(num_patches, num_masked_patches, replace=False)
        mask_indices = np.unravel_index(mask_indices, mask.shape)

        mask[mask_indices] = True

        for i in range(H // patch_size):
            for j in range(W // patch_size):
                if mask[i, j]:
                    masked_images[b, :, i * patch_size:(i + 1) * patch_size, j * patch_size:(j + 1) * patch_size] = 0

        unmasked_counts.append(num_patches - num_masked_patches)

    return masked_images, unmasked_counts

def CPM(images, patch_size=2, mask_ratio=0.5):
    B, C, H, W = images.shape
    masked_images = images.clone()
    num_patches = (H // patch_size) * (W // patch_size)
    num_masked_patches = int(num_patches * mask_ratio)
    unmasked_counts = []

    center_x, center_y = H // 2, W // 2
    sigma = max(H, W) / 0.0005

    for b in range(B):
        mask = np.zeros((H // patch_size, W // patch_size), dtype=bool)

        # Create a 2D grid of patch coordinates
        x = np.arange(H // patch_size)
        y = np.arange(W // patch_size)
        xv, yv = np.meshgrid(x, y, indexing='ij')

        # Calculate distances from the center
        distances = np.sqrt((xv - center_x // patch_size) ** 2 + (yv - center_y // patch_size) ** 2)

        # Calculate probabilities using an inverted Gaussian distribution
        probabilities = 1 - np.exp(-distances ** 2 / (2 * sigma ** 2))
        probabilities /= probabilities.sum()  # Normalize to sum to 1

        # Flatten probabilities and choose patches to mask
        probabilities_flat = probabilities.flatten()
        mask_indices = np.random.choice(num_patches, num_masked_patches, replace=False, p=probabilities_flat)
        mask_indices = np.unravel_index(mask_indices, mask.shape)

        mask[mask_indices] = True

        for i in range(H // patch_size):
            for j in range(W // patch_size):
                if mask[i, j]:
                    masked_images[b, :, i * patch_size:(i + 1) * patch_size, j * patch_size:(j + 1) * patch_size] = 0

        unmasked_counts.append(num_patches - num_masked_patches)

    return masked_images, unmasked_counts

def apply_filter_and_count_zeros(images, filter_3x3, stride=2):
    num_zeros = 0
    _, H, W = images.shape  # Images are expected to be (C, H, W) with C=1
    filter_size = filter_3x3.shape[0]

    # Calculate output dimensions
    out_h = (H - filter_size) // stride + 1
    out_w = (W - filter_size) // stride + 1

    for i in range(0, out_h * stride, stride):
        for j in range(0, out_w * stride, stride):
            # Extract the 3x3 patch
            patch = images[:, i:i + filter_size, j:j + filter_size]

            # Apply the filter (convolution-like operation)
            if patch.shape[1] == filter_size and patch.shape[2] == filter_size:
                filtered_value = (patch * filter_3x3).sum()

                # Check if the result is zero
                if filtered_value == 0:
                    num_zeros += 1

    return num_zeros

# Define the function to process the CIFAR-10 dataset and calculate the average number of zeros
def process_cifar10_and_calculate_average(trainloader, filter_3x3, stride, mask_functions, mask_ratios):
    results = {}

    for mask_name, mask_function in mask_functions.items():
        for MR in mask_ratios:
            total_zero_count = 0
            total_images = 0

            for data in trainloader:
                images, _ = data

                # Call the mask function with appropriate parameters
                if mask_name in ['PPM', 'Random', 'CPM']:
                    masked_images, _ = mask_function(images, patch_size=2, mask_ratio=MR)
                else:
                    masked_images, _ = mask_function(images, patch_size=2, mask_ratio=MR, importance_type='variance', how_many=1, noise_scale=0)

                for img in masked_images:
                    # Convert to single channel (keep only R channel)
                    single_channel_image = img[0:1]  # Use the first channel

                    # Apply filter and count zeros
                    num_zeros = apply_filter_and_count_zeros(single_channel_image, filter_3x3, stride)
                    total_zero_count += num_zeros
                    total_images += 1

            # Calculate the average number of zeros
            average_zeros = total_zero_count / total_images
            results[(mask_name, MR)] = average_zeros

    return results

if __name__ == '__main__':
    # Load CIFAR-10 dataset
    transform = transforms.Compose([
        transforms.ToTensor(),  # Convert to tensor
    ])

    trainset = torchvision.datasets.CIFAR10(root='./data', train=True, download=True, transform=transform)
    trainloader = torch.utils.data.DataLoader(trainset, batch_size=100, shuffle=False, num_workers=2)

    filter_3x3 = np.random.rand(3, 3)  # Random 3x3 filter
    stride = 2

    mask_functions = {
        'PPM': PPM,
        'TopK': TopK_mask,
        'Chessboard': chessboard_mask,
        'Random': random_mask,
        'CPM': CPM
    }

    mask_ratios = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9]

    results = process_cifar10_and_calculate_average(trainloader, filter_3x3, stride, mask_functions, mask_ratios)

    for (mask_name, MR), avg_zeros in results.items():
        print(f"Mask: {mask_name}, Ratio: {MR}, Average number of zeros per image: {avg_zeros}")

C:\Users\dowon\anaconda3\envs\dowon_simul\python.exe C:\Users\dowon\AppData\Local\Temp\660f4170-4045-4417-ac72-1ea99ca7b7a1_main.zip.7a1\main.py 
Files already downloaded and verified
Mask: PPM, Ratio: 0.1, Average number of zeros per image: 0.21532
Mask: PPM, Ratio: 0.2, Average number of zeros per image: 1.73868
Mask: PPM, Ratio: 0.3, Average number of zeros per image: 7.05648
Mask: PPM, Ratio: 0.4, Average number of zeros per image: 19.10272
Mask: PPM, Ratio: 0.5, Average number of zeros per image: 38.83234
Mask: PPM, Ratio: 0.6, Average number of zeros per image: 65.00442
Mask: PPM, Ratio: 0.7, Average number of zeros per image: 98.3821
Mask: PPM, Ratio: 0.8, Average number of zeros per image: 135.39268
Mask: PPM, Ratio: 0.9, Average number of zeros per image: 178.70678
Mask: TopK, Ratio: 0.1, Average number of zeros per image: 3.99518
Mask: TopK, Ratio: 0.2, Average number of zeros per image: 13.65404
Mask: TopK, Ratio: 0.3, Average number of zeros per image: 26.0119
Mask: TopK, Ratio: 0.4, Average number of zeros per image: 41.41238
Mask: TopK, Ratio: 0.5, Average number of zeros per image: 59.45274
Mask: TopK, Ratio: 0.6, Average number of zeros per image: 79.71408
Mask: TopK, Ratio: 0.7, Average number of zeros per image: 104.41978
Mask: TopK, Ratio: 0.8, Average number of zeros per image: 132.86384
Mask: TopK, Ratio: 0.9, Average number of zeros per image: 170.00042
Mask: Chessboard, Ratio: 0.1, Average number of zeros per image: 0.12278
Mask: Chessboard, Ratio: 0.2, Average number of zeros per image: 0.1284
Mask: Chessboard, Ratio: 0.3, Average number of zeros per image: 0.13188
Mask: Chessboard, Ratio: 0.4, Average number of zeros per image: 0.13374
Mask: Chessboard, Ratio: 0.5, Average number of zeros per image: 0.13464
Mask: Chessboard, Ratio: 0.6, Average number of zeros per image: 19.5235
Mask: Chessboard, Ratio: 0.7, Average number of zeros per image: 53.1513
Mask: Chessboard, Ratio: 0.8, Average number of zeros per image: 94.77904
Mask: Chessboard, Ratio: 0.9, Average number of zeros per image: 150.60244
Mask: Random, Ratio: 0.1, Average number of zeros per image: 0.13548
Mask: Random, Ratio: 0.2, Average number of zeros per image: 0.45008
Mask: Random, Ratio: 0.3, Average number of zeros per image: 1.79572
Mask: Random, Ratio: 0.4, Average number of zeros per image: 5.61766
Mask: Random, Ratio: 0.5, Average number of zeros per image: 13.92892
Mask: Random, Ratio: 0.6, Average number of zeros per image: 28.40562
Mask: Random, Ratio: 0.7, Average number of zeros per image: 53.40908
Mask: Random, Ratio: 0.8, Average number of zeros per image: 90.33156
Mask: Random, Ratio: 0.9, Average number of zeros per image: 146.29942
Mask: CPM, Ratio: 0.1, Average number of zeros per image: 0.16234
Mask: CPM, Ratio: 0.2, Average number of zeros per image: 0.87448
Mask: CPM, Ratio: 0.3, Average number of zeros per image: 3.64946
Mask: CPM, Ratio: 0.4, Average number of zeros per image: 10.67722
Mask: CPM, Ratio: 0.5, Average number of zeros per image: 24.21722
Mask: CPM, Ratio: 0.6, Average number of zeros per image: 45.21098
Mask: CPM, Ratio: 0.7, Average number of zeros per image: 76.89722
Mask: CPM, Ratio: 0.8, Average number of zeros per image: 117.37664
Mask: CPM, Ratio: 0.9, Average number of zeros per image: 168.22938

Process finished with exit code 0

 

 

% 주어진 데이터
ratios = 0.1:0.1:0.9; % Ratio 값

% Mask별 Average number of zeros per image
ppm_zeros = [0.21532, 1.73868, 7.05648, 19.10272, 38.83234, 65.00442, 98.3821, 135.39268, 178.70678];
topk_zeros = [3.99518, 13.65404, 26.0119, 41.41238, 59.45274, 79.71408, 104.41978, 132.86384, 170.00042];
chessboard_zeros = [0.12278, 0.1284, 0.13188, 0.13374, 0.13464, 19.5235, 53.1513, 94.77904, 150.60244];
random_zeros = [0.13548, 0.45008, 1.79572, 5.61766, 13.92892, 28.40562, 53.40908, 90.33156, 146.29942];
cpm_zeros = [0.16234, 0.87448, 3.64946, 10.67722, 24.21722, 45.21098, 76.89722, 117.37664, 168.22938];

% 그래프 생성
figure;
hold on;

% 각각의 Mask 데이터를 plot
plot(ratios, ppm_zeros, '-o', 'LineWidth', 2, 'DisplayName', 'PPM');
plot(ratios, topk_zeros, '-s', 'LineWidth', 2, 'DisplayName', 'TopK');
plot(ratios, cpm_zeros, '-d', 'LineWidth', 2, 'DisplayName', 'CPM');
plot(ratios, random_zeros, '-^', 'LineWidth', 2, 'DisplayName', 'Random');

% CBM 데이터를 별 모양, 빨간색으로 plot, MarkerSize로 크기 조정
plot(ratios, chessboard_zeros, '-*r', 'LineWidth', 2, 'DisplayName', 'Chessboard', 'MarkerSize', 10);

% 그래프 설정
xlabel('Masking ratio');
ylabel('Average count of zero patches filtered by CNN');
legend('show', 'Location', 'northwest'); % 범례를 왼쪽 상단에 위치
grid on;
hold off;

'DE > Code' 카테고리의 다른 글

Adaptive encoder  (0) 2024.08.06
Proposed net  (0) 2024.08.06
Patch selection code (CBS)  (0) 2024.08.05
Image (variance , entropy , edge)  (0) 2024.08.05
CheckerBoard Selection  (0) 2024.07.30
Comments