Artificial Intelligence/Deep Learning

텐서플로우(TensorFlow) (+Keras)

DaTALK 2021. 12. 7.

1. 서론

** 텐서플로우

= 유연하고, 효율적이며, 확장성 있는 딥러닝 프레임워크
(가장 많이 쓰이는 딥러닝 프레임워크 '텐서플로우' & '파이토치')

- 대형 클러스터 컴퓨터부터 스마트폰까지 다양한 디바이스에서 동작 가능

 

* 텐서플로우로 딥러닝 모델 구현

1) 데이터 전 처리하기

2) 딥러닝 모델 구축하기

3) 모델 학습시키기

4) 평가 및 예측

 

2. 데이터 전처리

* tensorflow 딥러닝 모델은 tensor 형태의 데이터를 입력 받음 (데이터 전처리의 필요성)

* tensor란 다차원 배열로서 tensorflow에서 사용하는 객체

(1차원은 vector / 2차원은 matrix / 3차원 이상은 tensor)

 

* 즉, 모든 데이터(pandas나 numpy로 정리된)를 tensor 형태의 데이터로 변환해 주어야 tensorflow 딥러닝 모델에 사용 가능하다

(사실 전처리 없이 바로 딥러닝 모델에 입력이 가능하나 모델 자체 내에서 전처리가 이루어짐)

 

[1] 실습

* 지도학습 관련 - 먼저 data를 feature data & label data로 나눈다.

 

* tf.data.Dataset

- tesnsor 형태로 데이터 변환

- from_tensor_slices의 파라미터로 feature와 label이 배열 형태로 들어가야 함수가 작동된다.
(dataframe이나 series 형태가 아님)

- .values의 리스트 형태로 들어가야 함

 

df = pd.read_csv('data.csv')
feature = df.drop(columns=['label'])
label = df['label']

dataset = tf.data.Dataset.from_tensor_slices((feature.values, label.values))

 

* Dataset API를 사용하여 딥러닝 모델용 Dataset 생성

 

{1} Epoch & Batch

* 딥러닝에 사용하는 데이터는 추가적인 전처리 작업 필요 (Epoch & Batch)

 

 

* Epoch = 한 번의 epoch는 전체 dataset에 대해 한 번 학습을 완료한 상태

* Batch = 나눠진 dataset (보통 mini-batch라고 표현)

- 딥러닝 학습에서 무수히 많은 w 가중치를 업데이트 해야 한다

- 따라서 데이터의 부담을 덜기 위해 1 Epoch를 넣는 것이 아니라 1 batch, 2 batch 등등 각각 넣어서 업데이트 (계산 load 부담 감소)

* Iteration = epoch를 나누어서 실행하는 횟수

 

ex) 총 데이터가 1000개이고 batch size가 100이라면

- 1 iteration은 100개 데이터에 대해서 학습을 뜻한다

- 1 epoch = 1000/(batch size) = 10 iteration

 

* batch() 안에 원하는 batch size를 설정한다
- 즉, 예를 들어 320개의 data가 있다면 총 10개의 batch가 만들어짐 (batch(32)일 경우)

 

dataset = dataset.batch(32)

 

{2} 예시 - 실습 코드

* 필요한 부분 import

 

import tensorflow as tf
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split

 

* 데이터를 가져오고 전처리

- 의미 없는 column 삭제

- label & feature로 나누어서 각각 X & Y에 저장

- train_test_split() 활용하여 훈련 & 테스트용 데이터로 분리

 

df = pd.read_csv("data.csv")

X = #part of df - feature data
Y = #part of df - label data

train_X, test_X, train_Y, test_Y = train_test_split(X, Y, test_size=0.3)

 

* 학습용 데이터(train data)를 이제 텐서플로우 모델에 입력하기 위해 tensor 형태로 변환한다.

 

train_ds = tf.data.Dataset.from_tensor_slices((train_X_data.values, train_Y_data.values))

 

* 학습용 데이터 - feature 데이터를 먼저 랜덤으로 셔플(shuffle method)하고 난 뒤, batch 메서드를 활용하여 해당 설정한 크기로 batch를 수행한다.

 

train_ds = train_ds.shuffle(len(train_X_data)).batch(batch_size=5)

 

* take 메서드를 사용하면 batch로 분리된 데이터를 뽑아서 확인 가능하다. (feature & label로 나누어서)

