본문 바로가기
프로젝트/수익형 웹 만들기

2021년 8월 24일 - Step 3 : Teachable Machine

by 철제백조 2021. 8. 24.

1. Teachable Machine를 통해 머신러닝 구현하기

 

https://teachablemachine.withgoogle.com/

 

Teachable Machine

Train a computer to recognize your own images, sounds, & poses. A fast, easy way to create machine learning models for your sites, apps, and more – no expertise or coding required.

teachablemachine.withgoogle.com

 

 

 

저번 1강에서 크롤링으로 다운받은 이미지들을 학습시킬 것이기에. "이미지 프로젝트"로 들어간다.

 

 

각 이미지들을 폴더 별로 분류했으므로, 각 클래스에 폴더처럼 분류를 해주자.

 

◎ 클래스명 작성 → 업로드 → 폴더 전체 드래그 앤 드롭 → 잘못 들어간 사진은 삭제(데이터 클랜징

 

다른 것들도 마찬가지로 작업 → 클래스 추가는 "Add a class" Train Model Export Model

 

◎ 업로드 Upload My Model → 클라우드 모델 업로드 후, 주소 카피

 

# 내 모델 주소

https://teachablemachine.withgoogle.com/models/OaWXZDTw-/

 


 

2. 웹 서비스 개발환경 세팅

 

구름 IDE → 새 컨테이너 생성 → Html/CSS/JS 선택 → 생성 → 실행

 

 

※ Html과 CSS의 기본 양식이 이미 작성되어 있고, "Open Preview"를 누르면 직접 코드가 실행된 화면을 바로 볼 수 있다.

 

 


 

3. 코드 작성하기

 

◎ 만든 모델 아래에 있는 예시 코드 복사 body 태그 안에 붙여넣기

 

 

 

 

Open Preview

 

 

해당 버튼을 누르면 웹캠이 시작되는 창으로 이동하는데, 사진 업로드 방식으로 바꿀 것이다.

 

 

◎ CodePen

https://codepen.io/

 

CodePen

An online code editor, learning environment, and community for front-end web development using HTML, CSS and JavaScript code snippets, projects, and web applications.

codepen.io

 

 

◎ 검색창에 "image upload" → 원하는 테마 선택(License 주의)

 

License 복사  → body & html 사이에 붙여넣기 → 주석처리 → Html 코드 복사

 

 

복사한 내용을 Start 버튼 아래 붙여넣기

 

※ 코드가 지저분하면 마우스 우측 - 코드 포멧팅 - HTML 포멧 : 깔끔하게 코드 정렬

 

 

CSS - style.CSS 에 붙여넣기

Java Script - Html 하단, 다른 스크립트와 함께 - Alt + Shift + P : 정렬

 

 

 

잘 적용된 모습이다.

이제 웹캠 대신에 우리가 업로드한 사진이 인식시키면 된다.

 

업로드한 사진을 F12를 통해 "file-upload-image"라는 클래스를 가진 이미지에 업로드한 이미지가 들어간 것을 볼 수 있다. 그럼 코드의 웹캠 부분을 그 이미지로 대체해주면 된다.

 

웹캠 루프 제거, predict 이미지 파일로 변경, 예측 버튼 추가

 

 

<!DOCTYPE html>
<html>
    <head>
        <link rel="stylesheet" href="style.css" />
    </head>
    <body>
        <div>Teachable Machine Image Model</div>
        <button type="button" onclick="init()">Start</button>
        <button type="button" onclick="predict()">예측</button>
        
        <script
            class="jsbin"
            src="https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"
        ></script>
        <div class="file-upload">
            <button
                class="file-upload-btn"
                type="button"
                onclick="$('.file-upload-input').trigger( 'click' )"
            >
                Add Image
            </button>

            <div class="image-upload-wrap">
                <input
                    class="file-upload-input"
                    type="file"
                    onchange="readURL(this);"
                    accept="image/*"
                />
                <div class="drag-text">
                    <h3>Drag and drop a file or select add Image</h3>
                </div>
            </div>
            <div class="file-upload-content">
                <img class="file-upload-image" id="game-image" src="#" alt="your image" />
                <div class="image-title-wrap">
                    <button type="button" onclick="removeUpload()" class="remove-image">
                        Remove <span class="image-title">Uploaded Image</span>
                    </button>
                </div>
            </div>
        </div>

        <div id="webcam-container"></div>
        <div id="label-container"></div>
        <script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@1.3.1/dist/tf.min.js"></script>
        <script src="https://cdn.jsdelivr.net/npm/@teachablemachine/image@0.8/dist/teachablemachine-image.min.js"></script>

        <script>
            function readURL(input) {
                if (input.files && input.files[0]) {
                    var reader = new FileReader();

                    reader.onload = function (e) {
                        $('.image-upload-wrap').hide();

                        $('.file-upload-image').attr('src', e.target.result);
                        $('.file-upload-content').show();

                        $('.image-title').html(input.files[0].name);
                    };

                    reader.readAsDataURL(input.files[0]);
                } else {
                    removeUpload();
                }
            }

            function removeUpload() {
                $('.file-upload-input').replaceWith($('.file-upload-input').clone());
                $('.file-upload-content').hide();
                $('.image-upload-wrap').show();
            }
            $('.image-upload-wrap').bind('dragover', function () {
                $('.image-upload-wrap').addClass('image-dropping');
            });
            $('.image-upload-wrap').bind('dragleave', function () {
                $('.image-upload-wrap').removeClass('image-dropping');
            });
        </script>

        <script type="text/javascript">
            // More API functions here:
            // https://github.com/googlecreativelab/teachablemachine-community/tree/master/libraries/image

            // the link to your model provided by Teachable Machine export panel
            const URL = 'https://teachablemachine.withgoogle.com/models/OaWXZDTw-/';

            let model, webcam, labelContainer, maxPredictions;

            // Load the image model and setup the webcam
            async function init() {
                const modelURL = URL + 'model.json';
                const metadataURL = URL + 'metadata.json';

                // load the model and metadata
                // Refer to tmImage.loadFromFiles() in the API to support files from a file picker
                // or files from your local hard drive
                // Note: the pose library adds "tmImage" object to your window (window.tmImage)
                model = await tmImage.load(modelURL, metadataURL);
                maxPredictions = model.getTotalClasses();

                labelContainer = document.getElementById('label-container');
                for (let i = 0; i < maxPredictions; i++) {
                    // and class labels
                    labelContainer.appendChild(document.createElement('div'));
                }
            }


            // run the webcam image through the image model
            async function predict() {
                // predict can take in an image, video or canvas html element
                var image = document.getElementById('game-image')
                const prediction = await model.predict(image, false);
                for (let i = 0; i < maxPredictions; i++) {
                    const classPrediction =
                        prediction[i].className + ': ' + prediction[i].probability.toFixed(2);
                    labelContainer.childNodes[i].innerHTML = classPrediction;
                }
            }
        </script>
    </body>

    <!-- Copyright (c) 2021 by Aaron Vanston (https://codepen.io/aaronvanston/pen/yNYOXR)

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  -->
</html>

 

 

출력 주소, 모바일에서도 구현이 가능하다.

 

https://game-face-looj.run.goorm.io/Game_Face/index.html

 

https://game-face-looj.run.goorm.io/Game_Face/index.html

 

game-face-looj.run.goorm.io

 

 

다음 장에서는 사용성을 높여보도록 하겠다.

 

 

 

 

 

댓글