다음을 통해 공유


이미지 변환 평가 CNTK

이 페이지에서는 ImageReader로 공급되는 데이터로 학습된 CNTK 모델에서 이미지를 평가하기 전에 이미지를 변환할 수 있는 몇 가지 구현에 대해 설명합니다. 작업 예제는 CSEvalClient 예제 프로그램의 일부로 제공되며, 특히 메서드를 참조합니다 EvaluateImageClassificationModel .

개요

CNTK ImageReader 플러그 인을 사용하면 학습, 테스트 및 평가를 위해 CNTK 모델에 이미지 데이터를 공급할 수 있습니다. ImageReader에는 설정 시 이미지 데이터에 대한 일부 즉석 변환을 수행하는 몇 가지 구성 가능한 기능이 있습니다. 이러한 가능한 변환은 다음과 같습니다.

  • 자르기
  • 크기 조정
  • 평균 적용
  • 강도
  • 레이아웃(HWC 및 CHW)

CNTK.exe 및 이미지 판독기를 사용하여 이미지 평가

이 경우 이미지 변환을 구성 파일에 지정할 수 있으며 Imagereader는 정의된 변환을 수행합니다.

EvalDll(EvalWrapper)을 통한 프로그래밍 방식 이미지 평가

이 경우 필요한 이미지 변환은 이미지가 Evalwrapper에 전달되기 전에 프로그래밍 방식으로 수행되어야 합니다.

이 섹션에서는 평가 전에 이러한 변환 중 일부를 수행할 수 있는 몇 가지 구현을 제공합니다.

예를 들어 CntkBitmapExtensions라는 정적 클래스에는 아래에 표시된 확장 메서드가 포함될 수 있습니다.

크기 조정

    /// <summary>
    /// Resizes an image
    /// </summary>
    /// <param name="image">The image to resize</param>
    /// <param name="width">New width in pixels</param>
    /// <param name="height">New height in pixesl</param>
    /// <param name="useHighQuality">Resize quality</param>
    /// <returns>The resized image</returns>
    public static Bitmap Resize(this Bitmap image, int width, int height, bool useHighQuality)
    {
        var rect = new Rectangle(0, 0, width, height);
        var newImg = new Bitmap(width, height);

        newImg.SetResolution(image.HorizontalResolution, image.VerticalResolution);

        using (var g = Graphics.FromImage(newImg))
        {
            g.CompositingMode = System.Drawing.Drawing2D.CompositingMode.SourceCopy;
            if (useHighQuality)
            {
                g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
                g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
                g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
                g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
            }
            else
            {
                g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.Default;
                g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.Default;
                g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.Default;
                g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.Default;
            }

            var attributes = new ImageAttributes();
            attributes.SetWrapMode(System.Drawing.Drawing2D.WrapMode.TileFlipXY);
            g.DrawImage(image, rect, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, attributes);
        }

        return newImg;
    }

이 경우 다음과 같은 호출이 발생할 수 있습니다.

 var testBitmap = new Bitmap(Bitmap.FromFile(@"C:\rocket.bmp")).Resize(224, 224, true);

이 명령은 이미지 크기를 224 x 224 픽셀 크기로 조정 C:\rocket.bmp 하여 고품질 이미지를 유지합니다.

HWC에서 CHW로 레이아웃 변환

주로 CNTK HWC 및 CHW라는 두 가지 레이아웃 유형이 사용됩니다. 첫 번째 HWC는 CNTK 사용되는 기본 형식입니다. 두 번째 CHW는 GPU에서 cuDNN에서 사용하는 형식입니다.

실제 파일 레이아웃은 다를 수 있습니다 . 파일 콘텐츠가 아닌 메모리 표현을 살펴보고 있습니다.

위의 설명은 가장 빠르게 움직이는 차원이 마지막으로 오는 일반적으로 사용되는 행 주 표기법을 참조합니다. CNTK 일반적으로 가장 빠르게 움직이는 차원을 먼저 사용하고 아래는 각각 "CWH" 및 "WHC"로 표현되는 열 주 표기법을 사용합니다.

즉, RGB 바이트를 사용하여 HWC 형식이 10x10인 비트맵을 가정하면 메모리 공간은 다음과 같습니다.

Offset (byte) :  0  1  2  3  4  5  6  7  8 ...29 30 31 32 33 34 35 36 37 ...
Height Pos    :  0  0  0  0  0  0  0  0  0 ... 0  0  0  1  1  1  1  1  1 ...
Width Pos     :  0  0  0  1  1  1  2  2  2 ... 9  9  9  0  0  0  1  1  1 ...
Color Index   :  B  G  R  B  G  R  B  G  R ... B  G  R  B  G  R  B  G  R ...

CHW의 경우 레이아웃은 다음과 같습니다.

Offset (byte) :  0  1  2  3 ... 9 10 11 12 13 ...90 91 92 93 ... 99 100 ... 199 200 ... 299 
Color Index   :  B  B  B  B ... B  B  B  B  B ... B  B  B  B ...  B   G ...   G   R ...   R
Height Pos    :  0  0  0  0 ... 0  0  0  0  0 ... 9  9  9  9 ...  9   0 ...   9   0 ...   9
Width Pos     :  0  1  2  3 ... 9  0  1  2  3 ... 0  1  2  3 ...  9   0 ...   9   0 ...   9

CHW 레이아웃으로 이미지 데이터를 추출할 수 있는 Bitmap확장 메서드는 다음과 같습니다.

    /// <summary>
    /// Extracts image pixels in CHW
    /// </summary>
    /// <param name="image">The bitmap image to extract features from</param>
    /// <returns>A list of pixels in HWC order</returns>
    public static List<float> ExtractCHW(this Bitmap image)
    {
        var features = new List<float>(image.Width * image.Height * 3);
        for (int c = 0; c < 3; c++)
        {
            for (int h = 0; h < image.Height; h++)
            {
                for (int w = 0; w < image.Width; w++)
                {
                    var pixel = image.GetPixel(w, h);
                    float v = c == 0 ? pixel.B : c == 1 ? pixel.G : pixel.R;

                    features.Add(v);
                }
            }
        }

        return features;
    }

이 메서드는 Bitmap.GetPixel 일부 메모리 레이아웃 뉘앙스를 처리하므로 변환 자체에 집중할 수 있습니다.

이제 이 메서드를 평가하기 전에 이미지 변환에 사용할 수 있습니다. Resize와 동일한 비트맵을 가정하면 다음 호출을 사용하여 CHW 레이아웃에서 해당 데이터를 추출할 수 있습니다.

var features = testBitmap.ExtractCHW();

features 이제 벡터를 이미지 분류 모델에 대한 계층 입력으로 사용할 수 있습니다. 작업 예제는 예제 프로그램의 일부로 CSEvalClient 제공되며, 특히 메서드를 참조합니다 EvaluateImageClassificationModel .