我是tensorflow.js和tensorflow的新手
上下文:我们已经使用自定义视觉训练了一个模型,以便从图像中识别头发的长度:短,中,长。该模型已导出,我们希望将其与tensorflow js一起在本地使用。从自定义视觉导出的文件是* .pb文件和labels.txt文件。
我使用了tensorflowjs_converter python脚本,这是我用来在json模型中转换冻结模型* .pb的命令:
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:短发即可。这是控制台的截图
这是我在客户端(打字稿)中用于预测的类:
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();
}
}
我的问题是:
感谢您的时间和答案
如果您需要更多信息,我很乐意将它们提供给您
我确实使用npm将tensorflowjs更新为1.0.0
我看到FrozenModel现在已弃用
导出我的自定义视觉模型会给我一个model.pb和labels.txt文件,如下所示:
我尝试将这些文件与python一起使用时一切正常... 我现在想将这个model.pb文件转换为model.json文件,以便与tensorflowjs一起使用,为此,我需要使用tensorflowjs_converter,问题在于转换此保存的模型的文件结构无效,请参见:https://www.tensorflow.org/guide/saved_model#structure_of_a_savedmodel_directory
唯一的工作是,如果我在转换器中使用Frozen_model格式并给出输出节点名称:loss ...像这样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模型加载和预测(我使用了prepare()并按照您的建议删除了输入和输出节点):
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();
}
}
感谢您的时间和答案
答案 0 :(得分:1)
我认为这是您代码中的一个简单错误:const INPUT_NODE_NAME = 'model_outputs';
应该是'model_inputs'
或实际上是什么。在这里,您将输出设置为输入图像,然后在不预测任何内容的情况下将其读回。
答案 1 :(得分:0)
也碰到了编译失败的着色器。 在其他功能更强大的计算机上运行它,问题消失了。
在我看来,Chrome没有足够的资源来成功