Tensorflow.js

Jess·2021년 11월 1일
0

머신러닝 & 딥러닝

목록 보기
4/4
post-thumbnail

Tensorflow(JavaScript)

  • 머신러닝 지도학습의 회귀(regression)

  • Neural Network 사용

  • 라이브러리 '텐서플로우' 의 종류
    - TensorFlow Python

    • TensorFlow JavaScript
      -> Web browser
      -> Node.js 에서 사용할 수 있음

1. 지도학습의 작업순서

  1. 과거의 데이터를 준비한다.
  2. 모델의 모양을 만든다.
  3. 데이터로 모델을 학습(FIT)한다.
  4. 모델을 이용한다.

2. 모델

  1. 남이 만든 모델 이용하기
  2. 기존 모델 다시 학습시키기
  3. 자바스크립트로 직접 ML 개발하기

a. 남이 만든 모델 이용하기

https://www.tensorflow.org/js?hl=ko

<!DOCTYPE html>
<html>
    <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="cat.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.

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

  // Load the model. Load 함수 호출
  mobilenet.load().then(model => {
    // Classify the image. img 태그를 classify 함수로 학습
    model.classify(img).then(predictions => {
      console.log('Predictions: ');
      console.log(predictions);
    });
  });
</script>
    </body>
</html>

b. 내가 만든 모델 이용하기

  1. Tensorflow.js 웹 브라우저 스크립트 태그 복사
    https://www.tensorflow.org/js/tutorials/setup?hl=ko#%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8_%ED%83%9C%EA%B7%B8%EB%A5%BC_%ED%86%B5%ED%95%9C_%EC%82%AC%EC%9A%A9%EB%B2%95
    <script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@2.0.0/dist/tf.min.js"></script>

  2. 에디터에 html 파일 생성

  3. 태그 안에 복사-붙여넣기
  4. 5.3.html

<!DOCTYPE html>
<html>
 
<head>
    <title>TensorFlow.js Tutorial - lemon</title>
 
    <!-- Import TensorFlow.js -->
    <script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@1.0.0/dist/tf.min.js"></script>
     
</head>
 
<body>
    <script>
        // 1. 과거의 데이터를 준비 
        var 온도 = [20,21,22,23]; // 독립변수
        var 판매량 = [40,42,44,46]; // 종속변수
        var 원인 = tf.tensor(온도); // tensor라는 형태로 변환해주는 과정 필요
        var 결과 = tf.tensor(판매량);
 
        // 2. 모델의 모양 만들기 : 데이터의 형식에 따라서 들어가는 숫자를 조정
        var X = tf.input({ shape: [1] }); // 입력 값 속성이 몇개인지
        var Y = tf.layers.dense({ units: 1 }).apply(X); // 결과 값 속성이 몇개인지
        var model = tf.model({ inputs: X, outputs: Y }); // 모델을 정의
        var compileParam = { optimizer: tf.train.adam(), loss: tf.losses.meanSquaredError }  // 입력값 ; optimizer(좀 더 효율적으로 모델을 만드는 것), loss(얼마나 모델이 잘 만들어졌는지 측정하기 위해 사용하는 것)
        model.compile(compileParam);
 
        // 3. 데이터로 모델을 학습(fit, trainning, running..)
        var fitParam = { epochs: 100}  // epoch : 학습 횟수 지정
        // var fitParam = { epochs: 100, callbacks:{onEpochEnd:function(epoch, logs){console.log('epoch', epoch, logs);}}} // loss 추가 예제
        model.fit(원인, 결과, fitParam).then(function (result) {
             
        	//4. 모델을 이용(학습이 끝났을 때 시행할 동작 정의)
            // 4.1 기존의 데이터를 이용
            var 예측한결과 = model.predict(원인); // 중요!!
            예측한결과.print();
 
         });  
 
        // 4.2 새로운 데이터를 이용
        var 다음주온도 = [15,16,17, 18, 19]
        var 다음주원인 = tf.tensor(다음주온도);
        var 다음주결과 = model.predict(다음주원인);
        다음주결과.print();
    </script>
</body>
 
</html>

3. 정확도 측정

  • 모델이 얼마나 잘 예측하는가를 의미하는 정확도 확인하기
    - loss
    • Mean Square Error
    • Root Mean Square Error
