Tensorflow Examples (Jupyter Notebook)

Bellow lists will be linked to github which includes jupyter files.
Personally I believe  Blog is not a effective tool to explain Tensorflow codes, so I decide to just post links to my github.

[chap01] Explain basic concept of tensorflow, graph, variable types, session use

[chap02] Data handling numpy, tensorflow shape methods, storage connections

[chap03] Basic Models explain concept of “machine learning (Data driven)”

[chap04] Basic Neural Networks (DNN, CNN, RNN)

[chap05] Working on .. make custom Reinforcement (with out gym)

[chap06] Working on .. Word 2 Vec based examples

[chap07] Working on .. scikit learn samples

[chap08] Working on .. making custom scikit learn app with estimator

[chap09] Working on .. Tensorboard usages

[chap10] Working on .. Customize AI Painter open source

Plan to make some NLP (ChatBot or understand Context) stuffs ..

chap02_data_handling
chap03_basic_models
chap04_basic_neural_networks
chap05_basic_reinforcement
chap06_rnn_with_word2vec
chap07_basic_scikit_learn
chap08_scikit_custom
chap09_tensorboard
chap10_nueral_style

TensorFlow – 기본문법 (6) – CNN Load & Predict

niektemme/tensorflow-mnist-predict

위 의 github 를 참조하였으며, 로컬에서 파일 로드, 배열 변환, 모델 로드 및 실행까지 간단하게 코드가 잘 정리되어 있습니다.  여기까지는 기본 구조를 파악하기 위함이었으니 기존예제들을 분석하는 위주로 진행하였지만, 다음부터는 가변적인 데이터 구조와 가변적인 모델을 감안한 개발을 시작하고자 합니다.

가. 로컬 이미지 로드 및 배열로 변환

def imageprepare(argv):
    """
    로컬에서 이미지를 받아서 Tensorflow 처리 가능한 형태로 변환하는 역할을 수행합니다.
    """
    im = Image.open(argv).convert('L')
    width = float(im.size[0])
    height = float(im.size[1])
    newImage = Image.new('L', (28, 28), (255))  # 우리가 테스트할 네트워크는 28/28 이미지이다

    # 입력된 28/28이 아닌 이미지를 28/28로 변환하기 위해 가로 세로 중 어느쪽이 큰지 확인
    if width > height:
        # 폭이 더 큰 경우 처리 로직
        nheight = int(round((20.0 / width * height), 0))  # resize height according to ratio width

        # 20/20 이미지로 변환하고
        img = im.resize((20, nheight), Image.ANTIALIAS).filter(ImageFilter.SHARPEN)
        wtop = int(round(((28 - nheight) / 2), 0))  #
        newImage.paste(img, (4, wtop))  # 리사이즈된 이미지를 흰색 바탕의 캔버스에 붙여 넣는다
    else:
        # 높이가 더 큰경우에 처리 로직
        nwidth = int(round((20.0 / height * width), 0))
        if (nwidth == 0):
            nwidth = 1
            # resize and sharpen
        img = im.resize((nwidth, 20), Image.ANTIALIAS).filter(ImageFilter.SHARPEN)
        wleft = int(round(((28 - nwidth) / 2), 0))
        newImage.paste(img, (wleft, 4))

    # newImage.save("sample.png")

    tv = list(newImage.getdata())  # 픽셀 데이터로 변환

    # 255의 RGB 0 흰색, 1 검은색의 이진수로 노멀라이제이션 작업을 수행
    tva = [(255 - x) * 1.0 / 255.0 for x in tv]
    return tva

나. 훈련시 사용한 모델을 동일하게 재 정의 합니다.

x = tf.placeholder(tf.float32, [None, 784])
    W = tf.Variable(tf.zeros([784, 10]))
    b = tf.Variable(tf.zeros([10]))

    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 conv2d(x, W):
        return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME')

    def max_pool_2x2(x):
        return tf.nn.max_pool(x, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')

    W_conv1 = weight_variable([5, 5, 1, 32])
    b_conv1 = bias_variable([32])

    x_image = tf.reshape(x, [-1, 28, 28, 1])
    h_conv1 = tf.nn.relu(conv2d(x_image, W_conv1) + b_conv1)
    h_pool1 = max_pool_2x2(h_conv1)

    W_conv2 = weight_variable([5, 5, 32, 64])
    b_conv2 = bias_variable([64])

    h_conv2 = tf.nn.relu(conv2d(h_pool1, W_conv2) + b_conv2)
    h_pool2 = max_pool_2x2(h_conv2)

    W_fc1 = weight_variable([7 * 7 * 64, 1024])
    b_fc1 = bias_variable([1024])

    h_pool2_flat = tf.reshape(h_pool2, [-1, 7 * 7 * 64])
    h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1)

    keep_prob = tf.placeholder(tf.float32)
    h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob)

    W_fc2 = weight_variable([1024, 10])
    b_fc2 = bias_variable([10])

    y_conv = tf.nn.softmax(tf.matmul(h_fc1_drop, W_fc2) + b_fc2)

다. 모델 복구 및 실행

init_op = tf.initialize_all_variables()
 saver = tf.train.Saver()

 """
 모델을 saver 를 사용하여 복구합니다.
 sess.run(init_op)
 saver.restore(sess, "model2.ckpt")
 """
 with tf.Session() as sess:
     sess.run(init_op)
     saver.restore(sess, "model2.ckpt")
     prediction = tf.argmax(y_conv, 1)
     return prediction.eval(feed_dict={x: [imvalue], keep_prob: 1.0}, session=sess)

전체 코드 링크

TensorFlow – 기본문법 (5) – CNN Train & Save

가. 테스트 코드 개요

본 테스트 코드는 TensorFlow 를 활용하여 CNN , max pool , drop out, softmax 를 적용하여 MNLP(손글씨 예제)를 학습 시키고 저장하는 예제이다.

테스트 코드 다운로드

나. 테스트 데이터 로딩 및 변수 선언

아래처럼 메트릭스 연산이 수행되기 때문에 위와 같이 데이터 사이즈를 잡은 것이다.
x : 인풋레이어에 사용할 변수 정의
y : 아웃풋레이어에 사용할 변수 정의
w : 784 X 10 개의 초기값 0을 갖는 메트릭스 생성
b : 10개짜리 배열 생성
y = x * w + b
x (784) * w(784*10) = x*w(10)
x*w(10) + b(10) = y(10)

#레파지토리에서 테스트 프로그램에 필요한 데이터 다운로드
mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)

sess = tf.InteractiveSession()

x = tf.placeholder(tf.float32, [None, 784])
y_= tf.placeholder(tf.float32, [None, 10])
W = tf.Variable(tf.zeros([784, 10]))
b = tf.Variable(tf.zeros([10]))
y = tf.nn.softmax(tf.matmul(x, W) + b)

 다. CNN(Convolutional Neural Network)

필터에 대해서 설명하고자 하면 CNN 의 동작 원리를 설명해야만한다. [5, 5, 1, 32] 는 5X5 사이즈의 단위 필터를 사용해서 인풋데이터(여기서는 28 X 28 사이즈 메트릭스)를 CNN연산을 하겠다는 것이다. Stride 가 [1,1] 이라고 하면 28X28크기 행렬을 5X5 사이즈의 메트릭스로가로세로 한칸씩 이동하면서 필터에 연산하겠다는 의미가 된다. 결과적으로 아웃풋은 24X24 사이즈가 된다. 왜냐하면 5X5 사이즈의  메트릭스로 이동할 수 있는 한계가 있기 때문이다. (메트릭스 끝부분 까지 이동할 수 없음) 이러한 경우 패딩 옵션을 사용하여 0으로 태두리를 채워넣어 메특릭스 사이즈를 동일하게 유지할 수도 있다
참조 :http://deeplearning4j.org/convolutionalnets.html

# 원하는 행렬 사이즈로 초기 값을 만들어서 리턴하는 메서드
def weight_variable(shape):
  initial = tf.truncated_normal(shape, stddev=0.1)
  return tf.Variable(initial)

# 0.1 로 초기값 지정하여 원하는 사이즈로 리턴
def bias_variable(shape):
  initial = tf.constant(0.1, shape=shape)
  return tf.Variable(initial)
def conv2d(x, W):
# tf.nn.conv2d(input, filter, strides, padding, use_cudnn
# _on_gpu=None, data_format=None, name=None)
# strides= [1 , stride, stride, 1] 차원축소 작업시 마스크 메트릭스를 이동하는 보복
# padding='SAME' 다음 레벨에서도 메특릭스가 줄어들지 않도록 패딩을 추가한다
  return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME')

# [filter_height, filter_width, in_channels, out_channels]
W_conv1 = weight_variable([5, 5, 1, 32])
b_conv1 = bias_variable([32])

 라. Max Pool

