블로그 이미지
Peter Note
Web & LLM FullStacker, Application Architecter, KnowHow Dispenser and Bike Rider

Publication

Category

Recent Post

2018. 8. 22. 14:40 Deep Learning/Tensorflow

이찬우님의 텐서플로우 유튜브강좌를 정리한다. 




강좌 3


로지스틱 비용함수를 만들기

  - 좌측과 우측에 대한 convex 를 만들기 위한 식

cost = tf.reduce_sum(-y*tf.log(output)-(1-y)*tf.log(1-output), reduction_indices=1)


prediction과 label끼리의 정확도를 판단하기 

  - 각자의 벡터 매칭이 맞으면 1, 틀리면 0으로 하는 값을 다시 n*1 벡터로 만든다. 

  - 해당 백터의 값에 대한 평균을 구한다. 

  - 이때 1, 0값은 bool이어서 float32로 변환하여 계산한다.

  - 잘 맞으면 평균 1 이 나온다. 

comp_pred = tf.equal(tf.argmax(output, 1), tf.argmax(y, 1))

accuracy = tf.reduce_mean(tf.cast(comp_pred, tf.float32))


모델 저장하기

  - Training시킨 모델을 저장하는 것을 Checkpoint라 한다.

  - 저장내용에는 Weight과 Model이 저장될 수 있다. 

  - Weight관련 Variable을 저장한후 Save한다.

  - 저장시 유의점은 Variable, placeholder 함수의 파라미터중 하나인 Name이 자동으로 지정된다. 

W_o = tf.Variable(tf.truncated_normal(shape=[HIDDEN2_SIZE, CLASSES], dtype=tf.float32))

b_o = tf.Variable( tf.zeros([CLASSES]), dtype=tf.float32)


param_list = [W_h1, b_h1, W_h2, b_h2, W_o, b_o]

saver = tf.train.Saver(param_list)


hidden1 = tf.sigmoid(tf.matmul(x, W_h1) + b_h1)

hidden2 = tf.sigmoid(tf.matmul(hidden1, W_h2) + b_h2)


....

for i in range(1000):

    _, loss = sess.run([train, cost, accuracy], feed_dict = feed_dict)

    if i % 100 == 0:

        saver.save(sess, './tensorflow_3_lec.ckpt')

        ...




강좌 4


저장된 Weight Restoring하기 

  - save 할 때 Widget의 Variable에 name을 지정한다. 

  - 

x = tf.placeholder(tf.float32, shape=[None, INPUT_SIZE], name='x')

y = tf.placeholder(tf.float32, shape=[None, CLASSES], name='y')

W_h1 = tf.Variable(tf.truncated_normal(shape=[INPUT_SIZE, HIDDEN1_SIZE], dtype=tf.float32), name='W_h1')

b_h1 = tf.Variable(tf.zeros([HIDDEN1_SIZE]), dtype=tf.float32, name='b_h1')

hidden1 = tf.sigmoid(tf.matmul(x, W_h1) + b_h1, name='hidden1')

hidden2 = tf.sigmoid(tf.matmul(hidden1, W_h2) + b_h2, name='hidden2')

output = tf.sigmoid(tf.matmul(hidden2, W_o) + b_o, name='output')

...

saver.restore(sess, './tensorflow_3.ckpt')




강좌 5


Tensorboard는 디버깅 용도이다. 공식 튜토리얼을 참조한다.

  - name_scope는 묶음 단위이다.

  - scalar: 로그 데이터 남기기

  - tf.summary.merge_all()

  - tf.summary.FileWriter(<dir>, session.graph) 

# 가설함수 

with tf.name_scope('hidden_layer_1') as h1scope:

    hidden1 = tf.sigmoid(tf.matmul(x, W_h1) + b_h1, name='hidden1')


with tf.name_scope('hidden_layer_2') as h2scope:

    hidden2 = tf.sigmoid(tf.matmul(hidden1, W_h2) + b_h2, name='hidden2')

    

with tf.name_scope('output_layer') as oscope:

    output = tf.sigmoid(tf.matmul(hidden2, W_o) + b_o, name='output')


....


# 수행 

sess= tf.Session()

sess.run(tf.global_variables_initializer())


merge = tf.summary.merge_all()


for i in range(1000):

    _, loss, acc = sess.run([train, cost, accuracy], feed_dict = feed_dict)

    if i % 100 == 0:

        train_writer = tf.summary.FileWriter('./summaries/', sess.graph)


$ tensorboard --logdir=./summaries 수행한다. 




강좌 6


Loading Data in Tensorflow 참조. CSV파일 읽기

  - decode_csv로 콤마기반의 csv파일을 읽어들인다.

  - record_defaults = [[1], [1], [1], [1], [1], [1], [1], [1], [1]]  Fixed 자리수에서 비어있는 값에 대한 default value이다. 

  - start_queue_runners는 Session.run이 수행되기전에 호출해서 queue를 실행해서 file이 queue에서 대기토록 한다.

  - Coordinator 는 Thread 관리를 수행한다.

!

Image 읽기

  - FixedLengthRecordReader로 읽음

  - decode_raw를 사용함




to be continue...




<참조>

  - 텐서플로우의 체크포인트 설명

  - 텐서플로우 Save & Restore

  - 파이썬의 With 구문 이해 





posted by Peter Note
2018. 8. 16. 15:06 Deep Learning/Read Paper

Data2Vis는 seq2seq를 통해 입력되는 데이터를 기반으로 출력으로 차트를 자동생성한다.




개념


