CNTK Utvärdera bildtransformeringar
På den här sidan beskrivs några möjliga implementeringar för att transformera bilder innan de utvärderas på en CNTK modell som har tränats med data som matas med ImageReader. Ett fungerande exempel tillhandahålls som en del av CSEvalClient-exempelprogrammet , särskilt referera till EvaluateImageClassificationModel
metoden .
Översikt
Med plugin-programmet CNTK ImageReader kan du mata in bilddata i CNTK modell för träning, testning och utvärdering. ImageReader har vissa konfigurerbara funktioner som när den är aktiverad kan utföra vissa direkttransformeringar till bilddata. Dessa möjliga transformeringar är:
- Beskärning
- Ändra storlek
- Tillämpa medelvärdet
- Intensitet
- Färg
- Layout (HWC jämfört med CHW)
Bildutvärdering med CNTK.exe och bildläsaren
I det här fallet kan bildtransformeringar anges i konfigurationsfilen, och Imagereader utför de definierade omvandlingarna.
Programmeringsbildutvärdering via EvalDll(EvalWrapper)
I det här fallet måste nödvändiga bildtransformeringar utföras programmatiskt innan avbildningen skickas till Evalwrapper.
Det här avsnittet innehåller några möjliga implementeringar för att utföra några av dessa transformeringar före utvärderingen.
Till exempel kan en statisk klass med namnet CntkBitmapExtensions innehålla tilläggsmetoderna som visas nedan.
Ändra storlek
/// <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;
}
I det här fallet kan ett eventuellt anrop vara:
var testBitmap = new Bitmap(Bitmap.FromFile(@"C:\rocket.bmp")).Resize(224, 224, true);
Det här kommandot ändrar storlek på C:\rocket.bmp
bilden till en storlek på 224 x 224 bildpunkter med en bild av hög kvalitet.
Layoutkonvertering från HWC till CHW
Det finns främst två layouttyper som används i CNTK: HWC och CHW. Det första HWC är standardformatet som används i CNTK. Den andra, CHW, är det format som används av cuDNN i GPU:n.
Observera att den faktiska fillayoutenkan vara annorlunda. Vi tittar på minnesrepresentationen, inte filinnehållet
Observera att beskrivningarna ovan refererar till den vanliga rad-större notationen där den snabbast rörliga dimensionen kommer sist. CNTK använder vanligtvis kolumnmajornotation som använder den snabbast rörliga dimensionen först och där nedanstående uttrycks som "CWH" respektive "WHC".
Det innebär att om vi antar en bitmapp med HWC-format av storlek 10x10 med RGB-byte, skulle minnesutrymmet motsvara:
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 ...
När det gäller chw skulle layouten vara:
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
En möjlig tilläggsmetod som extraherar avbildningsdata Bitmap
till CHW-layouten kan vara:
/// <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;
}
Metoden Bitmap.GetPixel
tar hand om några av minneslayoutens nyanser, så att vi kan fokusera på själva omvandlingen.
Den här metoden kan nu användas i vår bildtransformering före utvärderingen. Om vi antar samma bitmapp som i Ändra storlek kan vi extrahera dess data i CHW-layouten med följande anrop:
var features = testBitmap.ExtractCHW();
features
Vektorn kan nu användas som lagerindata till bildklassificeringsmodellen. Ett fungerande exempel tillhandahålls som en del av CSEvalClient
exempelprogrammet, i synnerhet refererar till EvaluateImageClassificationModel
metoden .