보통은 이렇게 생성한 메트릭스를 max pooling 을 사용하여 다시 한번 간소화한다.  위에서 필터링이 마스크에 대한 & 연산이었다면, max Pooling은 메트릭스에서 가장 큰 값 하나만 뽑아서 사용하는 방법이다. 아래와 같은 max pooling 정의 (mask [2,2] , stride[2,2] )를 4X4 메트릭스에 적용하면 2X2 메트릭스가 되는 것이다

# x :  [batch, height, width, channels]
# 2x2 행열에 가장 큰 값을 찾아서 추출, 가로세로 2칸씩이동
def max_pool_2x2(x):
  return tf.nn.max_pool(x, ksize=[1, 2, 2, 1],
                        strides=[1, 2, 2, 1], padding='SAME')

 마. Layer 1 :CNN + MaxPool

아래의 3줄로써 인풋 레이어에 대한 정의는 완료된다. 28X28 행렬 하나를 넣고 28X28행렬(원래는 24X24가 되지만 Padding 적용) 32개를 만들고 다시 max pool (2,2) 를 사용하여 14X14 메트릭스 32개를 리턴하는 레이어를 정의하였다
※ 메트릭스 단위로 정리하면 인풋 1개, 아웃풋 32개 이다

#인풋 데이터터 메트릭스를 변형한다. 784 개의 행렬을 갖는 복수의 데이터를
#[-1, 28, 28,1] 로 의 형태로 변형한다. 테스트 데이터 수 만큼 (-1) ,
#[28x28] 행렬로 만드는데 각 픽셀데이터는 rgb 데이터가 아니고 하나의 값만 갖도 변환
x_image = tf.reshape(x, [-1,28,28,1])
h_conv1 = tf.nn.relu(conv2d(x_image, W_conv1) + b_conv1)
h_pool1 = max_pool_2x2(h_conv1)

 바. Layer 2

1번 레이어에서 아웃풋을 32개를 전달하였음으로 2번 레이어의 인풋은 16X16 메트릭스 32개 그리고 아웃풋은 동일한 max pool 을 적용하여 8×8 메트릭스 64개를 출력한다.
정리하면 인풋 32개(14X14) 아웃풋 64개(7X7) 이 된다

W_conv2 = weight_variable([5, 5, 32, 64])
b_conv2 = bias_variable([64])

h_conv2 = tf.nn.relu(conv2d(h_pool1, W_conv2) + b_conv2)
h_pool2 = max_pool_2x2(h_conv2)

 사. Layer 3

현재 최종 데이터의 수는 7 X 7 X 64 = 3136 개 이지만 1024 개 를 사용한다
1024는 임의의 선택 값이다

W_fc1 = weight_variable([7 * 7 * 64, 1024])
b_fc1 = bias_variable([1024])
h_pool2_flat = tf.reshape(h_pool2, [-1, 7*7*64])
h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1)

 아. Drop Out

Dropout 은 데이터 간의 연과 관계가 큰 데이터들을 제거함으로써 과적합 문제를 해결하는 기법의 하나이다.

# drop out 연산의 결과를 담을 변수
keep_prob = tf.placeholder(tf.float32)
h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob)

차. Output Layer

마지막으로 1024개의 노드에서 10개의 (0~9까지 숫자)에 대한 확률을 Soft Max 를 이용하여 도출할 수 있도록 한다

W_fc2 = weight_variable([1024, 10])
b_fc2 = bias_variable([10])

y_conv=tf.nn.softmax(tf.matmul(h_fc1_drop, W_fc2) + b_fc2)

 카. 최적화

# Define loss and optimizer
cross_entropy = -tf.reduce_sum(y_*tf.log(y_conv))
train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)
correct_prediction = tf.equal(tf.argmax(y_conv,1), tf.argmax(y_,1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))

 타. 실행 및 저장

#50개씩, 20000번 반복학습
for i in range(20000):
  batch = mnist.train.next_batch(50)
  # 10회 단위로 한번씩 모델 정합성 테스트
  if i%100 == 0:
    train_accuracy = accuracy.eval(feed_dict={
        x:batch[0], y_: batch[1], keep_prob: 1.0})
    print("step %d, training accuracy %g"%(i, train_accuracy))
  # batch[0] 28X28 이미지,  batch[1] 숫자태그, keep_prob : Dropout 비율
  train_step.run(feed_dict={x: batch[0], y_: batch[1], keep_prob: 0.5})

# 모델에 사용된 모든 변수 값을 저장한다
save_path = saver.save(sess, "model2.ckpt")
print ("Model saved in file: ", save_path)

#최종적으로 모델의 정합성을 체크한다
print("test accuracy %g"%accuracy.eval(feed_dict={
    x: mnist.test.images, y_: mnist.test.labels, keep_prob: 1.0}))

sess.close()

 

[전체 코드]

# -*- coding: utf-8 -*-

"""
niektemme/tensorflow-mnist-predict 를 참조하였음

"""

import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data

#레파지토리에서 테스트 프로그램에 필요한 데이터 다운로드
mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)

sess = tf.InteractiveSession()
"""
모델 생성에 필요한 데이터 정의
x : 인풋레이어에 사용할 변수 정의
y : 아웃풋레이어에 사용할 변수 정의
w : 784 X 10 개의 초기값 0을 갖는 메트릭스 생성
b : 10개짜리 배열 생성
y = x * w + b
x (784) * w(784*10) = x*w(10)
x*w(10) + b(10) = y(10)
위에처럼 메트릭스 연산이 수행되기 때문에 위와 같이 데이터 사이즈를 잡은 것이다.
"""
x = tf.placeholder(tf.float32, [None, 784])
y_= tf.placeholder(tf.float32, [None, 10])
W = tf.Variable(tf.zeros([784, 10]))
b = tf.Variable(tf.zeros([10]))
y = tf.nn.softmax(tf.matmul(x, W) + b)


# 원하는 행렬 사이즈로 초기 값을 만들어서 리턴하는 메서드
def weight_variable(shape):
  initial = tf.truncated_normal(shape, stddev=0.1)
  return tf.Variable(initial)

# 0.1 로 초기값 지정하여 원하는 사이즈로 리턴
def bias_variable(shape):
  initial = tf.constant(0.1, shape=shape)
  return tf.Variable(initial)

"""
필터에 대해서 설명하고자 하면 CNN 의 동작 원리를 설명해야만한다.
[5, 5, 1, 32] 는 5X5 사이즈의 단위 필터를 사용해서 인풋데이터
(여기서는 28 X 28 사이즈 메트릭스)를 CNN연산을 하겠다는 것이다.
Stride 가 [1,1] 이라고 하면 28X28크기 행렬을 5X5 사이즈의
메트릭스로가로세로 한칸씩 이동하면서 필터에 연산하겠다는 의미가 된다.
결과적으로 아웃풋은 24X24 사이즈가 된다. 왜냐하면 5X5 사이즈의
메트릭스로 이동할 수 있는 한계가 있기 때문이다.
(메트릭스 끝부분 까지 이동할 수 없음)
이러한 경우 패딩 옵션을 사용하여 0으로 태두리를 채워넣어 메특릭스
사이즈를 동일하게 유지할 수도 있다
참조:http://deeplearning4j.org/convolutionalnets.html

"""
def conv2d(x, W):
# tf.nn.conv2d(input, filter, strides, padding, use_cudnn
# _on_gpu=None, data_format=None, name=None)
# strides= [1 , stride, stride, 1] 차원축소 작업시 마스크 메트릭스를 이동하는 보복
# padding='SAME' 다음 레벨에서도 메특릭스가 줄어들지 않도록 패딩을 추가한다
  return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME')


"""
보통은 이렇게 생성한 메트릭스를 max pooling 을 사용하여 다시 한번 간소화한다.
위에서 필터링이 마스크에 대한 & 연산이었다면, max Pooling은 메트릭스에서 가장
큰 값 하나만 뽑아서 사용하는 방법이다. 아래와 같은 max pooling 정의
(mask [2,2] , stride[2,2] )를 4X4 메트릭스에 적용하면 2X2 메트릭스가 될 것이다
"""
# x :  [batch, height, width, channels]
# 2x2 행열에 가장 큰 값을 찾아서 추출, 가로세로 2칸씩이동
def max_pool_2x2(x):
  return tf.nn.max_pool(x, ksize=[1, 2, 2, 1],
                        strides=[1, 2, 2, 1], padding='SAME')


# [filter_height, filter_width, in_channels, out_channels]
W_conv1 = weight_variable([5, 5, 1, 32])
b_conv1 = bias_variable([32])

