본문 바로가기

기술부터 가치까지

3. TensorFlow — 제주 머신러닝 스터디 그룹 & 머신러닝 야학

제주에서 머신러닝 스터디 그룹을 만들어 머신러닝 야학에 참여합니다!

해당 게시물은 머신러닝 스터디 그룹의 과제인 강의 요약 블로깅입니다.

대부분의 멘트는 머신러닝 야학에서 가져온 것임을 밝힙니다.

생활코딩은 동의 없이 수정, 배포를 허락하고 있습니다.

해당 강의는 생활코딩 유튜브에서도 무료로 시청하실 수 있습니다.

지도학습

이번 과정에서는 지도학습을 다뤄볼텐데요. 지도학습에 회귀(Regression)는 데이터가 숫자형일 경우, 분류(Classfication)는 범주형일 경우 사용합니다.

머신러닝에 주어진 문제를 해결하는 해결법을 머신러닝 알고리즘이라고 하고 유명한 것으로는 다음과 같습니다. 요리사의 요리법같은 것이죠!

- Decision Tree

- Random Forest

- KNN

- SVN

- Neural Network

이 중 생활코딩의 머신러닝 야학에서 사용하는 알고리즘은 Neural Network입니다. 두뇌를 모방하는 알고리즘이죠! 인공신경망이라고도 불리고, Deep learning으로도 불립니다.

인공지능 > 기계학습 > 딥러닝

같은 단어처럼 사용되지만 위 3개 단어는 구분되어져야 합니다. 가장 큰 범위는 인공지능이고, 가장 작은 범위는 딥러닝입니다.

- TensorFlow

- PyTorch

- Caffe2

- theano

위와 같은 여러 머신러닝과 관련된 라이브러리가 있습니다. 이중에서도 우리는 TensorFlow를 사용하도록 하겠습니다!

1. 과거의 데이터를 준비(원인, 결과 관계 파악하기)

2. 모델의 구조를 만듭니다.

3. 데이터로 모델을 학습(FIT)합니다. 다른 말로는 학습한다고 합니다.

4. 모델을 이용합니다. 새로운 데이터를 가지고 예측(Predict)합니다.

사용환경은 Colab을 사용합니다. 아래 영상에서 Colab 사용법을 익혀보세요.

회귀(Regression)

# 라이브러리 사용
import pandas as pd
### Alt + Enter ###
# 파일로부터 데이터 읽어오기
파일경로 = 'https://raw.githubusercontent.com/blackdew/tensorflow1/master/csv/lemonade.csv'
레모네이드 = pd.read_csv(파일경로)
파일경로 = 'https://raw.githubusercontent.com/blackdew/tensorflow1/master/csv/boston.csv'
보스턴 = pd.read_csv(파일경로)
파일경로 = 'https://raw.githubusercontent.com/blackdew/tensorflow1/master/csv/iris.csv'
아이리스 = pd.read_csv(파일경로)
### Alt + Enter ###
# 데이터의 모양확인
print(레모네이드.shape)
print(보스턴.shape)
print(아이리스.shape)
### Alt + Enter ###
# 데이터 칼럼이름 확인
print(레모네이드.columns)
print(보스턴.columns)
print(아이리스.columns)
### Alt + Enter ###
# 독립변수와 종속변수 분리
독립 = 레모네이드[['온도']]
종속 = 레모네이드[['판매량']]
print(독립.shape, 종속.shape)
### Alt + Enter ###
독립 = 보스턴[['crim', 'zn', 'indus', 'chas', 'nox',
             'rm', 'age', 'dis', 'rad', 'tax',
             'ptratio', 'b', 'lstat']]
종속 = 보스턴[['medv']]
print(독립.shape, 종속.shape)
### Alt + Enter ###
독립 = 아이리스[['꽃잎길이', '꽃잎폭', '꽃받침길이', '꽃받침폭']]
종속 = 아이리스[['품종']]
print(독립.shape, 종속.shape)
### Alt + Enter ###
# 각각의 데이터 확인해보기
print(레모네이드.head())
print(보스턴.head())
print(아이리스.head())

