Hard skills/Tensorflow (4)


작년 11월이 tensorflow 의 3주년이었습니다. tensorflow 는 출시된 이래로 지금까지 가장 사랑받는 딥러닝 라이브러리였습니다. 그리고 얼마전 tensorflow dev summit 에서 새로운 milestone 이라고 할 수 있는 tensorflow 2.0 소식이 발표되었습니다! (tensorflow dev summit 2019 의 동영성은 이 곳에서 볼 수 있습니다.)


Tensorflow 2.0의 주된 내용은 tf.keras 에 관한 것이라고 할 수 있습니다. 사실 Keras 는 2년 전부터 tensorflow에 통합되었습니다. Tensorflow 2.0 의 가장 큰 변화는 tf.keras 의 기능을 보다 강화하여 기존 tensorflow 와의 통합을 한 것이라고 할 수 있습니다. 즉, keras 를 단순히 high-level API 로 제시한 것이 아니라, 전면으로 내세워 tf 의 기능을 통합하려는 것입니다. 본 영상에서도 대부분 tf.keras 의 기능을 설명하고 있습니다. 

Keras 는 대규모 모델 보다는 간단한 모델을 빠르게 프로토타이핑을 하는데 강점이 있는 API 입니다. 따라서 사용하기는 힘들어도 대규모 네트워크를 구현할 때는 tensorflow 가 이점이 있었는데, tensorflow 2.0 에서는 keras와 tf 를 통합함으로써 keras 를 대규모 네트워크에서도 쉽고 효율적으로 사용할 수 있도록 강화한 것입니다. 

대표적인 내용은 아래와 같습니다. 

1. eager context 를 사용할 수 있다. 1.* 버전에서 tf.keras를 사용할 때는 keras 로 작성된 모델을 그래프로 변환하는 과정을 거쳤는데, 2 버전에서는 eager mode로 동작할 수 있다 (run_eagerly=True). 통해 eager 모드로 누릴 수 있는 이점을 누릴 수 있다. eager는 디버깅과 프로토타이핑을 쉽게 할 수 있다. 
2. tensorflow의 estimator 를 쉽게 사용할 수 있어, transfer learninng 이 쉽다.

3. tensorboard 와 keras 와의 통합이 매우 간단해졌다. call back 에 넣기만 하면 된다. 

4. distributed strategy 를 keras 에서 사용할 수 있다. 예를 들어, multi-gpu, multi-node 처리를 가능하게하는데, 이는 엄청난 성능의 증가를 가능하게 한다. 그리고 이것이 단 몇 줄로 가능하다. 

5. 모델을 저장하는 방식 (SavedMode)을 tf 와 keras 가 비슷하게 할 수 있다. 이는 다양한 플랫폼에서 interchangable 한 모델이 될 것이다. 


출처 - https://medium.com/tensorflow/whats-coming-in-tensorflow-2-0-d3663832e9b8


Tensorflow 2.0은 alpha 버전을 지금 사용할 수 있고, rc 버전 (release candidate) 이 올해 봄 중에 배포될 예정이라고 합니다. 전 지금까지 tensorflow 를 backend로 keras 를 사용해왔었는데, tensorflow 2.0이 release 되면 tensorflow 내부에서 keras 를 사용하는 쪽으로 바꾸어야겠습니다. 이외에도 tf 2.0 에서는 중복된 api 와 duplicated 된 api 를 제거하여 더욱 쉽게 라이브러리를 사용할 수 있도록 개선하였습니다. 이외에 다양한 개선점에 대해서는 해당 포스트를 참고하시면 좋을 것 같습니다.

  • 2019.07.12 12:34

    비밀댓글입니다


Tensorflow GPU 버전을 설치



설치버전

Cuda 9.0v

Cudnn 7.0.5v

tensorflow-gpu 1.9.0


GPU 

1080TI


운영체제

Ubuntu 16.04


설치방법

아래포스트를 기본으로 오류를 수정해나가면서 설치함

https://medium.com/@zhanwenchen/install-cuda-and-cudnn-for-tensorflow-gpu-on-ubuntu-79306e4ac04e


설치 팁

- Cuda, Cudnn을 먼저 설치하고, (이 때, Cuda Cudnn의 버전이 tensorflow 에서 지원하는지를 확인해야 함. 최신버전의 경우 tensorflow가 지원을 안하는 경우가 있을 수도 있음.) 이에 맞는 tensorflow-gpu를 설치하는 것이 좋다.