"""
Layer 1
아래의 3줄로써 인풋 레이어에 대한 정의는 완료된다. 28X28 행렬 하나를 넣고
28X28행렬(원래는 24X24가 되지만 Padding 적용) 32개를 만들고 다시 max pool
(2,2)를 사용하여 14X14 메트릭스 32개를 리턴하는 레이어를 정의하였다
메트릭스 단위로 정리하면 인풋 1개, 아웃풋 32개 이다 트
"""
#인풋 데이터터 메트릭스를 변형한다. 784 개의 행렬을 갖는 복수의 데이터를
#[-1, 28, 28,1] 로 의 형태로 변형한다. 테스트 데이터 수 만큼 (-1) ,
#[28x28] 행렬로 만드는데 각 픽셀데이터는 rgb 데이터가 아니고 하나의 값만 갖도 변환
x_image = tf.reshape(x, [-1,28,28,1])
h_conv1 = tf.nn.relu(conv2d(x_image, W_conv1) + b_conv1)
h_pool1 = max_pool_2x2(h_conv1)

"""
Layer 2
1번 레이어에서 아웃풋을 32개를 전달하였음으로 2번 레이어의 인풋은
14X14 메트릭스 32개 그리고 아웃풋은 동일한 max pool 을 적용하여 8x8 메트릭스
64개를 출력한다. 정리하면 인풋 32개(14X14) 아웃풋 64개(7X7) 이 된다
"""
W_conv2 = weight_variable([5, 5, 32, 64])
b_conv2 = bias_variable([64])

h_conv2 = tf.nn.relu(conv2d(h_pool1, W_conv2) + b_conv2)
h_pool2 = max_pool_2x2(h_conv2)

"""
Layer 3
현재 최종 데이터의 수는 7 X 7 X 64 = 3136 개 이지만 1024 개 를 사용한다
1024는 임의의 선택 값이다
"""
W_fc1 = weight_variable([7 * 7 * 64, 1024])
b_fc1 = bias_variable([1024])
h_pool2_flat = tf.reshape(h_pool2, [-1, 7*7*64])
h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1)


"""
Drop Out
Dropout 은 데이터 간의 연과 관계가 큰 데이터들을 제거함으로써 과적합 문제를
해결하는 기법의 하나이다.
"""
# drop out 연산의 결과를 담을 변수
keep_prob = tf.placeholder(tf.float32)
h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob)


"""
Out put Layer
마지막으로 1024개의 노드에서 10개의 (0~9까지 숫자)에 대한 확률을 Soft Max 를
이용하여 도출할 수 있도록 한다
"""
W_fc2 = weight_variable([1024, 10])
b_fc2 = bias_variable([10])

y_conv=tf.nn.softmax(tf.matmul(h_fc1_drop, W_fc2) + b_fc2)

# Define loss and optimizer
cross_entropy = -tf.reduce_sum(y_*tf.log(y_conv))
train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)
correct_prediction = tf.equal(tf.argmax(y_conv,1), tf.argmax(y_,1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))


"""
Train & Save Model
"""
saver = tf.train.Saver()
sess.run(tf.initialize_all_variables())

#50개씩, 20000번 반복학습
for i in range(20000):
  batch = mnist.train.next_batch(50)
  # 10회 단위로 한번씩 모델 정합성 테스트
  if i%100 == 0:
    train_accuracy = accuracy.eval(feed_dict={
        x:batch[0], y_: batch[1], keep_prob: 1.0})
    print("step %d, training accuracy %g"%(i, train_accuracy))
  # batch[0] 28X28 이미지,  batch[1] 숫자태그, keep_prob : Dropout 비율
  train_step.run(feed_dict={x: batch[0], y_: batch[1], keep_prob: 0.5})

# 모델에 사용된 모든 변수 값을 저장한다
save_path = saver.save(sess, "model2.ckpt")
print ("Model saved in file: ", save_path)

#최종적으로 모델의 정합성을 체크한다
print("test accuracy %g"%accuracy.eval(feed_dict={
    x: mnist.test.images, y_: mnist.test.labels, keep_prob: 1.0}))

sess.close()

 

TensorFlow – 기본문법 (4)

바 . Gradient Descent (Linear Regression)

R 에서 lm( y ~ x , data) 하고 coef  실행시켜주면 최적의 공식을 찾아주던  그것과 상당히 유사한 기능을  tensorflow 로 구현하였다고 보면된다. 모든 기계 학습에서의 최적화를 찾아가는 방법은 코스트를 구하고, 그 코스트가 최소가 되는 공식을 계속해서 변경하고  반복하면서 최적을 찾는 동일한 패턴을 갖는다. 아래의 예제 코드도 그 과정을 설명하는 코드라고 생각하면 된다.

[테스트 데이터 생성]

[x,y] 와 같은 형태의 복수 데이터를 생성한다. 이때, 우리만 알고 있는  x ~ y 사이의 관계식을 적용하여 데이터를 생성한다. 이것이 훈력을 통해서 찾고자 하는 목표 값이 되겠다

# 테스트를 위한 랜덤 값을 생성한다.
def make_data_set(weight, bias, train_num, max_x):

    data = np.random.randint(max_x, size=train_num)
    x = tf.constant(data, name='x')
    result = []

    for i in range(0, train_num):
        result.append([data[i], data[i] * weight + bias])

    return result

[최적의 식 찾기]

모델의 형태를 지정하고, 초기값을 지정한다.

# 최초의 추축 값 , 초기 값이라고 보면 된다.
    w = tf.Variable([1.0, 2.0], name="w")
    # 우리 모델은 아주 간단한 1차 방적식이다  y = a*x + b
    y_model = tf.mul(x, w[0]) + w[1]

그리고 테스트 데이터와 모델에서 유추한 값의 오차 (코스트)를 구하는 식을 정의

    # error 는 식으로 구한 y 값과 원래 가지고 있는 Y 값의 차이이다
    error = tf.square(y - y_model)

코스트가 최소화 되도록 훈련을 시킨다

    # 애러 값을 최소화 할 수 있는 방향으로 0.01 의 학습도로 공식을 수정해 간다
    train_op = tf.train.GradientDescentOptimizer(0.01).minimize(error)

나머지는  session 을 생성하여 실행하는 로직

[전체 코드]

# 최적의 회귀식을 찾아내는 기능이다. 최적의 회귀식이란 모든 점을 가장 잘 설명할 수 있는
# 각 점으로부터의 직선거리가 최소화되는 하나의 선을 구하는 것이다라고 보면 된다
def graident_descent(sets):

    # 테스트 데이터를 위한  placeholder 를 생성한다.
    # x, y 는 각 2차원 그래프의 x, y 좌표 값이라고 보면 된다.
    # 아래에서 for i in range(1000): 100번을 반복하면서 랜덤 값을 연산하기 위한
    # 변수로 사용할 것이다.
    x = tf.placeholder("float")
    y = tf.placeholder("float")

    # 최초의 추축 값 , 초기 값이라고 보면 된다.
    w = tf.Variable([1.0, 2.0], name="w")
    # 우리 모델은 아주 간단한 1차 방적식이다  y = a*x + b
    y_model = tf.mul(x, w[0]) + w[1]

    # error 는 식으로 구한 y 값과 원래 가지고 있는 Y 값의 차이이다
    error = tf.square(y - y_model)

    # 애러 값을 최소화 할 수 있는 방향으로 0.01 의 학습도로 공식을 수정해 간다
    train_op = tf.train.GradientDescentOptimizer(0.01).minimize(error)

    # 위에 정의한 변수들을 모두 등록한다.
    model = tf.initialize_all_variables()

    errors = []
    # 1000번을 반복하여 학습도를 조금식 올려 보자
    with tf.Session() as session:
        session.run(model)
        for set in sets:
            #print("{0} , {1}".format(set[0], set[1]))
            #session.run(train_op, feed_dict={x: set[0], y: set[1]})
            _, error_value = session.run([train_op, error], feed_dict={x: set[0], y: set[1]})
            errors.append(error_value)

        # for i in range(1000):
        #     x_value = np.random.rand()
        #     y_value = x_value * 2 + 6
        #     print("{0},{1}".format(x_value,y_value))
        #     session.run(train_op, feed_dict={x: x_value, y: y_value})

        w_value = session.run(w)

        print("Predicted model: {a:.3f}x + {b:.3f}".format(a=w_value[0], b=w_value[1]))
        return errors, w_value

[그래프 출력 ]

애러율 감소하는 것을 시각화하고, 데이터와 추측한 공식을 시각화 한다

# 애러율이 감소하는 것을 시각화
def draw_errorr_graph(errors):
    plt.plot([np.mean(errors[i - 50:i]) for i in range(len(errors))])
    plt.show()
    plt.savefig("errors.png")

# 최종적으로 추측한 그래프의 시각화
def draw_opt_line(all_samples, fomula, x_axis_max_num):

    start = [0  , fomula[1]]
    end = [x_axis_max_num, x_axis_max_num * fomula[0] + fomula[1]]

    for set in all_samples:
        plt.scatter(set[0], set[1], color='b')

    plt.plot(start , end, color='r')
    plt.show()

[애러율 감소]

스크린샷, 2016-09-02 01-12-44

 

[데이터와 유추한 공식]

스크린샷, 2016-09-02 01-12-59

[전체 테스트 코드]

