오픈튜토리얼스 8.13 ~ 8.26  머신러닝야학에서 배운

레몬에이드 판매량 예측, 보스턴 집값 예측, 붓꽃 분류를 tensorflow.js로 만들었습니다.

오픈튜토리얼스 머신러닝야학 내용은 아래 링크를 참조해 주세요!

https://opentutorials.org/course/4570

 

Tensorflow 1 - 생활코딩

수업소개 이 수업은 코드로 딥러닝을 구현해보는 딥러닝 기초 수업입니다.  텐서플로우를 이용하여 가장 간단한 형태의 텐서플로우 딥러닝 모델을 작성합니다. 무엇을 넣을까가 아니라, 무엇

opentutorials.org

nodejs version: 12.18.3

tensorflow.js version: 2.3.0

 

전체 코드

  // csv 파일 읽기
  const irisCSVPath = 'file://' + path.join(__dirname, '../data/iris.csv')
  const irisCSV = tf.data.csv(irisCSVPath, {
    hasHeader: true,
    columnConfigs: { '품종': { isLabel: true } }
  })

  // 데이터셋 만들기
  const irisDataset = irisCSV.map(({ xs, ys }) => {
    let label = null
    switch (ys['품종']) {
      case 'setosa':
        label = [1, 0, 0]
        break;
      case 'versicolor':
        label = [0, 1, 0]
        break;
      case 'virginica':
        label = [0, 0, 1]
        break;
      default:
        break;
    }
    return { xs: Object.values(xs), ys: label }
  }).batch(16).shuffle(10)

  // 모델 만들기
  const input = tf.input({ shape: [4] })

  let hidden = tf.layers.dense({ units: 8 }).apply(input)
  hidden = tf.layers.layerNormalization().apply(hidden)
  hidden = tf.layers.activation({ activation: 'selu' }).apply(hidden)

  hidden = tf.layers.dense({ units: 8 }).apply(hidden)
  hidden = tf.layers.layerNormalization().apply(hidden)
  hidden = tf.layers.activation({ activation: 'selu' }).apply(hidden)

  hidden = tf.layers.dense({ units: 8 }).apply(hidden)
  hidden = tf.layers.layerNormalization().apply(hidden)
  hidden = tf.layers.activation({ activation: 'selu' }).apply(hidden)

  const output = tf.layers.activation({ activation: 'softmax' }).apply(tf.layers.dense({ units: 3 }).apply(hidden))

  const model = tf.model({ inputs: input, outputs: output })
  model.compile({ optimizer: tf.train.adam(0.001), loss: 'categoricalCrossentropy', metrics: 'accuracy' })
  model.summary()

  // 모델 학습
  await model.fitDataset(irisDataset, {
    epochs: 1000
  })

  await model.fitDataset(irisDataset, {
    epochs: 10,
    callbacks: {
      onEpochEnd: async (epoch, logs) => {
        console.log(`epoch${epoch}: loss= ${logs.loss}, acc= ${logs.acc}`);
      }
    }
  })

  // 테스트 데이터로 분류 결과값 확인
  const testDataset = await createTestDataSet(irisDataset, 0, 0, 8)
  model.predict(testDataset.xs).print()
  testDataset.ys.print()
  model.getWeights()[0].print()

CSV 파일 읽기

iris csv 파일을 읽어 오면서 header를 가지고 있고 라벨이 품종이라는 점을 표시합니다.

  const irisCSVPath = 'file://' + path.join(__dirname, '../data/iris.csv')
  const irisCSV = tf.data.csv(irisCSVPath, {
    hasHeader: true,
    columnConfigs: { '품종': { isLabel: true } }
  })

데이터셋 만들기

python tensorflow에서는 get_dummies 함수를 사용하면 품종 항목이 나누어집니다.

하지만 tensorflow.js에서 찾을 수가 없었습니다.

ys는 라벨을 표시한 값이 객체 형식으로 담겨져 있어 '품종'이 무엇인지 확인하고 

switch 문을 사용해 값을 변경하여 줍니다.