해당 논문을 이해하기 위해 다음과 같은 단어의 개념을 이해해야 한다. 소스에서도 같은 용어를 쓰기 때문에 소스이해를 위해서도 중요하다. 


 - Data2Vis의 데모 사이트에 가면 간략한 설명이 나와 있다.


    

  

  - Attention mechanism을 이용한 encoder-decoder 아키텍쳐 모델이다.  

  - key/value 쌍의 데이터를 입력으로 하고 Vega-Lite기반의 출력을 생성한다. Vega-Lite는 JSON기반으로 차트를 생성해주는 스펙이다. 

  - 특징

     + encoder는 최종 context vector 하나로 만든다. 이것을 C 라고 표현한다. 위이 그림에서 가운데 위치한 C이다. 

     + decoder는 학습할 때 encoder의 "C"와 "<go>답안"을 입력받아 "답안<eos>"를 출력하는 학습을 한다. (참조)

     + encoder, decoder의 길이를 정해야 한다. 무한정일 수 없다.

     + 여기서 encoder, decoder는 동시에 학습할 수 있다. (참조)

     + 정답이 있는 데이터만 S2S 학습이 가능하다.

     + 단어들에 대한 벡터화한 수치 사전이 필요하다. (참조)

  - beam search

     + RNN의 학습 과정에서 트리 탐색 기법으로 쓰임

     + 최고우선탐색(Best-First-Search)기번을 기본으로 회되 기억해야 하는 노드 수를 제한해 효율성을 높이는 방식

     + beam : 사용자가 기억해야 하는 노드 수

  - LSTM

     + Backward Propagation(역전파)할 때에 Gradient Vanishing이나 Exploding되는 현상을 막기 위해 LSTM을 사용한다. 

     + 역전파할 때 미분한다. Gradient는 결국 기울기 이고, 미분또한 기울기를 구하는 것으로 역전파를 할 때 미분의 값이 작을 때 Gradient Vanshing이 발생하고, 클때 exploding이 발생한다.

     + Gradient Vanishing에 대한 자세한 설명은 영덕의 연구소를 참조한다.  





소스 설치 및 실행


소스를 깃헙에서 클론한다.

$ git clone https://github.com/victordibia/data2vis.git


환경 설정

  - Anacoda를 설치

  - Python v3.6.5 사용

  - Tensorflow v1.9.0 사용 (Anaconda Navigator UI에서 설치하지 않고 conda CLI로 버전을 지정해서 설치한다.)

$ conda install -c conda-forge tensorflow=1.9.0


모듈 설치

  - requirements.txt는 node.js의 package.json역할

$ cd data2vis

$ pip install -r requirements.txt


실행하기 

$ python webserver.py


브라우져에서 http://localhost:5016/  호출


디버깅하기

MS Code에서 다음 항목을 추가한다.

  - port: listen 포트

  - model_dir: 모델이 있는곳, 이곳에 seq2seq의 환경파일인 train_options.json 파일이 존재해야 한다. 

     해당 파일은 training 시킨 결과를 통해 자동으로 생성된다. 훈련시키는 방법에 대해서는 두번째 글 참조.

  - beam_width: 사용자가 기억해야 하는 노드수 5개