# -*- coding: utf-8 -*-
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt

# threadhold (5) 보다 값이 커지기 전까지 X 를 하나씩 증가시키면서 출력한다
def simple_loop_exp():

    x = tf.Variable(0., name='x')
    threshold = tf.constant(5.)

    model = tf.initialize_all_variables()

    with tf.Session() as session:
        session.run(model)
        while session.run(tf.less(x, threshold)):
            x = x + 1
            x_value = session.run(x)
            print(x_value)


# 테스트를 위한 랜덤 값을 생성한다.
def make_data_set(weight, bias, train_num, max_x):

    data = np.random.randint(max_x, size=train_num)
    x = tf.constant(data, name='x')
    result = []

    for i in range(0, train_num):
        result.append([data[i], data[i] * weight + bias])

    return result



# 최적의 회귀식을 찾아내는 기능이다. 최적의 회귀식이란 모든 점을 가장 잘 설명할 수 있는
# 각 점으로부터의 직선거리가 최소화되는 하나의 선을 구하는 것이다라고 보면 된다
def graident_descent(sets):

    # 테스트 데이터를 위한  placeholder 를 생성한다.
    # x, y 는 각 2차원 그래프의 x, y 좌표 값이라고 보면 된다.
    # 아래에서 for i in range(1000): 100번을 반복하면서 랜덤 값을 연산하기 위한
    # 변수로 사용할 것이다.
    x = tf.placeholder("float")
    y = tf.placeholder("float")

    # 최초의 추축 값 , 초기 값이라고 보면 된다.
    w = tf.Variable([1.0, 2.0], name="w")
    # 우리 모델은 아주 간단한 1차 방적식이다  y = a*x + b
    y_model = tf.mul(x, w[0]) + w[1]

    # error 는 식으로 구한 y 값과 원래 가지고 있는 Y 값의 차이이다
    error = tf.square(y - y_model)

    # 애러 값을 최소화 할 수 있는 방향으로 0.01 의 학습도로 공식을 수정해 간다
    train_op = tf.train.GradientDescentOptimizer(0.01).minimize(error)

    # 위에 정의한 변수들을 모두 등록한다.
    model = tf.initialize_all_variables()

    errors = []
    # 1000번을 반복하여 학습도를 조금식 올려 보자
    with tf.Session() as session:
        session.run(model)
        for set in sets:
            #print("{0} , {1}".format(set[0], set[1]))
            #session.run(train_op, feed_dict={x: set[0], y: set[1]})
            _, error_value = session.run([train_op, error], feed_dict={x: set[0], y: set[1]})
            errors.append(error_value)

        # for i in range(1000):
        #     x_value = np.random.rand()
        #     y_value = x_value * 2 + 6
        #     print("{0},{1}".format(x_value,y_value))
        #     session.run(train_op, feed_dict={x: x_value, y: y_value})

        w_value = session.run(w)

        print("Predicted model: {a:.3f}x + {b:.3f}".format(a=w_value[0], b=w_value[1]))
        return errors, w_value

# 애러율이 감소하는 것을 시각화
def draw_errorr_graph(errors):
    plt.plot([np.mean(errors[i - 50:i]) for i in range(len(errors))])
    plt.show()
    plt.savefig("errors.png")

# 최종적으로 추측한 그래프의 시각화
def draw_opt_line(all_samples, fomula, x_axis_max_num):

    start = [0  , fomula[1]]
    end = [x_axis_max_num, x_axis_max_num * fomula[0] + fomula[1]]

    for set in all_samples:
        plt.scatter(set[0], set[1], color='b')

    plt.plot(start , end, color='r')
    plt.show()


#생성하려고 하는 초기 데이터 변수
weight = 2
bias = 6
iter = 1000
x_axis_max_num = 5

# 초기 데이터를 생성합니다
data = make_data_set(weight , bias , iter, x_axis_max_num)

# 학습을 시켜 최적의 공식을 찾는다
errors, w_value = graident_descent(data)

# 애러율이 감소하는 그래프
draw_errorr_graph(errors)

# 최종 결과 , 데이터와, 유추한 선
draw_opt_line(data, w_value, x_axis_max_num)

 

TensorFlow – 기본문법 (3)

마. Clustering

이번 예제는 조금 복잡하다. K-Mean 클러스터링의 개념에 대해서 이해해야 하고, 몇몇 TensorFlow 의 Matrix 연산 메서드를 이해해야 한다. 아래는 전체 테스트 코드이다.
열심히 데이터가 따라가는 것을 체크하느라 실제 연산과는 상관없는 로그들이 포함되어 있다.

# -*- coding: utf-8 -*-
import tensorflow as tf
import numpy as np


# 랜덤하게 클러스터 데이터를 구성합니다.
def create_samples(n_clusters, n_samples_per_cluster, n_features, embiggen_factor, seed):
    np.random.seed(seed)
    slices = []
    centroids = []
    # Create samples for each cluster
    for i in range(n_clusters):

        # 평균이 0이고 표준편차가 5이고 2개의 데이터로 이루어진 500개의 랜덤 데이터 Pool 을 생성합니다
        samples = tf.random_normal((n_samples_per_cluster, n_features),
                               mean=0.0, stddev=5.0, dtype=tf.float32, seed=seed, name="cluster_{}".format(i))

        # 랜덤으로 중앙값을 만듭니다. 형태는 [X , Y] 가 되겠습니다.
        current_centroid = (np.random.random((1, n_features)) * embiggen_factor) - (embiggen_factor/2)

        # 각 그룹들의 중앙값을 무엇으로 만들었는지 그 이력을 저장합니다.
        centroids.append(current_centroid)

        # 이렇게 생성된 중앙 값을 500개의 랜덤 데이터에 더함으로써 해당 분포를 전체적으로 옮기도록 합니다.
        samples += current_centroid

        #최종적으로 완성된 각 클러스터별 데이터 셋을 저장합니다
        slices.append(samples)

    # 모든 클러스터 그룹의 그룹 데이터와 중앙값을 탠소플로우 변수로 정의하여 리턴합니다.
    samples = tf.concat(0, slices, name='samples')
    centroids = tf.concat(0, centroids, name='centroids')
    return centroids, samples

# all_samples 전체 샘플 배열( x, y 좌표로 구성) , 각 그룹의 중앙값 배열 , 클러스터의 수
def plot_clusters(all_samples, centroids, n_samples_per_cluster):
    import matplotlib.pyplot as plt

    # 0 ~ 1 구간을 len(centroids) 센터의 수 만큼으로 균등하게 나눈 배열을 생성함
    # linespace :[ 0.   0.5  1. ]
    print("linespace :{0}".format(np.linspace(0,1,len(centroids))))

    # 0 ~ 1 구간에 대응하는 색상 스팩트럼에서 대응하는 색상을 리턴
    # colur:[[1.00000000e+00   3.03152674e-01   1.53391655e-01   1.00000000e+00]
    #        [1.00000000e+00   1.22464680e-16   6.12323400e-17   1.00000000e+00]
    print("colur :{0}".format(plt.cm.rainbow([0.9, 1, 2, 3])))

    # 각 그룹의 색상을 다르게 해주기 위하여  RGB 색상 추출
    colour = plt.cm.rainbow(np.linspace(0,1,len(centroids)))


    # 중앙 값 배열을 기준으로 중앙점과 각 그룹에 해당하는 점을 표시
    for i, centroid in enumerate(centroids):
        # 각 배열에 해당하는 0 ~ 500 , 500 ~ 1000 , 1000 ~ 1500 구간을 나누어 색상을 지정하고 출력한다
        samples = all_samples[i*n_samples_per_cluster:(i+1)*n_samples_per_cluster]
        plt.scatter(samples[:,0], samples[:,1], c=colour[i])

        # 중앙점을 표시한다
        plt.plot(centroid[0], centroid[1], markersize=35, marker="x", color='k', mew=10)
        plt.plot(centroid[0], centroid[1], markersize=30, marker="x", color='m', mew=5)
    plt.show()

# https://www.tensorflow.org/versions/r0.10/api_docs
# 클러스터 중심좌표 3개를 랜덤으로 섞어서 다시 리턴
def choose_random_centroids(samples, n_clusters):

    # tf.shape(input, name=None)
    # 't' is [[[1, 1, 1], [2, 2, 2]], [[3, 3, 3], [4, 4, 4]]]
    # shape(t) == > [3]
    n_samples = tf.shape(samples)[0]

    # shape Test
    print("tf.shape Test! ")
    t = [[[1, 1, 1], [2, 2, 2]], [[3, 3, 3], [4, 4, 4]]]

    with tf.Session() as session:
        tt = tf.shape(t)
        rt = session.run(tt[0])
        print("tf.shape Test Result: {0} , {1}".format(tt, rt))

    # tf.random_shuffle
    # [[1, 2],       [[5, 6],
    # [3, 4],  ==>   [1, 2],
    # [5, 6]]        [3, 4]]
    random_indices = tf.random_shuffle(tf.range(0, n_samples))

    begin = [0, ]
    size = [n_clusters, ]
    size[0] = n_clusters
    # tf.slice ( input, form array , to array )
    centroid_indices = tf.slice(random_indices, begin, size)

    # gather mixed cluster again
    initial_centroids = tf.gather(samples, centroid_indices)
    return initial_centroids

