ml5js / ml5-library

Friendly machine learning for the web! πŸ€–
https://ml5js.org
Other
6.38k stars 906 forks source link

Always outputting the same thing. Might be something wrong with my HTML not sure #1472

Open JGJCode opened 9 months ago

JGJCode commented 9 months ago

Dear ml5 community,

I'm submitting a new issue. Please see the details below.

β†’ Step 1: Describe the issue πŸ“

Did you find a bug? Want to suggest an idea for feature?

β†’ Step 2: Screenshots or Relevant Documentation πŸ–Ό

Here's some helpful screenshots and/or documentation of the new feature

β†’ Step 3: Share an example of the issue πŸ¦„

Here's some example code or a demonstration of my feature in this issue, separate GitHub repo, or in the https://editor.p5js.org or codepen/jsfiddle/Glitch/etc...

Other relevant information, if applicable

β†’ Describe your setup πŸ¦„

Here's some helpful information about my setup...

JGJCode commented 9 months ago

I'm working on a website that classifies user drawn images using the ml5 doodleNet model. However, whenever I click the submit button it always says it identified the image as camouflage with 10.34% confidence? When I looked into the console, all result and confidence values were the same for each array, meaning the ml5 model may not have been working? I'm not sure how to fix it. Here's the script and apologies for the messy code

<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/addons/p5.dom.min.js"></script>
<script src="https://unpkg.com/ml5@latest/dist/ml5.min.js"></script>
<body>
    <div class="box">
        <canvas id="canvas"></canvas>
    </div>

    <div class="left" id="resultContainer" style="display: none;">
        <h1>Your Drawing</h1>
        <img id="Drawing" alt="Your Drawing" width="640" height="301.5">
        <h2>The Machine Learning Model classified it as <span id="classificationResult"></span></h2>
    </div>
        <button id="submitButton" class="button">Submit!</button>
        <button id="refreshButton" class="button">Restart</button>
    <script>
        var notEmpty = false;
        window.addEventListener('load', () => {
            resize();
            document.addEventListener('mousedown', startPainting);
            document.addEventListener('mouseup', stopPainting);
            document.addEventListener('mousemove', sketch);
            window.addEventListener('resize', resize);
        });

        const canvas = document.querySelector('#canvas');
        const ctx = canvas.getContext('2d');

        function resize() {
            ctx.canvas.width = window.innerWidth;
            ctx.canvas.height = window.innerHeight;
        }

        let coord = { x: 0, y: 0 };
        let paint = false;

        function getPosition(event) {
            coord.x = event.clientX - canvas.offsetLeft;
            coord.y = event.clientY - canvas.offsetTop;
        }

        function startPainting(event) {
            notEmpty = true;
            paint = true;
            getPosition(event);
        }

        function stopPainting() {
            paint = false;
        }

        function sketch(event) {
            if (event.type === 'click') {
            drawDot(event.clientX - canvas.offsetLeft, event.clientY - canvas.offsetTop);
            return;
        }

        if (!paint) return;
        ctx.beginPath();

        ctx.lineWidth = 5;

        ctx.lineCap = 'round';

        ctx.strokeStyle = 'black';

        ctx.moveTo(coord.x, coord.y);

        getPosition(event);

        ctx.lineTo(coord.x , coord.y);

        ctx.stroke();

        const submitButton = document.getElementById('submitButton');
        submitButton.addEventListener('click', submit);

        function captureBox() {
            var canvas1 = document.getElementById("canvas");
            return canvas1.toDataURL();
        }
        let doodleClassifier;
        let resultsDiv;
        let boxURL;
        function submit() {
            if (!notEmpty) {
                alert('Draw on the canvas');
                    return;
            }
            boxURL = captureBox();
            const drawing = document.getElementById('Drawing');
            drawing.src = boxURL;
            const submitButton=document.getElementById('submitButton');
            submitButton.style.display='none';

            const canvasContainer = document.querySelector('.box');
            const resultContainer = document.getElementById('resultContainer');
            canvasContainer.style.display = 'none';
            resultContainer.style.display = 'block';

            doodleClassifier=ml5.imageClassifier('DoodleNet',modelReady);
        }
        function modelReady(){
            var img=document.createElement('img')
            img.src=boxURL
            doodleClassifier.classify(img,gotResults);
        }
        function gotResults(error,results){
            if(error){
                console.error(error);
                return;
            }
            /*console.log(results);
            let content=`${results[0].label} ${nf(100*results[0].confidence,2,)}`
            resultsDiv.html(content)*/
            console.log(results);

            const classificationResultSpan = document.getElementById('classificationResult');
            const resultLabel = results[0].label;
            const resultConfidence = (results[0].confidence * 100).toFixed(2);
            classificationResultSpan.innerText = `${resultLabel} with ${resultConfidence}% confidence`;
        }
        const refreshButton = document.getElementById('refreshButton');
        refreshButton.addEventListener('click', refresh);

        function refresh() {
            window.location.href='/draw'
        }
    }
    </script>

