ML 범용 명령어 - mnist 예제

IRIS Discovery Service의 DSL 명령어를 활용하여, mnist 숫자 이미지 다운로드부터 전처리, 학습, 예측, 평가, 서빙하는 시나리오입니다.

mnist 이미지 다운로드

mnist 숫자 이미지를 아래 사이트에서 다운로드 및 압축을 해제합니다.

https://github.com/myleott/mnist_png/blob/master/mnist_png.tar.gz

개인 객체 저장소에 업로드

다운로드 받은 이미지 파일을 개인 객체 저장소에 업로드합니다. 수동으로 업로드하거나 아래 스크립트를 실행합니다.

아래는 업로드하는 python 스크립트 예제 입니다. 모두 업로드하는데 1~2시간정도 소요됩니다.

  • boto3 패키지가 필요합니다. pip install boto3
  • 아래 인자를 입력해주세요.
  • testing : test 이미지 로컬 디렉토리 경로
  • training : train 이미지 로컬 디렉토리 경로
  • bucket : 개인 객체 저장소의 bucket
  • prefix : 개인 객체 저장소의 key (상위 키)
  • endpoint_url : 개인 객체 저장소의 url
  • aws_access_key_id : 개인 객체 저장소의 access_key
  • aws_secret_access_key : 개인 객체 저장소의 secret_access_key
import boto3
import os

local = {
'testing': '/home/oss/tensorflow/mnist_img/mnist_png/mnist_png/testing',
'training': '/home/oss/tensorflow/mnist_img/mnist_png/mnist_png/training'
}
obj_storage = {
    'bucket': 'user1',
    'prefix': 'mnist',
}
obj_setting = {
    'endpoint_url': 'http://192.168.102.140:9015',
    'verify': False,
    'aws_access_key_id': 'minio',
    'aws_secret_access_key': '??'
}

def upload_obj(cli, files, bucket, keys):
    if isinstance(files, str):
        files = [files]
    if isinstance(keys, str):
        keys = [keys]

    for i, (file, key) in enumerate(zip(files, keys), 1):
        try:
            cli.upload_file(file, bucket, key)
            if i % 100==0:
                print('{}개 완료'.format(i))
        except ClientError as e:
            raise Exception('upload key[{}, {}] fail. {}'.format(bucket, key, e))

def make_path(root_path, obj_storage_prefix):
    local_path_list = []
    obj_path_list = []

    for path, dirs, files in os.walk(root_path):
        for file in files:
            full_path = os.path.join(path, file)
            obj_path=full_path.replace(root_path, obj_storage_prefix)
            obj_path_list.append(obj_path)
            local_path_list.append(full_path)
    return local_path_list, obj_path_list

mc = boto3.client('s3', **obj_setting)

local_path, obj_path = make_path(local['testing'], obj_storage['prefix'])
upload_obj(mc, local_path, obj_storage['bucket'], obj_path)

local_path, obj_path = make_path(local['training'], obj_storage['prefix'])
upload_obj(mc, local_path, obj_storage['bucket'], obj_path)

연결정보 등록

개인 객체저장소를 활용하기 위해 연결정보를 등록합니다.

IRIS UI에서 아래와 같이 대시보드 , 연결정보 를 차례로 클릭합니다.

연결정보 클릭

새 연결 정보를 클릭합니다.

새 연결정보 클릭

연결 이름, 데이터소스 유형, 연결정보를 입력하고 ``저장``버튼을 클릭합니다.

연결정보 저장

전처리

전처리는 IRIS Discovery Service의 img2tsv , splitter 를 사용합니다.

이미지 벡터화

mnist 숫자 이미지를 벡터 형태로 변환하여 tsv파일로 개인 객체 저장소에 저장합니다.

검색창에 아래 명령어를 각각 입력합니다.

  • 객체저장소의 mnist/0 폴더는 one-hot 백터 형식으로 라벨을 [1,0,0,0,0,0,0,0,0,0]로 할당하며, tag는 zero라고 줍니다.
  • 같은 방식으로 나머지 1~9 숫자 이미지도 벡터화합니다.

img2tsv src=OBJECTSTORAGE.MIN_AI:mnist/0 dst=tsv/0.tsv column_name=feature label=(label, [int32], [1,0,0,0,0,0,0,0,0,0]) tag=zero