#
def assign_to_nearest(samples, centroids):

    # expand_dims test
    # 't2' is a tensor of shape [2, 3, 5]
    # expand_dims ( data , location to add dim)
    with tf.Session() as session:
        t2 = [[2,3,5,6,7,8,9],[9,8,7,6,5,4,3,]]
        print("expand_before shape : {0}".format(session.run(tf.shape(t2))))
        print("expand_dims test : {0}, {1}".format(session.run(tf.shape(tf.expand_dims(t2, 0))),
                                                   session.run(tf.expand_dims(t2, 0))))
        print("expand_dims test : {0}, {1}".format(session.run(tf.shape(tf.expand_dims(t2, 1))),
                                                   session.run(tf.expand_dims(t2, 1))))
        print("expand_dims test : {0}, {1}".format(session.run(tf.shape(tf.expand_dims(t2, -1))),
                                                   session.run(tf.expand_dims(t2, -1))))


    # 차원을 추가한다
    expanded_vectors = tf.expand_dims(samples, 0)
    expanded_centroids = tf.expand_dims(centroids, 1)

    # (1) tf.reduce_sum
    ## 'x' is [[1, 1, 1]
    #         [1, 1, 1]]
    #tf.reduce_sum(x) ==> 6
    #tf.reduce_sum(x, 0) ==> [2, 2, 2]
    #tf.reduce_sum(x, 1) ==> [3, 3]
    #tf.reduce_sum(x, 1, keep_dims=True) ==> [[3], [3]]
    #tf.reduce_sum(x, [0, 1]) ==> 6

    # (2) tf.square(X) =  x^2

    # 모든 점들과 위에서 구한 랜덤 중앙점간의 거리의 합을 구한다
    distances = tf.reduce_sum( tf.square(
               tf.sub(expanded_vectors, expanded_centroids)), 2)

    # 가장 가까운 거리를 구한다
    mins = tf.argmin(distances, 0)
    #
    nearest_indices = mins
    return nearest_indices

# 새롭게 구한 중앙점 데이터를 업데이트
def update_centroids(samples, nearest_indices, n_clusters):
    # Updates the centroid to be the mean of all samples associated with it.
    nearest_indices = tf.to_int32(nearest_indices)
    partitions = tf.dynamic_partition(samples, nearest_indices, n_clusters)
    new_centroids = tf.concat(0, [tf.expand_dims(tf.reduce_mean(partition, 0), 0) for partition in partitions])
    return new_centroids

n_features = 2
n_clusters = 3
n_samples_per_cluster = 500
seed = 700
embiggen_factor = 70

# 복수 그룹의 군집 데이터를 만든다 의
data_centroids, samples = create_samples(n_clusters, n_samples_per_cluster, n_features, embiggen_factor, seed)
# 랜덤으로 중앙점을 생성한다
initial_centroids = choose_random_centroids(samples, n_clusters)
# 랜덤한 중앙점이 가장 가까운 그룹을 찾는다
nearest_indices = assign_to_nearest(samples, initial_centroids)
#
updated_centroids = update_centroids(samples, nearest_indices, n_clusters)

# 데이터 확인
with tf.Session() as session:
    print("[step 1] cent : {0} , sample : {1}".format(session.run(data_centroids), session.run(data_centroids)))
    print("[step 2] cent : {0} ".format(session.run(initial_centroids)))
    print("[step 3] cent : {0} ".format(session.run(nearest_indices)))
    print("[step 4] cent : {0} ".format(session.run(updated_centroids)))

# 세션에서 연산을 수행한다
model = tf.initialize_all_variables()
with tf.Session() as session:
    sample_values = session.run(samples)
    updated_centroid_value = session.run(updated_centroids)
    print(updated_centroid_value)

# 그래프를 출력한다
# 맷랩은 슈퍼유저로 실행하면 애러난다
plot_clusters(sample_values, updated_centroid_value, n_samples_per_cluster)

[데이터 준비]

데이터를 준비하는 함수입니다. 이번 예제는 군집분석의 종류중 하나인  K-Mean Clustering  을 TensorFlow 사용하여 분석하는 것 입니다. 이를 위해 데이터를 구성하는데 아래와 같이 우선 적정한 분산을 갖는 500개의 데이터 그룹을 만들어 냅니다.

# 평균이 0이고 표준편차가 5이고 2개의 데이터로 이루어진 500개의 랜덤 데이터 Pool 을 생성합니다
     samples = tf.random_normal((n_samples_per_cluster, n_features),
                            mean=0.0, stddev=5.0, dtype=tf.float32, seed=seed, name="cluster_{}".format(i))

그 후에 랜덤으로 3개의 중앙점을 만들어 냅니다. 그리고 해당 중앙값을 아까 만들었던 랜덤 데이터에 더해 줌으로써 각각의 데이터를 Shifting 을 해줍니다. 그러면 3개의 다른 그룹이 생성이 되겠지요. 아마 그림으로 표현하여 아래와 같이 될 것입니다.

X 마크는 제외하고 뒤에 점들이 생성이 되었다 이렇게 보시면 되겠습니다.

[데이터 생성 전체 코드]

# -*- coding: utf-8 -*-
import tensorflow as tf
import numpy as np


# 랜덤하게 클러스터 데이터를 구성합니다.
def create_samples(n_clusters, n_samples_per_cluster, n_features, embiggen_factor, seed):
    np.random.seed(seed)
    slices = []
    centroids = []
    # Create samples for each cluster
    for i in range(n_clusters):

        # 평균이 0이고 표준편차가 5이고 2개의 데이터로 이루어진 500개의 랜덤 데이터 Pool 을 생성합니다
        samples = tf.random_normal((n_samples_per_cluster, n_features),
                               mean=0.0, stddev=5.0, dtype=tf.float32, seed=seed, name="cluster_{}".format(i))

        # 랜덤으로 중앙값을 만듭니다. 형태는 [X , Y] 가 되겠습니다.
        current_centroid = (np.random.random((1, n_features)) * embiggen_factor) - (embiggen_factor/2)

        # 각 그룹들의 중앙값을 무엇으로 만들었는지 그 이력을 저장합니다.
        centroids.append(current_centroid)

        # 이렇게 생성된 중앙 값을 500개의 랜덤 데이터에 더함으로써 해당 분포를 전체적으로 옮기도록 합니다.
        samples += current_centroid

        #최종적으로 완성된 각 클러스터별 데이터 셋을 저장합니다
        slices.append(samples)

    # 모든 클러스터 그룹의 그룹 데이터와 중앙값을 탠소플로우 변수로 정의하여 리턴합니다.
    samples = tf.concat(0, slices, name='samples')
    centroids = tf.concat(0, centroids, name='centroids')
    return centroids, samples

[랜덤 중앙점 생성]

데이터는 생성을 하였고 이제 각 그룹의 중심을 찾는 로직을 테스트하기 위하여 중심좌표를 랜덤으로 섞어서 다시 리턴합니다.

# https://www.tensorflow.org/versions/r0.10/api_docs
# 클러스터 중심좌표 3개를 랜덤으로 섞어서 다시 리턴
def choose_random_centroids(samples, n_clusters):

    # tf.shape(input, name=None)
    # 't' is [[[1, 1, 1], [2, 2, 2]], [[3, 3, 3], [4, 4, 4]]]
    # shape(t) == > [3]
    n_samples = tf.shape(samples)[0]

    # shape Test
    print("tf.shape Test! ")
    t = [[[1, 1, 1], [2, 2, 2]], [[3, 3, 3], [4, 4, 4]]]

    with tf.Session() as session:
        tt = tf.shape(t)
        rt = session.run(tt[0])
        print("tf.shape Test Result: {0} , {1}".format(tt, rt))

    # tf.random_shuffle
    # [[1, 2],       [[5, 6],
    # [3, 4],  ==>   [1, 2],
    # [5, 6]]        [3, 4]]
    random_indices = tf.random_shuffle(tf.range(0, n_samples))

    begin = [0, ]
    size = [n_clusters, ]
    size[0] = n_clusters
    # tf.slice ( input, form array , to array )
    centroid_indices = tf.slice(random_indices, begin, size)

    # gather mixed cluster again
    initial_centroids = tf.gather(samples, centroid_indices)
    return initial_centroids

[근접 그룹 탐색]

위에서 구한 중앙점에서 각 500개 데이터를 갖고 있는 그룹의 점들과의 거리의 합을 구해서 각 그룹간의 거리의 합이 가장 적은 중앙점을 각 그룹으로 다시 맵핑하기 위한 작업