- Cuda, Cudnn, tensorflow-gpu는 서로 의존적이므로, 버전에 특히 신경 써야하고, 함부로 업그레이드 하지 않아야하고 현재 버전을 기록해 두어야한다. 

- 굳이 하나하나 Tool 별로 Document를 찾아가면서 설치하는 것보다, 먼저 설치한 사람의 설치 방법을 보고 설치하는 것이 훨씬 빠르고 안전하다. 

- 위 포스트에서 cuda와 cudnn이 설치 되었다는 것을 확인하는 방법으로 sample 코드를 실행하는 방법을 사용하였는데, 확실한 설치 여부를 알 수 있으므로 좋다. 


설치할 때 발생한 오류

1. libstdc++6 의 문제 

해결 : https://askubuntu.com/questions/671791/lib32stdc6-package-depends-on-gcc-base-but-my-installed-version-is-newer


2. tensorflow-gpu 버전 문제

pip install tensorflow-gpu를 통해 설치하니 tensorflow-gpu 1.12.0 버전이 설치됨. 근데, 이 버전에서는 구버전의 cudnn을 쓰지 않는 문제가 발생. 따라서 tensorflow-gpu를 1.9.0 버전으로 다운그레이드 함. 


설치 완료 후, Multi GPU 환경에서 default로 0번 gpu만 사용하는 문제


tensorflow를 import하기 전에 아래 문구를 삽입함으로써, 특정 gpu를 사용하도록 강제할 수 있다.


import os

os.environ["CUDA_VISIBLE_DEVICES"]= "2"   



또한 CPU를 사용하도록 강제하는 방법은 tensorflow를 import하기 전 아래 문구를 삽입하면 된다.

import os

os.environ["CUDA_VISIBLE_DEVICES"]= ""  



tensorflow의 이전 방법에서는 아래 문구를 통해 특정 gpu를 사용할 수 있었는데 1.9.0 버전에서는 아래 문구가 안 먹힌다. 


import keras.backend.tensorflow_backend as K
with K.tf.device('/gpu:2'):


/**

2017.02.02 작성자 : 3개월

Tensorflow - MNIST 단일 계층 신경망 트레이닝

*/


환경 : windows tensorflow, anaconda 4.3, python 3.5



Tensorflow를 통해 단일 계층 신경망을 구축하고 MNIST 데이터를 training하고 test 하는 예제입니다. 많은 예제들이 tensorflow 내부에 example로 있는 MNIST 데이터를 이용하지만 이 포스팅에서는 외부에 있는 MNIST pickle 파일을 다운로드하고 이를 읽어들여 모델을 구축해보았습니다. 사용한 MNIST pickle 파일은 https:na//github.com/mnielsen/neural-networks-and-deep-learning/blob/master/data/mnist.pkl.gz 이곳에서 다운로드 받을 수 있습니다. 


1. 데이터 읽기


import tensorflow as tf
import gzip, numpy
import pickle as cPickle
import pandas as pd

# Load the dataset
f = open('data/mnist.pkl', 'rb')
train_set, valid_set, test_set = cPickle.load(f, encoding='latin1')
f.close()

x_train, y_train = train_set
x_test, y_test = test_set


pickle로 불러온 변수에는 train_set, valid_set, test_set이 나뉘어져 있기 때문에 위와 같이 load하면 알아서 training, validation, test set으로 나눌 수 있습니다. 또한 각각은 튜플 자료구조형으로 또 다시 x, y로 나뉘어져 있기 때문에 x_train, y_train = train_set 구문을 통해 feature과 label을 분리할 수 있습니다. 이렇게 데이터를 빠르게 training을 적용할 수 있는 형태로 만들어낼 수 있다는 것이 pickle 파일의 좋은 점입니다. 하지만 예제가 아닌 실제 머신러닝 모델을 구축할 때는 이러한 과정을 모두 직접하여야 합니다. 이미지 파일을 읽어들여야하고 또 이것을 적절한 사이즈의 numpy array로 바꾸어야합니다. 


2. 데이터 전처리


y_train = pd.get_dummies(y_train)
y_test = pd.get_dummies(y_test)


label들을 one hot encoding합니다. tensorflow에서는 label을 one hot encoding 하여 제공하여야 합니다.