const irisDataset = irisCSV.map(({ xs, ys }) => {
    let label = null
    switch (ys['품종']) {
      case 'setosa':
        label = [1, 0, 0]
        break;
      case 'versicolor':
        label = [0, 1, 0]
        break;
      case 'virginica':
        label = [0, 0, 1]
        break;
      default:
        break;
    }
    return { xs: Object.values(xs), ys: label }
  }).batch(16).shuffle(10)

 


모델 만들기

보스턴 집값 예측과 같이 layerNormalization을 사용하였습니다.

다른 점은 활성화 함수가 마지막 레이어에서 분류에 적합한 softmax를 사용합니다.

학습률은 0.001이고 모델 학습을 하면서 정확도를 파악하기 위해 metrics 값으로 'accuracy'를 추가하였습니다. 

const input = tf.input({ shape: [4] })

  let hidden = tf.layers.dense({ units: 8 }).apply(input)
  hidden = tf.layers.layerNormalization().apply(hidden)
  hidden = tf.layers.activation({ activation: 'selu' }).apply(hidden)

  hidden = tf.layers.dense({ units: 8 }).apply(hidden)
  hidden = tf.layers.layerNormalization().apply(hidden)
  hidden = tf.layers.activation({ activation: 'selu' }).apply(hidden)

  hidden = tf.layers.dense({ units: 8 }).apply(hidden)
  hidden = tf.layers.layerNormalization().apply(hidden)
  hidden = tf.layers.activation({ activation: 'selu' }).apply(hidden)

  const output = tf.layers.activation({ activation: 'softmax' }).apply(tf.layers.dense({ units: 3 }).apply(hidden))

  const model = tf.model({ inputs: input, outputs: output })
  model.compile({ optimizer: tf.train.adam(0.001), loss: 'categoricalCrossentropy', metrics: 'accuracy' })
  model.summary()

모델 학습과 데이터셋 분류

기존 데이터셋에서 데이터를 가져와 확인 작업을 합니다.

getweights()[0] 은 첫번째 레이어가 가지는 weights 값들입니다.

  // 모델 학습
  await model.fitDataset(irisDataset, {
    epochs: 1000
  })

  await model.fitDataset(irisDataset, {
    epochs: 10,
    callbacks: {
      onEpochEnd: async (epoch, logs) => {
        console.log(`epoch${epoch}: loss= ${logs.loss}, acc= ${logs.acc}`);
      }
    }
  })

  // 테스트 데이터로 분류 결과값 확인
  const testDataset = await createTestDataSet(irisDataset, 0, 0, 8)
  model.predict(testDataset.xs).print()
  testDataset.ys.print()
  model.getWeights()[0].print()

결과값과 실제값 비교: 

Tensor
    [[0.0000133, 0.999977 , 0.0000097],
     [4e-7     , 0.9999844, 0.0000151],
     [0.0176175, 0.9823747, 0.0000078],
     [0.0000022, 0.9999913, 0.0000065],
     [0.0001166, 0.0010784, 0.998805 ],
     [0.0000383, 0.0020841, 0.9978777],
     [0.0000362, 0.002025 , 0.9979388],
     [0.0000181, 0.0106683, 0.9893135]]
Tensor
    [[0, 1, 0],
     [0, 1, 0],
     [0, 1, 0],
     [0, 1, 0],
     [0, 0, 1],
     [0, 0, 1],
     [0, 0, 1],
     [0, 0, 1]]

 

https://js.tensorflow.org/api/2.3.0/

 

TensorFlow.js | 자바스크립트 개발자를 위한 머신러닝

브라우저, Node.js 또는 Google Cloud Platform에서 모델을 학습시키고 배포합니다. TensorFlow.js는 자바스크립트 및 웹 개발을 위한 오픈소스 ML 플랫폼입니다.

www.tensorflow.org

 

'머신러닝' 카테고리의 다른 글

tensorflow.js 2) 보스턴 집값 예측  (0) 2020.08.27
tensorflow.js 1) 레몬에이드 판매량 예측  (0) 2020.08.27

+ Recent posts