Мы используем TensorFlow.js для создания и обучения пользовательской модели.Мы используем функцию tf.browser.fromPixels () для преобразования изображения в тензор.Мы хотим создать кастом и обучить кастомной модели.Для достижения этой цели мы создали две разные веб-страницы (то есть: 1-я страница предназначена для создания пользовательского режима и обучения его с изображениями и связанными с ними метками, 2-я страница используется для загрузки обученной модели и с использованием предварительно обученной модели, которую мы пытаемсячтобы предсказать изображение, чтобы получить ассоциированную метку с этим изображением) для достижения этой функциональности мы рассмотрим следующие свойства:
- AddImage (HTML_Image_Element, 'Label'): -Добавьте элемент image с меткой.Допустим, у нас есть три изображения для предсказания, а именно: img1, img2, img3 с тремя метками «A», «B» и «C» соответственно.
Train () / fit (): - Тренируйте эту пользовательскую модель со связанными метками.Поэтому мы хотим создать и обучить нашу модель с этими изображениями и соответствующими метками.
Сохранить / загрузить модель: - Чтобы сделать предварительно обученную модель пригодной для повторного использования,мы хотим сохранить обученную модель и загрузить эту модель всякий раз, когда мы хотим сделать прогноз с одним и тем же набором данных.С помощью функции save () мы получаем два файла, а именно: «model.json» и «model.weights.bin».
- Predict (): - После успешного обученияПосле загрузки модели мы можем загрузить эту модель на другой странице, чтобы пользователь мог прогнозировать изображения с помощью соответствующей метки, и он будет возвращать предсказанный ответ с прикрепленной меткой каждого изображения.Скажем, всякий раз, когда пользователь хочет предсказать 'img1', он отображает прогноз как имя класса 'A', аналогично, для прогнозов 'img2' с именем класса 'B' и для прогнозов 'img3' с именем класса 'C' со значением достоверности какхорошо.
Шаги, которые достигнуты: В вышеупомянутом требовании мы успешно выполнили следующие пункты:
В самомНа первой веб-странице мы создаем последовательную модель и добавляем изображения (путем преобразования в тензор) в модель.и после этого мы обучаем / подгоняем эту модель с этими изображениями и связываем метки.
После обучения мы можем легко сохранить () эту пользовательскую предварительно обученную модель для дальнейших предсказаний.с этим временем пользователь может предсказать любое конкретное изображение из набора данных, с которым он был использован во время обучения, модель дает ответ с соответствующей меткой, т. е. если пользователь хочет прогноз для «img1», ответ модели прогноз с меткой как «A '.
После сохранения модели мы можем теперь открыть вторую веб-страницу, где пользователь может делать прогноз с изображениями, не проводя никаких тренировок, используя предварительно обученную модель.на этом этапе мы можем загрузить нашу сохраненную модель и получить прогноз следующим образом:
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-я страница): Страница прогнозаС предварительно обученной моделью
Найдите здесь оба файла модели (.json и .bin): Пользовательские файлы модели
Ниже приведен код обеих страниц:
//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/tfjs@0.15.1"> </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/tfjs@0.15.1"> </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>
Пожалуйста, дайте нам знать, если мы идем не так, как нужно, или нам нужно предпринять какие-либо дополнительные шаги для достижения этой задачи.