I tried the commented block but nothing changed.

lindapaiste commented 8 months ago

There's definitely some sort of timing issue where it keeps loading the model until the results come back. See how it is fetching hundreds of times? image I have to dig into it more in order to understand why the model isn't getting the right image data, and why that tensorflow warning gets logged.

Edit: I fixed your timing issues, but I'm still getting the same bad results 😭

<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/addons/p5.dom.min.js"></script>
<script src="https://unpkg.com/ml5@latest/dist/ml5.min.js"></script>

<body>
  <div class="box">
    <canvas id="canvas"></canvas>
  </div>

  <div class="left" id="resultContainer" style="display: none;">
    <h1>Your Drawing</h1>
    <img id="Drawing" alt="Your Drawing" width="640" height="301.5">
    <h2>The Machine Learning Model classified it as <span id="classificationResult"></span></h2>
  </div>
  <button id="submitButton" class="button">Submit!</button>
  <button id="refreshButton" class="button">Restart</button>
  <script>
    var notEmpty = false;
    window.addEventListener('load', () => {
      resize();
      document.addEventListener('mousedown', startPainting);
      document.addEventListener('mouseup', stopPainting);
      document.addEventListener('mousemove', sketch);
      window.addEventListener('resize', resize);

      const submitButton = document.getElementById('submitButton');
      submitButton.addEventListener('click', submit);

      const refreshButton = document.getElementById('refreshButton');
      refreshButton.addEventListener('click', refresh);
    });

    const canvas = document.querySelector('#canvas');
    const ctx = canvas.getContext('2d');

    function resize() {
      ctx.canvas.width = window.innerWidth;
      ctx.canvas.height = window.innerHeight;
    }
    let coord = {
      x: 0,
      y: 0
    };
    let paint = false;

    function getPosition(event) {
      coord.x = event.clientX - canvas.offsetLeft;
      coord.y = event.clientY - canvas.offsetTop;
    }

    function startPainting(event) {
      notEmpty = true;
      paint = true;
      getPosition(event);
    }

    function stopPainting() {
      paint = false;
    }

    function sketch(event) {
      if (event.type === 'click') {
        drawDot(event.clientX - canvas.offsetLeft, event.clientY - canvas.offsetTop);
        return;
      }
      if (!paint) return;
      ctx.beginPath();
      ctx.lineWidth = 50;

      ctx.lineCap = 'round';
      ctx.strokeStyle = 'black';
      ctx.moveTo(coord.x, coord.y);
      getPosition(event);
      ctx.lineTo(coord.x, coord.y);
      ctx.stroke();
    }

      function captureBox() {
        var canvas1 = document.getElementById("canvas");
        return canvas1.toDataURL();
      }
      let doodleClassifier;
      let resultsDiv;
      let boxURL;

      function submit() {
        if (!notEmpty) {
          alert('Draw on the canvas');
          return;
        }
        boxURL = captureBox();
        const drawing = document.getElementById('Drawing');
        drawing.src = boxURL;
        const submitButton = document.getElementById('submitButton');
        submitButton.style.display = 'none';
        const canvasContainer = document.querySelector('.box');
        const resultContainer = document.getElementById('resultContainer');
        canvasContainer.style.display = 'none';
        resultContainer.style.display = 'block';
        doodleClassifier = ml5.imageClassifier('DoodleNet', modelReady);
      }

      function modelReady() {
        var img = document.createElement('img')
        img.src = boxURL
        doodleClassifier.classify(canvas, gotResults);
      }

      function gotResults(error, results) {
        if (error) {
          console.error(error);
          return;
        }
        /*console.log(results);
        let content=`${results[0].label} ${nf(100*results[0].confidence,2,)}`
        resultsDiv.html(content)*/
        console.log(results);
        const classificationResultSpan = document.getElementById('classificationResult');
        const resultLabel = results[0].label;
        const resultConfidence = (results[0].confidence * 100).toFixed(2);
        classificationResultSpan.innerText = `${resultLabel} with ${resultConfidence}% confidence`;
      }

      function refresh() {
        window.location.href = '/draw'
      }
  </script>