결과

total
6796

img2tsv src=OBJECTSTORAGE.MIN_AI:mnist/1 dst=tsv/1.tsv column_name=feature label=(label, [int32], [0,1,0,0,0,0,0,0,0,0]) tag=one img2tsv src=OBJECTSTORAGE.MIN_AI:mnist/2 dst=tsv/2.tsv column_name=feature label=(label, [int32], [0,0,1,0,0,0,0,0,0,0]) tag=two img2tsv src=OBJECTSTORAGE.MIN_AI:mnist/3 dst=tsv/3.tsv column_name=feature label=(label, [int32], [0,0,0,1,0,0,0,0,0,0]) tag=three img2tsv src=OBJECTSTORAGE.MIN_AI:mnist/4 dst=tsv/4.tsv column_name=feature label=(label, [int32], [0,0,0,0,1,0,0,0,0,0]) tag=four img2tsv src=OBJECTSTORAGE.MIN_AI:mnist/5 dst=tsv/5.tsv column_name=feature label=(label, [int32], [0,0,0,0,0,1,0,0,0,0]) tag=five img2tsv src=OBJECTSTORAGE.MIN_AI:mnist/6 dst=tsv/6.tsv column_name=feature label=(label, [int32], [0,0,0,0,0,0,1,0,0,0]) tag=six img2tsv src=OBJECTSTORAGE.MIN_AI:mnist/7 dst=tsv/7.tsv column_name=feature label=(label, [int32], [0,0,0,0,0,0,0,1,0,0]) tag=seven img2tsv src=OBJECTSTORAGE.MIN_AI:mnist/8 dst=tsv/8.tsv column_name=feature label=(label, [int32], [0,0,0,0,0,0,0,0,1,0]) tag=eight img2tsv src=OBJECTSTORAGE.MIN_AI:mnist/9 dst=tsv/9.tsv column_name=feature label=(label, [int32], [0,0,0,0,0,0,0,0,0,1]) tag=nine

train/test 분리

img2tsv에서 생성한 tsv 파일을 train/test, 80 대 20 비율로 분리하여 개인 객체 저장소에 저장합니다. 추가적으로 label과 tag 컬럼으로 사전데이터(dict.tsv)를 생성합니다.

검색창에 아래 명령어를 입력합니다.

splitter src=OBJECTSTORAGE.MIN_AI:tsv train=(train.tsv, 0.8) test=(test.tsv, 0.2) dictionary=(dict.tsv, label, tag)

결과

train test
54687 13793

test 데이터 등록

추후 예측에 활용하기 위해 splitter 명령어로 분리한 test데이터를 IRIS UI에 데이터 모델로 등록합니다.

데이터모델 생성을 위해 대시보드 - 데이터모델 을 클릭합니다.

데이터모델 클릭

모델 을 클릭합니다.

새 모델 클릭

연결 정보 를 선택하고 테스트 데이터 선택을 위해 찾아보기 를 클릭합니다.

찾아보기 클릭

팝업되는 창에서 TEST데이터를 찾아 선택된 파일 선택 을 클릭합니다.

선택된 파일 선택 클릭

분리기호를 \t 수정 후, 적용 - 분류 체크 를 클릭합니다. 모델 명을 mnist_test 로 입력 후 저장 버튼을 클릭합니다.

모델 생성

학습

학습은 IRIS Discovery Service의 fit 를 사용합니다.

설정 업로드

아래 python 스크립트를 활용하여 학습을 위한 설정을 개인 객체저장소에 업로드합니다.

  • boto3 패키지가 필요합니다. pip install boto3
  • 아래 인자를 입력해주세요.
  • bucket : 개인 객체 저장소의 bucket
  • key : 개인 객체 저장소의 key
  • endpoint_url : 개인 객체 저장소의 url
  • aws_access_key_id : 개인 객체 저장소의 access_key
  • aws_secret_access_key : 개인 객체 저장소의 secret_access_key
  • config : TFDeep 명령어 문서 를 참조하여 입력
import boto3
import json

bucket = 'user1'
key = 'angora_mnist_config.json'

obj_setting = {
    'endpoint_url': 'http://192.168.102.140:9015',
    'verify': False,
    'aws_access_key_id': 'minio',
    'aws_secret_access_key': '??'
}

