I'm trying to move a tensorflow model from its original html into a react app (built with create-react-app).
My App.js looks like this:
import logo from './logo.svg';
import * as tf from "@tensorflow/tfjs";
// import { loadImageclassification } from "@tensorflow/tfjs";
import './App.css';
import * as automl from "@tensorflow/tfjs-automl";
import * as modelJSON from './model.json';
function App() {
var loadFile = function(event) {
var image = document.getElementById('output');
image.src = URL.createObjectURL(event.target.files[0]);
run();
};
async function run() {
console.log(modelJSON);
// const model = await tf.loadImageclassification('model.json');
const model = await automl.loadImageClassification(modelJSON);
const image = document.getElementById('output');
const predictions = await model.classify(image);
console.log(predictions);
const pre = document.getElementById('result');
pre.textContent = JSON.stringify(predictions, null, 2);
}
return (
<div className="App">
<div className="hero-text">
<h1>classifier</h1>
<h3>Upload a picture to see what type it is! </h3>
<p>
<input type="file" accept="image/*" name="image" id="file" onChange={loadFile} />
</p>
<div id="demobox">
<p>
<label htmlFor="file">Upload your image</label>
</p>
</div>
<p><img id="output" width="200" alt="output" /></p>
<div className="result" id="result">
</div>
</div>
</div>
);
}
export default App;
My index.html looks like this:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta
name="description"
content="Web site created using create-react-app"
/>
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
</body>
</html>
I am getting the following error, which seems to be issuing from somewhere in the loadImageClassification
method:
Unhandled Rejection (TypeError): modelUrl.lastIndexOf is not a function
Apparently loadImageClassification uses a fetch request under the hood and so requires a remote file (which is strange, because it seemed to work fine in the static index.html original version of this same project).
So I am now trying it just with a localhost express server, which at present looks like this:
const modelJSON = require('./model.json');
const express = require("express");
const bodyParser = require("body-parser");
const CORS = require("cors");
const app = express();
app.use(bodyParser.json());
app.use(CORS());
let modelObj = modelJSON;
app.get("/", (req, res) => {
// console.log(modelObj);
res.send(modelObj);
});
app.listen(5000, () => {
console.log("Server listening on port 5000");
});
I can see the correct data when I navigate to localhost5000, but when I change
async function run() {
const model = await automl.loadImageClassification(modelJSON);
to
async function run() {
const modelUrl = "http://localhost:5000/";
const model = await automl.loadImageClassification(modelUrl);
I get these errors:
My server.js file now looks like this:
This produces the same errors as in the previous screenshot. (I am leaving in the comments that mess of an attempt to include all the shard files in this server.js file screenshot just because it may illustrate that I don't understand how to pass those ancillary model files to loadImageClassification
when it makes its fetch request.)
So presumably the problem now has to do with the fact that loadImageClassification
assumes that the ...shard__of6.bin
and dict
files are in the same directory as the model.json
file.
So the question may (?) be: how to simulate the file structure that it (i.e., loadImageClassification
) is expecting within a remote node server.
I'm don't understand why, when loadImageClassification is in the original static html, it does not seem to require a remote url from which to fetch model.json — but then when I put it in my react app, it suddenly gives me this error: "Fetch API cannot load file:///Users///client/src/model.json. URL scheme must be 'http' or 'https' for CORS request."
The app is mainly written in JavaScript as a Progressive Web App to allow cross-platform usage, so we were training a Keras model and converting it afterwards to TensorFlow.js. With the new “Export to TensorFlow.js” feature, we were able to test out using AutoML to greatly streamline our model creation workflow.
This article is 3rd part of my tensorflow.js + react.js series which intended to promote the usage of tensorflow.js in react. As an intro to the new reader, Tensorflow.js or TF.js is a library for machine learning in Javascript, which enables ML models to be used directly in the browser or in Node.js.
Access the React.js and Tensorflow.js Computer Vision Template. Install Tensorflow.js and setup the pre-built models. Build a React.js app that accesses the webcam. Make detection from the webcam in real-time. Let’s get started! Use React.js for the standalone front-end application. Capture images from the webcam for object detection.
We will use Microsoft’s COCO SSD pre-trained model, which allows us to perform real-time object detection on images. On the ‘App.js’ folder, we will import TensorFlow and the pre-built model into our application by issuing the following commands: The first command will first import the TensorFlow module into our application.
What's the location of the model on your local device?
Try changing
const modelUrl = "http://localhost:5000/"
to
const modelUrl = 'model/model.json'
if the model is in build/model/, or to whatever the location is.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With