분해 및 풀링을 사용하는 이미지 자동 인코더

목차

요약

image

Image\GettingStarted\07_Deconvolution_PY.py 예제에서는 디컨볼루션 및 풀링을 사용하여 간단한 이미지 자동 인코더를 생성하는 방법을 보여 줍니다(07_Deconvolution_BS.cntk는 해당 BrainScript 버전). 해상도가 28x28x1인 MNIST 데이터 세트를 사용하여 컨볼루션 및 풀링을 사용하여 7x7x1 표현으로 인코딩하고 원래 해상도로 디코딩합니다. 학습 기준은 RMSE(루트 평균 제곱 오차)입니다. 위의 그림은 MNIST 테스트 집합의 처음 5개 이미지에 대한 원본 이미지, 인코딩된 이미지 및 디코딩된 이미지의 시각화를 보여 줍니다.

설치 프로그램

예제를 실행하려면 MNIST 데이터 집합이 필요합니다. 폴더에서 Examples\Image\DataSets\MNIST 다음 명령을 실행하여 데이터를 가져올 수 있습니다.

python install_mnist.py

예제 실행

이 예제는 폴더에 Examples\Image\GettingStarted 있습니다. 이 예제를 실행하려면 다음 명령을 사용하여 Python CNTK 환경에서 Python 버전을 실행합니다.

python 07_Deconvolution_PY.py

또는 BrainScript 버전에 대한 이 명령:

cntk configFile=07_Deconvolution_BS.cntk

학습 및 테스트에 대한 RMSE 값은 각각 0.225 및 0.223입니다. 인코딩 및 디코딩된 이미지를 시각화하려면 다음 명령을 실행합니다.

python 07_Deconvolution_Visualizer.py

BrainScript 모델 및 False Python 모델에 대해 설정합니다use_brain_script_model=True. 시각화는 인코더 및 디코더 출력의 텍스트 표현과 함께 아래 Examples\Image\GettingStarted 폴더에 저장 Output 됩니다.

기술 세부 정보

다음은 BrainScript의 간단한 이미지 자동 인코더에 대한 모델 정의입니다(전체 구성 파일의 경우 Image\GettingStarted\07_Deconvolution_BS.cntk 참조).

    cMap = 1
    model = inputFeatures => {
        conv1   = ConvolutionalLayer {cMap, (5:5), pad = true, activation=ReLU}(inputFeatures)
        pool1   = MaxPoolingLayer    {(4:4), stride=(4:4)}(conv1)
        unpool1 = MaxUnpoolingLayer  {(4:4), stride=(4:4)}(pool1, conv1)
        deconv1 = DeconvLayer        {1, (5:5), cMap, lowerPad=(2:2:0), upperPad=(2:2:0), bias=false}(unpool1)
    }.deconv1

07_Deconvolution_PY.py의 해당 모델 정의는

    cMap = 1
    conv1   = cntk.layers.Convolution  ((5,5), cMap, pad=True, activation=cntk.ops.relu)(scaled_input)
    pool1   = cntk.layers.MaxPooling   ((4,4), (4,4))(conv1)
    unpool1 = cntk.layers.MaxUnpooling ((4,4), (4,4))(pool1, conv1)
    z       = cntk.layers.Deconvolution((5,5), num_channels, cMap, lower_pad=(0,2,2), upper_pad=(0,2,2), bias=False, init=cntk.glorot_uniform(0.001))(unpool1)
    

여기서 BrainScript 버전을 설명합니다. Python 버전은 유사합니다. 이 모델은 먼저 입력 기능에 깊이 cMap=1 가 있는 ConvolutionalLayer를 적용한 다음 ReLU 활성화를 적용하고 필터 모양과 보폭 (4:4)이 있는 MaxPoolingLayer를 사용합니다. 이로 인해 인코딩된 텐서 크기가 생성 7x7x1됩니다. 그런 다음 해당 필터 셰이프가 있는 MaxUnpoolingLayer 및 DeconvLayer를 사용하여 원래 해상도로 다시 디코딩합니다.