config = """
{
  "env": {
    "num_executors": 1,
    "num_ps": 0
  },
  "model": {
    "network": {
      "backend": "tensorflow",
      "class_name": "Sequential",
      "config": {
        "layers": [
          {
            "class_name": "Conv2D",
            "config": {
              "activation": "relu",
              "batch_input_shape": [
                null,
                28,
                28,
                1
              ],
              "filters": 32,
              "kernel_size": [
                3,
                3
              ]
            }
          },
          {
            "class_name": "MaxPooling2D",
            "config": {
              "data_format": "channels_last",
              "dtype": "float32",
              "name": "max_pooling2d",
              "padding": "valid",
              "pool_size": [
                2,
                2
              ],
              "strides": [
                2,
                2
              ],
              "trainable": true
            }
          },
          {
            "class_name": "Flatten",
            "config": {
              "data_format": "channels_last",
              "dtype": "float32",
              "name": "flatten",
              "trainable": true
            }
          },
          {
            "class_name": "Dense",
          "config": {
              "activation": "relu",
              "activity_regularizer": null,
              "bias_constraint": null,
              "bias_initializer": {
                "class_name": "Zeros",
                "config": {
                  "dtype": "float32"
                }
              },
              "bias_regularizer": null,
              "dtype": "float32",
              "kernel_constraint": null,
              "kernel_initializer": {
                "class_name": "GlorotUniform",
                "config": {
                  "dtype": "float32",
                  "seed": null
                }
              },
              "kernel_regularizer": null,
              "name": "dense",
              "trainable": true,
              "units": 64,
              "use_bias": true
            }
          },
          {
            "class_name": "Dense",
            "config": {
              "activation": "softmax",
              "activity_regularizer": null,
              "bias_constraint": null,
              "bias_initializer": {
                "class_name": "Zeros",
                "config": {
                  "dtype": "float32"
                }
              },
              "bias_regularizer": null,
              "dtype": "float32",
              "kernel_constraint": null,
              "kernel_initializer": {
                "class_name": "GlorotUniform",
                "config": {
                  "dtype": "float32",
                  "seed": null
                }
              },
              "kernel_regularizer": null,
              "name": "dense_1",
              "trainable": true,
              "units": 10,
              "use_bias": true
            }
          }
        ],
        "name": "sequential"
      },
      "keras_version": "2.2.4-tf"
    },
    "loss": "categorical_crossentropy",
    "metrics": "accuracy",
    "optimizer": {
      "SGD": {
        "learning_rate": 0.001
      }
    },
    "format": "h5"
  },
  "dataset": {
    "train": {
      "type": "minio",
      "endpoint": "192.168.102.140:9015",
      "access_key": "minio",
      "secret_key": "minio123",
      "bucket": "user1",
      "path": "train.tsv",
      "format": "tsv",
      "header": true
    },
    "dictionary": {
      "type": "minio",
      "endpoint": "192.168.102.140:9015",
      "access_key": "minio",
      "secret_key": "minio123",
      "bucket": "user1",
      "path": "dict.tsv",
      "format": "tsv",
      "header": true
    }
  },
  "tensor": {
    "feature": {
      "shape": "(28, 28, 1)",
      "type": "float32"
    },
    "label": {
      "shape": "(10, )",
      "type": "float32"
    },
    "interpret": {
      "shape": "()",
      "type": "int32"
    }
  },
  "fit": {
    "input": {
      "dataset": "train",
      "feature": "feature",
      "label": "label"
    },
    "checkpoint": {
      "save_weights_only": true
    }
  },
  "interpret": {
    "dataset": "dictionary",
    "key": "label",
    "value": "tag"
  }
}

"""

conn = boto3.resource('s3', **obj_setting)
obj = conn.Object(bucket, key)
obj.put(Body=config)

학습

config에 앞서 업로드한 설정파일을 넣어 모델명을 tf_minist로하여 학습합니다.

검색창에 아래 명령어를 입력합니다.

fit deep batch_size=128 epochs=2 config=OBJECTSTORAGE.MIN_AI:angora_mnist_config.json into tf_mnist

결과

losses metrics
{‘loss’: 2.2735725229548427} {‘accuracy’: 0.20473583}
{‘loss’: 2.150804412119167} {‘accuracy’: 0.41432425}

