본문 바로가기
Python_Tensorflow

[Python Tensorflow] tensorflow GetStarted 정리

by 신입같은 3년차 2018. 6. 11.
728x90
Tensorflow를 학습하면서 TensorFlow공식 홈페이지에 있는 GetStarted의 iris에 대한 예제를 진행하면서 정리해봤습니다.

저도 학습하는 입장에서 정확하지 않을수도 있습니다. 잘못된부분에 대해서는 지적 부탁드리며 예제는 이미 tensorflow에 나와있습니다.

어느정도 공부하는대로 주석을 한글로 달아서 올렸습니다. 화이팅하세요


# -*- coding:utf-8 -*-
from __future__ import absolute_import, division, print_function

import os
import matplotlib.pyplot as plt

import tensorflow as tf
import tensorflow.contrib.eager as tfe

tf.enable_eager_execution()

# iris_training.csv를 다운받을수 있는 download 경로
train_dataset_url = "http://download.tensorflow.org/data/iris_training.csv"

train_dataset_fp = tf.keras.utils.get_file(fname=os.path.basename(train_dataset_url),
                                           origin=train_dataset_url)

print("Local copy of the dataset file: {}".format(train_dataset_fp))

def parse_csv(line):
  example_defaults = [[0.], [0.], [0.], [0.], [0]]  # sets field types
  parsed_line = tf.decode_csv(line, example_defaults)

  # 첫번째 column ~ 네번째 column은 분류에 필요한 데이터 features
  features = tf.reshape(parsed_line[:-1], shape=(4,))

  # 마지막 column은 데이터를 분류하기위한 라벨에 대한 데이터.
  label = tf.reshape(parsed_line[-1], shape=())

  return features, label


def loss ( model , x , y) :
    y_ = model(x)
    return tf.losses.sparse_softmax_cross_entropy(labels=y , logits=y_)

def grad(model, inputs, targets):
  with tf.GradientTape() as tape:
    loss_value = loss(model, inputs, targets)
  return tape.gradient(loss_value, model.variables)


train_dataset = tf.data.TextLineDataset(train_dataset_fp)

# CSV의 첫번째 row 는 데이터의수 , 라벨링의수 , 각 라벨링 Name으로 이루어져 있어 첫번째 header, 즉 1번 row 를 날린다.
train_dataset = train_dataset.skip(1)             # skip the first header row

# train_dataset의 각각의 row에대해 parse_csv실행.
train_dataset = train_dataset.map(parse_csv)

# train_dataset을 shuufle을 통해 섞어준다 .
train_dataset = train_dataset.shuffle(buffer_size=1000)

# train_dataset을 32개씩 batch를 돌린다.
train_dataset = train_dataset.batch(32)


features , label = iter(train_dataset).next()
print("example features:", features[0])
print("example label:", label[0])


# Node가 10개인 두개의 Dense와 레이블 예측을 나타내는 Node가 3개인 출력 레이어를 말하며 선형 스택이기 때문에 위에서부터 아래로 수행.
# 첫번째 Dense의 input_shape는 분류할 데이터의 사이즈
# 마지막 Dense의 3은 Label의 갯수를 의미.
model = tf.keras.Sequential([
    tf.keras.layers.Dense(10 , activation="relu" , input_shape=(4,)),
    tf.keras.layers.Dense(10 , activation="relu"),
    tf.keras.layers.Dense(3)
])


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

# keep results for plotting
train_loss_results = []
train_accuracy_results = []

num_epochs = 201

for epoch in range(num_epochs):
    epoch_loss_avg = tfe.metrics.Mean()
    epoch_accuracy = tfe.metrics.Accuracy()

    # Training loop - using batches of 32
    for x, y in train_dataset:
        # Optimize the model
        grads = grad(model, x, y)
        optimizer.apply_gradients(zip(grads, model.variables),
                                  global_step=tf.train.get_or_create_global_step())

        # Track progress
        epoch_loss_avg(loss(model, x, y))  # add current batch loss
        # compare predicted label to actual label
        epoch_accuracy(tf.argmax(model(x), axis=1, output_type=tf.int32), y)

    # end epoch
    train_loss_results.append(epoch_loss_avg.result())
    train_accuracy_results.append(epoch_accuracy.result())

# 50개 마다 print
    if epoch % 50 == 0:
        print("Epoch {:03d}: Loss: {:.3f}, Accuracy: {:.3%}".format(epoch,
                                                                    epoch_loss_avg.result(),
                                                                    epoch_accuracy.result()))


fig, axes = plt.subplots(2, sharex=True, figsize=(12, 8))
fig.suptitle('Training Metrics')

axes[0].set_ylabel("Loss", fontsize=14)
axes[0].plot(train_loss_results)

axes[1].set_ylabel("Accuracy", fontsize=14)
axes[1].set_xlabel("Epoch", fontsize=14)
axes[1].plot(train_accuracy_results)

plt.show()

# iris_test.csv를 다운받기위한 test_url
test_url = "http://download.tensorflow.org/data/iris_test.csv"

# iris_test.csv 다운.
test_fp = tf.keras.utils.get_file(fname=os.path.basename(test_url),
                                  origin=test_url)

# 위와 동일 . 다만 iris_test_data일뿐.
test_dataset = tf.data.TextLineDataset(test_fp)
test_dataset = test_dataset.skip(1)             # skip header row
test_dataset = test_dataset.map(parse_csv)      # parse each row with the funcition created earlier
test_dataset = test_dataset.shuffle(1000)       # randomize
test_dataset = test_dataset.batch(32)

test_accuracy = tfe.metrics.Accuracy()

for (x, y) in test_dataset:
  prediction = tf.argmax(model(x), axis=1, output_type=tf.int32)
  test_accuracy(prediction, y)

print("Test set accuracy: {:.3%}".format(test_accuracy.result()))


# 각각의 Label에 대한 분류
class_ids = ["Iris setosa", "Iris versicolor", "Iris virginica"]

# 일반 배열을 Tensor로 변경
predict_dataset = tf.convert_to_tensor([
    [5.1, 3.3, 1.7, 0.5,],
    [5.9, 3.0, 4.2, 1.5,],
    [6.9, 3.1, 5.4, 2.1]
])

predictions = model(predict_dataset)

for i, logits in enumerate(predictions):

    # tensor 타입의 결과물을 다시 일반 정수 타입으로 변환.
    class_idx = tf.argmax(logits).numpy()
    name = class_ids[class_idx]
    print("Example {} prediction: {}".format(i, name))




728x90
반응형

댓글