AutonomicMachineLearning / MLFramework

1 stars 1 forks source link

Open Neural Network eXchange (ONNX) #5

Open chatterboy opened 5 years ago

chatterboy commented 5 years ago

목적 ONNX를 이용한 자율 기계학습 wrapper 기술 개발 필요성

ONNX란? ONNX는 기계학습에 대한 오픈 포멧으로 세 가지 컴포넌트들을 통하여 IR을 정의

tensorflow 모델을 onnx 모델로 변환

다음과 같은 네 가지 단계를 수행

  1. tensorflow에서 dataflow graph에 대한 graph_defcheckpoint를 저장
  2. graph_def의 구조 및 입출력에 대한 정보를 식별
  3. 위의 두 파일을 하나의 파일로 만드는 freezing 수행
  4. freezon tensorflow graph를 onnx model로 변환

TODO: 각 단계에 대한 상세한 설명 기술

graph_defcheckpoint 저장

import tensorflow as tf

from tensorflow.examples.tutorials.mnist import input_data

def weight_variable(shape):
    initial = tf.truncated_normal(shape, stddev=0.1)
    return tf.Variable(initial)

def bias_variable(shape):
    initial = tf.constant(0.1, shape=shape)
    return tf.Variable(initial)

def ann(x):
    with tf.name_scope('reshape'):
        input = tf.reshape(x, [-1, 28 * 28])

    with tf.name_scope('out'):
        W_h1 = weight_variable([28 * 28, 10])
        b_h1 = bias_variable([10])
        out = tf.matmul(input, W_h1) + b_h1

    return out

def main(_):
    mnist = input_data.read_data_sets('data')

    x = tf.placeholder(tf.float32, [None, 784])

    logits = ann(x)

    with open('graph-simple.pb', 'wb') as file:
        graph = tf.get_default_graph().as_graph_def(add_shapes=True)
        print("graph:\n{}".format(graph))
        file.write(graph.SerializeToString())

    y = tf.placeholder(tf.int64, [None])

    with tf.name_scope('loss'):
        cross_entropy = tf.losses.sparse_softmax_cross_entropy(
            labels=y, logits=logits
        )
    cross_entropy = tf.reduce_mean(cross_entropy)

    with tf.name_scope('adam_optimizer'):
        train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)

    with tf.name_scope('accuracy'):
        correct_prediction = tf.equal(tf.argmax(logits, 1), y)
        correct_prediction = tf.cast(correct_prediction, tf.float32)
    accuracy = tf.reduce_mean(correct_prediction)

    saver = tf.train.Saver()

    with tf.Session() as sess:
        sess.run(tf.global_variables_initializer())

        for i in range(10000):
            batch = mnist.train.next_batch(64)

            if i % 1000 == 0:
                train_accuracy = accuracy.eval(feed_dict={
                    x: batch[0], y: batch[1]})
                print("step: {}, training accuracy: {}".format(i, train_accuracy))

                save_path = saver.save(sess, 'ckpt-simple/model.ckpt')
                print("Model saved in path: {}".format(save_path))
            train_step.run(feed_dict={x: batch[0], y: batch[1]})

        print("test accuracy: {}".format(accuracy.eval(feed_dict={
            x: mnist.test.images, y: mnist.test.labels})))

if __name__ == '__main__':
    tf.app.run(main=main)

Freezing 수행

(onnx-test) > python -m tensorflow.python.tools.freeze_graph \
--input_graph=graph-simple.pb \
--input_binary=true \
--output_node_names="out/add" \
--input_checkpoint=ckpt-simple/model.ckpt \
--output_graph=frozen-simple.pb

tensorflow 모델 변환

(onnx-test) > python -m tf2onnx.convert \
--input frozen-simple.pb \
--output onnx-simple.onnx \
--inputs Placeholder:0 \
--outputs out/add:0 \
--verbose

참고 https://onnx.ai/ https://docs.microsoft.com/ko-kr/azure/machine-learning/service/how-to-build-deploy-onnx https://github.com/tensorflow/tensorflow/tree/v1.12.0/tensorflow/tools/graph_transforms https://github.com/onnx/tensorflow-onnx

chatterboy commented 5 years ago

Overview

Why a common IR?

Why two variants?

참고

https://github.com/onnx/onnx/blob/master/docs/Overview.md

chatterboy commented 5 years ago

Open Neural Network Exchange - ONNX

Purpose

Notes on model validation

Components

ONNX consists of the following components

The main distinction between ONNX and ONNX-ML:

Runtime Agnostic

Extensible computation graph model

Standard data types

참고

https://github.com/onnx/onnx/blob/master/docs/IR.md

chatterboy commented 5 years ago

flow

1. onnx_model = onnx.load('.onnx')

2. onnx_tf.backend.prepare(onnx_model)

3. prepare = TensorflowBackend.prepare

4. def prepare(cls, model, device='CPU', strict=True, **kwagrs):

함수 정의 부분은 아래와 같음

class TensorflowBackend(Backend):
    @classmethod
    def prepare(cls, model, device='CPU', strict=True, **kwagrgs):

5. return cls.onnx_model_to_tensorflow_rep(model, strict) (4번 함수)

6. onnx_model_to_tensorflow_rep(cls, model, strict):

ONXN 모델을 TensorflowRep 모델로 변환. 함수 정의 부분은 아래와 같음.

TensorflowBackend(Backend):
    ...
    @classmethod
    def onnx_model_to_tensorflow_rep(cls, model, strict):

7. return cls._onnx_graph_to_tensorflow_rep(model.graph, opset_import, strict) (6번 함수)

8. def _onnx_graph_to_tensorflow_rep(cls, graph_def, opset, strict):

함수 정의 부분은 아래와 같음.

9. return tf_rep (8번 함수)