{

    "version": "0.2.0",

    "configurations": [

        {

            "name": "Python: Data2Vis - Flask (0.11.x or later)",

            "type": "python",

            "request": "launch",

            "program": "${workspaceFolder}/webserver.py",

            "env": {

                "FLASK_APP": "${workspaceFolder}/webserver.py",

                "FLASK_ENV": "development"

            },

            "args": [

                "--port=5016",

                "--model_dir=vizmodel",

                "--beam_width=15"

            ]

        },

        {

            "name": "Python: Current File",

            "type": "python",

            "request": "launch",

            "program": "${file}"

        },

        .....

}


샘플 실행

  - 좌측 examples 메뉴를 클릭하고 입력창에 1이상의 값을 넣고, "Generate Examples" 버튼을 클릭하면 차트가 생성된다. 





seq2seq 모듈


구글이 개발한 tf-seq2seq 모듈 소스을 data2vis 폴더에 그대로 copy해 놓은 상태이다.  모델을 학습하고 검증하는 것은 실제 seq2seq가 하므로 tf-seq2seq 사용방법을 알아야 한다. 

   - tf-seq2seq 소개 블로그: Goolge NMT 논문 필수

   - seq2seq에 대한 기본 설명은 Arxiv의 Neural Machine Translation 논문을 참조한다. 

   - Tensorflow의 seq2seq 사용법



Configuration Training

  - 환경파일에는 Input data, model, training parameter를 정의한다.

  - vismodel의 train_options.json 파일을 사용한다.

  - optimizer 종류와 learning_rate등을 지정. Adam 옵티마이저를 사용.

  - vocab_target, vocab_source 임베딩을 위한 벡터 카운트를 만들기 위해 파일 지정

  - decoder, encoder class와 params을 설정. 둘 다 LSTMCell 사용

  - attention class와 params 설정

  - inference, bridge, embedding 설정

  - source/target.max_seq_len 으로 string의 크기 지정

  - 모델 옵션 설명

  - 인코더 옵션 설명

  - 디코더 옵션 설명


{

    "model_class": "AttentionSeq2Seq",

    "model_params": {

        "optimizer.name": "Adam",

        "decoder.class": "seq2seq.decoders.AttentionDecoder",

        "inference.beam_search.beam_width": 5,

        "decoder.params": {

            "rnn_cell": {

                "dropout_input_keep_prob": 0.5,

                "num_layers": 2,

                "cell_params": {

                    "num_units": 512

                },

                "dropout_output_keep_prob": 1.0,

                "cell_class": "LSTMCell"

            },

            "max_decode_length": 2000

        },

        "optimizer.learning_rate": 0.0001,

        "source.reverse": false,

        "source.max_seq_len": 500,

        "attention.params": {

            "num_units": 512

        },

        "attention.class": "seq2seq.decoders.attention.AttentionLayerDot",

        "vocab_target": "sourcedata/vocab.target",

        "target.max_seq_len": 500,

        "optimizer.params": {

            "epsilon": 8e-07

        },

        "bridge.class": "seq2seq.models.bridges.ZeroBridge",

        "vocab_source": "sourcedata/vocab.source",

        "encoder.params": {

            "rnn_cell": {

                "dropout_input_keep_prob": 0.5,

                "num_layers": 2,

                "cell_params": {

                    "num_units": 512

                },

                "dropout_output_keep_prob": 1.0,

                "cell_class": "LSTMCell"

            }

        },

        "encoder.class": "seq2seq.encoders.BidirectionalRNNEncoder",

        "embedding.dim": 512

    }

}



Training 

  - 모델과 교육데이터가 갖추어져 있으면 훈련을 수행한다.

  - /sourcedata안에 source, target의 trainig data가 존재한다.

  - utils/data_gen.py에서 /examples 폴더의 vega spec을 읽어와 training data를 만들고 있다. 



Prediction

  - 모델 Training을 받은 후 예측을 시작할 수 있다. 

  - DecodeText 클래스를 사용하고, Input pipeline은 ParallelTextInputPipeline을 사용함. 

    + DecodeText는 모델 예측을 가져와 표준 출력으로 추력하는 작업을 수행함

    + DumpAttention과 DumpBeams을 이용해 모델 수행시 디버깅을 할 수 있다. 파일로 쓰는 것임.

    + input pipline은 데이터를 읽는 방법을 정의한다.



Decoding with Beam Search

  - 빔 검색은 번역 성능을 향상시키는 일반적으로 사용되는 디코딩 기술이다. 

  - 빔 검색은 메모리에 가설 또는 빔(beam)을 놓고 가장 높은 점수인 것을 선택한다. 



Evaluating specific checkpoint

  - Training을 통해 다양한 모델의 체크포인트를 저장한다.

  - BLEU (bilingual evaluation understudy)를 통해 번역 성능 평가. 

 


Checkpoint에 대한 설명

- Saving

  + model 을 만드는 코드 의존적인 포멧을 갖는다.

  + 체크포인트는 training하며 생성된 모델의 버전이다.

  + Estimator가 checkpoint를 model_dir 위치에 저장한다. 

  + events 파일은 tensorboard가 시각시에 사용한다. 

  + Saver를 통해 체크포인트를 Saving/Restoring 한다. 


checkpoint

events.out.tfevents.timestamp.hostname

graph.pbtxt

model.ckpt-1.data-00000-of-00001

model.ckpt-1.index

model.ckpt-1.meta

model.ckpt-200.data-00000-of-00001

model.ckpt-200.index

model.ckpt-200.meta


- Restoring

  + Estimator는 train()을 호출하면 model의 그래프를 model_fn()을 호출해서 생성한다. 

  + Estimator는 최근의 checkpoint를 통해 새로운 모델의 weight을 초기화 한다. 






webserver.py 이해


파이썬 웹서비스는 Flask를 이용한다.  data2vis/static 과 templates가 Flask운영을 위해 사용된다. 


webserver.py 실행 순서

- port, vizmodel, beam_width를 아규먼트를 받는다.

- vizmodel/train_options.json을 기반으로 TrainOption 오브젝트를 생성

train_options = training_utils.TrainOptions.load(model_dir_input)


- model params을 사용해 model class를 생성함. AttensionSeq2Seq.py (attension_seq2seq.py)

model_params = _deep_merge_dict(model_params, _maybe_load_yaml(model_params))

model = model_cls(params=model_params, mode=tf.contrib.learn.ModeKeys.INFER)


- inference task 생성. DecodeText 생성

if (str(tdict["class"]) == "DecodeText"):

        task = task_cls(tdict["params"], callback_func=_save_prediction_to_dict)


- ParallelTextInputPipeline pipeline 생성

input_pipeline_infer = input_pipeline.make_input_pipeline_from_def(

    fl_input_pipeline,

    mode=tf.contrib.learn.ModeKeys.INFER,

    shuffle=False,

    num_epochs=1)


- inference를 사용하는 (Tensorflow) graph 생성.

  + seq2seq/inference/inference.py에서 pipeline과 batch_size를 통해 input function을 만들고

  + input function의  feature와 label을 model의 파라미터로 사용해서 model의 build를 호출한다. 

predictions, _, _ = create_inference_graph( model=model, input_pipeline=input_pipeline_infer, batch_size=batch_size)


- Listen을 하고, Flask의 routing을 설정한다. "Generate Examples" 버튼 클릭시 호출 

  + test data를 사용한다. 

  + normalize를 해준다. (foward_norm, backward_norm)

  + decode result를 가지고 vega spec을 만들어 return한다. 

@app.route("/examplesdata")

def examplesdata():

    source_data = data_utils.load_test_dataset()

    f_names = data_utils.generate_field_types(source_data)

    data_utils.forward_norm(source_data, destination_file, f_names)


    run_inference()

    

    decoded_string_post = data_utils.backward_norm(decoded_string[0], f_names)


    try:

        vega_spec = json.loads(decoded_string_post)

        vega_spec["data"] = {"values": source_data}

        response_payload = {"vegaspec": vega_spec, "status": True}

    except JSONDecodeError as e:

        response_payload = {

            "status": False,

            "reason": "Model did not produce a valid vegalite JSON",

            "vegaspec": decoded_string

        }

    return jsonify(response_payload)





<참조>


  - Data2Vis 소개글, 깃헙 소스, Arxiv 링크

  - deeep 블로그
     seq2seq 에 대한 쉬운 설명글

     Attention 메카니즘설명 (소개한 Arxiv 링크)

  - ratsgo 블로그
     RNN과 LSTM 이해

     seq2seq를 이용한 뉴스 제목 추출하기
     설명에 대한 소스 (2018년 tensorflow 버전에 맞지않다)

     beam search 이해 in Recursive Neural Network

  - 구글 제공
     seq2seq 문서

  - Tensorflow의 seq2seq 한글 설명, 2014년 Arxiv에 소개된 seq2seq pdf

  - 라온피플 블로그
     RNN, LSTM, GRU 소개

  - 영덕의 연구소 블로그
     Gradient Vanishing 문제 개념

  - Naivsphere 블로그

    SGD (Stochastic Gradient Descent)에 대한 글

  - 카카오 IT 브런치
     BLEU: NMT 평가 방식 설명

  - skymind.ai

  - epoch, batch_size 용어 이해 (MNIST epoch, batch 설명)

posted by Peter Note
2018. 8. 11. 16:12 Deep Learning

텐서플로우 강좌를 들으면서 다음의 모델을 실습으로 쥬피터에 코딩을 했다. 여기서 Cost function을 짤때 log함수를 왜 사용하고 앞에 - (마이너스)값은 왜 붙이는지 정리해 본다. 



준비

  - 아나콘다 설치

  - jupyter notebook 실행

  - python v3 


import tensorflow as tf


input_data = [[1, 5, 3, 7, 8, 10, 12]]

label_data = [0, 0, 0, 1, 0]


INPUT_SIZE = 7

HIDDEN1_SIZE=10

HIDDEN2_SIZE=8

CLASSES = 5

Learing_Rate = .05


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

y = tf.placeholder(tf.float32, shape=[CLASSES])


feed_dict = {x: input_data, y: label_data}


W_h1 = tf.Variable(tf.truncated_normal(shape=[INPUT_SIZE, HIDDEN1_SIZE], dtype=tf.float32))

b_h1 = tf.Variable( tf.zeros([HIDDEN1_SIZE]), dtype=tf.float32)

hidden1 = tf.sigmoid(tf.matmul(x, W_h1) + b_h1)


W_h2 = tf.Variable(tf.truncated_normal(shape=[HIDDEN1_SIZE, HIDDEN2_SIZE], dtype=tf.float32))

b_h2 = tf.Variable( tf.zeros([HIDDEN2_SIZE]), dtype=tf.float32)

hidden2 = tf.sigmoid(tf.matmul(hidden1, W_h2) + b_h2)


W_o = tf.Variable(tf.truncated_normal(shape=[HIDDEN2_SIZE, CLASSES], dtype=tf.float32))

b_o = tf.Variable( tf.zeros([CLASSES]), dtype=tf.float32)

output = tf.sigmoid(tf.matmul(hidden2, W_o) + b_o)


cost = tf.reduce_mean(-y*tf.log(output)-(1-y)*tf.log(1-output))

train = tf.train.GradientDescentOptimizer(Learing_Rate).minimize(cost)


sess= tf.Session()

init = tf.initialize_all_variables()

sess.run(init)


for i in range(10):

    _, loss = sess.run([train, cost], feed_dict = feed_dict)

    print('step:', i)

    print('lost:', loss)


//결과

step: 0
lost: 0.794413
step: 1
lost: 0.780786
step: 2
lost: 0.767388
step: 3
lost: 0.754181
step: 4
lost: 0.741128
step: 5
lost: 0.728179
step: 6
lost: 0.715276
step: 7
lost: 0.702345
step: 8
lost: 0.689285
step: 9
lost: 0.675957



cost(비용) 함수의 목적은 비용 판단을 통해 올바른 W(가중치, 기울기)와 b(바이어스, 시작점)을 찾는 것이다. 다시 말하면 목표하는 W과 b를 찾을 수 있다면, 어떤 형태가 되었건 비용함수라고 부를 수 있다는 뜻이다. 



Inference => Loss => Training => Evaluation  순서로 진행을 한다. 좋은 예제로 MNIST.py 구글 강좌 예제 소스를 먼저 참조해 보자.


- Inference: 가설함수 수립

- Loss: 비용함수 수립

- Training: 최적화 작업 수행하여 Loss (Cost)가 작아지는 W, b 값을 구함

- Evaluation: 검증은 Training을 통해 구해진 W, b가 가설함수에 적용되어 test data를 넣었을 때, Labeled data와 일치하는지 검증함




Step-1) 가설함수 

  - matmul 은 Matrix Mutiply의 약어이다. 

  - sigmoid는 binary classification의 한계를 넘기 위해 적용. sigmoid 그래프는 중심축 0을 중심으로 좌측은 0으로, 우측을 1로 수렴한다.

  - 가설함수 (Hyphothesis):  H(x) = sigmoid(Wx + b) 로 결과값은 0 또는 1의 값을 갖는다. 수학 공식으로 하면,

     H(x) = 1 / (1 + math.exp(-(Wx + b))

     소스에서는  output = tf.sigmoid(tf.matmul(hidden2, W_o) + b_o) 이 가설함수이다.



Step-2) 비용함수

  - 가설함수를 정의했다면 해당 가설 함수의 적정한 W, b를 찾기 위해 비용(Cost) 함수를 정의한다.

     비용함수는 예측값과 실제값의 차이에 대한 평균값을 구한다. 로지스틱 회귀에 사용되는 실제 비용함수를 수학 공식으로 하면,

     cost = (1/n) * sum( -y_origin * log(sigmoid(Wx + b)) - (1 - y_origin) * log(1 - (sigmoide(Wx + b))) 

       n: 트레이닝 데이이터 수

       y_origin: 트레이닝에 에 사용될 x에 대한 입력값

     소스에서는  cost = tf.reduce_mean(-y*tf.log(output)-(1-y)*tf.log(1-output)) 이 비용함수이다. 


  - 비용함수에서 가설함수의 e를 사용하는게 아니라 log를 사용하는 이유는 e를 통해 비용함수를 그리면 다음과 같이 나오기 때문에 매끈한 경사를 만들기 위해 e의 역치함수인 log를 사용한다. 

    비용함수는 y=1 일때와 y=0 일때는 나누어 계산한다. 


  - 측정(실제 입력)값 y=1 일때는 -log(H(x)), -log(가설함수) 즉 -log(sigmoide(Wx + b)) 를 사용하고 그래프로 보면 sigmoid(Wx+b)가 0~1사이에 있고 -log(0~1)을 그린다. 

     H가 1이면 cost(1) = 0 이 되고, H가 0이면 cost = 무한대가 된다.

     좌측의 밥그릇이 된다.

     측정(실제 입력)값 y=0 일때는 가설값이 0이 되어야 한다. 이는 0에 가까울 수록 cost는 0에 가까워야 한다. -log(1 - sigmoid(Wx + b)) 되고 log(1 - (0~1)) 이 된다. 

    우측의 밥그릇이 된다.

     요약하면 -log(h)는 좌측, -log(1-h)는 우측이다. 


  * 주의할 것은 Linear Regression (binary classification)을 하기 위해 평균에 제곱을 하지 않는다. 

 

  - y=0 일때와 y=1일때의 각 수식을 하나의 수직으로 만들기 위해 다음 공식을 사용해 합쳐서 표현한다. 소스에서는 -y*tf.log(output)-(1-y)*tf.log(1-output) 이 된다. 

  


      y * A + (1-y) * B => y * -log(H(x)) + (1-y) * -log(1 - H(x)) => -y*log(H(x)) - (1-y)*log(1 - H(x))  => -( y*log(H(x)) + (1-y)*log(1 - H(x)) )


  - 이것을 다시 재구성하면 다음과 같다. 소스에서는 cost = tf.reduce_mean(-y*tf.log(output)-(1-y)*tf.log(1-output)) 이다.

  



Step-3) 옵티마이저

  -  코스트함수가 정해지면 옵티마이저를 설정한다. 

      경사하강법 (GradientDescent)는 cost(W)을 미분을 적용해서 W의 다음 위치를 계산하는 공식이다. 다음 위치로 이동하는 것은 Learning Rate (이동하는 Step 크기)로 정해진다.

  - W 와 b의 적정값을 계산하기 위해 비용함수를 만들었다면 학습을 통해 GradientDescent가 W와 b값을 구한다. 여기서 나온 W,b를 통해 예측을 수행한다.

  - 소스는  tf.train.GradientDescentOptimizer(Learing_Rate).minimize(cost) 이다.

  - GradientDescent Optimizer는 gradient를 계산해서 변수에 적용하는 일을 동시에 하는 함수이다. W와 b를 적절하게 계산해서 변경하는 역할을 하며, 그 진행 방향이 cost가 작아지는 쪽으로 수행한다. train을 수행하게 되면 텐서 그래프의 모든 변수의 값이 자동 변경되며 계산된다. 소스는 _, loss = sess.run([train, cost], feed_dict = feed_dict) 이다.


  - 또한 텐서를 run하기 전에 그래프에 연결된 모든 variable을 초기화해야 한다. 

  - 옵티마이저 설명 참조

  



