Home 캡스톤일지 | ~ 10.04 생활코딩으로 간단히 살펴본 TensorflowJS
Post
Cancel

캡스톤일지 | ~ 10.04 생활코딩으로 간단히 살펴본 TensorflowJS

지난 2주간은 요구사항분석서를 쓰느라 정말 정신이 없었다😱
내가 맡은 부분은 UML 클래스 다이어그램과 데이터베이스 설계쪽이였는데.. 정처기 공부하면서 배운 내용들은 다 어디로갔는지..
심져 이번 발표는 내 차례라 대본쓰고 발표준비하느라 진이 다빠져버려따..
다행히 요구사항 분석서에는 크게 문제가 없었고! 교수님께서 추가하라는 내용만 조금 보완해서 수정하면 될 듯!



개발환경을 스프링에서 노드로 변경하였기에 우리는 텐서플로우 파이썬이 아닌 자바스크립트로 개발할 예정
파이썬으로 머신러닝 후 모델을 저장해서 쓸까도 고민했지만.. 그래도 js로 하는 방법도 알아야할 것 같아 찾아보던 중 찾은 생활코딩 

📍 [생활코딩] Tensorflow(Javascript) https://opentutorials.org/course/4628
📍 [Tensorflow.js] https://www.tensorflow.org/js/?hl=ko

텐서플로우 라이브러리 준비

script tag 이용 (브라우저를 통해 실행 가능)

1
<script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@1.0.0/dist/tf.min.js"></script>

노드 모듈 install

1
npm install @tensorflow/tfjs

EX1. 있는 모델 불러와 사용해보기

📄 tensorflow > js > 모델보기 https://www.tensorflow.org/js/models?hl=ko

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <!-- Load TensorFlow.js. This is required to use MobileNet. -->
    <script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@1.0.1"> </script>
    <!-- Load the MobileNet model. -->
    <script src="https://cdn.jsdelivr.net/npm/@tensorflow-models/mobilenet@1.0.0"> </script>

    <!-- Replace this with your image. Make sure CORS settings allow reading the image! -->
    <img id="img" src="dog.JPG"></img>

    <!-- Place your code in the script tag below. You can also use an external .js file -->
    <script>
        // Notice there is no 'import' statement. 'mobilenet' and 'tf' is
        // available on the index-page because of the script tag above.

        const img = document.getElementById('img'); // img 태그에 담긴 이미지

        // Load the model.
        mobilenet.load().then(model => { // 모델이 인자로 전달
            // Classify the image.
            model.classify(img).then(predictions => {
                // 모델의 분류 호출, 이미지 전달 
                console.log('Predictions: ');
                console.log(predictions);
            });
        });
    </script>
</body>

</html>

발생한 오류 1)

Uncaught (in promise) DOMException : Failed to execute ‘texImage2D’ on ‘WebGL2RenderingContext’: Tainted canvases may not be loaded

🙆‍♀️ 해결 https://stackoverflow.com/questions/59577407/uncaught-in-promise-domexception-failed-to-execute-teximage2d-on-webgl2ren

cdn으로 불러온 모델로 로컬 이미지를 이용하기 위해 별도의 조치가 필요한 모양.. 하여 img 태그에 crossorigin 속성을 추가해줌
그 결과 이미지 태그는 인식하지 못해 브라우저에 이미지는 안뜨지만 분류 결과는 확인 가능 image

난 분명 강아지 사진 했는데 뭔가 이상…….

발생한 오류 2)

Access to image at ‘file:///Users/juran/dev/opentutorials-tfjs/dog.JPG’ from origin ‘null’ has been blocked by CORS policy
: Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, chrome-untrusted, https.

🙆‍♀️ 참고 및 해결 https://velog.io/@takeknowledge/%EB%A1%9C%EC%BB%AC%EC%97%90%EC%84%9C-CORS-policy-%EA%B4%80%EB%A0%A8-%EC%97%90%EB%9F%AC%EA%B0%80-%EB%B0%9C%EC%83%9D%ED%95%98%EB%8A%94-%EC%9D%B4%EC%9C%A0-3gk4gyhreu

원인은

  • <script type=module> 은 로컬에서 실행시 자바스크립트 모듈 보안 요구로 인해 CORS 에러가 발생한다
  • 로컬시스템에서 로컬 파일 리소스를 요청할 때는 origin(출처)이 null로 넘어가기 때문에 CORS 에러가 발생한다.

따라서 노드 서버에 연결해 파일을 실행시켜 보았다. image

이미지도 잘 뜨고 image

결과도 잘 뜨는 모습 확인

