共用方式為


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);

此命令會將 C:\rocket.bmp 影像大小調整為 224 x 224 圖元,以維持高品質的影像。

從 HWC 轉換為 CHW 的配置

CNTK中主要使用兩種版面配置類型:HWC 和 CHW。 第一個,HWC 是用於CNTK的預設格式。 第二個 CHW 是 GPU 中 cuDNN 所使用的格式。

請注意,實際的 檔案 配置 可能 不同。 我們正在查看記憶體標記法,而不是檔案內容

請注意,上述描述是指最快速移動維度最後一個常用資料 列主要 標記法。 CNTK通常會使用最快速移動維度的資料行主要標記法,其中以下分別會以 「CWH」 和 「WHC」 表示。

這表示假設使用 RGB 位元組大小為 10x10 的 HWC 格式點陣圖,記憶體空間會對應至:

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

將 影像資料擷取 Bitmap 至 CHW 配置的可能擴充方法可能是:

    /// <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 方法。