print('x_train shape : ',x_train.shape) # (50000, 784)
print('y_train shape : ',y_train.shape) # (50000, 10)
print('x_test shape : ',x_test.shape) # (10000, 784)
print('y_test shape : ',y_test.shape) # (10000, 10)


training data와 test data의 형태(shape)를 프린트하여 보겠습니다. MNIST 데이터는 28*28 흑백 이미지이므로 총 784개의 픽셀이 있는데 이를 feature로 보아 784개의 feature가 있음을 알 수 있습니다. 


[mnist 데이터 모양]



또한 training data의 갯수는 50000개이기 때문에 x_train의 모양은 50000*784 입니다. label의 갯수도 50000개이며 class의 갯수가 0~9까지 10개이므로 y_train은 50000*10입니다. 만약 label이 1인 경우 y는 [0 1 0 0 0 0 0 0 0 0 0] 으로 encoding 됩니다. y_train에는 이러한 y가 50000개 있다고 생각하면 됩니다.


3. 모델 작성


x = tf.placeholder('float', [None, 784]) W = tf.Variable(tf.zeros([784,10])) b = tf.Variable(tf.zeros([10])) y = tf.nn.softmax(tf.matmul(x, W) + b) y_ = tf.placeholder('float', [None, 10]) cross_entropy = -tf.reduce_sum(y_*tf.log(y)) train_step = tf.train.GradientDescentOptimizer(0.01).minimize(cross_entropy)


윗 부분은 데이터를 읽어들이고 numpy와 pandas를 이용하여 데이터를 전처리 한 것이었다면 이제부터는 본격적으로 tensorflow 코드를 작성하여 보겠습니다.


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


우선 placeholder을 이용해 x가 들어갈 공간을 만들어줍니다. 이 때 [None, 784]에서 None은 데이터의 갯수는 자유롭게 설정하겠다는 뜻입니다. 하지만 feature의 갯수 784는 고정되어 있습니다. 


W = tf.Variable(tf.zeros([784,10]))


그 다음 weight matrix를 만드는데 input layer의 노드가 784개이고 output layer의 노드가 10개이므로 총 784*10개의 weights가 필요한 것을 알 수 있습니다. 이를 위해 W라는 tensorflow 변수를 만들고 0으로 초기화 시킵니다. 


b = tf.Variable(tf.zeros([10]))


bias는 output layer의 node수만큼 필요하므로 10개를 만들고 0으로 초기화 시킵니다.


y = tf.nn.softmax(tf.matmul(x, W) + b)


그 다음 x와 W를 매트릭스 곱셈을 하고 bias를 더한 것에 softmax 함수를 취하여 이를 y 변수로 만들어줍니다. 수식으로 표현하면  y = softmax(xW+b) 이 됩니다. 이 때 y는 '예측값' 입니다.


cross_entropy = -tf.reduce_sum(y_*tf.log(y)) train_step = tf.train.GradientDescentOptimizer(0.01).minimize(cross_entropy)


손실 함수로는 classification의 경우 크로스 엔트로피를 사용하게 됩니다. -y_*log(y) 에는 데이터들의 크로스 엔트로피들의 2차원 텐서가 담겨져 있습니다. reduce_sum 함수를 통해 이 크로스 엔트로피들의 평균을 구합니다. 이 때 reduce_sum 함수는 지정된 차원을 따라 평균을 내는 것입니다. 2차원인 경우 지정할 차원이 1개 밖에 없으므로 차원을 따로 지정한 필요가 없습니다. 그래서 이 경우에는 reduce_sum 함수는 평균을 구한다고 생각하시면 됩니다.



4. 배치 트레이닝


sess = tf.Session()
sess.run(tf.global_variables_initializer())

batch_size = 100 # 배치 사이즈 지정
training_epochs = 3 # epoch 횟수 지정

# epoch 횟수만큼 반복
for epoch in range(training_epochs) :
    batch_count = int(x_train.shape[0]/100) # 배치의 갯수
    for i in range(batch_count) : # 배치를 순차적으로 읽는 루프
        # 배치사이즈 만큼 데이터를 읽어옴
        batch_xs, batch_ys = x_train[i*batch_size:i*batch_size+batch_size], y_train[i*batch_size:i*batch_size+batch_size] 
        
        # training, 이를 통해 W, b Variable 값을 조정함
        sess.run(train_step, feed_dict = {x : batch_xs, y_ : batch_ys})
        
        # [True False True False False True True ....] 와 같은 boolean vector
        correct_prediction = tf.equal(tf.argmax(y,1), tf.argmax(y_,1))
        
        # [1 0 1 0 0 1 1 ...]로 변환 후 평균값을 구하면 accuracy 구할 수 있음
        accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))
        
        # 5번 배치를 읽고 이를 트레이닝한 후 정확도 출력
        if i % 5 == 0 : 
            print(str(epoch+1)+' epoch '+ str(i)+' batch ', sess.run(accuracy, feed_dict={x: x_test[0:100], y_: y_test[0:100]}))