def assign_to_nearest(samples, centroids):

    # expand_dims test
    # 't2' is a tensor of shape [2, 3, 5]
    # expand_dims ( data , location to add dim)
    with tf.Session() as session:
        t2 = [[2,3,5,6,7,8,9],[9,8,7,6,5,4,3,]]
        print("expand_before shape : {0}".format(session.run(tf.shape(t2))))
        print("expand_dims test : {0}, {1}".format(session.run(tf.shape(tf.expand_dims(t2, 0))),
                                                   session.run(tf.expand_dims(t2, 0))))
        print("expand_dims test : {0}, {1}".format(session.run(tf.shape(tf.expand_dims(t2, 1))),
                                                   session.run(tf.expand_dims(t2, 1))))
        print("expand_dims test : {0}, {1}".format(session.run(tf.shape(tf.expand_dims(t2, -1))),
                                                   session.run(tf.expand_dims(t2, -1))))


    # 차원을 추가한다
    expanded_vectors = tf.expand_dims(samples, 0)
    expanded_centroids = tf.expand_dims(centroids, 1)

    # (1) tf.reduce_sum
    ## 'x' is [[1, 1, 1]
    #         [1, 1, 1]]
    #tf.reduce_sum(x) ==> 6
    #tf.reduce_sum(x, 0) ==> [2, 2, 2]
    #tf.reduce_sum(x, 1) ==> [3, 3]
    #tf.reduce_sum(x, 1, keep_dims=True) ==> [[3], [3]]
    #tf.reduce_sum(x, [0, 1]) ==> 6

    # (2) tf.square(X) =  x^2

    # 모든 점들과 위에서 구한 랜덤 중앙점간의 거리의 합을 구한다
    distances = tf.reduce_sum( tf.square(
               tf.sub(expanded_vectors, expanded_centroids)), 2)

    # 가장 가까운 거리를 구한다
    mins = tf.argmin(distances, 0)
    #
    nearest_indices = mins
    return nearest_indices

[ 화면에 출력하기 위해서 모든 데이터를 합치는 작업]

# 새롭게 구한 중앙점 데이터를 업데이트
def update_centroids(samples, nearest_indices, n_clusters):
    # Updates the centroid to be the mean of all samples associated with it.
    nearest_indices = tf.to_int32(nearest_indices)
    partitions = tf.dynamic_partition(samples, nearest_indices, n_clusters)
    new_centroids = tf.concat(0, [tf.expand_dims(tf.reduce_mean(partition, 0), 0) for partition in partitions])
    return new_centroids

n_features = 2
n_clusters = 3
n_samples_per_cluster = 500
seed = 700
embiggen_factor = 70

# 복수 그룹의 군집 데이터를 만든다 의
data_centroids, samples = create_samples(n_clusters, n_samples_per_cluster, n_features, embiggen_factor, seed)
# 랜덤으로 중앙점을 생성한다
initial_centroids = choose_random_centroids(samples, n_clusters)
# 랜덤한 중앙점이 가장 가까운 그룹을 찾는다
nearest_indices = assign_to_nearest(samples, initial_centroids)
#
updated_centroids = update_centroids(samples, nearest_indices, n_clusters)

# 데이터 확인
with tf.Session() as session:
    print("[step 1] cent : {0} , sample : {1}".format(session.run(data_centroids), session.run(data_centroids)))
    print("[step 2] cent : {0} ".format(session.run(initial_centroids)))
    print("[step 3] cent : {0} ".format(session.run(nearest_indices)))
    print("[step 4] cent : {0} ".format(session.run(updated_centroids)))

# 세션에서 연산을 수행한다
model = tf.initialize_all_variables()
with tf.Session() as session:
    sample_values = session.run(samples)
    updated_centroid_value = session.run(updated_centroids)
    print(updated_centroid_value)

# 그래프를 출력한다
# 맷랩은 슈퍼유저로 실행하면 애러난다
plot_clusters(sample_values, updated_centroid_value, n_samples_per_cluster)

[데이터 편집 및 그래프 출력]

데이터를 화면에 출력하기 위한 함수입니다. 결과는 아래와 같은 그래프입니다.

루트 권한으로 실행하면 애러가 나니 주의하시면 되겠습니다.

# all_samples 전체 샘플 배열( x, y 좌표로 구성) , 각 그룹의 중앙값 배열 , 클러스터의 수
def plot_clusters(all_samples, centroids, n_samples_per_cluster):
    import matplotlib.pyplot as plt

    # 0 ~ 1 구간을 len(centroids) 센터의 수 만큼으로 균등하게 나눈 배열을 생성함
    # linespace :[ 0.   0.5  1. ]
    print("linespace :{0}".format(np.linspace(0,1,len(centroids))))

    # 0 ~ 1 구간에 대응하는 색상 스팩트럼에서 대응하는 색상을 리턴
    # colur:[[1.00000000e+00   3.03152674e-01   1.53391655e-01   1.00000000e+00]
    #        [1.00000000e+00   1.22464680e-16   6.12323400e-17   1.00000000e+00]
    print("colur :{0}".format(plt.cm.rainbow([0.9, 1, 2, 3])))

    # 각 그룹의 색상을 다르게 해주기 위하여  RGB 색상 추출
    colour = plt.cm.rainbow(np.linspace(0,1,len(centroids)))


    # 중앙 값 배열을 기준으로 중앙점과 각 그룹에 해당하는 점을 표시
    for i, centroid in enumerate(centroids):
        # 각 배열에 해당하는 0 ~ 500 , 500 ~ 1000 , 1000 ~ 1500 구간을 나누어 색상을 지정하고 출력한다
        samples = all_samples[i*n_samples_per_cluster:(i+1)*n_samples_per_cluster]
        plt.scatter(samples[:,0], samples[:,1], c=colour[i])

        # 중앙점을 표시한다
        plt.plot(centroid[0], centroid[1], markersize=35, marker="x", color='k', mew=10)
        plt.plot(centroid[0], centroid[1], markersize=30, marker="x", color='m', mew=5)
    plt.show()

스크린샷, 2016-09-01 19-30-15

TensorFlow – 기본문법 (2)

가. Variables

[잘못된 사용의 예]

# CASE1
# 아래처럼은 동작하지 않음, 왜 냐면 Tensor 연산은 Session 위에서 이루어져야 하기 때문
try :
# 일반적인 변수처럼 처리하려고 하면 발생한느 현상
x = tf.constant(35, name='x')
y = tf.Variable(x + 5, name='y')

#<tensorflow.python.ops.variables.Variable object at 0x7fabe98cced0>
print(y)
except:
print("ERROR-1")

[잘 사용한 예]

# CASE2
# 아래처럼 실행하면 40이 리턴됨
try :
    x = tf.constant([35, 40, 45], name='x')
    y = tf.Variable(x + 5, name='y')

    # 지금까지 정의한 변수를 Session 에서 사용할 수 있도록 초기화 합니다
    model = tf.initialize_all_variables()

    # with Session as 구분 사용시 Session 종료는 자동
    with tf.Session() as session:
        session.run(model)
        print(session.run(y))
except:
    print("ERROR-2")

[Numpy 를 사용하여 사이즈간 큰 데이터 생성 및 처리 테스트]

# CASE3
# numpy 를 사용해서 사이즈가 큰 데이터를 생성하고 식을 조금 복잡하게 수행
try:
    data = np.random.randint(1000, size=10000)
    x = tf.constant(data, name='x')
    y = tf.Variable(x**2 + 5*x + 5, name='y')

    model = tf.initialize_all_variables()

    with tf.Session() as session:
        session.run(model)
        print(session.run(y))
except:
    print("ERROR-3")

 

[루프 연산]

# CASE4
# for i in range(5): 을 사용한 루프 연산
try:
    x = tf.Variable(0, name='x')

    model = tf.initialize_all_variables()

    with tf.Session() as session:
        for i in range(5):
            session.run(model)
            x = x + 1
            print(session.run(x))

except:
    print("ERROR-4")

 

[TensorBoard 연동]

TensorBoard는 별도의 실행이 필요한 Tool 로써 아래와 같이 사용하면 됨

# 실행 방법 :  tensorboard --logdir=/tmp/basic
# http://localhost:6006

[분석 파일 생성 ]

# CASE5
# TensorBoard 를 활용한 그래프 출력
try:
    data = np.random.randint(1000, size=10000)
    x = tf.constant(data, name='x')
    y = tf.Variable(x**2 + 5*x + 5, name='y')

    with tf.Session() as session:

        merged = tf.merge_all_summaries()
        writer = tf.train.SummaryWriter("/tmp/basic", session.graph)
        model = tf.initialize_all_variables()
        session.run(model)
        print(session.run(y))

        # 실행 방법 :  tensorboard --logdir=/tmp/basic
        # http://localhost:6006
except:
    print("ERROR-5")

나.  Array

[이미지 로딩]