우선 위 코드를 colab에 입력하고 각 라인이 내려올 때마다 Alt + Enter를 눌러주세요.

각각의 파일 경로로 가시면 다른 데이터를 엑셀처럼 표 형태로 볼 수 있습니다. 물론, 보고 싶은 변수명을 아래처럼 그대로 적어주시고 Ctrl + Enter를 눌러주시면 표 형태로 볼 수 있어요. 앞에 print 안넣어 주셔도 됩니다.

### Ctrl + Enter ###
레모네이드

 

앞선 4개의 파트로 나누어 아래 내용을 실습해보도록 하겠습니다.

 

### Alt + Enter ###
# 라이브러리 사용
import tensorflow as tf
import pandas as pd

### Alt + Enter ###
# 1. 데이터를 준비합니다.
파일경로 = 'https://raw.githubusercontent.com/blackdew/tensorflow1/master/csv/lemonade.csv'
레모네이드 = pd.read_csv(파일경로)
레모네이드.head()
 
### Alt + Enter ###
# 종속변수, 독립변수
독립 = 레모네이드[['온도']]
종속 = 레모네이드[['판매량']]
print(독립.shape, 종속.shape)

### Alt + Enter ###
# 2. 모델을 만듭니다.
X = tf.keras.layers.Input(shape=[1])
Y = tf.keras.layers.Dense(1)(X)
model = tf.keras.models.Model(X, Y)
model.compile(loss='mse')

### Alt + Enter ###
# 3. 모델을 학습시킵니다.
model.fit(독립, 종속, epochs=1000, verbose=0) #출력하지 않겠다는 표시
model.fit(독립, 종속, epochs=10)

### Alt + Enter ###
# 4. 모델을 이용합니다.
print(model.predict(독립))
print(model.predict([[15]]))

앞서 해본 것처럼 위 코드를 colab에 입력하고 각 라인이 내려올 때마다 Alt + Enter를 눌러주세요. 타이핑이 능숙치 않으셔도, 복사하지 마시고 한 번 직접 해보시길 권해드립니다.

Tensorflow 1–7. 레모네이드 판매 예측

 

여기서 각각 독립변수와 종속변수가 어디에 들어가는지 꼭 기억해두세요. 독립변수가 3개일 때에는 shape가 [3]이 됩니다. 이렇게 사용하면, 어떤 코드에든 적용할 수 있습니다!

epochs, 에포크라고 읽습니다. 학습을 몇 번 반복할 것인지에 대한 것입니다. 숫자가 너무 크면 학습이 느리니 적당하게 학습을 시켜봅시다. 학습을 시킬 때마다 loss의 지표는 0에 가까워 집니다.

Tensorflow 1–8. 손실의 의미

 

0에 가까워진다는 것은 모델의 예측 결과와 실제 종속변수와의 차이가 거의 없다는 것입니다! loss가 원하는 수준까지 반복해서 학습을 시켜야 합니다.

median value는 중앙값입니다. 평균을 대푯값으로 쓰기 적절치 않은 곳이 있는데요. 대표적으로 연봉입니다. 연봉은 임금이 높은 사람들이 평균을 너무 많이 끌어올려서, 전체 분포로 보았을 때 소수만 가지고 있는 값이지만(이상치) 그러한 값들로 인해 전체 평균이 분포의 중앙에 위치하지는 못하는 상황이 발생됩니다. 이럴 때 사용하는 값이 중앙값입니다.

아래 데이터는 보스톤 집 값의 통계표입니다. 맨 오른쪽 컬럼은 중앙값이에요.

Tensorflow 1–10. 보스턴집값예측, 예측 전 중앙값 식

 

Tensorflow 1–10. 보스턴집값예측, 예측 후 중앙값 식

 

자, 이제 TensorFlow를 사용하여 집값을 예측해봅시다!

### Alt + Enter ###
# 라이브러리 사용
import tensorflow as tf
import pandas as pd