- take(n): n개의 batch를 선택

 

[(train_features_batch, label_batch)] = train_ds.take(1)

 

3. 모델 구현

[1] Keras

* 텐서플로우의 패키지로 제공되는 고수준 API

* 딥러닝 모델을 간단하고 빠르게 구현이 가능하다

- keras를 통해서 매우 쉽게 모델 구축이 가능하다.

{1} 여러 Keras 메소드 - 모델 생성

* 모델 클래스 객체 생성

- 딥러닝 객체를 선언

 

tf.keras.models.Sequential()

 

* 모델의 각 layer 구성

- units: 레이어 안의 node 수

(즉, Dense()를 적용함으로써 여러 퍼셉트론이 한꺼번에 생성이 됨)

- activation: 적용할 activaiton 함수 설정 (예: 시그모이드, ReLU 등등)

 

tf.keras.layers.Dense(units, activation)

 

* Input Layer 입력 형태 지정

- 입력 형태에 대한 정보를 필요로 한다

- input_shape / input_dim 인자 설정하기

 

예) (하단) 입력이 2개, 출력이 1개인 모델

 

model = tf.keras.models.Sequential([

# -- input layer --
tf.keras.layers.Dense(10, input_dim = 2, activation = 'sigmoid'), #2 inputs & 10 nodes
# or
tf.keras.layers.Dense(10, input_shape = (2,), activation = 'sigmoid'), #2 inputs & 10 nodes

# -- second layer --
tf.keras.layers.Dense(10, activation = 'sigmoid'), # 10 nodes

# -- last layer -- 
tf.keras.layers.Dense(1, activation='sigmoid') # 1 node
])

model.summary()

 

* 모델에 layer 추가하기

 

[model].add(tf.keras.layers.Dense(units, activation))

 

- model 빈 객체를 추가한 뒤, add 메서드를 계속 붙이면서 layer를 계속 만들어 나가는 방식

 

model = tf.keras.models.Sequential()

model.add(tf.keras.layers.Dense(10, input_dim=2, activation='sigmoid'))
model.add(tf.keras.layers.Dense(10, activation='sigmoid'))
model.add(tf.kears.layers.Dense(1, activation='sigmoid'))

 

{2} 여러 Keras 메소드 - 모델 학습

* 모델 학습방식을 설정하기 위한 함수

- optimizer: 모델 학습 최적화 방법 (gradient외 SGD, momentum, Adam 등등)

- loss: 손실 함수 설정 (대표적인 회귀 MSE / 분류에서는 Cross Entropy 자주 사용)

- (if any) metrics: epoch마다 계산되는 평가 지표

 

[model].compile(optimizer, loss, metrics)

 

* 모델을 학습시키기 위한 함수

- x) feature 데이터

- y) label 데이터

- or tensor 형태의 dataset을 () 안에 그대로 넣어줘도 됨

- (if any) verbose = 학습 시, 화면에 출력되는 형태를 설정
(0: 표기 없음, 1: 진행 바, 2: epoch당 한 줄 출력)

- epcohs = 100으로 100개만큼 학습 설정

 

[model].fit(x,y,epochs,verbose)

 

* 예시

- MSE를 loss로 설정 (회귀), 최적화 방식은 'SGD(Stocastic Gradient Descent)'

- accuracy 정확도 기반 측정

- verbose: epoch당 한 줄 출력하는 방식으로 설정

- 100번 epoch 학습 주기 설정

 

mode.compile(loss='mean_squared_error', optimizer='SGD', metrics=['accuracy'])
model.fit(dataset, epochs=100, verbose=2)

 

{3} 여러 Keras 메소드 - 평가 및 예측

* 모델 평가 (test data 이용)

- evaluate 함수 사용

- x는 feature data / y는 label data

 

[model].evaluate(x,y)

 

* 모델의 예측을 수행하기 위한 함수 (test data 이용)

- predict 함수 사용

- x는 예측하고자 하는 데이터

 

[model].predict(x)

 

* 예시 - 평가 및 예측

 

loss, acc = model.evaluate(X_test, Y_test) #if metrics=['accuracy']
predicted_labels_test = model.predict(X_test)

#compare Y_test.iloc[i] & predicted_labels_test[i][0]

 

4. (실습) '신경망 모델로 붓꽃의 종류를 분류하기'

