신경망은 deep learning의 기본 모델이라 할 수 있다. 입력층(input layer), 은닉층(hidden layer), 출력층(output layer)로 구성된 다층 퍼셉트론(MLP, Multi-Layer Perceptron) 구조를 가진다.
입력층의 각 노드는 특징을 입력받는다. 따라서 편향을 고려하지 않는다면 입력 노드 수는 특징 개수와 같다. 또한 최종 노드는 라벨 혹은 클래스의 개수와 같다. 반면 은닉층은 층과 노드수를 지정해주어야 한다. 은닉층의 복잡도는 모델의 복잡도와 직결된다.
① 입력값을 가중합 → ② 활성화 함수 적용 → ③ 그 결과를 다음 노드 전달(혹은 출력층에서 결과 생성)
n: 이전 층의 노드 수, a: 활성화 함수,
w_i: 이전 층의 i번째 노드와 해당 노드를 연결하는 에지(edge)에 부여된 가중치, v_i: i번째 노드에 저장된 값
신경망에 비선형성을 부여하는 함수
출력 범위 (0, 1)
기울기 소실(Vanishing Gradient)문제 발생: 신경망의 층이 많을 때 입력과 가까운 가중치가 제대로 학습되지 않는 문제
0보다 크면 그대로, 0 이하면 0 출력
기울기 소실 문제 해결
죽은 뉴런 문제 발생: 도함수가 0이하의 값에 대해 0을 반환해서 이전 층의 출력이 0 이하이면 가중치 학습이 되지 않음
0보다 크면 그대로, 0 이하면 0.01을 곱한 값 출력
렐루 문제 해결 (그러나 렐루를 표준처럼 사용)
다중 클래스 분류에 사용
각 출력을 확률로 변환
① 모든 가중치를 임의로 초기화하고 이터레이션 수를 1로 설정
② 학습 데이터를 모델에 입력하여 예측값과 오차를 계산 (순전파 + 손실 계산)
③ 오차를 바탕으로 출력층에 가까운 가중치부터 순서대로 업데이트 (역전파 + 경사 하강법)
④ 더이상 업데이트되지 않거나 최대 이터레이션 수에 도달하면 학습 종료
신경망은 가중합 연산이 여러번 반복되는 모델이므로 특징의 스케일에 크게 영향을 받는다. 따라서 스케일링이 필수적이다.
신경망 모델 구조가 복잡하고 데이터가 적으면 해가 빠르게 수렴하기 어렵다. 그래서 수렴하지 못하고 최대 이터레이션 횟수에 도달해서 알고리즘이 종료되는 경우가 잦다. 그렇다고 최대 이터레이션 횟수를 너무 크게 설정하면 과적합이 일어날 가능성이 커진다.
또한 학습률이 클수록 수렴 속도가 빨라지지만, 수렴하지 못할 가능성도 커진다.
신경망 모델의 성능은 초기 가중치에 영향을 크게 받는다. 따라서 여러 신경망 모델을 비교할 때 우연에 의해 결과가 뒤바뀌는 것을 방지하기 위해 시드를 고정해야 한다. 혹은 시드를 파라미터로 간주하여 여러 개의 시드를 비교한다.
# 데이터 로드 및 분할
import pandas as pd
from sklearn.model_selection import train_test_split
df = pd.read_csv("../../data/regression/puma32h.csv")
X = df.drop('y', axis = 1)
y = df['y']
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state = 50)
# 신경망 이용 회귀 모델 학습 및 MAE 평가
from sklearn.neural_network import MLPRegressor as NN
from sklearn.metrics import mean_absolute_error as MAE
model = NN(random_state = 50).fit(X_train, y_train) #hidden_layer_sizes=(100,)
y_pred = model.predict(X_test)
mae = MAE(y_test, y_pred)
print(mae)
# 모델 구조 비교
model1 = NN(hidden_layer_sizes = (5, ), random_state = 50).fit(X_train,y_train)
model2 = NN(hidden_layer_sizes = (10, 10), random_state = 50).fit(X_train,y_train)
model3 = NN(hidden_layer_sizes = (100, 100, 100), random_state = 50).fit(X_train,y_train)
y1_pred = model1.predict(X_test)
y2_pred = model2.predict(X_test)
y3_pred = model3.predict(X_test)
mae1 = MAE(y_test, y1_pred)
mae2 = MAE(y_test, y2_pred)
mae3 = MAE(y_test, y3_pred)
print(mae1, mae2, mae3)
# 모델 구조 추가 비교
model4 = NN(hidden_layer_sizes = (15, 15), random_state = 2022).fit(X_train, y_train)
model5 = NN(hidden_layer_sizes = (10, 5), random_state = 2022).fit(X_train, y_train)
model6 = NN(hidden_layer_sizes = (20, ), random_state = 2022).fit(X_train, y_train)
y4_pred = model4.predict(X_test)
y5_pred = model5.predict(X_test)
y6_pred = model6.predict(X_test)
mae4 = MAE(y_test, y4_pred)
mae5 = MAE(y_test, y5_pred)
mae6 = MAE(y_test, y6_pred)
print(mae4, mae5, mae6)
# 최대 이터레이션 도달
model = NN(random_state = 50).fit(X_train, y_train)
y_pred = model.predict(X_test)
mae = MAE(y_test, y_pred)
print(mae) # ConvergenceWarning발생(max_iter 200으로 가중치 수렴 못함)
# 최대 이터레이션 설정
model = NN(random_state = 50, max_iter = 10000).fit(X_train, y_train)
y_pred = model.predict(X_test)
mae = MAE(y_test, y_pred)
print(mae) #오차 줄어듦(과적합 주의)
참고
GIL's LAB, 「파이썬을 활용한 머신러닝 자동화 시스템 구축」, 위키북스(2022)
Activation fucntion(2)-tanh/ReLU/LeakyReLU/ELU/Maxout
[ML] 최적화란? (0) | 2025.02.16 |
---|---|
[ML/python] 앙상블 (voting, bagging, boosting, stacking, 랜덤포레스트, XGBoost, LightGBM) (0) | 2025.02.15 |
[ML/python] 결정 트리 (decision tree, DTC, class_weight, export_text, plot_tree) (0) | 2025.02.14 |
[ML/python] K-최근접 이웃(K-Nearest Neighbors, K-NN) (0) | 2025.02.14 |
[ML/python] 선형모델 (multiple linear regression, Lasso, Ridge, logistic) (0) | 2025.02.12 |