pytorch에서 커널을 변경하여 동일한 이미지에 대해 conv2d하는 메모

3314 단어 PyTorchconvolution

배경


  • 이미지 처리에서 필터를 변경하여 동일한 이미지에 각각 다른 필터 N 개를 적용 (conv2d)하고 싶습니다.
  • scipy.signal.convolve 그렇다면 느리다 ( mode=fft 에서 빨리 할 수 ​​있지만, 근사적인 결과가 될 것 같아...?) 그래서, pytorch 로 처리한다 (CUDA 를 사용할 수 있으면 GPU 로 고속화가 (예상 가능)
  • 흑백 이미지로 설정

  • depthwise convolution (Conv2d에서 groups 설정)이 필요한지 궁금했지만 in_channel = 1, out_channel = N에서 OK였습니다.

    절차



    weight는 [N, 1, KH, KW]로 만들 수 있습니다.
    device = torch.device('cuda') if torch.cuda.is_available() else torch.device('cpu')
    
    
    kernel_size = [3, 3]
    
    num_kernels = 4
    
    kernel = torch.zeros([num_kernels, 1, kernel_size[1], kernel_size[0]], dtype=torch.float32).to(device)
    
    # テスト用に channel ごとに all 1s, 2s, 3s, ... なのを用意する
    for i in range(num_kernels):
        kernel[i] = float(i) + 1
    
    print(kernel)
    
    
    tensor([[[[1., 1., 1.],
              [1., 1., 1.],
              [1., 1., 1.]]],
    
    
            [[[2., 2., 2.],
              [2., 2., 2.],
              [2., 2., 2.]]],
    
    
            [[[3., 3., 3.],
              [3., 3., 3.],
              [3., 3., 3.]]],
    
    
            [[[4., 4., 4.],
              [4., 4., 4.],
              [4., 4., 4.]]]], device='cuda:0')
    

    그런 다음 다음과 같이 conv2d를 설정 + 실행하십시오!
    
    # assume default stride and dilation and odd kernel size 
    conv = torch.nn.Conv2d(1, num_kernels, kernel_size, padding=[kernel_size[1]//2, kernel_size[0] // 2], bias=False, padding_mode='replicate')
    conv.weight = torch.nn.Parameter(kernel)
    
    img = np.ones(img_size).astype('float32')
    
    x = torch.from_numpy(img).to(device)
    
    # [h, w] -> [1, 1(c), h, w]
    x = torch.unsqueeze(torch.unsqueeze(x, 0), 0)
    
    # forward pass(eval convolution)
    with torch.no_grad():
        f = conv(x)
    
    f = f.to('cpu')
    print(f)
    
    tensor([[[[ 9.,  9.,  9.,  ...,  9.,  9.,  9.],
              [ 9.,  9.,  9.,  ...,  9.,  9.,  9.],
              [ 9.,  9.,  9.,  ...,  9.,  9.,  9.],
              ...,
              [ 9.,  9.,  9.,  ...,  9.,  9.,  9.],
              [ 9.,  9.,  9.,  ...,  9.,  9.,  9.],
              [ 9.,  9.,  9.,  ...,  9.,  9.,  9.]],
    
             [[18., 18., 18.,  ..., 18., 18., 18.],
              [18., 18., 18.,  ..., 18., 18., 18.],
              [18., 18., 18.,  ..., 18., 18., 18.],
              ...,
              [18., 18., 18.,  ..., 18., 18., 18.],
              [18., 18., 18.,  ..., 18., 18., 18.],
              [18., 18., 18.,  ..., 18., 18., 18.]],
    
             [[27., 27., 27.,  ..., 27., 27., 27.],
              [27., 27., 27.,  ..., 27., 27., 27.],
              [27., 27., 27.,  ..., 27., 27., 27.],
              ...,
              [27., 27., 27.,  ..., 27., 27., 27.],
              [27., 27., 27.,  ..., 27., 27., 27.],
              [27., 27., 27.,  ..., 27., 27., 27.]],
    
             [[36., 36., 36.,  ..., 36., 36., 36.],
              [36., 36., 36.,  ..., 36., 36., 36.],
              [36., 36., 36.,  ..., 36., 36., 36.],
              ...,
              [36., 36., 36.,  ..., 36., 36., 36.],
              [36., 36., 36.,  ..., 36., 36., 36.],
              [36., 36., 36.,  ..., 36., 36., 36.]]]])
    

    Voila!

    Channel (layer)마다 다른 kernel이 적용되고 있습니다!

    TODO



    RGB 이미지로 시도

    좋은 웹페이지 즐겨찾기