STUDY/ML

[딥러닝] 심층 신경망

moru_xz 2023. 4. 12. 14:01

✅ 정리

- 심층 신경망: 2개 이상의 층을 포함한 신경망

- 렐루 함수: 이미지 분류 모델의 은닉층에 많이 사용하는 활성화 함수 

- 옵티마이저: 신경망의 가중치와 절편을 학습하기 위한 알고리즘 또는 방법(SGD, 네스테로프 모멘텀, RMSprop, Adam … )

- add(): 케라스 모델에 층을 추가하는 메서드

- summary(): 케라스 모델의 정보를 출력하는 메서드

- SGD: 기본경사 하강법 옵티마이저 클래스 (learning_rate 기본값은 0.01, momentum 매개변수에 0이상 값을 지정하면 모멘텀 최적화 수행, nesterov 매개변수를 True로 설정하면 네스테로프 모멘텀 최적화 수행)

- Adagrad: 옵티마이저 클래스 (learning_rate 기본값은 0.001, initial_accumulator_value 매개변수에서 누적 초깃값을 지정할 수 있으며 기본값은 0.1)

- RMSprop: 옵티마이저 클래스 (learning_rate 기본값은 0.001, rho 매개변수에서 감소 비율 지정하며 기본값은 0.9)

- Adam: 옵티마이저 클래스 (learning_rate 기본값은 0.001)

데이터셋 불러오기

from tensorflow import keras

train_scaled = train_input / 255.0
train_scaled = train_scaled.reshape(-1, 28*28)

from sklearn.model_selection import train_test_split
train_scaled, val_scaled, train_target, val_target = train_test_split(
    train_scaled, train_target, test_size = 0.2, random_state = 42
)

 

층이 2개인 심증신경망 모델 구조

- 신경망 모델과 다른 점은 입력층과 출력층 사이에 밀집층이 추가된 것 = 은닉층(hidden layer)

- 은닉층에 주황색 원으로 활성화 함수가 표시되어있는데 출력층에 적용했던 소프트맥스 함수도 마찬가지로 활성화 함수

- 출력층에 적용하는 활성화 함수는 종류가 제한되어 있임 -> 이진 분류: 시그모이드, 다중 분류: 소프트 맥스

- but,  은닉층 활성화 함수는 비교적 자유로움 (sigmoid, relu 등)

- 분류 문제는 클래스에 대한 확률을 출력하기 위해 활성화 함수를 사용하지만 회귀의 출력은 임의의 어떤 숫자이므로 활성화 함수 적용 X -> 출력층의 선형 방정식의 계산을 그대로 출력 

 

 

dense1 = keras.layers.Dense(100, activation = 'sigmoid', input_shape = (784, ))
dense2 = keras.layers.Dense(10, activation = 'softmax')

- dense1 은 100개의 뉴런을 가진 밀집층(은닉층)

- 활성화 함수는 sigmoid

- 입력의 크기는 (784, )

- 은닉층의 뉴런의 개수를 정하는 기준은 없지만 적어도 출력층의 뉴런보다는 많게 만들어야 함 -> 클래스 10개에 대한 확률을 예측해야 하는데 이전 은닉층의 뉴런이 10개보 다 적다면 부족한 정보가 전달 

- dense2는 출력층 

 

심층 신경망 만들기

model = keras.Sequential([dense1, dense2])

- 여러 층을 추가할 때는 리스트로 만들어 전달 -> 출력층이 무조건 마지막에 

 

model.summary()

- summary() 메서드 호출하면 층에 대한 정보를 얻을 수 있음

출력 크기 를 보면 (None, 100)

: 첫 번째 차원은 샘플의 개수를 나타냄 -> 샘플 개수가 아직 정의되어 있지 않아 None

why? 케라스 모델의 fit() 메서드에 훈련 데이터를 주입하면 이 데이터를 한 번에 모두 사용하지 않고 잘게 나누어 여러 번에 경사 하강법 단계 수행 (= 미니 배치 경사 하강법) 

케라스의 기본 미니배치 크기는 32개인데 이 값은 fit() 매서드에서 batch_size 매개변수로 바꿀 수 있음 -> 따라서 샘플 개수를 고정하지 않고 어떤 배치 크기에도 유연하게 대응할 수 있도록 None 으로 설정 

두 번째 100은 은닉층의 뉴런 개수를 100개로 두었으니 100개의 출력이 나옴 -> 샘플마다 784개의 픽셀값이 은닉층을 통과하면서 100개의 특성으로 압축 

Param

: 모델 파라미터 개수가 출력 -> 이 층은 Dense 층이므로 입력 픽셀 784개와 100개의 모든 조합에 대한 가중치 있음 그리고 뉴런마다 1개의 절편이 있음 

 

층 추가하는 다른 방법

Sequential 클래스의 생성자 안에서 바로 Dense 클래스의 객체 만드는 경우 많음

model = keras.Sequential([
    keras.layers.Dense(100, activation = 'sigmoid', input_shape = (784, ),
                       name = 'hidden'),
                       keras.layers.Dense(10, activation = 'softmax', name = 'output')
], name = 'FASHION MNIST MODEL')

model.summary()

-> 편리하지만 많은 층을 추가하려면 Sequential 클래스의 생성자 너무 길어짐 

 

add() 매서드 활용

model = keras.Sequential()
model.add(keras.layers.Dense(100, activation = 'sigmoid', input_shape = (784, )))
model.add(keras.layers.Dense(10, activation = 'softmax'))

model.summary()

 

 

훈련

model.compile(loss = 'sparse_categorical_crossentropy', metrics = 'accuracy')
model.fit(train_scaled, train_target, epochs = 5)

 

 

렐루 함수 

