ABOUT ME

-

  • Fancy Softmax classification
    Application programming/TensorFlow 2020. 6. 6. 15:32
    <Fancy Softmax classification>
    
    import tensorflow as tf
    import numpy as np
    
    # Predicting animal type based on various features
    xy = np.loadtxt('data-04-zoo.csv', delimiter=',', dtype=np.float32)
    # 모든 행과 마지막 행을 뺀 2차원 배열이 x의 값
    x_data = xy[:, 0:-1]
    # 모든 행과 마지막 행을 가진 배열이 y의 값
    y_data = xy[:, [-1]]
    
    # y의 종류 갯수 (동물의 개채종 숫자)
    nb_classes = 7  # 0 ~ 6
    
    # x의 속성값들. (다리의 갯수나 알을 낳는지 등등의 16개 속성값)
    X = tf.placeholder(tf.float32, [None, 16])
    # y의 속성값. (무슨 종이냐라는 속성값 하나밖에 존재하지 않음으로 1)
    Y = tf.placeholder(tf.int32, [None, 1])  # 0 ~ 6
    
    # one_hot 이 아니기에 최대값만 1로 설정해주고 나머지는 0으로 만드는 one_hot 으로 변환
    # Y(0에서 6까지의 수)를 넣고, 데이터들이 몇개의 클래스 인지(종의 숫자)를 알려줘야 함.
    Y_one_hot = tf.one_hot(Y, nb_classes)  # one hot
    # one_hot 으로 바꿨을 때 배열에 한차원이 추가되기 때문에 차원을 다시 하나 줄여주는 기능
    # one_hot rank N을 변환시키면 rank 가 N + 1이 되어버림. 예를들어
    # [[0], [3]] 을 변환시키면 [[[1000000]], [[0001000]]] 이렇게 대괄호가 추가되어 아웃풋  
      됨.
    # reshape 에 one_hot 결과물을 집어 넣고 행은 '-1' 즉 알아서 하고 열은 7인 2차원 배열로  
      만들어 달라고 요구
    Y_one_hot = tf.reshape(Y_one_hot, [-1, nb_classes])
    
    # W는 x에 곱해지는 값이기 때문에 x의 열이 16이니 W의 행이 16, 거기에 무슨 종인지 대입해봐야
      하기 때문에 종의 갯수 열)
    W = tf.Variable(tf.random_normal([16, nb_classes]), name='weight')
    # Y에 더해지는 값. W와 x의 곱이 [None, nb_classes]이기 때문에 그 결과의 열에 더해질 랜덤의
      값들이 때문에 1차원 배열이며 크기는 nb_classes 인 배열로 선언하고 랜덤값 집어넣음.
    b = tf.Variable(tf.random_normal([nb_classes]), name='bias')
    
    # tf.nn.softmax computes softmax activations
    # softmax = exp(logits) / reduce_sum(exp(logits), dim)
    # 기본적인 로짓 선언 초기화
    logits = tf.matmul(X, W) + b
    # 시그모이드가 아닌 softmax 를 사용
    hypothesis = tf.nn.softmax(logits)
    
    # Cross entropy cost/loss
    # cost = tf.reduce_mean(-tf.reduce_sum(Y * tf.log(hypothesis), axis=1))
    # optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.1).minimize(cost)
    # 위에 있는 기존의 Softmax 식 처럼 복잡했던 식을 문자만으로 간단하게 표현하기 위한 식.
    
    # 코스트를 계산하기 위해 one_hot 을 적용한 Y 데이터와 로짓을 넣어줌.
    cost_i = tf.nn.softmax_cross_entropy_with_logits(logits=logits, labels=Y_one_hot)
    # 위의 코스트들을 평균내고 최종적인 코스트를 완성함.
    cost = tf.reduce_mean(cost_i)
    # 옵티마이저에게 그래디센을 이용하여 cost 를 최소화 하라고 명령.
    optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.1).minimize(cost)
    
    # 우리가 예측한 값. 예측한 값(확률)을 argmax 를 이용하여 0에서 6 사이의 값으로 만들어 줌
    prediction = tf.argmax(hypothesis, 1)
    # 실제의 값과 비교하는 연산.
    correct_prediction = tf.equal(prediction, tf.argmax(Y_one_hot, 1))
    # 맞게 예측을 한 것들을 모아서 평균을 내 accuracy 에 넣어 줌.
    accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
    # Launch graph
    with tf.Session() as sess:
        sess.run(tf.global_variables_initializer())
    
        for step in range(2000):
            # 옵티마이저에 x_y_data 를 넣어서 러닝을 시킴.
            sess.run(optimizer, feed_dict={X: x_data, Y: y_data})
            if step % 100 == 0:
                loss, acc = sess.run([cost, accuracy], feed_dict={X: x_data, Y: y_data})
                print("Step: {:5}\tLoss: {:.3f}\tAcc: {:.2%}".format(step, loss, acc))
    
        # Let's see if we can predict
        pred = sess.run(prediction, feed_dict={X: x_data})
        # y_data: (N,1) = flatten => (N, ) matches pred.shape
        # flatten 이란 y의 값이 [[1],[0]]일때 [1, 0] 처럼 바꾸어 주는 기능.
        # zip 이란 pred, y_data.flatten() 가 리스트이기 때문에 각각의 엘리먼트를 p와 y에
          넘겨주기 편하게 하기 위해서 씀.
        for p, y in zip(pred, y_data.flatten()):
            print("[{}] Prediction: {} True Y: {}".format(p == int(y), p, int(y)))

    'Application programming > TensorFlow' 카테고리의 다른 글

    MNIST  (0) 2020.06.06
    Softmax classification  (0) 2020.06.06
    Logistic Regression  (0) 2020.06.06
    Multi variable input & Load data  (0) 2020.06.06

    댓글

Designed by Tistory.