이 부분을 이해하기 위해서는 우선 배치 트레이닝에 대하여 알아야 합니다. 배치 트레이닝이란 트레이닝 데이터를 일정 사이즈로 쪼갠 미니 배치(mini batch)를 통해 Gradient Descent를 하는 방법입니다. 일반적인 Gradient Descent 방법은 전체 트레이닝 데이터를 한 번 쭉 보고 gradient를 구한 후 weights와 bias를 '한 번' 업데이트 시킵니다. 하지만 이런 방법은 computation cost가 높습니다. 하지만 미니 배치를 이용한 방법은 전체 데이터의 샘플인 미니 배치를 통해 전체 데이터를 근사 시킵니다. 그리고 이것만 보고 gradient를 구한 후 weight, bias를 업데이트 시킵니다. 예를 들어 배치 사이즈가 128이면 128개의 데이터 샘플들만 보고 gradient를 구한 후 weight, bias를 업데이트 하게 됩니다. 이전 방식에 비해 훨씬 빠르게 weight를 업데이트 시킬 수 있죠. 이렇게 weight를 구하는 방식은 Stochastic Gradient Descent 방법이라고 부릅니다. 실제로 일반적인 Gradient Descent 방법보다는 Stochastic Gradient Descent 방법이 더 많이 쓰입니다. 팁으로는 배치 사이즈는 메모리가 허용하는 범위 내에서 최대한 크게 잡는 것이 좋습니다. 그리고 보통 배치사이즈는 128, 256, 512와 같이 2의 배수로 잡는 경우가 많은데 혹자는 이를 CPU 연산의 효율을 증가시킨다고 합니다. 하지만 111, 234와 같이 아무 배치 사이즈나 잡아도 트레이닝은 잘 합니다.


이러한 배치 트레이닝의 방식을 이해한다면 위의 텐서플로우 코드도 어렵지 않게 이해할 수 있습니다. 


sess = tf.Session()
sess.run(tf.global_variables_initializer())

세션을 만들고 variable을 초기화 시킵니다. 

  • 텐서플로우에서 Variable은 반드시 위와 같이 초기화 시키고 이용해야합니다.

batch_size = 100 # 배치 사이즈 지정
training_epochs = 3 # epoch 횟수 지정


배치 사이즈와 epoch를 정합니다. epoch은 '전체 데이터를 보는 횟수' 입니다.


# epoch 횟수만큼 반복 for epoch in range(training_epochs) : batch_count = int(x_train.shape[0]/100) # 배치의 갯수 for i in range(batch_count) : # 배치를 순차적으로 읽는 루프 # 배치사이즈 만큼 데이터를 읽어옴 batch_xs, batch_ys = x_train[i*batch_size:i*batch_size+batch_size], y_train[i*batch_size:i*batch_size+batch_size] # training, 이를 통해 W, b Variable 값을 조정함 sess.run(train_step, feed_dict = {x : batch_xs, y_ : batch_ys}) # [True False True False False True True ....] 와 같은 boolean vector correct_prediction = tf.equal(tf.argmax(y,1), tf.argmax(y_,1)) # [1 0 1 0 0 1 1 ...]로 변환 후 평균값을 구하면 accuracy 구할 수 있음 accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float")) # 5번 배치를 읽고 이를 트레이닝한 후 정확도 출력 if i % 5 == 0 : print(str(epoch+1)+' epoch '+ str(i)+' batch ', sess.run(accuracy, feed_dict={x: x_test[0:100], y_: y_test[0:100]}))