// 데이터로 모델 학습하는 부분 
var fitParam = { 
	epochs: 100,
	callbacks:{
		onEpochEnd: # Epoch가 끝날 때 마다 콘솔창에 결과 출력
			function(epoch, logs){
				console.log('epoch', epoch, logs, 'RMSE=>', logs.sqrt(logs.loss));
				}
			}
	} // loss 추가 예제
    model.fit(원인, 결과, fitParam).then(function (result) {
             
        	//4. 모델을 이용(학습이 끝났을 때 시행할 동작 정의)
            // 4.1 기존의 데이터를 이용
            var 예측한결과 = model.predict(원인); // 중요!!
            예측한결과.print();
 
         });  
  • 오차값 : 0에 가까울 수록 모델 학습이 뛰어남을 나타냄

  • loss

  • Mean Squared Error(MSE) : 평균 제곱 오차 (양수화)
    각 오차를 제곱하여 합한 후 평균을 구함

  • Root Mean Squared Error(RMSE) : 평균 제곱근 오차 (양수화, 실제로 얼마나 오차나는지 체감 가능)
    평균 제곱 오차에 제곱근을 취한 값

 var compileParam = {
	optimizer: tf.train.adam(),
	loss: tf.losses.meanSquaredError  // MSE로 설정
} 

4. 모델의 정체

  • y = a*x + b
    a : 가중치(weight)
    b : 편향(bias)

  • 텐서에서 값 가져오기

const a = tf.tensor([[1, 2], [3, 4]]);
// Returns the multi dimensional array of values.
console.log(a.arraySync());
// Returns the flattened data that backs the tensor.
console.log(a.dataSync());

5. 모델의 저장과 불러오기

https://www.tensorflow.org/js/guide/save_load?hl=ko

6. 여러개의 변수

  • y = a*x + b
    a : 가중치(weight) ex) x1 x2 x3 ... xn
    b : 편향(bias)

  • Boston Housing Price 예제

<!DOCTYPE html>
<html>
 
<head>
    <title>TensorFlow.js Tutorial - boston housing </title>
 
    <!-- Import TensorFlow.js -->
    <script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@1.0.0/dist/tf.min.js"></script>
    <script src="10.3.js"></script>
</head>
 
<body>
    <script>
        
        var 보스톤_원인 = [
            [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]
        ];
        var 보스톤_결과 = [
            [24], 
            [21.6]
        ];
       
     
        // 1. 과거의 데이터를 준비합니다. 
        var 원인 = tf.tensor(보스톤_원인);
        var 결과 = tf.tensor(보스톤_결과);
 
        // 2. 모델의 모양을 만듭니다. 
        var X = tf.input({ shape: [13] });
        var Y = tf.layers.dense({ units: 1 }).apply(X);
        var model = tf.model({ inputs: X, outputs: Y });
        var compileParam = { optimizer: tf.train.adam(), loss: tf.losses.meanSquaredError }
        model.compile(compileParam);
 
        // 3. 데이터로 모델을 학습시킵니다. 
//      var fitParam = {epochs: 100}
        var fitParam = { 
          epochs: 100, 
          callbacks:{
            onEpochEnd:
              function(epoch, logs){
                console.log('epoch', epoch, logs, 'RMSE=>', Math.sqrt(logs.loss));
              }
          }
        } // loss 추가 예제
        model.fit(원인, 결과, fitParam).then(function (result) {
             
            // 4. 모델을 이용합니다. 
            // 4.1 기존의 데이터를 이용
            var 예측한결과 = model.predict(원인);
            예측한결과.print();
 
        });  
 
        // 4.2 새로운 데이터를 이용
        var 다음주온도 = [15,16,17,18,19]
        var 다음주원인 = tf.tensor(다음주온도);
        var 다음주결과 = model.predict(다음주원인);
        다음주결과.print();
    </script>
</body>
 
</html>
  • 복수개의 독립변수가 복수개의 종속변수에 영향을 미치는 경우
<!DOCTYPE html>
<html>
 
<head>
    <title>TensorFlow.js Tutorial - boston housing</title>
 
    <!-- Import TensorFlow.js -->
    <script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@1.0.0/dist/tf.min.js"></script>
    <script src="10.4.js"></script>
</head>
 
<body>
    <script>
     
        // 1. 과거의 데이터를 준비합니다. 
        var 원인 = tf.tensor(보스톤_원인);
        var 결과 = tf.tensor(보스톤_결과);
 
        // 2. 모델의 모양을 만듭니다. ** 변경된 부분 ** 
        var X = tf.input({ shape: [12] });
        var Y = tf.layers.dense({ units: 2 }).apply(X);
        var model = tf.model({ inputs: X, outputs: Y });
        var compileParam = { optimizer: tf.train.adam(), loss: tf.losses.meanSquaredError }
        model.compile(compileParam);
 
        // 3. 데이터로 모델을 학습시킵니다. 