### Alt + Enter ###
# 1.과거의 데이터를 준비합니다.
파일경로 = 'https://raw.githubusercontent.com/blackdew/tensorflow1/master/csv/boston.csv'
보스턴 = pd.read_csv(파일경로)
print(보스턴.columns)
보스턴.head()

### Alt + Enter ###
# 독립변수, 종속변수 분리
독립 = 보스턴[['crim', 'zn', 'indus', 'chas', 'nox', 'rm', 'age', 
             'dis', 'rad', 'tax',
             'ptratio', 'b', 'lstat']]
종속 = 보스턴[['medv']]
print(독립.shape, 종속.shape)

### Alt + Enter ###
# 2. 모델의 구조를 만듭니다
X = tf.keras.layers.Input(shape=[13])
Y = tf.keras.layers.Dense(1)(X)
model = tf.keras.models.Model(X, Y)
model.compile(loss='mse')

### Alt + Enter ###
# 3.데이터로 모델을 학습(FIT)합니다.
model.fit(독립, 종속, epochs=1000, verbose=0)
model.fit(독립, 종속, epochs=10)

### Alt + Enter ###
# 4. 모델을 이용합니다
print(model.predict(독립[5:10]))
# 종속변수 확인
print(종속[5:10])

### Alt + Enter ###
# 모델의 수식 확인
print(model.get_weights())

여기서 3번 절차, 모델의 구조를 만드는 과정을 좀 더 살펴보도록 하겠습니다.

Tensorflow 1–11. 수식과 퍼셉트론

 

Tensorflow 1–11. 수식과 퍼셉트론

 

이 4줄의 코드가 바로 가중치(Weight)편향(Bias)을 구하는 식입니다! 매우 중요한 개념이니 꼭 기억해주세요.

딥러닝 워크북입니다. 딥러닝이 실제로 어떻게 학습하는지 엑셀로 풀어쓴 것입니다.

https://bit.ly/2DEBlPd

사용방법도 있으니 꼭 실습을 해보시길 바랍니다! :)

분류(Classification)

Tensorflow 1–14. 아이리스 품종 분류

 

이번에는 아이리스 품종을 분류하는 문제를 풀어보도록 하겠습니다. 위에서 사용한 지도학습은 숫자로 회귀(Regression)으로 풀 수 있지만, 여기서는 종속변수가 범주형으로 분류(Classification)으로 풀어야 합니다.

역시나 매우 중요한 개념이므로 정리해두고 갑시다.

- 종속변수가 숫자일 경우 — 회귀 알고리즘 사용

- 종속변수가 범주일 경우 — 분류 알고리즘 사용

여기서 범주가 숫자일 경우도 있으니 주의해주세요! 중요한 것은 그 숫자가 숫자만큼의 의미를 지니고 있는가 입니다. 예를 들어 월별 달력의 경우 요일의 데이터는 숫자이지만, 회귀가 아니라 범주입니다!

1. 과거의 데이터를 준비(원인, 결과 관계 파악하기)

2. 모델의 구조를 만듭니다.

3. 데이터로 모델을 학습(FIT)합니다. 다른 말로는 학습한다고 합니다.

4. 모델을 이용합니다. 새로운 데이터를 가지고 예측(Predict)합니다.

분류문제 역시 회귀와 같은 방법으로 문제를 풀게 됩니다.

# 라이브러리 사용
import tensorflow as tf
import pandas as pd

### Alt + Enter ###
# 1.과거의 데이터를 준비합니다.
파일경로 = 'https://raw.githubusercontent.com/blackdew/tensorflow1/master/csv/iris.csv'
아이리스 = pd.read_csv(파일경로)
아이리스.head()
# 원핫인코딩
아이리스 = pd.get_dummies(아이리스)
# 종속변수, 독립변수
독립 = 아이리스[['꽃잎길이', '꽃잎폭', '꽃받침길이', '꽃받침폭']]
종속 = 아이리스[['품종_setosa', '품종_versicolor', '품종_virginica']]
print(독립.shape, 종속.shape)