이제 마지막 트레이닝 파트입니다. 미니 배치를 구할 때 전체 데이터에서 샘플 데이터를 랜덤으로 뽑는 방식도 있지만 여기서는 그냥 순차적으로 배치를 만들었습니다. 0번부터 100번까지를 1배치, 101번부터 200번까지를 2배치와 같은 방식으로 말입니다. (사실 데이터의 순서에 어떠한 규칙이 있다면 이러한 방식은 좋지 않을 수 있습니다.) epoch만큼 전체 데이터를 보아아햐고 또 배치 사이즈만큼 전체 데이터를 쪼개야하니까 이중 for문을 써야하는 것을 알 수 있습니다. 그리고 두 번째 for문에서는 i라는 인덱스와 batch_size라는 변수를 이용하여 원하는 만큼 데이터를 계속해서 불러온후 Gradient Descent를 하면됩니다. 각각의 문장이 의미하는바는 코드에 주석으로 써두었습니다. 


5. 결과



 배치 트레이닝을 100번 했을 때 이미 정확도가 0.93에 육박하는 것을 알 수 있습니다.




트레이닝이 끝났을 때의 최종 정확도는 0.96 이었습니다. 이미 100번 트레이닝을 했을 때 정확도가 0.93이었기 때문에 그 이상의 training은 의미가 없었을지도 모릅니다. 지금은 validation과정 없이 마구잡이로 트레이닝을 했지만 보통은 언제 training을 끝내야하는지 잘 선택하여야합니다. 계속되는 불필요한 training은 overfitting을 유발할 수 있기 때문입니다. 


  • 퀵러너 2017.03.14 09:32

    안녕하세요.
    딥 러닝을 공부하고 있는 학생입니다.
    블로그에 TensorFlow 관련글이 많지는 않지만,
    이 포스팅이 제가 원하는 부분에서 많은 도움이 됐어요. 감사합니다.
    한가지 여쭤보고 싶은게 있는데요..

    Batch size가 1이되면 online learning이라고 하잖아요?
    제가 만들고자 하는 시스템에서는 데이터 샘플이 1분에 100개 단위로 들어와요.
    그러면 1분이 지나면 100개, 2분이 지나면 200개, 10분이 지나면 1000개, 1시간이 지나면 6000개 이런식인데,
    저는 이걸 1분 단위로 계속 model update를 해주고 싶거든요.

    즉,
    1분이 지나면 100개에 대한 model이 생성되고
    2분이 지나면 200개에대한 누적 model(이전 100개 + 최근 100개)이 업데이트되고
    3분이 지나면 300개에 대한 누적 model(이전 200개 + 최근 100개)이 업데이트되고...
    이런식이고 싶은데,
    epoch(전체 데이터를 보는 횟수)가 1이라면 매 1분마다 최근 100개에 대한 batch만 추가로 보면 되니 시간적으로 상관이 없을 것 같은데
    epoch가 2만 되더라도, 매 1분마다 최근 100개에 대한 batch만 보는 것이 아니라, 이전의 batch 들에 대해서도 봐야 하잖아요?
    그러면 시간이 가면 갈수록 model update를 할 때 학습 시간이 증가할텐데......... 어떡하면 되나요?

    batch 1에 대한 model을 생성하고,
    batch 2가 들어오면 기존 model에다가 update만 빠르게 해주고
    batch 3이 들어오면 기존 model에다가 update만 빠르게 해주고.. 이러고 싶거든요..

    설명을 잘 드리고 싶다보니 글이 길어졌네요... 답변 꼭 부탁드리겠습니다!!!

    • Deepplay 2017.03.30 15:10 신고

      안녕하세요. 답변이 늦어서 죄송합니다! ㅎㅎ

      그런 경우에는 간단하게 말하자면 학습한 웨이트를 저장했다가 다음 학습할 때 사용하시면 됩니다.

      즉, 100개에 데이터에 대해 학습하여 모델이 생성되었을 때 다음번 100개가 들어왔다면 다시 처음부터 200개의 데이터를 학습할 필요 없이, 100개의 데이터를 학습한 모델의 weight를 파일 형태로 저장해놨다가 불러와서 그 weight에 나머지 100개만 학습하시면 됩니다.

      python에서는 hdf5 같은 특정 파일 형태로 weight를 저장하거나 불러올 수 있습니다.

  • DaesooLee 2018.05.22 15:39

    텐서플로우에서 배치 트레이닝 코딩 부분 잘봤습니다~

  • passenger 2018.11.01 12:45

    배치 구현 고민하면서 많은 구글링을 하였는데, 이렇게 간단한 방법으로 구현하다니.. 감사합니다 ㅎㅎ
    문제를 너무 복잡하게만 생각해도 안되겠군요 ㅎㅎ

    • Deepplay 2018.11.01 14:04 신고

      감사합니다 tensorflow에서는 이중 for문 돌면서 배치단위로 weight update만 해주면 될 정도로 쉽게 구현됩니다 :)