//         var fitParam = {epochs: 100}
        var fitParam = { 
          epochs: 100, 
          callbacks:{
            onEpochEnd:
              function(epoch, logs){
                console.log('epoch', epoch, logs, 'RMSE=>', Math.sqrt(logs.loss));
              }
          }
        } // loss 추가 예제
        model.fit(원인, 결과, fitParam).then(function (result) {
             
            // 4. 모델을 이용합니다. 
            // 4.1 기존의 데이터를 이용
            var 예측한결과 = model.predict(원인);
            예측한결과.print();
 
        });  
 
        // 4.2 새로운 데이터를 이용
        // var 다음주온도 = [15,16,17,18,19]
        // var 다음주원인 = tf.tensor(다음주온도);
        // var 다음주결과 = model.predict(다음주원인);
        // 다음주결과.print();
    </script>
</body>
 
</html>

7. tensorflowjs-vis

<!DOCTYPE html>
<html>
 
<head>
    <title>TensorFlow.js Tutorial - boston housing </title>
 
    <!-- Import TensorFlow.js -->
    <script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@1.0.0/dist/tf.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs-vis"></script>
    <script src="10.3.js"></script>
</head>
 
<body>
    <script>
        /*
        var 보스톤_원인 = [
            [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]
        ];
        var 보스톤_결과 = [
            [24], 
            [21.6]
        ];
        */
     
        // 1. 과거의 데이터를 준비합니다. 
        var 원인 = tf.tensor(보스톤_원인);
        var 결과 = tf.tensor(보스톤_결과);
 
        // 2. 모델의 모양을 만듭니다. 
        var X = tf.input({ shape: [13] });
        var Y = tf.layers.dense({ units: 1 }).apply(X);
        var model = tf.model({ inputs: X, outputs: Y });
        var compileParam = { optimizer: tf.train.adam(), loss: tf.losses.meanSquaredError }
        model.compile(compileParam);
        tfvis.show.modelSummary({name:'요약', tab:'모델'}, model);
 
        // 3. 데이터로 모델을 학습시킵니다. 
//         var fitParam = {epochs: 100}
        var _history = [];
        var fitParam = { 
          epochs: 100, 
          callbacks:{
            onEpochEnd:
              function(epoch, logs){
                console.log('epoch', epoch, logs, 'RMSE=>', Math.sqrt(logs.loss));
                _history.push(logs);
                tfvis.show.history({name:'loss', tab:'역사'}, _history, ['loss']);
              }
          }
        } // loss 추가 예제
        model.fit(원인, 결과, fitParam).then(function (result) {
             
            // 4. 모델을 이용합니다. 
            // 4.1 기존의 데이터를 이용
            var 예측한결과 = model.predict(원인);
            예측한결과.print();
 
        });  
 
        // 4.2 새로운 데이터를 이용
        // var 다음주온도 = [15,16,17,18,19]
        // var 다음주원인 = tf.tensor(다음주온도);
        // var 다음주결과 = model.predict(다음주원인);
        // 다음주결과.print();
    </script>
</body>
 
</html>

8. 딥러닝

  • 최적의 가중치를 찾음
  • 적당한 규모의 hidden layer를 찾는 것이 중요 : 보통 1개로 충분하고 경과를 확인후 추가
  • 히든 레이어를 추가하는 예제
<!DOCTYPE html>
<html>
 
<head>
    <title>TensorFlow.js Tutorial - boston housing </title>
 
    <!-- Import TensorFlow.js -->
    <script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@1.0.0/dist/tf.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs-vis"></script>
    <script src="10.3.js"></script>
</head>
 
<body>
    <script>
        /*
        var 보스톤_원인 = [
            [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]
        ];
        var 보스톤_결과 = [
            [24], 
            [21.6]
        ];
        */
     
        // 1. 과거의 데이터를 준비합니다. 
        var 원인 = tf.tensor(보스톤_원인);
        var 결과 = tf.tensor(보스톤_결과);
 
        // 2. <<<<<<<히든 레이어 추가 part>>>>>>>>> + activation function 지정
        var X = tf.input({ shape: [13] });
        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);
        tfvis.show.modelSummary({name:'요약', tab:'모델'}, model);
 
        // 3. 데이터로 모델을 학습시킵니다. 
//         var fitParam = {epochs: 100}
        var _history = [];
        var fitParam = { 
          epochs: 100, 
          callbacks:{
            onEpochEnd:
              function(epoch, logs){
                console.log('epoch', epoch, logs, 'RMSE=>', Math.sqrt(logs.loss));
                _history.push(logs);
                tfvis.show.history({name:'loss', tab:'역사'}, _history, ['loss']);
              }
          }
        } // loss 추가 예제
        model.fit(원인, 결과, fitParam).then(function (result) {
             
            // 4. 모델을 이용합니다. 
            // 4.1 기존의 데이터를 이용
            var 예측한결과 = model.predict(원인);
            예측한결과.print();
 
        });  
 
        // 4.2 새로운 데이터를 이용
        // var 다음주온도 = [15,16,17,18,19]
        // var 다음주원인 = tf.tensor(다음주온도);
        // var 다음주결과 = model.predict(다음주원인);
        // 다음주결과.print();
    </script>
