Различные прогнозы при работе в Node вместо Browser (с использованием той же модели model_web - python конвертированной) - PullRequest
0 голосов
/ 14 февраля 2020

довольно плохо знакомы с ML и тензорным потоком!

Я создал модель обнаружения объектов с http://cloud.annotations.ai, которая позволяет обучать и конвертировать модель в различных форматах, tf js (model_web ) тоже. Этот веб-сайт также предоставляет шаблоны для запуска модели в браузере (реагирующее приложение) ... точно так же, как вы делаете - возможно, это тот же код, который не потратил достаточно времени.

Так что у меня запущена эта модель внутри браузера, давая прогноз об объектах на фотографии с довольно хорошими результатами, учитывая количество примеров, которые я привел, и оценку прогноза (0,89). данная ограничительная рамка тоже хороша.

Но, к сожалению, у меня не было «только одного видео» для анализа кадр за кадром в браузере, у меня их много. Поэтому я решил переключиться на node.js, портируя код как есть. Угадай, что? TF. js опирается на DOM и компоненты браузера, и практически нет примеров, которые работают с Node. Так что ничего страшного, просто провел утро, выясняя все недостающие части. Наконец, я могу запустить свою модель поверх видео, которые разделены на кадры, с приличной скоростью - хотя при использовании баннера tf * 1041 с надписью «Здравствуйте, используйте tf js -node для увеличения скорости». * -узел - но результаты кажутся странными. Сравнение одного и того же изображения с той же папкой model_web дало тот же прогноз, но с более низким показателем (0,80 вместо 0,89) и другим ограничивающим прямоугольником, причем объект не центрировался вообще.

(TL; DR)

Имеет ли tf js различную реализацию библиотек (узел tf js и tf js), которые по-разному используют одну и ту же модель? Я не думаю, что это может быть проблемой ввода, потому что - после долгого поиска и борьбы - я придумываю два способа передать изображение в tf.browser.getPixel в Node (и я все еще задаюсь вопросом, почему я должен использовать метод «браузер» внутри узла tf js). Кто-нибудь делал сравнения?

Итак ... вот код, который я использовал, для вашей справки:

model_web загружается с tf.loadGraphModel("file://path/to/model_web/model.json");

двумя разными способами конвертировать JPG и заставить его работать с tf.browser.getPixel ()

const inkjet = require('inkjet');
const {createCanvas, loadImage} = require('canvas');

const decodeJPGInkjet = (file) => {
    return new Promise((rs, rj) => {
        fs.readFile(file).then((buffer) => {
            inkjet.decode(buffer, (err, decoded) => {
                if (err) {
                    rj(err);
                } else {
                    rs(decoded);
                }
            });
        });
    });
};

const decodeJPGCanvas = (file) => {
    return loadImage(file).then((image) => {
        const canvas = createCanvas(image.width, image.height);
        const ctx = canvas.getContext('2d');
        ctx.drawImage(image, 0, 0, image.width, image.height);
        const data = ctx.getImageData(0, 0, image.width, image.height);
        return {data: new Uint8Array(data.data), width: data.width, height: data.height};
    });
};

, и это код, который использует загруженную модель для предоставления прогнозов - один и тот же код для узла и браузера, найденный в https://github.com/cloud-annotations/javascript-sdk/blob/master/src/index.js - не работает на узле как есть, я изменил require("@tensorflow/tfjs"); на require("@tensorflow/tfjs-node"); и заменил fetch на fs.read

const runObjectDetectionPrediction = async (graph, labels, input) => {
    const batched = tf.tidy(() => {
        const img = tf.browser.fromPixels(input);
        // Reshape to a single-element batch so we can pass it to executeAsync.
        return img.expandDims(0);
    });

    const height = batched.shape[1];
    const width = batched.shape[2];

    const result = await graph.executeAsync(batched);

    const scores = result[0].dataSync();
    const boxes = result[1].dataSync();

    // clean the webgl tensors
    batched.dispose();
    tf.dispose(result);

    const [maxScores, classes] = calculateMaxScores(
        scores,
        result[0].shape[1],
        result[0].shape[2]
    );

    const prevBackend = tf.getBackend();
    // run post process in cpu
    tf.setBackend("cpu");
    const indexTensor = tf.tidy(() => {
        const boxes2 = tf.tensor2d(boxes, [result[1].shape[1], result[1].shape[3]]);
        return tf.image.nonMaxSuppression(
            boxes2,
            maxScores,
            20, // maxNumBoxes
            0.5, // iou_threshold
            0.5 // score_threshold
        );
    });
    const indexes = indexTensor.dataSync();
    indexTensor.dispose();
    // restore previous backend
    tf.setBackend(prevBackend);

    return buildDetectedObjects(
        width,
        height,
        boxes,
        maxScores,
        indexes,
        classes,
        labels
    );
};

1 Ответ

0 голосов
/ 19 февраля 2020

Различная реализация библиотек (узел tf js и tf js), которые по-разному используют одну и ту же модель

Если одна и та же модель развернута в обеих в браузере и в nodejs прогноз будет одинаковым.

Если прогнозируемое значение отличается, оно может быть связано с тензором, используемым для прогнозирования. Обработка от тензора к изображению может отличаться, в результате чего для прогнозирования используются разные тензоры, что приводит к разным результатам.

Я нашел два способа передачи изображения в tf.browser. .getPixel в Node (и я все еще задаюсь вопросом, почему я должен использовать метод «browser» внутри tf js -node)

Пакет canvas использует систему graphi c для создания браузер, как холст, который может использоваться nodejs. Это позволяет использовать пространство имен tf.browser, особенно когда речь идет о преобразовании изображений. Однако для создания тензора все еще можно использовать буфер nodejs.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...