/**

날짜 : 2017/1/30

작성자 : 3개월

텐서플로우 상수, 변수, 플레이스 홀더

**/


어떠한 프로그래밍 언어를 배울 때 해당 언어의 자료구조에 대한 이해는 매우 중요하다. 자료를 대상으로 어플리케이션을 만들거나 예측 모델을 만들기 때문이다. 텐서플로우에서의 자료구조는 크게 상수(Constant), 변수(Variable), 심볼릭변수(placeholder)로 나뉜다. 세 종류는 특성이 모두 다르므로 이를 제대로 아는 것이 중요하다. 아래는 텐서플로우에서 이 자료 구조들을 어떻게 생성하고 다루는지 실습한 것이다. 


1. 상수


기본적인 상수 생성 방법 


""" 텐서플로우 상수
    references : 텐서플로우 첫걸음 &
    https://tensorflowkorea.gitbooks.io/tensorflow-kr/content/g3doc/api_docs/python/constant_op.html
"""
import tensorflow as tf

points = [[1,2,3],[4,5,6]] # 2차원 배열
print(points)

vectors = tf.constant(points) # 텐서플로우 상수 생성

print(vectors) # Tensor("Const_9:0", shape=(2, 3), dtype=int32)
print(vectors.get_shape()) # 2x3

expanded_vectors = tf.expand_dims(vectors, 0) # 2-D 텐서를 3-D 텐서로 차원 확장

print(expanded_vectors) # Tensor("ExpandDims_6:0", shape=(1, 2, 3), dtype=int32)
print(expanded_vectors.get_shape()) # 1x2x3

# value 를 출력하려면 아래와 같이 세션 생성 후 run 해야함
sess = tf.Session()
print(sess.run(vectors)) # [[1 2 3]
                         # [4 5 6]]
print(sess.run(expanded_vectors)) #[[[1 2 3]
                                  # [4 5 6]]]


상수를 생성하는 여러가지 방법


""" 상수를 생성하는 여러가지 방법 """
zeros = tf.zeros_like([4,3,3], dtype=tf.int32, name='zeros')
print(sess.run(zeros)) # [0,0,0] (입력으로 받은 텐서와 같은 shape의 텐서인데 0으로 초기화된 것)

# zeros와 zeros_like의 차이점 잘 비교. 일반적으로 zeros를 많이 쓸거 같음.
zeros2 = tf.zeros([3,4,5], dtype=tf.int32, name='zeros2')
print(sess.run(zeros2)) # 0으로 초기화된 3x4x5 텐서가 만들어짐

ones = tf.ones([2,2,3], dtype=tf.float32)
print(sess.run(ones)) # 1로 초기화된 2x2x3 텐서가 만들어짐

fill = tf.fill([2,3], 9) # 9로 초기화된 2x3 텐서
print(sess.run(fill))

contant = tf.constant([2,3,4]) # 주어진 텐서를 그대로 텐서플로우 변수로 전환
print(sess.run(contant)) # [2 3 4]

tensor = tf.constant(-1.0, shape=[2, 3])# tf.fill([2,3], -1.0) 과 같음
print(sess.run(tensor))


* 난수 상수 생성 -> weight 초기화 할 때 자주 이용


""" 난수 상수 생성 """
# 정규분포 난수
norm = tf.random_normal([2, 3], mean=-1, stddev=4)
print(sess.run(norm))

# 주어진 값들을 shuffle
c = tf.constant([[1, 2], [3, 4], [5, 6]])
shuff = tf.random_shuffle(c)
print(sess.run(shuff))

# 균등분포 난수
unif = tf.random_uniform([2,3], minval=0, maxval=3)
print(sess.run(unif))


시퀀스 상수 생성


""" 시퀀스 """
lin = tf.linspace(10.0, 12.0, 3, name="linspace")
print(sess.run(lin))

# start부터 시작하여 limit까지 (limit는 포함하지 않음) delta의 증가량만큼 확장하며 정수 리스트를 생성합니다.
ran = tf.range(start=3, limit=7, delta=1) 
print(sess.run(ran)) # [3 4 5 6]