Step-4) 가절 검증

  - Accuracy or Evaluation

  - output 은 hypothesis 가설함수로 이것을 실제 테스트를 해본다. 

  - Linear에서 x, y 데이터를 placeholder를 통해 train 시키고, 최종 W,b가 구해진 가설함수에 대해서 test 데이터를 넣어 보고 예측이 맞는지 검증한다. 

  - Linear Regression 예 (Linear Regression에 대한 이해 참조)

import tensorflow as tf

x_data = [1.,2.,3.]

y_data = [1.,2.,3.]


W = tf.Variable(tf.random_uniform([1], -100., 100.))

b = tf.Variable(tf.random_uniform([1], -100., 100.))


X = tf.placeholder(tf.float32)

Y = tf.placeholder(tf.float32)


h = W * X + b

cost = tf.reduce_mean(tf.square(h - Y))


rate = tf.Variable(0.1)

op = tf.train.GradientDescentOptimizer(rate)

train = op.minimize(cost)


init = tf.initialize_all_variables()


sess = tf.Session()

sess.run(init)


for step in range(2001):

    sess.run(train, feed_dict = {X: x_data, Y: y_data})

    if step % 100 == 0:

        print(step, sess.run(cost, feed_dict={X: x_data, Y: y_data}), sess.run(W), sess.run(b))


