'Can't Load Models for face-api.js

I don't understand how to load the "models" so that the client side of my React web app can start analyzing images. I don't even really understand what a "model" is.

I started by doing npm i face-api.js.

Then, I imported it into my SignUp component by typing import * as faceapi from 'face-api.js' at the top.

In my componentDidMount() function, I put the following code:

faceapi.nets.ssdMobilenetv1.loadFromUri('/models').then(result => {
  console.log(result);
}).catch(error => {
  console.log(error)
})

That gives me the following error: SyntaxError: "JSON.parse: unexpected character at line 1 column 1 of the JSON data"

So I tried looking for a "models" directory in the face-api.js directory, but couldn't find anything. Then I went back to the Github and found a "weights" folder (which I read are related to models). I downloaded it, and put it's contents in a "models" folder near my SignUp component (see attached pic). Still the same error.

Ultimately, all I want to do is know whether a user uploads a pictures containing a face. Any face. I don't need anything more than that. What am I doing wrong?

Text



Solution 1:[1]

For my example using VueJs i added the models in the public / dist directory and i followed the directions for the github examples.

Promise.all([
faceapi.nets.faceRecognitionNet.loadFromUri('/models'), 
faceapi.nets.ssdMobilenetv1.loadFromUri('/models'), faceapi.nets.faceLandmark68Net.loadFromUri('/models'),
])
.then(async () => {//some code goes here})

Sample I used

Solution 2:[2]

You can use loadFromDisk instead of loadFromUri.

or

You can change the model's filename extension to .dir instead of .json.

Solution 3:[3]

When you run this :

faceapi.nets.ssdMobilenetv1.loadFromUri('/models')

It looks for models in the the public/models directory but it will only load the json file.(Verify this by checking the Network Tab in the browser). It might run on your local machine but will fail when you deploy.

In our case it failed in production because it needed the data from *_shard1 file but our server was unable to fetch those file without any extension. To solve this issue we suffixed all those file with ".shard" extension and changed the path in the respective json file : From :

...,"paths": ["file_name_shard1"]}]

To:

...,"paths": ["file_name_shard1.shard"] 

Found this solution here: https://github.com/justadudewhohacks/face-api.js/issues/131

Solution 4:[4]

Smarann Educations's reply above is very useful, except that I made the following changes to get mine to work on the production server:

  • Instead of ".shard" extension, as advised by Smarann Educations, I input a ".bin" extension to the shard files. And, similarly, in the corresponding json files, I updated the paths to ".bin" instead of ".shard", as suggested by Smarann Educations. This ".bin" suggestion is in one of the comments at the link that Smarann Educations provided in his reply

  • I modified all the loadFromUri('/models') statements to loadFromUri('./models') - So, replaced '/models' with './models' (Notice the dot before the slash)

Solution 5:[5]

I had the same issue in react, but in development and productions servers. So, to fix it locally (on localhost), just put the models folder in the public folder.

To fix in on server, you should put the models folder into build/static. So I added in package.json script:

"replace_models": 
  "node -e \"const fs = require('fs-extra'); 
   fs.copy('./build/models', './build/static/models').then(
     () => {fs.removeSync('./build/models'); 
     return console.log('success!')}
    ).catch(err => console.error(err))\"
  " 

And then:

"build": "react-scripts build && npm run replace_models"

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Muje
Solution 2 KHJcode
Solution 3 Smarann Educations
Solution 4 Nikhil
Solution 5