accuracy가 41% 입니다. 높이기 위해 epochs을 3번 더 주어 이어서 학습합니다.

검색창에 아래 명령어를 입력합니다.

fit deep batch_size=128 epochs=3 retrain=True config=OBJECTSTORAGE.MIN_AI:angora_mnist_config.json into tf_mnist

결과

losses metrics
{‘loss’: 1.9149726856615126} {‘accuracy’: 0.5695675}
{‘loss’: 1.5214702637539697} {‘accuracy’: 0.67936534}
{‘loss’: 1.1004468156504876} {‘accuracy’: 0.76993394}

평가

평가는 IRIS Discovery Service의 eval 를 사용합니다.

학습된 모델을 평가하기 위해 검색창에 아래 명령어를 입력합니다. 평가 데이터는 앞서 생성한 mnist_test 를 사용합니다.

model name = 'mnist_test' model_owner = root | eval deep tf_mnist feature=feature label=label rate=0.8 repeat=3

결과

no losses metrics
1 {‘loss’: 0.8852438026895889} {‘acc’: 0.8077567}
2 {‘loss’: 0.8139687060163571} {‘acc’: 0.84133184}
3 {‘loss’: 0.818142257630825} {‘acc’: 0.8341704}

예측

예측은 IRIS Discovery Service의 predict 를 사용합니다.

학습된 모델로 예측을 위해 검색창에 아래 명령어를 입력합니다. 예측 데이터는 앞서 생성한 mnist_test 를 사용합니다.

model name = 'mnist_test' model_owner = root | predict tf_mnist feature

결과

label tag feature prediction interpreted
1,0,0,0,0,0,0,0,0,0 zero 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0…. 1,0,0,0,0,0,0,0,0,0 zero

배포

배포는 IRIS Discovery Service의 mlmodel deploy 를 사용합니다.

학습 모델을 버저닝하여 서빙합니다.

검색창에 아래 명령어를 입력합니다.

mlmodel deploy tf_mnist label='test'

결과

result latest_version serving_name
on 1 root_tf_mnist

예측 (서빙)

예측 (서빙)은 IRIS Discovery Service의 serving predict 를 사용합니다.

앞서 배포한 모델을 테스트데이터로 예측합니다. 예측 데이터는 앞서 생성한 mnist_test 를 사용합니다.

검색창에 아래 명령어를 입력합니다.

model name = 'mnist_test' | top 30 feature | serving predict tf_mnist col=feature shape=[(28,28,1)] layer_name=Conv1_input tag=(zero, one, two, three, four, five, six, seven, egiht, nine, ten)

결과

label tag feature predictions probability interpreted
0,0,0,0,0,1,0,0,0,0 five 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0… [0.62, 0.01, 0.04…] 0.62 five
1,0,0,0,0,0,0,0,0,0 zero 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0… [0.14, 0.03, 0.03…] 0.38 zero

조회

조회는 IRIS Discovery Service의 mlmodel , serving status 를 사용합니다.

ml 모델 목록을 보기 위해 아래 명령어를 입력합니다. 배포한 모델은 serving 속성이 on 으로 됩니다.

mlmodel list

결과

id user name type category algorithm serving create modified
1 root tf_mnist tf classification deep on 2019/11/19 00:11:22 2019/11/19 00:11:33

tf_mnist 모델을 상세 조회하기 위해 아래 명령어를 입력합니다.

mlmodel summary tf_mnist

결과

name value
id 1
user root
name tf_mnist
filename saved_model.pb
format saved_model
type tf
category deep
algorithm deep
feature feature
label label
parameter {‘batch_size’: 128, ‘epochs’: 5, ‘continuous’: ‘True’, ‘config’: ‘objectstorage.MINIO_AI_SOURCE:USERS/pjh0347/mnist/angora_mnist_config.json’}
evaluation []
cross_validation {}
grid_info {}
train_cnt 55260
elapsed 569.0207872390747
dictionary dict.tsv
cdate 20200323171102
mdate 20200324100417
serving off
serving_name root_tf_mnist
state DONE

tf_mnist 모델의 서빙 상태를 조회하기 위해 아래 명령어를 입력합니다.

serving status tf_mnist

version state label
1 AVAILABLE test