</body>
 
</html>

TensorFlow.js Classification (분류 작업 시키기)

1. Classification

  • TensorFlor.js와 데이터를 쉽게 다룰 수 있도록 돕는 'Danfo.js'를 사용
  • 前에 배운 것 - Regression : 회귀
  • 종속변수가 숫자가 아니라 라벨이 되어 있을 때 -> Classification(분류)를 사용
  • 과정
    1) 과거의 데이터 필요
    2) 모델 모양 만들고
    3) 모델 학습을 시키는 것
    차이점은 ? 숫자가 아니라 문자가 결과라는 것!
    --> How ? 문자를 : 숫자에 대응시키면 됨.
    주의 : 숫자의 크기는 의미가 없음. just 라벨임.

2. 데이터 준비하기, 학습하기

  • 인터넷에 있는 raw 데이터에서 결과 값을 하나하나 라벨 -> 숫자로 매칭하는 과정은 매우 번거로움
  • 이럴 때 쓸 수 있는 도구가 바로 'Danfo.js'임!
  • <- 이 코드를 head에 넣어 사용함
<html>
<head>
    <!-- 버전에 따라서 예제가 동작하지 않는 경우가 있습니다. 아래 버전을 권장합니다. -->
    <script src="https://cdn.jsdelivr.net/npm/danfojs@0.1.2/dist/index.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@2.4.0/dist/tf.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs-vis"></script>
</head>
<body>
<script>

// 여기서 dfd는 danfo.js의 모듈의 이름  
dfd.read_csv('https://raw.githubusercontent.com/blackdew/tensorflow1/master/csv/iris.csv').then(function(data){
        console.log(data); // 데이터에 무엇이 들어있는지 확인
        data.print(); // 표로 출력할 수 있는 기능 
        독립변수 = data.loc({columns:['꽃잎길이','꽃잎폭','꽃받침길이','꽃받침폭']});
  
        독립변수.print();
        var encoder = new dfd.OneHotEncoder(); // 원핫인코딩 제공!!!!
        종속변수 = encoder.fit(data['품종']); // 품종 column의 정보를 원핫인코딩함
        data['품종'].print();
        종속변수.print(); // 원핫인코딩한 결과 표로 출력
         
        var X = tf.input({ shape: [4]}); // 4개의 입력
        var H = tf.layers.dense({ units: 4, activation:'relu'}).apply(X);
     
        var Y = tf.layers.dense({ units: 3}).apply(H); // 출력층, 원핫인코딩으로 컬럼이 3개가 되었으므로 '3'
        var Y = tf.layers.dense({ units: 3, activation:'softmax'}).apply(H);
     
        model = tf.model({ inputs: X, outputs: Y }); // 모델 제작
         
        var compileParam = { optimizer: tf.train.adam(), loss: tf.losses.meanSquaredError, metrics:['accuracy'] } // 회귀
        var compileParam = { optimizer: tf.train.adam(), loss: 'categoricalCrossentropy'} // 분류
     
        model.compile(compileParam);
         
        tfvis.show.modelSummary({name:'요약', tab:'모델'}, model);
 
    //     // 3. 데이터로 모델을 학습시킵니다. 
        _history = [];
        var fitParam = { 
          epochs: 100, // 100번 학습
          callbacks:{
            onEpochEnd: // 학습 상태 확인
              function(epoch, logs){ 
                console.log('epoch', epoch, logs, 'RMSE=>', Math.sqrt(logs.loss));
                _history.push(logs); // 보기 좋게 그래프로 표시
                tfvis.show.history({name:'loss', tab:'역사'}, _history, ['loss']);
                tfvis.show.history({name:'accuracy', tab:'역사'}, _history, ['acc']); // 정확도에 대한 그래프 표현
              }
          }
        } 
         
        model.fit(독립변수.tensor, 종속변수.tensor, fitParam).then(function (result) { // danfo에서 제공하는 tensor로 DataFrame 사용 
            // 4. 모델을 이용합니다. 
            // 4.1 기존의 데이터를 이용
            예측한결과 = new dfd.DataFrame(model.predict(독립변수.tensor)); //danfo.js의 DataFrame으로 가져옴
            예측한결과.print();
            종속변수.print();
 
        });  
    })
</script>
</body>
</html>

3. 분류스러운 학습

  • 컴퓨터에서는 확률을 0과 1 사이의 숫자로 바꿔야 사용하기 쉬움
  • 어떻게? softmax라는 activationFunction을 사용해서 바꿈
  • 분류에서는 MSE가 아닌 loss로 categoricalCrossentropy를 사용함
  • accuracy는 0~1 사이의 값. 1에 가까울 수록 높은 정확도를 가짐
profile
시작

0개의 댓글