### Alt + Enter ###
# 2. 모델의 구조를 만듭니다
X = tf.keras.layers.Input(shape=[4])
Y = tf.keras.layers.Dense(3, activation='softmax')(X)
model = tf.keras.models.Model(X, Y)
model.compile(loss='categorical_crossentropy',
metrics='accuracy')

### Alt + Enter ###
# 3.데이터로 모델을 학습(FIT)합니다.
model.fit(독립, 종속, epochs=1000, verbose=0)
model.fit(독립, 종속, epochs=10)

### Alt + Enter ###
# 4. 모델을 이용합니다
# 맨 처음 데이터 5개
print(model.predict(독립[:5]))
print(종속[:5])
# 맨 마지막 데이터 5개
print(model.predict(독립[-5:]))
print(종속[-5:])

### Alt + Enter ###
# weights & bias 출력
print(model.get_weights())

그런데 아래 데이터를 보시면 y는 범주인데 오른쪽은 모두 수식입니다. 수식으로 범주를 만드려면, 범주도 숫자로 변환하는 작업이 필요합니다.

Tensorflow 1–15. 원핫인코딩

 

Tensorflow 1–15. 원핫인코딩

 

이렇게 우리가 원하는 범주형 데이터를 수치형으로 변경시켜주는 작업을 원핫인코딩입니다. 이 작업을 해주는 코드가 아래 코드입니다.

# 원핫인코딩
아이리스 = pd.get_dummies(아이리스)

이렇게 하면 4개의 독립 변수가 생기고, 3개의 종속변수가 생기게 됩니다.

아래처럼요.

Tensorflow 1–15. 원핫인코딩

 

이 부분을 표현하고 있는 코드는 아래와 같습니다.

# 2. 모델의 구조를 만듭니다
X = tf.keras.layers.Input(shape=[4])
Y = tf.keras.layers.Dense(3, activation='softmax')(X)
model = tf.keras.models.Model(X, Y)
model.compile(loss='categorical_crossentropy',
metrics='accuracy')

우리가 한 분류의 예측치로 가장 많이 활용되는 알고리즘은 sigmoid와 softmax입니다. 이중에서 softmax를 사용합니다. 비율을 예측하기 위해 softmax를 사용한다는 것, 이것만 꼭 기억해주세요. 아래처럼 결과가 나오게 됩니다.

Tensorflow 1–16. softmax

 

여기서 두번째 row에서 setosa가 나올 확률은 각각 70%, 30%, 0%입니다.

Tensorflow 1–16. softmax

 

좀 더 살펴봅시다. 왜 softmax라는 함수로 한 번 더 감싸주어야 했을까요? 그것은 분류모델이 0부터 1의 값을 가지기 때문에 그렇습니다. 회귀는 양의 무한대 값과, 음의 무한대 값까지의 값을 가지게 됩니다. 그런데 분류는 그렇지 않죠.

여기서 분류와 회귀에 사용하는 loss 측정 알고리즘도 변하게 됩니다.

#분류에 사용
model.compile(loss='categorical_crossentropy')

#회귀에 사용
model.compile(loss='mse')

여기에 정확도를 추가하고 싶으면 아래와 같은 코드로 작성이 가능합니다. 이는 분류에만 사용할 수 있습니다.

#분류에 사용
model.compile(loss='categorical_crossentropy',
              metrics='accuracy')

accuracy보다는 학습이 되고 있다는 것은 loss를 보시면 됩니다. loss가 떨어진 다는 것은 데이터 정확도가 올라간다는 얘기이니까요.

Tensorflow 1–17. 아이리스 품종 분류 (실습)

 

예측한 값 첫번째 row를 보시면 virginica일 확률이 70%인 것을 볼 수 있습니다. 정확도는 모두 맞춘 것을 볼 수 있죠.

히든레이어

자, 이제 계층을 쌓아 딥러닝을 만들어 보도록 하겠습니다! 아래 그림을 참고해주세요.

Tensorflow 1–18. 히든레이어

