Несколько дней go я переключился с тензорного потока на фастай для моего c# проекта. Но сейчас у меня проблема с нормализацией. Для обоих я использую конвейер onnx для загрузки модели и данных.
var onnxPipeline = mLContext.Transforms.ResizeImages(resizing: ImageResizingEstimator.ResizingKind.Fill, outputColumnName: inputName,
imageWidth: ImageSettings.imageWidth, imageHeight: ImageSettings.imageHeight,
inputColumnName: nameof(ImageInputData.Image))
.Append(mLContext.Transforms.ExtractPixels(outputColumnName: inputName, interleavePixelColors: true, scaleImage: 1 / 255f))
.Append(mLContext.Transforms.ApplyOnnxModel(outputColumnName: outputName, inputColumnName: inputName, modelFile: onnxModelPath));
var emptyData = mLContext.Data.LoadFromEnumerable(new List<ImageInputData>());
var onnxModel = onnxPipeline.Fit(emptyData);
с
class ImageInputData
{
[ImageType(ImageSettings.imageHeight, ImageSettings.imageWidth)]
public Bitmap Image { get; set; }
public ImageInputData(byte[] image)
{
using (var ms = new MemoryStream(image))
{
Image = new Bitmap(ms);
}
}
public ImageInputData(Bitmap image)
{
Image = image;
}
}
После использования fastai я узнал, что модели получают лучшую точность, если данные нормализованы с указанным средним значением c и стандартным отклонением (потому что я использовал для модели resnet34 это должно быть {0,485, 0,456, 0,406} стандартное значение = {0,229, 0,224, 0,225} соответственно). Таким образом, значения пикселей (для каждого цвета c.) Должны быть преобразованы с этими значениями, чтобы соответствовать изображениям тренировок. Но как я могу достичь этого в C#? До сих пор я пробовал:
int imageSize = 256;
double[] means = new double[] { 0.485, 0.456, 0.406 }; // used in fastai model
double[] stds = new double[] { 0.229, 0.224, 0.225 };
Bitmap bitmapImage = inputBitmap;
Image image = bitmapImage;
Color[] pixels = new Color[imageSize * imageSize];
for (int x = 0; x < bitmapImage.Width; x++)
{
for (int y = 0; y < bitmapImage.Height; y++)
{
Color pixel = bitmapImage.GetPixel(x, y);
pixels[x + y] = pixel;
double red = (pixel.R - (means[0] * 255)) / (stds[0] * 255); // *255 to scale the mean and std values to the Bitmap
double gre = (pixel.G - (means[1] * 255)) / (stds[1] * 255);
double blu = (pixel.B - (means[2] * 255)) / (stds[2] * 255);
Color pixel_n = Color.FromArgb(pixel.A, (int)red, (int)gre, (int)blu);
bitmapImage.SetPixel(x, y, pixel_n);
}
}
Конечно, он не работает, потому что значения цветов не могут быть отрицательными (что я понял только позже). Но как мне добиться этой нормализации между -1 и 1 для моей модели в C# с помощью onnx-модели?
Есть ли другой способ подачи модели или обработки нормализации?
Любая помощь будет оценена!