디코더 부분은 원래 784 (28x28) 숫자를 49 ( 167x7)로 압축합니다. ConvolutionalLayer에 대한 깊이 1 만 사용하면 인코더 결과를 의미 있는 방식으로 시각화할 수 있다는 이점이 있습니다(이 페이지의 맨 위에 있는 그림 참조). 예를 들어 압축을 줄이고 더 나은 디코딩 결과를 갖도록 cMap=3 나선형 필터의 수를 늘릴 수 있습니다. 이 예제에서는 학습 및 테스트 모두에 대한 RMSE가 으로 줄어듭니다 0.196. 압축을 줄이는 또 다른 방법은 풀링 계층에 더 작은 필터 모양과 보폭을 사용하는 것입니다. 풀링 및 풀링 모두에 사용하면 (2:2) 인코딩된 크기의 14x14x1 텐서가 생성되고 이 예제의 RMSE가 학습 및 0.131 테스트용으로 0.136 줄어듭니다. 아래 그림은 논의된 세 가지 설정에 대해 설정된 MNIST 테스트 집합의 처음 5개 이미지에 대한 원본 이미지 및 디코딩된 이미지의 시각화를 보여 줍니다.

image

디컨볼루션 및 풀링 해제

MaxUnpoolingLayer 및 DeconvLayer를 좀 더 자세히 살펴보겠습니다.

MaxUnpoolingLayer {(4:4), stride=(4:4)}(pool1, conv1)

MaxPoolingLayer에는 해당 풀링 계층(pool1 이 경우)의 출력과 해당 풀링 계층conv1 (이 경우)의 입력인 두 개의 입력이 필요합니다. conv1는 CNTK CNTK 소위 스위치 변수를 저장하지 않으므로 풀링 해제 작업의 대상을 확인하는 데 필요합니다(자세한 내용은 여기 참조).

DeconvLayer {1, (5:5), cMap, lowerPad=(2:2:0), upperPad=(2:2:0)}

DeconvLayer의 첫 번째 매개 변수는 출력 볼륨의 깊이이고, 두 번째 매개 변수는 커널 셰이프(width:height)이고, 세 번째 매개 변수는 입력 볼륨의 깊이입니다. 출력 텐서(이 경우 28x28)의 원하는 너비와 높이를 달성하려면 패딩 매개 변수를 커널 모양에 따라 설정해야 합니다. DeconvLayer에 대한 자세한 내용은 레이어 참조 페이지를 참조하세요.

다중 계층 자동 인코더

더 복잡한 자동 인코더를 위해 더 많은 Conv/Deconv 및 풀/풀/풀 계층을 쌓을 수 있습니다. 다음은 사용할 수 있는 각 형식의 두 계층이 있는 07_Deconvolution_BS.cntk 예제입니다(파일의 모델을 바꾸기만 하면 됩니다).

    inputDim = 1
    cMap1 = 5
    cMap2 = 1
    model = inputFeatures => {
        conv_A   = ConvolutionalLayer {cMap1, (5:5), pad = true, activation=ReLU}(inputFeatures)
        pool_A   = MaxPoolingLayer    {(2:2), stride=(2:2)}(conv_A)
        conv_B   = ConvolutionalLayer {cMap2, (5:5), pad = true, activation=ReLU}(pool_A)
        pool_B   = MaxPoolingLayer    {(2:2), stride=(2:2)}(conv_B)
        unpool_B = MaxUnpoolingLayer  {(2:2), stride=(2:2)}(pool_B, conv_B)
        deconv_B = DeconvLayer        {cMap1, (5:5), cMap2, lowerPad=(2:2:0), upperPad=(2:2:0)}(unpool_B)
        unpool_A = MaxUnpoolingLayer  {(2:2), stride=(2:2)}(deconv_B, conv_A)
        deconv_A = DeconvLayer        {inputDim, (5:5), cMap1, lowerPad=(2:2:0), upperPad=(2:2:0)}(unpool_A)
    }.deconv_A

인코더 출력에 대한 올바른 노드 이름을 해결하기 위해 실행하기 전에 대체해야 z.pool1z.pool_B07_Deconvolution_Visualizer.py 하는 결과를 시각화합니다. 모델의 모든 노드 이름을 조사하려면 Python 스크립트에서 주석 처리를 print_all_node_names(model_file) 제거하기만 하면됩니다.