# start의 default는 0
ran2 = tf.range(8)
print(sess.run(ran2)) # [0 1 2 3 4 5 6 7]


난수 생성시 Seed의 활용

  • seed를 활용함으로써 매 실행마다 같은 결과를 내도록 할 수 있다.


""" 난수 생성시 seed의 활용 """
a = tf.random_uniform([1], seed=1) # seed를 주고 random한 값을 생성하면 매 session마다 값이 같음
b = tf.random_normal([1])

# Repeatedly running this block with the same graph will generate the same
# sequence of values for 'a', but different sequences of values for 'b'.
print("Session 1")
with tf.Session() as sess1:
  print(sess1.run(a))  # generates 'A1'
  print(sess1.run(a))  # generates 'A2'
  print(sess1.run(b))  # generates 'B1'
  print(sess1.run(b))  # generates 'B2'

print("Session 2")
with tf.Session() as sess2:
  print(sess2.run(a))  # generates 'A1'
  print(sess2.run(a))  # generates 'A2'
  print(sess2.run(b))  # generates 'B3'
  print(sess2.run(b))  # generates 'B4'
    
# tf.set_random_seed를 통해 모든 random value generation function들이 매번 같은 값을 반환함    
tf.set_random_seed(1234)
a = tf.random_uniform([1])
b = tf.random_normal([1])

# Repeatedly running this block with the same graph will generate different
# sequences of 'a' and 'b'.
print("Session 1")
with tf.Session() as sess1:
  print(sess1.run(a))  # generates 'A1'
  print(sess1.run(a))  # generates 'A2'
  print(sess1.run(b))  # generates 'B1'
  print(sess1.run(b))  # generates 'B2'

print("Session 2")
with tf.Session() as sess2:
  print(sess2.run(a))  # generates 'A1'
  print(sess2.run(a))  # generates 'A2'
  print(sess2.run(b))  # generates 'B1'
  print(sess2.run(b))  # generates 'B2'


2. 변수


변수 생성


""" 텐서플로우 변수 
    reference : https://tensorflowkorea.gitbooks.io/tensorflow-kr/content/g3doc/how_tos/variables/
"""
# 두 변수를 생성.
weights = tf.Variable(tf.random_normal([784, 200], stddev=0.35),
                      name="weights")
biases = tf.Variable(tf.zeros([200]), name="biases")

# 변수는 반드시 initialization 해야한다.


변수 초기화

  • 변수는 초기화하지 않으면 사용할 수 없다. 반드시 initialization 하여야 한다.


# 변수 초기화

# 두 변수를 생성
weights = tf.Variable(tf.random_normal([784, 200], stddev=0.35),
                      name="weights")
biases = tf.Variable(tf.zeros([200]), name="biases")

# 변수 초기화 오퍼레이션을 초기화
init_op = tf.global_variables_initializer()

# 나중에 모델을 실행할때
with tf.Session() as sess:
    sess.run(init_op) # initialization 연산 실행
    print(sess.run(weights))
    print(sess.run(biases))


다른 변수값을 참조하여 변수 초기화


# 다른 변수값을 참조하여 초기화 하기

# 랜덤 값으로 새로운 변수 초기화
weights = tf.Variable(tf.random_normal([784, 200], stddev=0.35),
                      name="weights")
# weights와 같은 값으로 다른 변수 초기화
w2 = tf.Variable(weights.initialized_value(), name="w2")
# weights의 2배 값으로 다른 변수 초기화
w_twice = tf.Variable(weights.initialized_value() * 2.0, name="w_twice")

# 변수 초기화 오퍼레이션을 초기화
init_op = tf.global_variables_initializer()

with tf.Session() as sess : 
    sess.run(init_op)
    print(sess.run(w2))
    print(sess.run(w_twice))



3. 플레이스홀더

실행시에 데이터를 제공하는 방법으로 실제 딥러닝 모델 구축시 많이 쓰인다. sess.run 에서 feed_dict에 dictionary 형식으로 값을 넣어주면 되고 이를 feeding이라 한다.


""" 텐서플로우 심볼릭 변수(플레이스홀더)
"""
a = tf.placeholder("float")
b = tf.placeholder("float")

y = tf.mul(a,b)

sess = tf.Session()

print(sess.run(y, feed_dict={a : 3, b: 5})) # 15.0