Читаю стати как получить вектор изображения для анализа аномалий и отклонения от нормальных изображений. Везде советуют взять модель обученные классифицировать (например AlexNet). И получить вектор из предпоследнего слоя модели, после чего его уже
сравнивать.
Я использую для этого C# и для взаимодействия с моделями советуют использовать ML.NET и модели формата .onnx
Однако как получить данные из промежуточных слоев? У меня это не получается, я использую единственную модель AlexNet доступную на
huggingface . И в ней нет промежуточных слоев. Я подумал, что может быть это такая модель и я могу использовать любую другую
модель, но не одна не обладает такими слоями (посмотреть можно
здесь). Как мне взять вектор из предпоследнего слоя до слоя классификации или добавить этот слой? Или может быть есть другой подход?
Заранее благодарю за ответ.
Пример кода из документации для вывода значений из промежуточных слоев:
static async Task Main(string[] args)
{
// Путь к модели
string modelPath = @"C:\Users\*\AlexNet\model (5).onnx";
// Путь к изображению
string imagePath = @"C:\Users\*\1.jpg";
// Загрузка модели
using var session = new InferenceSession(modelPath);
// Получение информации о входных и выходных тензорах
var inputMeta = session.InputMetadata;
var outputMeta = session.OutputMetadata;
// Получение имен всех выходов (слоев)
var outputNames = session.OutputMetadata.Keys.ToList();
// Загрузка и предварительная обработка изображения
var inputTensor = PreprocessImage(imagePath, new[] { 1, 3, 224, 224 });
// Создание списка входных данных для инференса
var inputs = new List<NamedOnnxValue>
{
NamedOnnxValue.CreateFromTensor("input.1", inputTensor)
};
// Запуск инференса
using var results = session.Run(inputs);
// Печать результатов для каждого выходного тензора
foreach (var outputName in outputNames)
{
var result = results.FirstOrDefault(r => r.Name == outputName);
if (result != null)
{
Console.WriteLine($"Output name: {result.Name}");
var tensor = result.AsTensor<float>();
var values = tensor.ToArray();
//Console.WriteLine($"Output shape: {string.Join(", ", tensor.Dimensions)}");
Console.WriteLine($"Output values: {string.Join(", ", values.Take(10))}"); // Печать первых 10 значений для примера
}
}
}
static Tensor<float> PreprocessImage(string imagePath, int[] targetSize)
{
// Загрузка изображения
using var image = Image.FromFile(imagePath);
// Преобразование изображения в массив байтов
using var bitmap = new Bitmap(image, new Size(targetSize[2], targetSize[3]));
var bitmapData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
// Извлечение данных изображения
var bytes = new byte[bitmapData.Stride * bitmapData.Height];
System.Runtime.InteropServices.Marshal.Copy(bitmapData.Scan0, bytes, 0, bytes.Length);
bitmap.UnlockBits(bitmapData);
// Преобразование данных в тензор
var tensor = new DenseTensor<float>(targetSize);
for (int y = 0; y < targetSize[2]; y++)
{
for (int x = 0; x < targetSize[3]; x++)
{
var offset = (y * bitmapData.Stride) + (x * 3);
var r = bytes[offset + 2];
var g = bytes[offset + 1];
var b = bytes[offset];
tensor[0, 0, y, x] = r / 255f;
tensor[0, 1, y, x] = g / 255f;
tensor[0, 2, y, x] = b / 255f;
}
}
return tensor;
}