[1] 주어진 dataset & 개요

* Iris 데이터가 주어졌을 때 붓꽃의 종류를 분류하는 신경망 모델을 구현한다.

* Iris 데이터는 꽃받침 길이, 꽃받침 넓이, 꽃잎 길이, 꽃잎 넓이 4가지 변수 & 3종류의 붓꽃 클래스로 구성되어 있다.

 

 

[2] 모델 구현 위한 데이터 전처리

* 먼저 필요한 부분 import를 한다.

* sklearn에 저장된 데이터를 불러온다 (X feature, Y label)

* 불러온 데이터를 dataframe으로 변환하고 feature는 X와 Y에 각각 feature와 label을 저장한다

* train_test_split를 사용해서 train data & test data로 분리한다. (test size는 20%, random state는 42로 설정)

* 마지막으로 모델의 input으로 넣기 위해 tensor 형태로 변환한다.

 

import tensorflow as tf
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.datasets import load_iris

np.random.seed(100)
tf.random.set_seed(100)

X, Y = load_iris(return_X_y = True)

df = pd.DataFrame(X, columns=['꽃받침 길이','꽃받침 넓이', '꽃잎 길이', '꽃잎 넓이'])
df['클래스'] = Y

X = df.drop(columns=['클래스'])
Y = df['클래스']

train_X, test_X, train_Y, test_Y = train_test_split(X, Y, test_size=0.2, random_state = 42)

train_ds = tf.data.Dataset.from_tensor_slices((train_X.values, train_Y))
train_ds = train_ds.shuffle(len(train_X)).batch(batch_size=5)

 

[3] 신경망 모델 구축

* 단층 신경망으로 입력과 출력층만 존재하는 모델을 구축한다.

* 10개의 node & 4개의 feature (총 네 개의 특징이므로) & 그리고 출력층은 3가지의 label로 출력되므로 3개의 node로 구성한다.

* 출력층의 활성함수 종류는 'softmax'

 

model = tf.keras.models.Sequential([
    tf.keras.layers.Dense(), #10 nodes, input_dimension is 4
    tf.keras.layers.Dense() #3 labels, activation function is 'softmax'
    ])

 

[4] 모델의 학습 수행 및 평가, 예측

* 분류에서는 loss함수로 주로 sparse_categorical_crossentropy를 많이 사용한다

* adam optimizer를 사용하며, 측정지표는 accruacy

* 학습 시 총 100번의 epochs & verbose = 2로 매 epoch당의 진행 결과 화면에 출력 방식

 

* evaluate() & predict()를 통해 평가 & 예측을 진행한다.

 

model.compile(loss='sparse_categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
history = model.fit(train_ds, epochs=100, verbose=2)

loss, acc = model.evaluate(test_X, test_Y)

predictions = model.predict(test_X)

 

* 결과를 출력한다.

- test data의 정확도 값 출력: acc

- 일부 5개만 추출하여 실제값과 예측값을 각각 뽑아 서로 동일한지 비교해본다.

(test_Y.iloc[i] & np.argmax(predictions[i]))

 

print("테스트 데이터의 Accuracy 값: ", acc)
for i in range(5):
    print("%d 번째 테스트 데이터의 실제값: %d" % (i, test_Y.iloc[i]))
    print("%d 번째 테스트 데이터의 예측값: %d" % (i, np.argmax(predictions[i])))

 

* 결과 (더보기 열기)

 

더보기
더보기

테스트 데이터의 Accuracy 값: 1.0

 

0 번째 테스트 데이터의 실제값: 1

0 번째 테스트 데이터의 예측값: 1

1 번째 테스트 데이터의 실제값: 0

1 번째 테스트 데이터의 예측값: 0

2 번째 테스트 데이터의 실제값: 2

2 번째 테스트 데이터의 예측값: 2

3 번째 테스트 데이터의 실제값: 1

3 번째 테스트 데이터의 예측값: 1

4 번째 테스트 데이터의 실제값: 1

4 번째 테스트 데이터의 예측값: 1

 

- 정확도는 1.0으로 100%의 정확도를 보였으며

- 총 5개의 test data를 통해 예측한 값이 실제값과 완전 동일함을 알 수 있다.

 

 

 

 

 

 

- 출처 - 2021 NIPA/AI 기본/응용 교육과정

댓글