참고 서적
도서명: 모두의 딥러닝 저자 : 조태호 출판 : 길벗 발매 : 2020.01.27 |
모델 설계하기
'폐암 수술 환자의 생존율 예측하기'의 딥러닝 코드를 다시 한번 옮겨 보면 다음 코드와 같다.
# 딥러닝을 구동하는 데 필요한 케라스 함수 호출
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense
# 필요한 라이브러리 불러옴
import numpy as np
import tensorflow as tf
# 실행할 때마다 같은 결과를 출력하기 위해 설정하는 부분
np.random.seed(3)
tf.random.set_seed(3)
# 준비된 수술 환자 데이터를 불러옴
Data_set = np.loadtxt(”../dataset/ThoraricSurgery.csv”, delimiter=”,”)
# 환자의 기록과 수술 결과를 X와 Y로 구분하여 저장
X = Data_set[:,0:17]
Y = Data_set[:,17]
# 딥러닝 구조를 결정(모델을 설정하고 실행하는 부분)
model = Sequential( )
model.add(Dense(30, input_dim=17, activation=‘relu’))
model.add(Dense(1, activation=‘sigmoid’))
# 딥러닝 실행
model.compile(loss=‘mean_squared_error’, optimizer=‘adam’, metrics=[‘accuracy’])
model.fit(X, Y, epochs=100, batch_size=10)
딥러닝의 모델을 설정하고 구동하는 부분은 모두 model이라는 함수를 선언하며 시작이 된다.
먼저 model = Sequential( ) 로 시작되는 부분은 딥러닝의 구조를 짜고 층을 설정하는 부분(쉽게 말해 레이어를 담기 위한 그릇) , layers Dense는 층, 모델이다.
이어서 나오는 model.compile( ) 부분은 위에서 정해진 모델을 컴퓨터가 알아들을 수 있게끔 컴파일 하는 부분이다. 그리고 model.fit( ) 으로 시작하는 부분은 모델을 실제로 수행하는 부분이다.
1. 입력층, 은닉층, 출력층
먼저 딥러닝의 구조를 짜고 층을 설정하는 부분을 보면 다음과 같다.
model = Sequential( )
model.add(Dense(30, input_dim=17, activation=‘relu’))
model.add(Dense(1, activation=‘sigmoid’))
Sequential( ) 함수를 model로 선언해 놓고 model.add( )라는 라인을 추가하면 새로운 층이 만들어진다.
코드에는 model.add( )로 시작되는 라인이 두 개가 있으므로 두 개의 층을 가진 모델을 만든 것이다. 맨 마지막 층은 결과를 출력하는 '출력층'이 된다. 나머지는 모두 '은닉층'의 역할을 한다. 따라서 지금 만들어진 이 두 개의 층은 각각 은닉층과 출력층이 된다.
model.add(Dense(30, input_dim=17, activation=‘relu’))
model.add( ) 함수를 통해 새로운 층을 만들고 나면 Dense( ) 함수를 통해 이 층에 몇개의 노드를 만들 것인지를 숫자로 써준다. 30이라고 되어 있는 것은 이 층에 30개의 노드를 만들겠다는 것이다. 이어서 input_dim 이라는 변수는 입력 데이터에서 몇 개의 값을 가져올지를 정하는 것이다.
keras는 입력층을 따로 만드는 것이 아니라, 첫 번째 은닉층에 input_dim을 적어줌으로써 첫 번째 Dense가 은닉층 + 입력층의 역할을 겸한다. 여기서 다루는 폐암 수술 환자의 생존 여부 데이터에는 17개의 입력 값들이 있다. 따라서 데이터에서 17개의 값을 받아 은닉층의 30개 노드로 보낸다는 뜻이다.
은닉층의 각 노드는 17개의 입력 값에서 임의의 가중치를 가지고 각 노드로 전송되어 활성화 함수를 만난다. 그리고 활성화 함수를 거친 결괏값이 출력층으로 전달된다. 이때 활성화 함수로 무엇을 사용할지 지정해야 하는데 activation 부분에 우리가 원하는 활성화 함수를 적어주면 된다. 여기서는 렐루를 사용하였다.
model.add(Dense(1, activation=‘sigmoid’))
위의 코드는 마지막 층이므로 이 층이 곧 출력층이 된다. 출력 값을 하나로 정해서 보여 줘야 하므로 출력층의 노드 수는 1개이다. 그리고 이 노드에서 입력받은 값 역시 활성화 함수를 거쳐 최종 출력 값으로 나와야 한다. 여기서는 시그모이드(sigmoid)를 활성화 함수로 사용하였다.
2. 모델 컴파일
model.compile(loss=‘mean_squared_error’, optimizer=‘adam’, metrics=[‘accuracy’])
model.fit(X, Y, epochs=100, batch_size=10)
model.compile 부분은 앞서 지정한 모델이 효과적으로 구현될 수 있게 여러 가지 환경을 설정해 주면서 컴파일하는 부분이다. 먼저 어떤 오차 함수를 사용할지를 정해야 한다. 여기서는 평균 제곱 오차 함수(mean_squared_error)를 사용하였다.
경우에 따라서 오차 함수를 바꾸면 더 좋은 효과를 나타내기도 한다. 오차 함수에는 평균 제곱 오차 계열의 함수 외에도 교차 엔트로피 계열이 함수가 있다. 교차 엔트로피 계열의 함수는 출력 값에 로그를 취해서, 오차가 커지면 수렴 속도가 빨라지고 오차가 작아지면 수렴 속도가 감소하게끔 만든 것이다.
이어서 최적화를 위한 방법도 고를 수 있다. 여기서는 Adam을 사용하였다. 이를 모두 종합하여 도식으로 나타내면 다음 그림과 같다.
다음으로 metrics( ) 함수는 모델이 컴파일될 때 모델 수행 결과를 나타내게끔 설정하는 부분이다. 정확도를 측정하기 위해 사용되는 테스트 샘플을 학습 과정에서 제외시킴으로써 과적합 문제(overfitting, 특정 데이터에서는 잘 작동하나 다른 데이터에서는 잘 작동하지 않는 문제)를 방지하는 기능을 담고 있다.
3. 교차 엔트로피
교차 엔트로피는 주로 분류 문제에서 많이 사용되는데, 특별히 예측 값이 참과 거짓 둘 중 하나인 형식일 때는 binary_crossentropy (이항 교차 엔트로피)를 쓴다. 지금 구하고자 하는 것은 생존(1) 또는 사망(0) 둘 중 하나이므로 binary_crossentropy를 사용할 수 있는 좋은 예라고 할 수 있다.
binary_crossentropy를 적용하려면 앞 식의 mean_squared_error 자리에 binary_crossentropy를 입력하면 된다. 이를 실행하면 예측 정확도(Accuracy)가 약간 향상되는 것을 알 수 있다.
현재 딥러닝과 관련하여 케라스에서 사용되는 대표적인 오차 함수는 다음과 같다.
4. 모델 실행하기
모델을 정의하고 컴파일하고 나면 이제 실행시킬 차례이다. 앞서 컴파일 단계에서 정해진 환경을 주어진 데이터를 불러 실행시킬 때 사용되는 함수는 다음과 같이 model.fit( ) 부분이다.
model.fit(X, Y, epochs=100, batch_size=10)
주어진 폐암 수술 환자의 생존 여부 데이터는 총 470명의 환자에게서 17개의 정보를 정리한 것이다. 이때 각 정보를 '속성'이라고 부른다. 그리고 생존 여부를 클래스, 가로 한 줄에 해당하는 각 환자의 정보를 각각 '샘플'이라고 한다. 주어진 데이터에는 총 470개의 샘플이 각각 17개의 속성을 가지고 있는 것이다.
학습 프로세스가 모든 샘플에 대해 한 번 실행되는 것을 1 epoch (에포크)라고 한다. 코드에서 epochs = 100으로 지정한 것은 각 샘플이 처음부터 끝까지 100번 재사용될 때까지 실행을 반복하라는 뜻이다.
batch_size는 샘플을 한 번에 몇 개씩 처리할지를 정하는 부분으로 batch_size = 10은 전체 470개의 샘플을 10개씩 끊어서 집어넣으라는 뜻이 된다. batch_size가 너무 크면 학습 속도가 느려지고, 너무 작으면 각 실행 값의 편차가 생겨서 전체 결괏값이 불안정해질 수 있다. 따라서 자신의 컴퓨터 메모리가 감당할 만큼의 batch_size를 찾아 설정해 주는 것이 좋다.
1. 폐암 환자 데이터
AI에서 가장 중요한 부분이자 기반이 되야 하는 것이 '좋은 데이터'이다.
폐함 환자 생존률 데이터는 '모두의 딥러닝' 예제의 [ThoraricSurgery.csv]를 사용하였고,
직접 [test.csv]를 만들어 가상의 환자를 만들어 보았다.
* ThoraricSurgery.csv : 구글에 치면 다운받을 수 있는 깃허브 주소가 나온다.
[ThoraricSurgery.csv] 데이터의 구조를 살펴보자.
- 데이터에는 470명의 환자 정보가 들어있다.
- 각 '속성' 정보는 [종양 유형, 폐활량, 기침, 흡연 여부 등] 각각의 17개의 환자의 정보가 담겨있다.
- '클래스'에는 [수술 후 생존, 사망 여부] 정보가 담겨 있다.
[test.csv] 데이터 구조도 살펴보자.
- 글쓴이가 만든 가상의 환자 정보이다.
- 각 '속성' 정보는 [종양 유형, 폐활량, 기침, 흡연 여부 등] 위와 같이 17개의 환자의 정보가 담겨있다.
- '클래스'인 [수술 후 생존, 사망 여부] 정보는 우리가 모델을 통해 예측해볼 것이다!
2. Training
# 딥러닝에 필요한 케라스 함수 호출
from keras.models import Sequential, load_model
from keras.layers import Dense
# 필요 라이브러리 호출
import numpy as np
import tensorflow as tf
# 실행 시마다 같은 결과값 도출을 위한 시드 설정
np.random.seed(0)
tf.random.set_seed(0)
# csv 파일을 읽어 ','기준으로 나눠 Dataset에 불러오기
Dataset = np.loadtxt("ThoraricSurgery.csv", delimiter=",")
# 환자 정보는 0-16번(17개)까지이므로 해당 부분까지 X에 담기
X = Dataset[:, 0:17]
# 수술 후 결과는 마지막 17번은 클래스로 Y에 담기
Y = Dataset[:, 17]
# 딥러닝 모델 구조 설정(3개층, 속성이 17개 input 값, relu와 sigmoid 활성화 함수 이용)
model = Sequential()
model.add(Dense(30, input_dim=17, activation='relu'))
model.add(Dense(15, activation='relu'))
model.add(Dense(1, activation='sigmoid'))
# 딥러닝 실행(오차함수는 평균제곱오차, 최적화함수는 adam 이용)
model.compile(loss='mean_squared_error', optimizer='adam', metrics=['accuracy'])
model.fit(X, Y, epochs=30, batch_size=5)
# 만들어진 모델 저장
model.save('Predict_Model.h5')
중간에 Dataset을 출력한 사진이다.
다음과 같이 470명 환자의 17가지 정보가 들어간 이중 리스트가 만들어졌다.
중간 X와 Y를 출력한 사진이다.
X엔 환자 정보가, Y엔 마지막 컬럼인 생존여부부분이 들어간 것을 볼 수 있다.
모델의 정확도이다.
5개 단위(batch-size)로 30번(epochs) 학습시켜 85.74% 정확도를 가진 모델을 만들었다.
그리고 다음과 같이 잘 저장되었다.
3. Testing
# 딥러닝에 필요한 케라스 함수 호출
from keras.models import load_model
from keras.utils import np_utils
# 필요 라이브러리 호출
import numpy as np
# csv 파일을 읽어 ','기준으로 나눠 Dataset에 불러오기
Dataset = np.loadtxt("test.csv", delimiter=",")
# 환자 정보는 0-16번(17개)까지이므로 해당 부분까지 X에 담기
X = Dataset[:, 0:17]
# 수술 후 결과 정보인 예측값 변수 초기화
Y = []
# 모델 불러오기
model = load_model('Predict_Model.h5')
# X 값에 대한 predict_classes 함수 실행결과 Y에 저장
Y = model.predict_classes(X)
print('Predict : ', Y)
중간 Dataset 변수를 출력한 사진이다.
3명의 가상 환자 정보가 잘 들어간 것을 알 수 있다.
마지막 예측 결과 사진이다.
3명의 가상 환자에 대해 다음과 같은 결과를 도출했다.
- 1번 가상 환자 : 수술 후 사망 예상
- 2번 가상 환자 : 수술 후 사망 예상
- 3번 가상 환자 : 수술 후 생존 예상
이라는 결과를 내놓았다.
4. 신뢰성
여기서 한가지 밝힐 사실이 있다.
이 가상 환자 세명은 사실 [ThoraricSurgery.csv] 데이터의 환자의 정보를 참고하여 만들었다.
위 두명은 수술 후 사망했던 환자 정보와 유사한 속성 정보를 집어넣었고
마지막 한명은 수술 후 생존했던 환자 정보와 유사하게 속성 정보를 집어넣었다.
보시다시피 결과는 예상과 같았다.
이러한 결과는 모델에 대한 정확도를 보여주는 또 한가지의 지표가 되었다.
'공부정리 > 모두의 딥러닝 (교재 정리)' 카테고리의 다른 글
[deeplearning] 모델 설계하기 (2) - Loss function, Metrics (0) | 2022.05.16 |
---|---|
[deeplearning] 신경망의 이해 - 신경망에서 딥러닝으로 (0) | 2022.05.02 |
[deeplearning] 신경망의 이해 - 오차 역전파 (0) | 2022.04.29 |
[deeplearning] 신경망의 이해 - 퍼셉트론, 다층 퍼셉트론 (0) | 2022.04.29 |
[deeplearning] 딥러닝의 동작 원리 - 로지스틱 회귀 (0) | 2022.04.14 |