print('Test:', sess.run(h, feed_dict={X: 5}))




<참조>

- 김성훈 교수님 강좌 요약 블로그

- 조대협의 로지스틱 회귀 분석 블로그

- Tensorflow 유튜브 강의

- 로지스틱 회귀 이해

- 선형, 비선형 회귀 모델의 이해

- Tensorflow의 자료형 이해, 상수/변수/플레이스홀더 이해

- 선형 회귀를 Tensorflow로 구현하기

posted by Peter Note
2018. 7. 9. 14:46 Deep Learning/NN by Sung Kim

TensorBoard 사용하기 강좌를 정리한다





TensorBoard 사용하기 


5개의 step 을 거친다. 

1) 어떤것을 로깅할 것인지 정한다

2) all summary

3) summary 기록할 파일 위치 지정

4) session.run 실행

5) 별도 터미널에서 tensorboard --logdir=<지정폴더> 수행




Scalar (스케일러)





Histogram 

다차원 텐서의 경우 사용함. 



Graph

흐름도를 보고 싶을 경우 사용함.

- name_scope 사용하여 Layer를 구분하여 보기 좋게 한다. (접혔다 폈다 할 수 있음)




remote에 있는 tensorboard 보기





Multi run 하기 

부모 폴더만을 지정하면 child folder를 자동으로 보여줌 







9 Layer Tensorboard 구성시 문제점 


Deep Network을 다음과 같이 구성하고 Learning을 시킨 것이 Deep Learning이다. 



name_scope로 구분하여 Tensorboard에 표현 (강좌)

deep network를 구성할 때 코드로만 보면 어려울 수 있다. 이것을 시각화하여 다음과 같이 표현한다. 




결과 : 서로의 연결과 가중치(Weight)를 쉽게 볼 수 있다. 



9 layer를 거친다고 해서 정확도가 높아지는 것은 아니다. 2,3 layer는 잘 학습이 되지만 3 layer넘어가면 학습도가 떨어진다. 

이유: 결과의 1보다 작은 소숫점의 값을 multiply할 수록 더 작은 소숫점 값이 되어 버려서 gradient값이 살라진게 된다. 





Network으로 표현하면 좌측으로 갈 수록 점점 정확도가 떨어짐. 2006년까지 겨울이 찾아옮.

- 힌튼교수가 해결: Sigmoid를 잘 못 쓴것 같다. 

- ReLU를 적용해 보자. 








ReLU (Rectified Linear Unit, 렐루)


힌트 교수의 잘 못한 부분중 4번째 




ReLU 사용


- z값이 커질수로 1보다 작다라는 sigmoid를 0보다 커질 수록 갈 때까지 커진다.

- 대신 0보다 작으면 무조건 0이 된다. 


Sigmoid 대신 relu를 사용한다. 수식으로 표현하면 하고 앞으로 neural network에서는 최종 Layer를 빼고 hidden부분은 sigmoid를 사용하지 않고 relu를 사용해야 한다. 




9 layer의 relu와 sigmoid 사용 예




Activation Function

sigmoid와 relu등을 activation function이라고 하는데 다른 것들도 있다.

- sigmoid

- ReLU

- Leaky ReLU: 0이하일 때 약간 값을 살려줌

- ELU: 0이하일 때 원하는 값으로 살려줌

- Maxout



비교하면 LeRU 계열의 정확도가 높다.






참조


- 김성훈교수님의 TensorBoard 사용 강좌

- 김성훈교수님의 Backpropagation (chain rule) 희석 강좌

posted by Peter Note
2018. 7. 6. 17:31 Deep Learning/NN by Sung Kim

