Я новичок в tenorflow.js и tenorflow
Контекст: мы обучили модель, используя нестандартное зрение для распознавания по изображению, длина волос: короткая, средняя, длинная. Эта модель была экспортирована, и мы хотели бы использовать ее локально с tenorflow js. Экспортируемые файлы из пользовательского видения - это файл * .pb и файл label.txt.
Я использовал скрипт python tenorflowjs_converter, вот команда, которую я использовал для преобразования замороженной модели * .pb в модель json:
tensorflowjs_converter --input_format=tf_frozen_model --output_node_names='model_outputs' --output_json OUTPUT_JSON C:\python\tf_models\hairlength\model.pb C:\python\tf_models\exports\
Затем я вставляю этот model.json и осколки в папку активов моего углового клиента. Затем я пытаюсь загрузить модель и даю ему изображение, чтобы получить прогноз, но все, что я получаю, это значения индексов, которые выходят за границы, так как мне нужны только 0: длинная, 1: средняя, 2: короткая длина волос. Вот захват консоли
![prediction list](https://i.stack.imgur.com/jZfTx.png)
Это класс, который я использовал в моем клиенте (машинопись) для предсказаний:
import * as tf from '@tensorflow/tfjs';
// import {HAIRLENGTH_LABELS} from './hairlength';
import { FrozenModel } from '@tensorflow/tfjs';
const MODEL = 'assets/models/hairlength/model.json';
const INPUT_NODE_NAME = 'model_outputs';
const OUTPUT_NODE_NAME = 'model_outputs';
const PREPROCESS_DIVISOR = tf.scalar(255 / 2);
export class MobileNetHairLength {
private model: FrozenModel;
private labels = ['long', 'mid', 'short'];
constructor() {}
async load(){
this.model = await tf.loadGraphModel(MODEL);
}
dispose() {
if (this.model) {
this.model.dispose();
}
}
/**
* Infer through MobileNet. This does standard ImageNet pre-processing before
* inferring through the model. This method returns named activations as well
* as softmax logits.
*
* @param input un-preprocessed input Array.
* @return The softmax logits.
*/
predict(input) {
const preprocessedInput = tf.div(
tf.sub(input, PREPROCESS_DIVISOR),
PREPROCESS_DIVISOR);
const reshapedInput =
preprocessedInput.reshape([1, ...preprocessedInput.shape]);
// tslint:disable-next-line:no-unused-expression
return this.model.execute({[INPUT_NODE_NAME]: reshapedInput}, OUTPUT_NODE_NAME);
}
getTopKClasses(logits, topK: number) {
const predictions = tf.tidy(() => {
return tf.softmax(logits);
});
const values = predictions.dataSync();
predictions.dispose();
let predictionList = [];
for (let i = 0; i < values.length; i++) {
predictionList.push({value: values[i], index: i});
}
predictionList = predictionList
.sort((a, b) => {
return b.value - a.value;
})
.slice(0, topK);
console.log(predictionList);
return predictionList.map(x => {
return {label: this.labels[x.index], value: x.value};
});
}
}
И этот класс, который вызывает вышеупомянутый, я просто даю элемент canvas:
import 'babel-polyfill';
import * as tf from '@tensorflow/tfjs';
import { MobileNetHairLength } from './mobilenet-hairlength';
export class PredictionHairLength {
constructor() {}
async predict(canvas) {
const mobileNet = new MobileNetHairLength();
await mobileNet.load();
const pixels = tf.browser.fromPixels(canvas);
console.log('Prediction');
const result = mobileNet.predict(pixels);
const topK = mobileNet.getTopKClasses(result, 3);
topK.forEach(x => {
console.log( `${x.value.toFixed(3)}: ${x.label}\n` );
});
mobileNet.dispose();
}
}
Мои вопросы:
Правильна ли команда преобразования Python?
Я что-то упустил в своем клиенте, чтобы получить правильные индексы?
Спасибо за ваше время и ответы
Если вам нужна дополнительная информация, я был бы рад предоставить ее вам
Обновления 10/03/2019
Я обновил тензор потока до 1.0.0, используя npm
Я видел, что FrozenModel устарела
Экспорт моей пользовательской модели видения дает мне файлы model.pb и tags.txt, например:
![custom vision exports](https://i.stack.imgur.com/Bks3J.png)
Я пытался использовать эти файлы с Python, все работает нормально ...
Теперь я хотел бы преобразовать этот файл model.pb в файл model.json, чтобы использовать его с tennorflowjs, для этого мне нужно использовать tennsflowjs_converter, проблема в том, что структура файла для преобразования этой сохраненной модели недопустима, см. https://www.tensorflow.org/guide/saved_model#structure_of_a_savedmodel_directory
Единственное, что работает, если я использую формат frozen_model в конвертере и даю имя узла вывода: потеря ... как это tensorflowjs_converter --input_format=tf_frozen_model --output_node_names='loss' --output_json OUTPUT_JSON C:\python\tf_models\hairlength\model.pb C:\python\tf_models\exports\
Это выходные данные, которые я получаю при выполнении вышеуказанной команды:
затем я загружаю модель, вот мой код для загрузки и прогнозирования с использованием экспортированной модели json (я использую предикат () и удаляю узлы ввода и вывода, как вы мне посоветовали):
import * as tf from '@tensorflow/tfjs';
import { GraphModel } from '@tensorflow/tfjs';
const MODEL = 'assets/models/hairlength/model.json';
// const INPUT_NODE_NAME = 'Placeholder';
// const OUTPUT_NODE_NAME = 'loss';
const PREPROCESS_DIVISOR = tf.scalar(255 / 2);
export class MobileNetHairLength {
private model: GraphModel;
private labels = ['long', 'mid', 'short'];
constructor() {}
async load() {
this.model = await tf.loadGraphModel(MODEL);
}
dispose() {
if (this.model) {
this.model.dispose();
}
}
/**
* Infer through MobileNet. This does standard ImageNet pre-processing before
* inferring through the model. This method returns named activations as well
* as softmax logits.
*
* @param input un-preprocessed input Array.
* @return The softmax logits.
*/
predict(input: tf.Tensor<tf.Rank>) {
const preprocessedInput = tf.div(
tf.sub(input.asType('float32'), PREPROCESS_DIVISOR),
PREPROCESS_DIVISOR);
const reshapedInput =
preprocessedInput.reshape([...preprocessedInput.shape]);
return this.model.predict(reshapedInput);
}
getTopKClasses(logits, topK: number) {
const predictions = tf.tidy(() => {
return tf.softmax(logits);
});
const values = predictions.dataSync();
predictions.dispose();
let predictionList = [];
for (let i = 0; i < values.length; i++) {
predictionList.push({value: values[i], index: i});
}
predictionList = predictionList
.sort((a, b) => {
return b.value - a.value;
})
.slice(0, topK);
console.log(predictionList);
return predictionList.map(x => {
return {label: this.labels[x.index], value: x.value};
});
}
}
И вызывающий класс вот этот:
import 'babel-polyfill';
import * as tf from '@tensorflow/tfjs';
import { MobileNetHairLength } from './mobilenet-hairlength';
export class PredictionHairLength {
constructor() {}
async predict(canvas) {
// Convert to tensor
const mobileNet = new MobileNetHairLength();
await mobileNet.load();
const imgTensor = tf.browser.fromPixels(canvas);
console.log(imgTensor);
// Init input with correct shape
const input = tf.zeros([1, 224, 224, 3]);
// Add img to input
input[0] = imgTensor;
console.log('Prediction');
const result = mobileNet.predict(input);
console.log(result);
const topK = mobileNet.getTopKClasses(result, 3);
topK.forEach(x => {
console.log( `${x.value.toFixed(3)}: ${x.label}\n` );
});
mobileNet.dispose();
}
}
Тогда отправка элемента canvas, взятого из потока веб-камеры, выдает мне эту ошибку:
![js error](https://i.stack.imgur.com/45QNa.png)
Как можно запустить команду конвертера в формате «сохраненная модель», поскольку структура файла неверна?
Почему я получаю 'Ошибка компиляции фрагмента шейдера, бесконечность: необъявленный идентификатор в tf-core.esm'?
Спасибо за ваше время и ответы