# -*- coding: utf-8 -*-
import os
import tensorflow as tf
import matplotlib.image as mpimg

# 이미지를 로딩한다
filename = os.path.dirname(__file__) + "/MarshOrchid.jpg"
image = mpimg.imread(filename)
height, width, depth = image.shape

# 이미지의 메트릭스 형태 출력
print("1. Initial : height :{0} , width :{1} , depth :{2}".format(height, width, depth))

 

[축을 변경]

perm 에서 데이터 순서대로 축의 순서를 의미하며, 입력하는 숫자가 바꾸고 싶은 축의
변호가 된다. 아래의 예는 2 번 축과 3 번 축을 서로 바꾸겠다라는 의미가 된다

tf.transpose(x, perm=[0, 2, 1])
# 축을 변경한다
try:
    x = tf.Variable(image, name='x')

    model = tf.initialize_all_variables()

    with tf.Session() as session:
        # Array 위치가 축 (x,y,z), 거기에 입력하는 숫자가 바꾸고 싶은 차원
        x = tf.transpose(x, perm=[0, 2, 1])
        #x = tf.transpose(x, perm=[0 ,1, 2])
        session.run(model)
        result = session.run(x)

    height, width, depth = result.shape
    print("2. Transpose : height :{0} , width :{1} , depth :{2}".format(height, width, depth))

except Exception as err:
    print(err)

 

[데이터 순서 정렬]

뭔가 약간 잘 이해가 안가는 부분이 있는데 우선 아래 처럼 사용하면 X 축 데이터에 대해
역순으로 재 정렬하게 된다.

# 배열의 순서를 변경한다
try:
    #보기 좋게 데이터를 축소해보자
    tem_len = 2
    temp_img = image[0:tem_len][0:tem_len]

    x = tf.Variable(temp_img, name='x')
    model = tf.initialize_all_variables()

    #변경전 데이터 출력
    for i in range(tem_len):
        for j in range(tem_len):
            print("Before :[{0},{1}] : {2}".format(i, j, temp_img[i][j]))


    #다른 메서드들 : https://www.tensorflow.org/versions/r0.10/api_docs/python/array_ops.html
    #x는 인풋 데이터
    #데이터 사이즈 [width] * height = [5, 5, 5, 5, 5] 생성
    # seq_dim 1 : 데이터의 순서가 역순으로 정렬 됨
    # seq_dim 2 : 데이터 안의 내용이 역순 정렬
    #seq_dim 3 : seq_dim must be < input.dims() (3 vs 3)
    #batch_dim = 0 위에서 아래로 연산 수행
    with tf.Session() as session:
        x = tf.reverse_sequence(x, [tem_len] * tem_len, 2, batch_dim=0)
        session.run(model)
        result = session.run(x)

    #변경후 데이터 출력
    for i in range(tem_len):
        for j in range(tem_len):
            print("After :[{0},{1}] : {2}".format(i, j, result[i][j]))

except Exception as err:
    print(err)

 

다.  PlaceHolder

아래는 PlaceHolder  를 설명하는 예제이다 . PlaceHolder 란 값은 미정인데, 어떤 타입, 데이터 구조를 갖는 데이터를 정의하겠다라는 말이다.

아래는 어떤 데이터인지는 모르겠지만,  float  타입으로 사이즈가 3인 데이터를 정의하겠다라는 것이다. 만약 데이터의 수도 정의할 수 없다면 None 을 정의해주면 된다.

x1 = tf.placeholder("float", 3)
x2 = tf.placeholder("float", None)

이렇게 정의한 데이터는 아래와 같이 실제 데이터를 맵핑할 수 있다

with tf.Session() as session:
    result = session.run(y, feed_dict={x1: [1, 2, 3], x2: [1, 2, 3], x3: [1, 2, 3] })

[전체 코드]

# -*- coding: utf-8 -*-
import tensorflow as tf
import numpy as np


# 데이터 타입, 사이즈 정의 ,None은 무한대
x1 = tf.placeholder("float", 3)
x2 = tf.placeholder("float", None)
x3 = tf.placeholder("float", 3)
y = x1 * 2 + x2 + x3

# 데이터의 형태는 아래와 같이 이중 배열로로 정의 가능
x4 = tf.placeholder("float", [None, 3])
y2 = x4 + 1

# 기본적으로 연산하려면 세션에서 해야됨
with tf.Session() as session:

    # 데이터 직접 삽입
    result = session.run(y, feed_dict={x1: [1, 2, 3], x2: [1, 2, 3], x3: [1, 2, 3] })
    print(result)

    # 데이터 직접 삽입
    x_data = [[1, 2, 3], [4, 5, 6], ]
    result2 = session.run(y2, feed_dict={x4: x_data})
    print(result2)


# 이미지와 동일하게 가로, 세로, RGB 처럼 표현하는 테스트 데이터를 만들어 보자
data1 = np.random.randint(10)    # 이미지로 치면 빨간색
data2 = np.random.randint(10)    # 초록색
data3 = np.random.randint(10)    # 파란색

# 이미지로 치면 3색 표현 , 가로 5, 세로 5 인 이미지가 되겠다
raw_image_data = [[[data1, data2, data3]] * 5 ] * 5

# 데이터! 출력
print("1. Original : {0}".format(raw_image_data))

# 홀더를 만든다 이홀더는 가로 세로 사이즈 제한은 없고 색은 3가지 RGB 로 표현
# 하는 모든 데이터를 커버 할 수 있다
image = tf.placeholder("uint8", [None, None, 3])

# 메트릭스를 자른다, 첫번째는 소스 메트릭스, 두번재는 시작 주소, 세번째는 끝 메트릭스
# 시작과 끝 사이의 데이터만 리턴한다, -1은 데이터 최대 길이라는 이야기다
slice = tf.slice(image, [0, 0, 0], [-1, 1, -1])

# 슬라이스를 연산한다
with tf.Session() as session:
    result = session.run(slice, feed_dict={image: raw_image_data})

# 슬라이스 연산후 데이터
print("2. Transformed : {0}".format(result))

 

[결과]

/root/anaconda2/bin/python /root/PycharmProjects/TensorLearn/chap3_placeholder.py
[  4.   8.  12.]
[[ 2.  3.  4.]
 [ 5.  6.  7.]]
1. Original : [[[3, 5, 9], [3, 5, 9], [3, 5, 9], [3, 5, 9], [3, 5, 9]], [[3, 5, 9], [3, 5, 9], [3, 5, 9], [3, 5, 9], [3, 5, 9]], [[3, 5, 9], [3, 5, 9], [3, 5, 9], [3, 5, 9], [3, 5, 9]], [[3, 5, 9], [3, 5, 9], [3, 5, 9], [3, 5, 9], [3, 5, 9]], [[3, 5, 9], [3, 5, 9], [3, 5, 9], [3, 5, 9], [3, 5, 9]]]
2. Transformed : [[[3 5 9]]

 [[3 5 9]]

 [[3 5 9]]

 [[3 5 9]]

 [[3 5 9]]]

 

라.  Interactive Session

[기존 방식]

# CASE 1 : with session syntax
# 아래와 같이 사용시 자동으로 세션이 종료됨, 단 Sessin.run 을 일일히 실행 필요
try:

    x = tf.constant(data, name='x')
    y = tf.Variable(x**2 + 5*x + 5, name='y')

    model = tf.initialize_all_variables()

    with tf.Session() as session:
        session.run(model)
        print(session.run(y))
except:
    print("ERROR-1")

 

[interactive 방식]

# CASE 2 : InteractiveSession
# 매번 session.run 을 할 필요가 없음, 단 마지막에 session.close() 필수
try:
    session = tf.InteractiveSession()
    x = tf.constant(data, name='x')
    y = x ** 2 + 5 * x + 5
    print(y.eval())

    session.close()

except:
    print("ERROR-2")

 

TensorFlow – 기본 문법 (1)

공식 사이트 : https://www.tensorflow.org/versions/r0.10/how_tos/variables/index.html#variables-creation-initialization-saving-and-loading

공식사이트에 있는 튜토리얼 내용을 직접 예제를 만들어 보면서  그 내용을 정리
하고자 함

가 . Variables  의 생성과 저장

시작하기에 앞서  Variables  에 대해서 설명할 필요가 있다. 모델을 구성하는 주요 값인
WEIGHT , BIAS 와  같은 학습 값의 구조, 초기 값 등을 정의하는 변수이다.

[초기값 정의 방법]

스크린샷, 2016-08-28 08-54-19

[chap1_save_variables.py]

변수를 생성하고 파일로 저장하는 예제 코드

# -*- coding: utf-8 -*-

import tensorflow as tf