XOR 문제 풀기 강좌를 정리한다. 





Neural Network (NN)


XOR 를 Linear한 선으로 구분을 지을 수 없었다. NN에서 어떻게 해결하는가? Y1, Y2 가 Y예측으로 수렴되어 계산하는 것을 풀어본다. 





matrix를 곱하고, sigmoid function인 S(..)을 태워서 값이 0, 1중 어디에 근접하는지 살핀다. 


나머지를 다 계산해 본다. 나머지까지 답이 맞으면 만들어 놓은 Network이 맞는 것이된다. 



위의 3개 Network을 통해 XOR결과가 제대로 나왔다. 하나의 Neural Network을 만들었다. 



Multinomiad Classification처럼 하나의 Vector로 만들 수 있다. W, B가 matrix화 된다.


위의 것을 수식으로 표현할 수 있다.


과제는 여기서 W1, b1을 어떻게 알 수 있을까? 이다. 다음 강좌에서 알아본다. 



Deep NN for XOR (강좌)


여러개의 Layer를 만들어 INPUT, OUTPUT을 조절한다. 

- 이전 layer의 OUTPUT은 다음 Layer의 INPUT이 된다. (소스)



Deep & wide (강좌)


처음 INPUT 이 2개이고, 마지막 OUTPUT 이 1개 이다. 

- 최초 INPUT Layer

- 마지막 OUTPUT Layer

- 중간 HIDDEN Layer



HIDDEN Layer는 개발자 마음대로 넣으면 된다. 예로 9개의 Layer를 만들 경우는 다음과 같다. 

- Deep Network을 만들고 이것을 학습시키면 Deep Learning이 된다






참조


- 김성훈교수님의 XOR 문제 풀기 강좌

- 김성훈교수님의 XOR 문제를 NN으로 풀기 강좌

posted by Peter Note
2018. 7. 6. 16:59 Deep Learning/NN by Sung Kim

Tensorflow Manipulation 강좌를 정리한다.





Array


- rank, shape, axis을 array로 나타냄.

- [-1] array의 마지막 item

- t[2:5] index 3부터 5까지 items

- t[:2] 처음부터 index 2까지 

- t[3:] index 3에서 끝까지 


[1,2,3] rank(1), shape(3)

[[1,2],[3,4]] rank(2), shape(2,2)


axis=0 가장 바깥쪽, axis=-1 가장 안쪽을 표현하고 axis을 통해 shape을 이동한다. 







Matrix Manipulation


matmul


matrix 곱은 반드시 matmul을 사용한다. 

- tf.matmul((2,2) , (2,1)) => (2,1)




broadcasting


matrix끼리 shape이 다르더라도 matrix끼리 연산을 가능토록 shape을 자동으로 맞춰준다. 잘 알고 사용하면 좋지만 조심해라. 



reduce_mean 


(평균) 호출시 입력값들의 type에 주의한다.


axis를 0 이냐 1 이냐에 따라 다른다.

>>> import tensorflow as tf

>>> sess = tf.Session()

>>> sess.run(tf.global_variables_initializer())

>>> x = [[1.,2.],[3.,4.]]

>>> tf.reduce_mean(x).eval(session=sess)

2.5


>>> tf.reduce_mean(x, axis=1).eval(session=sess)

array([1.5, 3.5], dtype=float32)



reduce_sum 


axis=-1  제일 안쪽값을 합치고 이에 대한 평균을 낸다. 



argmax


큰값이 있는 위치 index를 구하는 것이다. 



reshape


주로 (...., z) 가장 안쪽에 있는 z 값은 그대로 가져가고, 앞의 것을 reshape한다.



reshape 하나의 형태 sqeeze는 펴주는 역할, expand_dims 차원을 더 추가할 경우 




One Hot 


가장 큰 값이 있는 곳을 1로 하고 나머지는 0으로 바꿈. One hot을 하면 dimension (rank)가 하나 더 생기므로 다시 reshape을 한다. 

마지막 3만 남기고 나머지는 차원 1로 만들어주는 것 



Casting


타입 바꿔주기 



Stack


쌓기를 만들어줌. 주어진 데이터들에서 axis와 stack을 이용해 새로운 matrix를 만듦



Ones and Zeros like


가지고 있는 shape과 똑같은 0 또는 1로 채워진 shape을 만들때 사용



Zip


복수의 tensor를 한방에 처리하기 





참조


- 김성훈교수님의 Tensorflow Manipulation 강좌

- reduce_sum reduce_mean 사용법

posted by Peter Note
2018. 7. 4. 14:45 Deep Learning/NN by Sung Kim

Multi Variable Linear Regression 강좌를 정리한다. 





Linear Regression 기본 개념

- Hypothesis: H(x) = Wx + b   => Input값을 통해 가설을 세운다. W, b에 따라 선의 모양일 달라진다.

- Cost function: cost(W,b) = H(x) - y 실제값의 차에 대한 제곱에 평균   =>    결과값을 바탕으로 가설을 검증하고 가장 적은 값을 갖는 W, b를 구한다. (참조)

- Gradient descent algorithm: 미분의 기울기에 따른 아래로 수렴되는 알고리즘  => Cost function을 최소화 하기 위한 최적화 알고리즘을 사용한다. (참조)

   -> 그릇처럼 밑으로 수렴되는 Convex Fuction을 사용하여 오류를 제거한다.


기존은 하나의 Input variable만 사용했다면 여러개의 multi variable에 대한 예측



변수(Variable)이 여러개(Multi)일 때 Matrix를 이용한다. Matrix를 사용할 때는 X가 앞에 오고 W가 뒤에 온다. + b 가 없을 때 수식은 아래와 같다. 



(x1, x2, x3)를 하나의 Instance라고 부른다. Instance가 많을 경우 다음과 같은 수식을 사용한다. W는 동일하다. 