- 시그모이드 함수는 오른쪽과 왼쪽 끝으로 ㄱㄹ수록 그래프가 누워있기 때문에 올바른 출력을 만드는데 신속하게 대응 X 

- 층이 많은 심층 신경망일수록 효과가 누적되어 학습 더 어렵게 만듦 

=> 이를 개선하고자 렐루ReLU 함수의 등장 

 

 

- 입력이 양수일 경우 그냥 입력을 통과시키고 음수일 경우 0으로 만듦 

- 렐루 함수는 특히 이미지 처리에서 좋은 성능을 냄 

 

Flatten 층

- 배치 차원을 제외하고 나머지 입력 차원을 모두 일렬로 펼치는 역할 (입력에 곱해지는 가중치나 절편은 없음)

model = keras.Sequential()
model.add(keras.layers.Flatten(input_shape = (28, 28)))
model.add(keras.layers.Dense(100, activation = 'relu'))
model.add(keras.layers.Dense(10, activation = 'softmax'))

model.summary()

 

- Flatten을 하면 저 reshape 과정을 안 해도 됨 

 

정리

(train_input, train_target), (test_input, test_target) = keras.datasets.fashion_mnist.load_data()
train_scaled = train_input / 255.0

from sklearn.model_selection import train_test_split
train_scaled, val_scaled, train_target, val_target = train_test_split(
    train_scaled, train_target, test_size = 0.2, random_state = 42)

model = keras.Sequential()
model.add(keras.layers.Flatten(input_shape = (28, 28)))
model.add(keras.layers.Dense(100, activation = 'relu'))
model.add(keras.layers.Dense(10, activation = 'softmax'))

model.compile(loss = 'sparse_categorical_crossentropy', metrics = 'accuracy')
model.fit(train_scaled, train_target, epochs = 5)

model.evaluate(val_scaled, val_target)

- 은닉층 추가하기 전보다 성능 향상

 

옵티마이저

- 손실함수를 최소화하는 방향으로 가중치를 갱신하는 알고리즘

model.compile(optimizer = 'sgd', loss = 'sparse_categorical_crossentropy', metrics = 'accuracy')
sgd = keras.optimizers.SGD()
model.compile(optimizer = sgd, loss = 'sparse_categorical_crossentropy', metrics = 'accuracy')

-> SGD 의 학습률을 바꾸고 싶다면 learning_ratea 매개변수 지정하여 사용 가능

 

다양한 옵티마이저

https://www.slideshare.net/yongho/ss-79607172/49

- 기본 경사 하강법 옵티마이저는 모두 SGD 클래스에서 제공 

- SGD 클래스의 momentum매개변수의 기본값은 0인데 이를 9보다 큰 값으로 지정하면 마치 그레디언트를 가속도 처럼 사용하는 모멘텀 최적화를 사용

- 보통 momentum 매개변수는 0.9 이상 지정

- SGD클래스의 nesterov 매개변수를 기본값 False 에서 True 로 바꾸면 네스테로프 모멘텀 최정화를 사용

sgd = keras.optimizers.SGD(momentum = 0.9, nesterov = True)

-> 네스테로프 모멘텀은 모멘텀 최적화를 2번 반복하여 구현 => 대부분의 경우 네스테로프 모멘텀 최적화가 기본 확률적 경사 하강법보다 더 나은 성능 제공 

 

- 모델이 최적점에 가까이 갈수록 학습률을 낮출 수 있는데 이렇게 하면 안정적으로 최적점에 수렴할 가능성이 높음 -> 이런 학습률을 적응적 학습률(adaptive learning rate)라고 함 이런 방식들은 학습률 매개변수를 튜닝하는 수고를 덜 수 있음 

-> 'adagrad', 'rmsprop' (optimizer 매개변수의 기본값이 rmsprop)

adagrad = keras.optimizers.Adagrad()
model.compile(optimizer = adagrad, loss = 'sparse_categorical_crossentropy', 
              metrics = 'accuracy')
rmsprop = keras.optimizers.RMSprop()
model.compile(optimizer = rmsprop, loss = 'sparse_categorical_crossentropy', 
              metrics = 'accuracy')

 

Adam 클래스 매개변수 기본값 사용하여 MNIST 모델 훈련

model = keras.Sequential()
model.add(keras.layers.Flatten(input_shape = (28, 28)))
model.add(keras.layers.Dense(100, activation = 'relu'))
model.add(keras.layers.Dense(10, activation = 'softmax'))

model.compile(optimizer = 'adam', loss = 'sparse_categorical_crossentropy', 
              metrics = 'accuracy')
model.fit(train_scaled, train_target, epochs = 5)

model.evaluate(val_scaled, val_target)

-> 출력 결과 보면 RMSprop과 결과 비슷 (오히려 검증세트에서는 낮은 성능을 보여주기도)

 


참고: https://hongong.hanbit.co.kr/%ED%98%BC%EC%9E%90-%EA%B3%B5%EB%B6%80%ED%95%98%EB%8A%94-%EB%A8%B8%EC%8B%A0%EB%9F%AC%EB%8B%9D-%EB%94%A5%EB%9F%AC%EB%8B%9D/

 

혼자 공부하는 머신러닝+딥러닝

혼자 공부하는 머신러닝 딥러닝, 무료 동영상 강의, 머신러닝+딥러닝 용어집을 다운로드 하세요. 포기하지 마세요! 독학으로 충분히 하실 수 있습니다. ‘때론 혼자, 때론 같이’ 하며 힘이 되겠

hongong.hanbit.co.kr

 

'STUDY > ML' 카테고리의 다른 글

[ML] fit_transform()과 transform()  (0) 2023.03.18
[ML] Binary Encoding과 One Hot Encoding  (0) 2023.03.18
[혼공머신] 01. 나의 첫 머신러닝  (0) 2023.02.10