def main(_):
    # 탠소플로우 변수 생성 , 파이선 리턴 값은 tf.Variable 이 된다.
    weights = tf.Variable(tf.random_normal([784, 200], stddev=0.35),name="weights")
    biases = tf.Variable(tf.zeros([200]), name="biases")

    # 위에 정의한 변수를 변형하여 다른 이름으로 재 정의 할 수 있다
    w2 = tf.Variable(weights.initialized_value(), name="w2")
    w_twice = tf.Variable(weights.initialized_value() * 2.0, name="w_twice")
    temp1 = tf.constant(5.0)
    temp2 = tf.constant(10.0)
    temp3 = tf.add(temp1, temp2)

    # 값을 찍어 보면 탠소 플로우 베리어블 객체의 내용을 확인 가능
    print("weight : " + str(weights.initialized_value()))
    print("biases : " + str(biases.initialized_value()))
    print("w2 : " + str(w2.initialized_value()))
    print("w_twice : " + str(w_twice.initialized_value()))
    print("temp1 : " + str(temp1))
    print("temp2 : " + str(temp2))
    print("temp3 : " + str(temp3))

    # 위에 정의한 변수들을 실제로 탠소플로우 모델 메모리에 등록한다
    init_op = tf.initialize_all_variables()

    print(init_op)
    # 값을 직어 보면 아래와 같다
    # name: "init"
    # op: "NoOp"
    # input: "^weights/Assign"
    # input: "^biases/Assign"
    # input: "^w2/Assign"
    # input: "^w_twice/Assign"


    #저장에는 tf.train.Saver 를 사용한다
    saver = tf.train.Saver()

    # 실제 메모리와 코어를 사용할 세션을 생성
    with tf.Session() as sess:
        # 메모리에 등록하는 액션을 실제로 실행
        result = sess.run(init_op)

        # 더하기 연산 수행과 그 결과
        result2 = sess.run(temp3)
        print("result2 : " + str(result2))

        #지정한 경로에 해당 세션의 모든 정보를 저장한다
        save_path = saver.save(sess, "/tmp/model.ckpt")
        print("Model saved in file: %s" % save_path)


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

 

스크린샷, 2016-08-28 08-58-03

 

나. 저장된 데이터의 복구

[chap2_restore_variables.py]

저장한 변수들을 로드하는 예제 , 실제로는 모델을 훈련하는 과정 후에 저장이 되었어야
하지만 모델을 훈련하는 과정은 생략되어 있음

# -*- coding: utf-8 -*-

import tensorflow as tf


def main(_):
    # 저장할때와 마찬가지로 변수명 자체는 생성 필요 . 이니셜 값 자체는 동일해야 함
    weights = tf.Variable(tf.random_normal([784, 200], stddev=0.35),name="weights")
    biases = tf.Variable(tf.zeros([200]), name="biases")
    w2 = tf.Variable(weights.initialized_value(), name="w2")
    w_twice = tf.Variable(weights.initialized_value() * 5.0, name="w_twice")
    temp1 = tf.constant(0.0)
    temp2 = tf.constant(0.0)
    temp3 = tf.add(temp1, temp2)

    # 값을 찍어 보면 탠소 플로우 베리어블 객체의 내용을 확인 가능
    print("weight : " + str(weights.initialized_value()))
    print("biases : " + str(biases.initialized_value()))
    print("w2 : " + str(w2.initialized_value()))
    print("w_twice : " + str(w_twice.initialized_value()))
    print("temp1 : " + str(temp1))
    print("temp2 : " + str(temp2))
    print("temp3 : " + str(temp3))

    #저장에는 tf.train.Saver 를 사용한다
    saver = tf.train.Saver()

    # 실제 메모리와 코어를 사용할 세션을 생성
    with tf.Session() as sess:
        #
        saver.restore(sess, "/tmp/model.ckpt")
        print("Model restored.")

        # 값을 찍어 보면 탠소 플로우 베리어블 객체의 내용을 확인 가능
        # 더하기 연산 수행과 그 결과
        result2 = sess.run(temp3)
        print("result2 : " + str(result2))

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

 

스크린샷, 2016-08-28 08-58-30

Python – postgresql – Django – REST – TensorFlow 서비스 개발(3)

가. 지금까지 완료 된 것

– 1부 링크  : http://wp.me/p7xrpI-9h
– 2부 링크 :  http://wp.me/p7xrpI-9G

– Anaconda 설치
– TensorFlow 설치
– Pycharm 설치
– postgresql 설치
– Django 설치
– Django Service 생성
– snippets APP 생성 완료
– Snippet Model 생성
– postgresql  동기화 완료
– Serializer 생성 , REST API  생성 & TEST
– Class Based REST API

나. 이제 하려고 하는것

– REST 요청을 통해서 동적 Network Configuration 생성 (4부)
– REST 요청을 통해서 Training 기동 (기본 예제 사용)
– Trainging 결과를 Tensorflow Serving 을 통해서 DB 저장
– REST 요청을 통해서 Training 된 결과(모델 구조, 학습결과) 조회 (4부)
– REST 요청을 통해서 TensorFlow Serving 기동 저장된 결과를 읽어서 모델을 구성하고
요청된 결과에 대한 예측을 수행하여 리턴

다. Rest  –  TensorFlow  예제 호출

단순히 REST호출을 통해서 TensorFlow 가 정상적으로 동작하는지 확인

[urls.py]

스크린샷, 2016-08-28 06-06-52

[views.py]

스크린샷, 2016-08-28 06-09-34

[tensor_test.py]

스크린샷, 2016-08-28 06-07-17

[테스트 결과 – 서버]

스크린샷, 2016-08-28 06-11-06

[테스트 결과 – 클라이언트]

스크린샷, 2016-08-28 06-08-09

라. Rest  – Iris  예제 학습 및 저장

간단히 REST호출을 통해서 TensorFlow DNN 을 학습하고 그 결과를 파일로 저장

[urls.py]

스크린샷, 2016-08-28 23-21-46

[views.py]

스크린샷, 2016-08-28 23-22-11

[tensor_test.py]

스크린샷, 2016-08-28 22-47-11

[테스트]

스크린샷, 2016-08-28 23-23-33

마. Rest  – Iris  학습 모델 로드 및 예측

이전에 학습한 모델을 복구해서 별도의 학습없이 테스트 케이스에 대해
예측만 실행하여 리턴 테스트

[tensor_test.py]측

스크린샷, 2016-08-28 23-21-17

[테스트]

스크린샷, 2016-08-28 23-23-03

[환경 설정] Anaconda-PyCharm-TensorFlow

[참조 사이트]
https://www.tensorflow.org/versions/r0.10/get_started/os_setup.html#download-and-setup
http://yeramee.tistory.com/1

어짜피 GPU 는 없는 관계로  CPU 버전으로 심플하게 설치

가. Anaconda 설치

[설치 파일 다운로드]
– 다운로드 :  https://www.continuum.io/downloads

wget https://repo.continuum.io/archive/Anaconda2-4.1.1-Linux-x86_64.sh

 

[설치 및 설정]
아래와 같이

bash /home/user/Downloads/Anaconda2-4.1.1-Linux-x86_64.sh
vi ~/.bashrc
export PATH="$HOME/anaconda2/bin;$PATH"
$ python
Python 2.7.12 |Anaconda 4.1.1 (64-bit)

[Trouble Shooting]
– 기 설치된 python 과 충돌하는 경우 해결방안
– .bashrc 에 추가 : source ~/anaconda2/bin/activate ~/anaconda2/
* 이 방법이 최선인지는 잘 모르겠음, 우선 문제는 해결

나. TensorFlow 설치

아래의 두 가지 방법중 어떤 것으로 설치하여도 상관 없다

[Using PIP]

https://www.tensorflow.org/versions/r0.10/get_started/os_setup.html#download-and-setup 에서 참조하여 자신의 OS 및 파이썬 버전에 맞는 경로를 세팅할 수 있도록 한다.

# Ubuntu/Linux 64-bit, CPU only, Python 2.7 $ export TF_BINARY_URL=https://storage.googleapis.com/tensorflow/linux/cpu/tensorflow-0.10.0rc0-cp27-none-linux_x86_64.whl
# Python 2 
$ source activate tensorflow
$ pip install --ignore-installed --upgrade $TF_BINARY_UR

[Using Conda]

$ conda create -n tensorflow python=2.7
$ source activate tensorflow
$ conda install -c conda-forge tensorflow
다.  pyCharm 설치

[다운로드]
-다 운로드 : https://www.jetbrains.com/pycharm/download/#section=linux

wget https://download.jetbrains.com/python/pycharm-community-2016.2.3.tar.gz

[설치 및 실행]

tar xvzf /home/user/Downloads/pycharm-community-2016.2.1.tar.gz pyc
bash /home/user/Downloads/pyc/bin/pycharm.sh

[Interpreator 설정]

File >> Settings >> Project >> ProjectInterpreator 
root/anaconda2/bin/python 으로 설정

[TEST]

https://github.com/aymericdamien/TensorFlow-Examples

아무 소스코드나 복사하여 실행하여 테스트

스크린샷, 2016-08-18 22-35-31