- X: [Instance, #x]

- W: [#w, #]

연산시 #x와 #w의 숫자는 같아야 한다. 계산 결과는 [instance, #] 이 된다. 




위의 5값은 instance의 갯수는 가변이므로 n으로 표현한다. 보통 Tensorflow에서 None으로 표현하면 n개를 말한다. 그리고 n Output의 경우일때는 다음과 같다.



이론과 실제 구현상 공식. 수학적 의미는 거의 같다.







Tensorflow 실습하기 


x1, x2, x3 instance가 있고, 결과 Y 하나가 나온다.


 Maxtrix를 이용해서 구현해 본다. (예제)


import tensorflow as tf

tf.set_random_seed(777)  # for reproducibility


x_data = [[73., 80., 75.],

          [93., 88., 93.],

          [89., 91., 90.],

          [96., 98., 100.],

          [73., 66., 70.]]

y_data = [[152.],

          [185.],

          [180.],

          [196.],

          [142.]]



# placeholders for a tensor that will be always fed.

X = tf.placeholder(tf.float32, shape=[None, 3])

Y = tf.placeholder(tf.float32, shape=[None, 1])


W = tf.Variable(tf.random_normal([3, 1]), name='weight')

b = tf.Variable(tf.random_normal([1]), name='bias')


# Hypothesis

hypothesis = tf.matmul(X, W) + b


# Simplified cost/loss function

cost = tf.reduce_mean(tf.square(hypothesis - Y))


# Minimize

optimizer = tf.train.GradientDescentOptimizer(learning_rate=1e-5)

train = optimizer.minimize(cost)


# Launch the graph in a session.

sess = tf.Session()

# Initializes global variables in the graph.

sess.run(tf.global_variables_initializer())


for step in range(2001):

    cost_val, hy_val, _ = sess.run([cost, hypothesis, train], feed_dict={X: x_data, Y: y_data})

    if step % 10 == 0:

        print(step, "Cost: ", cost_val, "\nPrediction:\n", hy_val)


==> 결과

... 


2000 cost:  7.4047155

prediction:

 [[154.63629]

 [182.36778]

 [181.60802]

 [197.86899]

 [137.86888]]






파일에서 읽어 실행하기 


Python 의 numpy를 이용하여 읽어오고 slicing한다. (예제)


import numpy as np


xy = np.loadtxt('data-01-test-score.csv', delimiter=',', dtype=np.float32)

x_data = xy[:, 0:-1] # slicing

y_data = xy[:, [-1]]


읽을 내용이 많을 경우 한번에 가져오지 않고 Queuing하여 처리하는 Queue Runners를 제공한다. (예제)

Step-1: 여러개의 파일을 읽어온다. 

Step-2: 파일에서 key, value을 가져온다. 

Step-3: 값을 decoding한다.



import tensorflow as tf

tf.set_random_seed(777)  # for reproducibility


filename_queue = tf.train.string_input_producer(['data-01-test-score.csv'], shuffle=False, name='filename_queue')


reader = tf.TextLineReader()

key, value = reader.read(filename_queue)


# Default values, in case of empty columns. Also specifies the type of the

# decoded result.

record_defaults = [[0.], [0.], [0.], [0.]]

xy = tf.decode_csv(value, record_defaults=record_defaults)


# collect batches of csv in

train_x_batch, train_y_batch = tf.train.batch([xy[0:-1], xy[-1:]], batch_size=10) #10 개씩 처리 


# placeholders for a tensor that will be always fed.

X = tf.placeholder(tf.float32, shape=[None, 3])

Y = tf.placeholder(tf.float32, shape=[None, 1])


W = tf.Variable(tf.random_normal([3, 1]), name='weight')

b = tf.Variable(tf.random_normal([1]), name='bias')


# Hypothesis

hypothesis = tf.matmul(X, W) + b


# Simplified cost/loss function

cost = tf.reduce_mean(tf.square(hypothesis - Y))


# Minimize

optimizer = tf.train.GradientDescentOptimizer(learning_rate=1e-5)

train = optimizer.minimize(cost)


# Launch the graph in a session.

sess = tf.Session()

# Initializes global variables in the graph.

sess.run(tf.global_variables_initializer())


# Start populating the filename queue.

coord = tf.train.Coordinator()

threads = tf.train.start_queue_runners(sess=sess, coord=coord)


for step in range(2001):

    x_batch, y_batch = sess.run([train_x_batch, train_y_batch])

    cost_val, hy_val, _ = sess.run(

        [cost, hypothesis, train], feed_dict={X: x_batch, Y: y_batch})

    if step % 10 == 0:

        print(step, "Cost: ", cost_val, "\nPrediction:\n", hy_val)


coord.request_stop()

coord.join(threads)


# Ask my score

print("Your score will be ",

      sess.run(hypothesis, feed_dict={X: [[100, 70, 101]]}))


print("Other scores will be ",

      sess.run(hypothesis, feed_dict={X: [[60, 70, 110], [90, 100, 80]]}))





참고


- 김성훈교수님의 Multi-Variable linear regression 강좌

- Github 예제 4-1

- Github 예제 4-2 using Matrix

- 선형 & 다중 회귀분석


posted by Peter Note
2018. 7. 3. 17:49 Deep Learning/NN by Sung Kim

Tensorflow를 이용해 Minimized Cost를 구하는 Algorithm실습 강좌를 정리한다.





Matplotlib 을 이용한 차팅


Python을 통해 그래프를 그리기 위해 matplotlib을 가이드에따라 설치한다. 

$ python -mpip install -U matplotlib


다음으로 ~/.matplotlib 밑에 matplotlibrc  파일을 생성하고 다음 내역을 작성한다. (참조)

backend: TkAgg


다음 코드를 작성하고 실행한다. 

W = 1 이 최소화를 위한 값이라는 것을 알 수 있다.






"W := W - 미분값" 이해


- 미분값은 경사도를 의미하고 좌에서 우로 내려가면 - 값, 좌에서 우로 올라가면 + 값이다.

- 마이너스 값이 되면 W + 미분값이 되어 W가 큰값으로 옮겨가고, W - 미분값은 W가 작은 값으로 수렴한다. 

  + a 알파값: learning-rate 상수값

  + = 은 assign펑션을 이용해 descent를 update에 할당한다. 

  + update operation를 run하면 graph를 통해 일련의 동작이 일어난다.  


Graph를 실행하는 단계

- Session생성

- 글로벌 값 초기화

- session.run 으로 Node (operation)수행



직접 미분을 구현하지 않고 위처럼 GradientDescentOptimizer를 사용할 수 있다.  만일 gradient값을 수정하고 싶을 때는 compute_gradient(cost)로 얻은 값을 직접 수정하여 적용할 수 있다.

gvs = optimizer.compute_gradient(cost)

// gvs를 customizing한다. 

apply_gradients = optimizer.apply_gradients(gvs)


....

sess.run(apply_gradients)






참조


김성훈교수님의 Minimized Cost function 실습 강좌

- Lab-03-2-minimizing_cost_show_graph.py

posted by Peter Note
2018. 7. 3. 15:59 Deep Learning/NN by Sung Kim

Cost를 Minimize하는 방법 강좌를 정리한다. 





가설(Hyperthesis) 단순화


b를 제거하고 cost(W)에 대해 구한다. 이때 최소화 되는 구간을 찾는다. 그래프상으로 Y축 cost(W)와 X축 W의 관계에서 cost(W) = 0  인 지점이 최소화 지점이다. 



경사를 따라 내려가는 알고리즘 = Gradient Descent Algorithm 을 사용한다.

- 경사도가 있는 곳을 따라 움직이면서 cost를 줄인다. 미분이 경사도를 구하는 공식임.

- 즉, 해당 점의 기울기를 구한다.


Gradient Descent Algorithm Formal





Convex function


Cost function을 3차원으로 그렸을 때, 내려가는 경사를 잘 못 잡으면 내려간 곳의 W, b값이 틀려 질 수 있다. 알고리즘이 잘 동작하지 않는 예


Convex function을 통해 그릇형태로 만들어 어디를 내려오던 원하는 지점으로 수렴할 수 있다. Cost function을 만든 후 검증할 때 Convex function이 된다면 Linear Regression의 cost function은 잘 된 것으로 판명된다. 







참조


- 김성훈교수님의 Minimize Cost 강좌

posted by Peter Note
2018. 7. 3. 14:56 Deep Learning/NN by Sung Kim

Linear Regression의 Tensorflow 실습 강좌를 정리해 본다. 





Hypothesis & Cost function (예측과 비용 함수)



학습을 통해 cost function의 W와 b를 minimized하는게 목적이다. 

- step-1: Node라는 operation 단위를 만든다. 

- step-2: Session.run을 통해 operation한다. 

- step-3: 결과값을 산출한다. 



Tensorflow는 W, b를 Variable로 할당한다. Variable이란 tensorflow가 변경하는 값이다라는 의미이다. 


H(x) 가설 구하기


$ python3

>>> import tensorflow as tf

>>> x_train = [1,2,3]

>>> y_train = [1,2,3]

>>> W = tf.Variable(tf.random_normal([1]), name='weight')

>>> b = tf.Variable(tf.random_normal([1]), name='bias')

>>> hypothesis = x_train * W + b


cost(W,b) 구하기

- reduce_mean: 전체 평균

- square: 제곱

>>> cost = tf.reduce_mean(tf.square(hypothesis - y_train))



minimize Cost 구하기

- GradienDescent 를 사용해서 minimize한다.

>>> optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.01)

>>> train = optimizer.minimize(cost)





Graph 실행하기


Tensorflow의 Session을 만들고, 글로벌 변수값을 초기화 해준다. 

- 2000번을 돌리면서 20번만다 출력해 본다. 

- sess.run(train): 학습을 시킨다. 처음 Cost를 랜덤하게 가면서 학습할 수록 값이 작이진다. 

   sess.run(W): 1에 수렴하고

   sess.run(b): 작은 값이 수렴한다.

>>> sess = tf.Session()

>>> sess.run(tf.global_variables_initializer())

>>> for step in range(2001):

...     sess.run(train)

...     if step % 20 == 0:

...             print(step, sess.run(cost), sess.run(W), sess.run(b))

...

0 8.145951 [-0.13096063] [-0.43867812]

20 0.0741704 [0.87371004] [0.00051325]

40 0.0009571453 [0.9702482] [0.04034551]

   ... 생략 ...

1960 2.7972684e-08 [0.9998057] [0.00044152]

1980 2.5414716e-08 [0.99981487] [0.00042076]

2000 2.3086448e-08 [0.9998234] [0.00040107]


위의 train은 여러 Node가 연결된 graph가 된다. 






Placeholder로 수행하기


수행시 필요할 때 값을 동적으로 전달하여 train해 본다. 

- X, Y placeholder를 만든다. 

- feed_dict를 통해 값을 할당한다.

>>> X = tf.placeholder(tf.float32)

>>> Y = tf.placeholder(tf.float32)

>>> for step in range(2001):

...     cost_val, W_val, b_val, _ = sess.run([cost, W, b, train], feed_dict={X: [1,2,3], Y:[1,2,3]})

...     if step % 20 == 0:

...             print(step, cost_val, W_val, b_val)

...

0 2.3086448e-08 [0.9998238] [0.00040011]

20 2.0964555e-08 [0.99983215] [0.00038142]






참조


- 김성훈교수님의 Linear Regression의 Tensorflow 실습

- Github 실습 코드

posted by Peter Note
2018. 7. 3. 14:17 Deep Learning/NN by Sung Kim

인프런의 모두를 위한 딥러닝을 공부하기 위해 Tensorflow를 설치해 보았다. 





Python 설치


python은 3.6.6을 설치한다. 3.7를 설치하고 Tensorflow를 설치하니 오류가 있었다. 


- Python v3.6.6설치

- pip python package 매니져를 업데이트 한다. 

curl https://bootstrap.pypa.io/get-pip.py | python


- virtualenv를 통해 특정 폴더에 대해 python version을 적용한다. 맨뒤 옵션이 특정 폴더이다.

$ virtualenv --system-site-packages -p python3 /Users/prototyping/machine-learning

$ cd machine-learning 

$ source ./bin/activate

(machine-learning)

~/prototyping/machine-learning

$




Tensorflow 설치


pip3를 이용해서 설치하는 방법이 실패하여 직접 download url을 입력한다. 

$ pip3 install --upgrade tensorflow (실패하면 아래 직접 URL 지정한다)

$ pip3 install --upgrade https://storage.googleapis.com/tensorflow/mac/cpu/tensorflow-1.8.0-py3-none-any.whl



이제 시작해 보자...



참조


- Mac에서 virtualenv설치하기

posted by Peter Note
prev 1 next