我们使用TensorFlow.js来创建和训练自定义模型。我们使用tf.browser.fromPixels()函数将图像转换为张量。我们想要创建自定义并训练自定义模型。在实现这一目标方面,我们创建了两个不同的网页(即:第一页用于创建自定义模式并使用图像及其相关标签进行训练,第二页用于加载训练模型,并使用预先训练的模型我们正在尝试预测图像以获得此图像的关联标签)为了实现此功能,我们将查看以下属性:
取得的成果:在上述要求中,我们成功实施了以下几点:
prediction:::0.9590839743614197,0.0006004410679452121,0.002040663966909051,0.001962134148925543,0.008351234719157219,0.004203603137284517,0.010159854777157307,0.007813011296093464,0.0013025108492001891,0.004482310265302658
仍然需要实现:在培训自定义模型时,我们在自定义模型中同时添加图像和标签。但是当我们保存model.json文件然后在这个.json文件中时,我们无法在添加和训练模型时找到我们与图像('A','B'和'C')关联的标签。因此,当我们在第二页中添加此model.json并尝试预测时,模型不会显示关联标签。我们在训练/适合时无法在模型(model.json)中添加标签。请查找代码和附加的网页截图,以便更好地理解。
以下是一些附件/ sample_code,有助于理解要求:预测页面(第2页):Prediction Page With Pre-trained model
在这里找到模型文件(.json和.bin):Custom model files
以下是两个页面的代码:
//2nd Page which is for prediction -
<apex:page sidebar="false" >
<head>
<title>Predict with tensorflowJS</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@tensorflow/[email protected]"> </script>
</head>
<div class="container mt-5">
<div class="row">
<div class="col-12">
<div class="progress progress-bar progress-bar-striped progress-bar-animated mb-2">Loading Model</div>
</div>
</div>
<div class="row">
<div class="col-3">
<select id="model-selector" class="custom-select" >
<option>mobilenet</option>
</select>
</div>
</div>
<input type="file" id="load" multiple="multiple" /><br/>
<label for="avatar">Load Model:</label>
<div class="row">
<input id ="image-selector" class="form-control border-0" type="file"/>
</div>
<div class="col-6">
<button id="predict-button" class="btn btn-dark float-right">Predict</button>
</div>
</div>
<div class="row">
<div class="col">
<h2>Prediction</h2>
<ol id="prediction-list"></ol>
</div>
</div>
<div class="row">
<div class="col-12">
<h2 class="ml-3">Image</h2>
<img id="selected-image" class="ml-3" src="" crossorigin="anonymous" width="400" height="300"/>
</div>
</div>
<script>
$(document).ready()
{
$('.progress-bar').hide();
}
$("#image-selector").change(function(){
let reader = new FileReader();
reader.onload = function(){
let dataURL = reader.result;
$("#selected-image").attr("src",dataURL);
$("#prediction-list").empty();
}
let file = $("#image-selector").prop('files')[0];
reader.readAsDataURL(file);
});
$("#model-selector").ready(function(){
loadModel($("#model-selector").val());
$('.progress-bar').show();
})
let model;
let cutomModelJson;
let cutomModelbin;
async function loadModel(name){
$("#load").change(async function(){
for (var i = 0; i < $(this).get(0).files.length; ++i) {
console.log('AllFiles:::'+JSON.stringify($(this).get(0).files[i]));
if($(this).get(0).files[i].name == 'my-model-1.json'){
cutomModelJson = $(this).get(0).files[i];
}else{
cutomModelbin = $(this).get(0).files[i];
}
}
console.log('cutomModelJson::'+cutomModelJson.name+'cutomModelbin::'+cutomModelbin.name);
model = await tf.loadModel(tf.io.browserFiles([cutomModelJson, cutomModelbin]));
console.log('model'+JSON.stringify(model));
});
}
$("#predict-button").click(async function(){
let image= $('#selected-image').get(0);
console.log('image',image);
let tensor = preprocessImage(image,$("#model-selector").val());
const resize_image = tf.reshape(tensor, [1, 224, 224, 3],'resize');
console.log('tensor',tensor);
console.log('resize_image',resize_image);
console.log('model1',model);
let prediction = await model.predict(tensor).data();
console.log('prediction:::'+ prediction);
let top5 = Array.from(prediction)
.map(function(p,i){
return {
probability: p,
className: prediction[i]
};
}).sort(function(a,b){
return b.probability-a.probability;
}).slice(0,1);
$("#prediction-list").empty();
top5.forEach(function(p){
$("#prediction-list").append(`<li>${p.className}:${p.probability.toFixed(6)}</li>`);
});
});
function preprocessImage(image,modelName)
{
let tensor=tf.browser.fromPixels(image)
.resizeNearestNeighbor([224,224])
.toFloat();
console.log('tensor pro', tensor);
if(modelName==undefined)
{
return tensor.expandDims();
}
if(modelName=="mobilenet")
{
let offset=tf.scalar(127.5);
console.log('offset',offset);
return tensor.sub(offset)
.div(offset)
.expandDims();
}
else
{
throw new Error("UnKnown Model error");
}
}
</script>
//1st Page which is for Create and train model -
<apex:page sidebar="false">
<head>
<title>Add image and train model with tensorflowJS</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@tensorflow/[email protected]"> </script>
<script src="https://unpkg.com/@tensorflow-models/mobilenet"></script>
</head>
<div class="container mt-5">
<div class="row">
<div class="col-12">
<div class="progress progress-bar progress-bar-striped progress-bar-animated mb-2">Loading Model</div>
</div>
</div>
<div class="row">
<div class="col-3">
<select id="model-selector" class="custom-select" >
<option>mobilenet</option>
</select>
</div>
</div>
<div class="row">
<input id ="image-selector" class="form-control border-0" type="file"/>
</div>
<div class="col-6">
<button id="predict-button" class="btn btn-dark float-right">Predict</button>
</div>
</div>
<div class="row">
<div class="col">
<h2>Prediction></h2>
<ol id="prediction-list"></ol>
</div>
</div>
<div class="row">
<div class="col-12">
<h2 class="ml-3">Image</h2>
<img id="selected-image" src="{!$Resource.cat}" crossorigin="anonymous" width="400" height="300" />
</div>
</div>
<script>
$("#model-selector").ready(function(){
loadModel($("#model-selector").val());
})
let model;
async function loadModel(name){
model = tf.sequential();
console.log('model::'+JSON.stringify(model));
}
$("#predict-button").click(async function(){
let image= $('#selected-image').get(0);
console.log('image:::',image);
let tensor = preprocessImage(image,$("#model-selector").val());
const resize_image = tf.reshape(tensor, [1, 224, 224, 3],'resize');
console.log('tensorFromImage:::',resize_image);
// Labels
const label = ['cat'];
const setLabel = Array.from(new Set(label));
const ys = tf.oneHot(tf.tensor1d(label.map((a) => setLabel.findIndex(e => e === a)), 'int32'), 10)
console.log('ys:::'+ys);
model.add(tf.layers.conv2d({
inputShape: [224, 224 , 3],
kernelSize: 5,
filters: 8,
strides: 1,
activation: 'relu',
kernelInitializer: 'VarianceScaling'
}));
model.add(tf.layers.maxPooling2d({poolSize: 2, strides: 2}));
model.add(tf.layers.maxPooling2d({poolSize: 2, strides: 2}));
model.add(tf.layers.flatten({}));
model.add(tf.layers.dense({units: 64, activation: 'relu'}));
model.add(tf.layers.dense({units: 10, activation: 'softmax'}));
model.compile({
loss: 'meanSquaredError',
optimizer : 'sgd'
})
// Train the model using the data.
model.fit(resize_image, ys, {epochs: 100}).then((loss) => {
const t = model.predict(resize_image);
console.log('Prediction:::'+t);
pred = t.argMax(1).dataSync(); // get the class of highest probability
const labelsPred = Array.from(pred).map(e => setLabel[e])
console.log('labelsPred:::'+labelsPred);
const saveResults = model.save('downloads://my-model-1');
console.log(saveResults);
}).catch((e) => {
console.log(e.message);
})
});
function preprocessImage(image,modelName)
{
let tensor = tf.browser.fromPixels(image)
.resizeNearestNeighbor([224,224])
.toFloat();
console.log('tensor pro:::', tensor);
if(modelName==undefined)
{
return tensor.expandDims();
}
if(modelName=="mobilenet")
{
let offset=tf.scalar(127.5);
console.log('offset:::',offset);
return tensor.sub(offset)
.div(offset)
.expandDims();
}
else
{
throw new Error("UnKnown Model error");
}
}
</script>
如果我们在任何地方或需要实施任何额外步骤以实现此任务时出错,请告诉我们。
保存的模型不包含标签名称。保存的模型包含模型的拓扑和体系结构的权重。
加载已保存的模型后,可以预测最后一层的每个给定类的置信度。根据该预测,人们只能判断第一类是最可能的还是第二类或第三类......但是,无法判断该类是“A”还是“B”还是“C”,... 。 举些例子。实际上即使是最初的模型也做不到。这是另一个处理。
通常,在进行分类时,在拟合模型之前存在单一编码。因此该模型没有标签“A”,“B”或“C”的语义。例如,对于三个类,它仅具有“100”,“010”,“001”的语义。给定张量,一个预测可以是[0.1,0.3,0.6],表明输入最可能属于第三类。
在输出模型之后,要获得标签名称,必须执行后面的编码过程,如下所示
// take the index i of the highest probability
// indexing the element i of the array of labels
在此过程中,模型始终不知道标签名称。因此,此信息不会保存在任何地方。因此,如果加载的模型用于不同阶段的预测,则应该有一种方法可以在所有这些阶段传递标签名称数组。这个片段信息可以来自服务器,也可以保存在localStorage上 - 人们可以考虑很多方法,除了期望模型加载自己给它。