" 학습이 더 잘되도록 하는 방법들 소개하는 챕터"
신경망이 제일 처음 만들어질 때 가중치의 숫자값이 랜덤으로 생성이 됩니다.
입력층 -----------------> 은닉층 -----------------> 출력층 768 100 10
(100, 768) ◎ ( 768, 100 ) = (100, 100 ) ◎ (100, 10 ) = (100,10) ↑ ↑ 은닉층의 가중치 행렬(W1) 출력층쪽의 가중치(W2)
가중치 행렬의 숫자가 W1 만해도 76800개가 만들어지고 W2 는 1000개의 숫자가 처음에 랜덤으로 생성이 됩니다. 학습이 잘되게 하려면 이 숫자들이 정규분포 형태를 보여야합니다.
독립변수들의 데이터가 정규분포 형태이고 종속변수도 정규분포 형태면 학습이 아주 잘됩니다. 그런데 정규분포 형태가 아니면 학습이 원만하지 않을거다라고 예상을 하고 있어야합니다.
그런데 가중치도 마찬가지고 처음부터 정규분포 형태로 구성되어야 학습이 잘됩니다. 학습 시킬 데이터는 정규분포가 아니어도 어쩔수 없지만 가중치는 정규분포로 구성할 수 있습니다.
■ 이론설명1. 생성되는 가중치 숫자들의 표준편차가 너무 큰 경우
그림 6-10
■ 이론설명2. 생성되는 가중치 숫자들의 표준편차가 너무 작은 경우
그림 6-11
■ 이론설명3. 신경망 학습이 잘되는 가중치 구성의 경우
그림6-13
※ 텐써 플로우에서는 가중치 초기값이 어떻게 구성될까요 ?
1. he 초기화 : relu 함수와 궁합이 잘 맞습니다.
예: model.add( Dense(64, activation='relu', kernel_initializer='he_normal'))
2. Glorotuniform 초기화
예: model.add( Dense(64, activation='relu', kernel_initializer='glorot_uniform'))
3. RadomNormal 초기화 : sigmoid 와 궁합이 잘 맞습니다.
예: model.add( Dense(64, activation='relu', kernel_initializer=initializers.RandomNormal(mean=0., stddev=0.05))
4. zeros 초기화
예: model.add( Dense(64, activation='relu', kernel_initializer='zeros'))
문제1. relu 함수와 짝꿍인 he 초기화 가중치 구성으로 앞에서 만들었던 필기체 신경망을 300 에폭으로 돌리고 식사하러 가세요 ~
#1. mnist 필기체 데이터 불러오기
from tensorflow.keras.datasets import mnist
from tensorflow.keras.utils import to_categorical
(x_train, y_train), (x_test, y_test) = mnist.load_data()
# 차원 축소하기
x_train = x_train.reshape((x_train.shape[0], 784)).astype('float32') / 255
x_test = x_test.reshape((x_test.shape[0], 784)).astype('float32') / 255
# 레이블을 one-hot encoding으로 변환하기
y_train = to_categorical(y_train, 10)
y_test = to_categorical(y_test, 10)
#2. 신경망 구성에 필요한 모듈 불러오기
import tensorflow as tf
tf.random.set_seed(777)
import numpy as np
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Flatten
from tensorflow.keras.optimizers import SGD
from tensorflow.keras.losses import categorical_crossentropy
#3. 모델 구성하기
model = Sequential()
model = Sequential()
model.add(Flatten( input_shape=(784, ) ) ) # 입력층 0층
model.add(Dense(64, activation='relu', kernel_initializer='he_normal')) # 은닉층(1층)
model.add(Dense(32, activation='relu', kernel_initializer='he_normal')) # 은닉층(2층)
model.add(Dense(64, activation='relu', kernel_initializer='he_normal')) # 은닉층(3층)
model.add(Dense(10, activation='softmax') ) # 출력층(4층)
# 모델 준비하기
model.compile(optimizer=SGD(),
loss=categorical_crossentropy, # 분류를 위한 오차함수
metrics=['accuracy']) # 분류 문제에 맞는 평가 지표 사용
# 학습 시키기
history = model.fit( x_train, y_train,
epochs= 300,
batch_size=100,
validation_data = (x_test, y_test) )
model.evaluate( x_test, y_test )
import matplotlib.pyplot as plt
import numpy as np
# 예시로 accuracy 리스트 값을 사용
train_acc_list = history.history['accuracy'] # 훈련 데이터의 정확도 리스트
test_acc_list = history.history['val_accuracy'] # 테스트 데이터의 정확도 리스트
# 에포크 수에 따른 x축 데이터 생성
x = np.arange(len(train_acc_list))
# 시각화
plt.figure(figsize=(8, 6)) # 그래프 크기 설정
plt.plot(x, train_acc_list, label='Train Accuracy') # 훈련 데이터 정확도 라인
plt.plot(x, test_acc_list, label='Test Accuracy', linestyle='--') # 테스트 데이터 정확도 라인
# 그래프의 축, 범위 및 레이블 설정
plt.ylim(0.8, 1.0) # y축 범위를 0.8에서 1.0까지로 설정
plt.xlabel('Epochs', fontsize=12) # x축 레이블
plt.ylabel('Accuracy', fontsize=12) # y축 레이블
# 범례 추가 및 위치 설정
plt.legend(loc='lower right', fontsize=12)
# 타이틀 추가 (선택 사항)
plt.title('Train vs Test Accuracy', fontsize=14)
# 그래프 출력
plt.show()