에이블 스쿨

[9주차] 딥러닝(2)_이진, 다중분류 모델링

메롱메롱메롱나 2024. 11. 1. 01:30

1. 은닉층에서는 어떤 일이 ?!

1) 연결

Fully Connected Locally Connected
모든 노드 간에 연결 특정 노드들을 묶어서 제어

 

2) 학습

예측 값, 실제 값을 비교하며 오차함수로 오차를 계산하고

-> 오차를 줄이기 위해, 가중치(파라미터)를 업데이트

=> 오차를 최소화하는 최적의 가중치를 찾음

 

3) Feature Representation

* Locally Connected에서

(1) 은닉층의 각 노드는 새로운 요인(feature)을 만들어냄

      - 기존의 변수(입력 변수)의 가중치를 활용

-> 여기서 집값을 예측할 때 Z1은 내부적 요인, Z2는 외부적 요인으로 구분지을 수 있음

 

(2) 내부요인과 외부요인에 다른 가중치를 두어 최종집 값을 예측 가능

-> 최종 집값 = 0.7*내부요인 + 0.3*외부요인

 

=> 즉, 기존의 데이터를 가지고 새로운 특징을 만들어 냄. 이는 오차를 최소화해주는 유익한 특징일 것.

     *Feature Engineering

      : 은닉층에서는 기존 데이터가 새롭게 표현(Representation)되었다.

 

2. 이진분류 모델링

: 최종 예측의 값이 0 또는 1인것

 - 최종 예측 결과를 활성함수(Activation Function)를 활용하여 0 또는 1로 변환

 

1) 활성함수(Sigmoid)

   - 이진분류는 출력층에서 sigmoid함수를 사용해서 결과를 0, 1로 변환 (0~1 사이의 확률 값)

   - 은닉층에서는 relu함수를 사용해서 깊이있는 학습

 

2) 오차함수(Binary_Crossentropy)

  : 이진분류에서는 binary_crossentropy를 사용해서 오차를 평가함. 

 

- y가 1인데, 1로 예측했으면 오차를 0에 가깝게

- y가 1인데, 0으로 예측했으면 오차를 ∞에 가깝게

- y가 0인데, 1로 예측했으면 오차를 ∞ 에 가깝게

- y가 0인데, 0으로 예측했으면 오차를 0에 가깝게

 

* y = 1일때, 

① y = 1일때, 예측이 0.9라면, 오차함수 그래프에 따라 오차값이 0.11

③ y = 1일때, 예측이 0.5라면, 오차함수 그래프에 따라 오차값이 0.69

 

* y = 0일때, 

① y = 0일때, 예측이 0.3이라면, 1-0.3 = 0.7로 변환 후, 함수에 따라 오차값이 0.36

    (y가 0라면 예측이 작을 수록 오차가 적어야함. y가 0, 1일때 모두 같은 오차함수로 판별해야하기 때문에 1-예측값을 해줌)

 

* 최종 오차

   : 이 오차들의 평균을 계산하여 최종오차로 출력

 

3) 모델 평가

* 예측값 후속 처리

  : 0, 1로 결과가 나와야하므로 예측 결과를 0.5기준으로 잘라서 1, 0으로 변환 (np.where)

 

*classification report

  : recall, precision, f1-score, accuracy 확인 가능

 

<실습>

** 범주형 데이터인데 0, 1로 되어있는 것이 아니라면 가변수화 필수 !!!!

x = pd.get_dummies(x, columns = dum_cols ,drop_first = True)
# 입력노드 개수 확인 ------------------------------------------
n = x_train.shape[1]

# 모델 구조 짜기 ----------------------------------------------
# 메모리 정리
clear_session()

# 모델 만들기
model1 = Sequential([Input(shape = (n,)),
                     Dense(20, activation = 'relu'), #은닉층
                     Dense(10, activation = 'relu'),
                     Dense(1, activation = 'sigmoid')]) #출력층

#모델 정보
model1.summary()

# 모델 컴파일 + 학습 -----------------------------------------------
model1.compile(optimizer=Adam(learning_rate=0.01), loss='binary_crossentropy', metrics = ['Accuracy']) # 학습할 때 accuracy도 같이 뜸
hist = model1.fit(x_train, y_train, epochs=30, validation_split=.2).history

# 모델 평가 -----------------------------------------------------------
pred1 = model1.predict(x_val)
pred1 = np.where(pred1 >= 0.5, 1, 0) # 출력결과 자르기

print(classification_report(y_val, pred1))

 

3. 다중분류 모델링

: 다중분류 모델에서 출력 층의 노드 수 = y의 범주 수

  - 최종 예측 확률이 범주마다 출력

 

1) Softmax

 : 각 범주(Class)별로 예측한 값을 하나의 확률 값으로 변환해주는 활성함수

   - 확률이므로 범주 별 확률의 합은 1

 

 

2) 다중분류 오차 계산

: 실제 값이 1인 클래스의 예측확률과 실제값을 비교 

 

3) 전처리

: 다중분류는 y를 전처리 해주어야 함. 

  • 방법 1 : 정수 인코딩(클래스를 0, 1, 2 .... 값으로 변환) + sparse_categorical_crossentropy(오차함수)
  • 방법 2 : 원-핫 인코딩(가변수화) + categorical_crossentropy(오차함수)

=> 방법 1을 사용 !!

 

4) 정수 인코딩 + sparse_categorical_crossentropy

* 정수 인코딩 : 타겟(y)의 범주를 0부터 순차증가하는 정수로 인코딩

   - int_encoder.classes : 인코딩된 범주 조회

 

* loss='sparse_categorical_crossentropy’

  - 인코딩한 y(해당 인덱스)의 예측확률 계산. -log

 

5) 평가

* 예측결과에 대한 후속처리

 : 각 클래스별 확률 값(예측결과) 중 가장 큰 값의 인덱스로 변환 np.argmax()

   그 후 이에 대한 예측 값으로 예측평가(confusion_matrix, classification_report) 진행

 

*argmax : 행, 열의 가장 큰 값의 인덱스를 반환 

- np.argmax(a, axis = 0)

: 의 인덱스를 출력

 

- np.argmax(a, axis = 1)

: 의 인덱스를 출력

 

 

<실습>

# 입력노드 개수 확인 ------------------------------------------
n = x_train.shape[1]

# 모델 구조 짜기 ----------------------------------------------
# 메모리 정리
clear_session()

# 모델 만들기
model = Sequential([Input(shape = (n,)),
                     Dense(20, activation = 'relu'), #은닉층
                     Dense(10, activation = 'relu'),
                     Dense( 3, activation = 'softmax')] ) #y의 클래스의 수만큼 출력층 노드를 구성. 함수는 소프트 맥스

# 모델요약
model.summary()

# 모델 컴파일 + 학습 -----------------------------------------------
model.compile(optimizer=Adam(0.1), loss= 'sparse_categorical_crossentropy')
hist = model1.fit(x_train, y_train, epochs=50, validation_split=.2).history

# 모델 평가 -----------------------------------------------------------
pred = model.predict(x_val)
pred = pred.argmax(axis=1) #예측값을 argmax

print(confusion_matrix(y_val, pred))
print(classification_report(y_val, pred))

argmax

 

 

 

728x90