# 2. 모델의 구조를 만듭니다
X = tf.keras.layers.Input(shape=[4])
H = tf.keras.layers.Dense(10, activation='swish')(X) 
Y = tf.keras.layers.Dense(1, activation='softmax')(H)
model = tf.keras.models.Model(X, Y)
model.compile(loss='categorical_crossentropy',
metrics='accuracy') 

아래 명령어를 사용하면 어떤 Model모양이 만들어졌는지 확인할 수 있습니다. 이렇게 만든 것이 히든레이어 1개를 쌓은 것입니다.

model.summary()

이번에는 히든레이어를 3개 만들어보도록 하겠습니다.

# 2. 모델의 구조를 만듭니다
X = tf.keras.layers.Input(shape=[4])
H = tf.keras.layers.Dense(8, activation='swish')(X) 
H = tf.keras.layers.Dense(8, activation='swish')(H)
H = tf.keras.layers.Dense(8, activation='swish')(H)
H = tf.keras.layers.Dense(8, activation='swish')(H)
Y = tf.keras.layers.Dense(3, activation='softmax')(H)
model = tf.keras.models.Model(X, Y)
model.compile(loss='categorical_crossentropy',
metrics='accuracy')

데이터 처리를 위한 팁

- 변수(칼럼)타입 확인

데이터.dtypes

 

- 변수를 범주형으로 변경

데이터['칼럼명'].astype('int') 데이터['칼럼명'].astype('float')

 

- NA 값의 처리

데이터.isna().sum() #NA 갯수 체크
데이터['칼럼명'].fillna(특정숫자) #데이터 값 채우기

 

원핫인코딩을 할 때 품종 타입을 범주형으로 바꾸는 작업을 해야 합니다.

이럴때 사용하는 것이 아래 명령어 입니다. 꼭 기억해두세요.

데이터['필드명'] = 데이터['필드명'].astype('category')
인코딩 = pd.get_dummies(데이터)
인코딩

효율이 좋은 Model을 만들기 위한 팁

import tensorflow as tf
import pandas as pd

### Alt + Enter ###
# 1.과거의 데이터를 준비합니다.
파일경로 = 'https://raw.githubusercontent.com/blackdew/tensorflow1/master/csv/boston.csv'
보스턴 = pd.read_csv(파일경로)

### Alt + Enter ###
# 종속변수, 독립변수
독립 = 보스턴[['crim', 'zn', 'indus', 'chas', 'nox',
             'rm', 'age', 'dis', 'rad', 'tax', 
             'ptratio', 'b', 'lstat']]
종속 = 보스턴[['medv']]
print(독립.shape, 종속.shape)

### Alt + Enter ###
# 2. 모델의 구조를 만듭니다
X = tf.keras.layers.Input(shape=[13])
H = tf.keras.layers.Dense(8, activation='swish')(X)
H = tf.keras.layers.Dense(8, activation='swish')(H)
H = tf.keras.layers.Dense(8, activation='swish')(H)
Y = tf.keras.layers.Dense(1)(H)
model = tf.keras.models.Model(X, Y)
model.compile(loss='mse')

# 2. 모델의 구조를 BatchNormalization layer를 사용하여 만든다.
X = tf.keras.layers.Input(shape=[13])
H = tf.keras.layers.Dense(8)(X)
H = tf.keras.layers.BatchNormalization()(H)
H = tf.keras.layers.Activation('swish')(H)
H = tf.keras.layers.Dense(8)(H)
H = tf.keras.layers.BatchNormalization()(H)
H = tf.keras.layers.Activation('swish')(H)
H = tf.keras.layers.Dense(8)(H)
H = tf.keras.layers.BatchNormalization()(H)
H = tf.keras.layers.Activation('swish')(H)
Y = tf.keras.layers.Dense(1)(H)
model = tf.keras.models.Model(X, Y)
model.compile(loss='mse')

### Alt + Enter ###
# 3.데이터로 모델을 학습(FIT)합니다.
model.fit(독립, 종속, epochs=1000)