EX2. 온도(temper)가 주어졌을 때 판매량(sales) 예측

  1. 학습시킬 데이터 준비
    1
    2
    3
    4
    5
    
     // sales = temper * 2
     var temper = [20,21,22,23];
     var sales = [40,42,44,46]; 
     var cause = tf.tensor(temper);
     var results = tf.tensor(sales);
    
  2. 모델 모양 만들기
    1
    2
    3
    4
    5
    
     var X = tf.input({ shape: [1] }); // 입력 x
     var Y = tf.layers.dense({ units: 1 }).apply(X); // 출력 y
     var model = tf.model({ inputs: X, outputs: Y }); // x와 y 연결
     var compileParam = { optimizer: tf.train.adam(), loss: tf.losses.meanSquaredError } // 최적화함수, 손실함수
     model.compile(compileParam); // 모델 생성
    
  3. 모델 학습
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    
     var fitParam = { 
         epochs: 1000, //학습 epoch 
         callbacks:{
             onEpochEnd:function(epoch, logs){
             // 각 epoch 마다 loss 로그
                 console.log('epoch', epoch, logs, "RMSE=>", Math.sqrt(logs.loss)); 
             }
         }
     }
    
     model.fit(cause, results, fitParam).then(function (result) {
         var predict_result = model.predict(cause);
         predict_result.print();
     });
    

    각 epoch마다 loss 로그 image

  4. 학습한 모델을 이용하여 새로운 데이터에 대한 예측

    1
    2
    3
    4
    
     var next_temper = [15, 16, 17, 18, 19]
     var next_cause = tf.tensor(next_temper);
     var next_results = model.predict(next_cause);
     next_results.print();
    

    Tensor [[2.6036754], [2.7289047], [2.8541341], [2.9793634]]

    image

    데이터 양도 적고 epoch도 작아서 정확도가 매우 좋지 않은 모습 ㅠㅠ

    weight와 bias

    1
    2
    3
    4
    5
    6
    
     // weight
     var weights = model.getWeights()
     var weight = weights[0].arraySync()[0][0];
    
     // bias
     var bias = weights[1].arraySync()[0];
    

EX3. 모델 저장과 불러오기

📄 Tensorflow.js > 가이드 > 모델 저장 및 로드 https://www.tensorflow.org/js/guide/save_load?hl=ko

모델 저장

  • 모델 파일 다운로드
    1
    
    model.save('downloads://lemon'); // 모델 파일 다운로드
    

    image

  • 브라우저 저장
    1
    
    model.save('localstorage://lemon');
    

    image

모델 불러오기

  • localstorage에 저장된 모델 불러오기
    1
    2
    
    tf.loadLayersModel('localstorage://lemon').then(function(model){
          model.predict(tf.tensor([20])).print();
    

EX4. 보스턴 집값 예측

📄 파이썬ver. 선형분석
2021.06.29 - [python/kdigital] - [K-DIGITAL] 머신러닝 알고리즘(1) 회귀분석(선형, 로지스틱) - sklearn 실습

📄 파이썬ver. 의사결정트리
2021.06.30 - [python/kdigital] - [K-DIGITAL] 머신러닝 알고리즘(3) 의사결정트리 - sklearn 실습

  1. 데이터 로드
    1
    
     <script src="data.js"></script>
    
    • script
      1
      2
      
        var cause = tf.tensor(boston_cause);
        var result = tf.tensor(boston_result);
      
    • data.js
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      
        var boston_cause = [
            [0.00632,18,2.31,0,0.538,6.575,65.2,4.09,1,296,15.3,396.9,4.98],
            [0.02731,0,7.07,0,0.469,6.421,78.9,4.9671,2,242,17.8,396.9,9.14],
            [0.02729,0,7.07,0,0.469,7.185,61.1,4.9671,2,242,17.8,392.83,4.03], ..
        ]
      
        var boston_result = [[24],
            [21.6],
            [34.7],
            [33.4],
            [36.2],
            [28.7],
            [22.9], ...
        ]
      
  2. 모델 생성

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    
     var X = tf.input({ shape: [13] });
    
     // hidden layer
     var H1 = tf.layers.dense({ units: 13, activation:'relu' }).apply(X);
     var H2 = tf.layers.dense({ units: 13, activation:'relu' }).apply(H1);
    
     var Y = tf.layers.dense({ units: 1 }).apply(H2);
    
     var model = tf.model({ inputs: X, outputs: Y });
     var compileParam = { optimizer: tf.train.adam(), loss: tf.losses.meanSquaredError }
     model.compile(compileParam);
    
    • 종속 변수가 1개일 때 Y의 layer units = 1
    • 히든 레이어 생성(units(노드)의 수는 입력층과 출력층의 개수 사이)
  3. 모델 학습
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    
     var _history = [];
     var fitParam = { 
     epochs: 100, 
     callbacks:{
         onEpochEnd:
             function(epoch, logs){
                 console.log('epoch', epoch, logs, 'RMSE=>', Math.sqrt(logs.loss));
             }
         }
     }
    
     model.fit(cause, result, fitParam).then(function (result) {
         var predict_result = model.predict(cause);
         predict_result.print();
     });
    

EX4. 모델 학습 시각화

모델 생성부분 추가

1
tfvis.show.modelSummary({name:'summary', tab:'model'}, model);

모델 학습 fitParam 항목 추가

1
2
_history.push(logs);
tfvis.show.history({name:'loss', tab:'history'}, _history, ['loss']);

실행 화면

  • 실시간으로 학습이 진행되며 측정되는 loss 그래프로 보여줌 image


시간이 많지 않았고 간단히 텐서플로가 js에서는 어떤지 살펴보기 위해 들은거라 이정도에서 멈췄다. 오랜만에 머신러닝 코드를 보니…. 기억이 하나도 안난다.. 방학동안 열심히 교육듣던 나 어디갔는지.. 그래도 대충 어떤식으로 js에서는 작동하고 어떻게 써야하는지 대충 감을 잡을 수 있었다. 된다면 파이썬으로 학습시켜서 모델 만들고 이를 js에서 불러서 사용하고싶은데.. 잘 될지는 모르겠다.
tensorflow.js 강의가 더 있던데 일단 공부해봐야겠다.
역시 생활코딩에는 없는게 없군

This post is licensed under CC BY 4.0 by the author.

캡스톤일지 | ~ 09.24 서비스 기획과 미디어파이프 테스트

캡스톤일지 | ~ 10.05 NodeJS TDD 웹개발 훑어보기(1)