인공 신경망
퍼셉트론(perceptron), 다층 퍼셉트론 (MLP)
이전 내용
심층 신경망 훈련
◆ 심층 신경망(Deep Neural Network, DNN)
[인공 신경망 실습을 통해 알게 된 두 가지]
1. 퍼셉트론은 인간의 뉴런을 모방한 '인공신경망'이다.
2. 다층 퍼셉트론은 퍼셉트론을 직렬로, 병렬로 연결하여 1개 이상의 은닉층을 가진 구조이다.
XOR문제, 기울기 소실 문제 등으로 인공신경망의 인기는 빠르게 식어갔다. 그러다 2006년 인공신경망 대신 심층 신경망(Deep Neural Network, DNN)이라는 용어가 사용되기 시작했다. 가중치 초기화 설정, ReLU 함수, 컴퓨터 성능 발전 등 다양한 방법으로 기울기 소실의 문제를 어느정도 해결하였다고 한다.
다층 퍼셉트론에서 은닉층을 많이 늘린 구조를 심층 신경망이라고 말할 수 있는데, 일반적으로 은닉층이 3개 이상인 구조를 심층 신경망이라고 하며, 이러한 심층 신경망을 이용하여 컴퓨터가 문제를 해결하는 과정을 딥러닝(Deep learning)이라고 한다. 즉 딥러닝은 컴퓨터가 데이터를 스스로 학습하여 문제를 해결하는 머신러닝(Machine learning) 방법 중 하나이다.
[심층 신경망 훈련 중 마주할 수 있는 문제들]
수백 개의 뉴런으로 구성된 10개 이상의 층을 수십만 개의 가중치로 연결해 훨씬 더 깊은 인공 신경망을 훈련한다고 생각해보면, 심층 신경망을 훈련하는 것은 쉬운 일이 아니며, 훈련 중에 아래와 같은 문제를 마주할 수 있다.
- 심층 신경망의 출력 층에서 멀어질수록 그레이디언트가 점점 더 작아지거나 커지는 문제가 나타날 수 있으며, 두 문제 모두 하위 층을 매우 훈련하기 어렵게 만든다.
- 대규모 신경망을 위한 훈현 데이터가 충분하지 않거나 레이블을 만드는 작업에 비용이 너무 많이 들어갈 수 있다.
- 훈련이 극단적으로 느려질 수 있다.
- 수백만 개의 파라미터를 가진 모델은 훈련 세트에 과대적합될 위험이 매우 크며, 특히 훈련 샘플이 충분치 않거나 잡음이 많은 경우에는 과대적합 될 확률이 더 크다.
해결책2 - 전이 학습, 비지도 사전 훈련
전이 학습과 비지도 사전 훈련은 레이블된 데이터가 적을 때 복잡한 문제를 다루는 데 도움이 된다.
- 전이 학습: 한 작업 또는 데이터 세트를 통해 얻은 지식을 사용하여 다른 관련 작업 및/또는 다른 데이터 세트에서 모델 성능을 개선하는 머신 러닝 기술이다. 다시 말해, 전이 학습은 한 환경에서 학습된 내용을 사용하여 다른 환경에서 일반화를 개선하는 것이다.
- 비지도 사전 훈련: 레이블된 훈련 데이터가 많지 않을 때 수행하는 것이다. 말그대로 비지도 학습 기법으로 레이블이 없는 전체 데이터로 모델을 훈련한 다음, 지도학습 기법을 사용하여 레이블된 데이터만으로 최종 학습을 위해 세밀하게 튜닝하는 것이다. 비지도 학습 부분은 한 번에 하나의 층씩 훈련하거나 바로 전체 모델을 훈련할 수 있다.
1. 전이 학습: 사전 훈련된 층 재사용하기
해결하려는 것과 비슷한 유형의 문제를 처리한 신경망이 이미 있는지 찾았다면 최상위 층을 제외하고 대부분의 층을 재사용할 수 있는데, 이 방법(전이 학습)은 훈련 속도를 크게 높일 뿐만 아니라 필요한 훈련 데이터도 크게 줄여준다.
만약 이 신경망을 훈련할 때는 첫 번째 신경망의 일부를 재사용해 보는데, 만약 원래 문제에서 사용한 것과 크기가 다른 이미지를 입력으로 사용한다면 원본 모델에 맞는 크기로 변경하는 전처리 단계를 추가해야 한다. 일반적으로 전이 학습은 저수준 특성이 비슷한 입력에서 잘 작동한다.
보통 원본 모델의 출력 층을 바꿔야 하는데, 이 층은 새로운 작업에 가장 유용하지 않거나 새로운 작업에 필요한 출력 개수와 맞지 않을 수 있다.
또한, 원본 모델의 상위 은닉 층은 하위 은닉 층보다 덜 유용한데, 새로운 작업에 유용한 고수준 특성은 원본 작업에서 유용했던 특성과는 상당히 다르기 때문이다. 따라서 재사용할 층 개수를 잘 선정할 수 있어야 한다.
[전이 학습 과정]
- 재사용하는 층을 모두 동결: 경사 하강법으로 가중치가 고정된 상태로 남도록 훈련되지 않는 가중치로 만듦.
- 모델 훈련 및 성능 평가: 맨 위에 있는 한두 개의 은닉 층의 동결을 해제하고 역전파를 통해 가중치를 조정하여 성능이 향상되는지 확인.
- 훈련 데이터가 많을수록 많은 층의 동결 해제
- 재사용 층의 동결을 해제할 때는 학습률을 줄이면 가중치를 세밀하게 튜닝하는 데 도움.
- 좋은 성능을 낼 수 없고 훈련 데이터가 적을 경우, 상위 은닉 층을 제거하고 남은 은닉 층을 다시 동결.
- 재사용할 은닉 층의 적절한 개수를 찾을 때까지 반복.
- 훈련 데이터가 많을 경우, 은닉 층을 제거하는 대신 다른 것으로 바꾸거나 더 많은 은닉 층 추가.
1-1. 케라스를 사용한 전이 학습(feat. 패션MNIST 데이터셋)
예를 들어 샌들과 셔츠를 제외한 8개의 클래스만 있는 패션 MNIST 데이터셋의 클래스를 분류하는 작업 A를 만들고 훈련시 켜 90% 이상의 정확도가 나오는 꽤 좋은 성능의 모델 A가 있다. 만약 모델 A에서 제외된 샌들과 셔츠 이미지를 구분하는 작업 B를 해결하기 위해 이진 분류기(양성=셔츠, 음성=샌들)를 훈련하려 하는데, 레이블된 이미지는 겨우 200개로 매우 적다. 이를 위해 모델 A와 구조가 거의 비슷한 모델 B라는 새 모델을 훈련하여 90% 이상의 테스트 정확도를 얻었다.
그런데 작업 B는 모델 A가 해결하는 작업 A와 매우 비슷하다는 것을 깨달았을 때, 전이 학습이 도움이 될 수 있는지를 확인해 본다.
1) 모델 A 생성 및 저장
먼저 '모델 A'를 만들기 위해, 패션 MNIST를 작업 A와 B로 분할한 다음 모델 A를 학습하고 "my_model_A"에 저장한다.
pos_class_id = class_names.index("Pullover")
neg_class_id = class_names.index("T-shirt/top")
def split_dataset(X, y):
y_for_B = (y == pos_class_id) | (y == neg_class_id)
y_A = y[~y_for_B]
y_B = (y[y_for_B] == pos_class_id).astype(np.float32)
old_class_ids = list(set(range(10)) - set([neg_class_id, pos_class_id]))
for old_class_id, new_class_id in zip(old_class_ids, range(8)):
y_A[y_A == old_class_id] = new_class_id # A에 대한 클래스 ID 재정의
return ((X[~y_for_B], y_A), (X[y_for_B], y_B))
(X_train_A, y_train_A), (X_train_B, y_train_B) = split_dataset(X_train, y_train)
(X_valid_A, y_valid_A), (X_valid_B, y_valid_B) = split_dataset(X_valid, y_valid)
(X_test_A, y_test_A), (X_test_B, y_test_B) = split_dataset(X_test, y_test)
X_train_B = X_train_B[:200]
y_train_B = y_train_B[:200]
tf.random.set_seed(42)
model_A = tf.keras.Sequential([
tf.keras.layers.Flatten(input_shape=[28, 28]),
tf.keras.layers.Dense(100, activation="relu",
kernel_initializer="he_normal"),
tf.keras.layers.Dense(100, activation="relu",
kernel_initializer="he_normal"),
tf.keras.layers.Dense(100, activation="relu",
kernel_initializer="he_normal"),
tf.keras.layers.Dense(8, activation="softmax")
])
model_A.compile(loss="sparse_categorical_crossentropy",
optimizer=tf.keras.optimizers.SGD(learning_rate=0.001),
metrics=["accuracy"])
history = model_A.fit(X_train_A, y_train_A, epochs=20,
validation_data=(X_valid_A, y_valid_A))
model_A.save("my_model_A.keras")
2) 모델 A 로드 및 모델 A의 층을 기반으로 새로운 모델 생성
출력 층만 제외하고 모든 층을 재사용한다.
model_A = tf.keras.models.load_model('my_model_A.keras')
model_B_on_A = tf.keras.Sequential(model_A.layers[:-1]) # 새로운 모델 생성
model_B_on_A.add(tf.keras.layers.Dense(1, activation='sigmoid'))
3) 모델 A의 구조 복제 및 가중치 복사
model_A와 model_B_on_A는 일부 층을 공유하기 때문에, model_B_on_A를 훈련할 때 model_A도 영향을 받는다. 이를 원치 않는다면 층을 재사용하기 전에 model_A를 클론해야 하며, clone_model() 메서드로 모델 A의 구조를 복제한 후 가중치를 복사한다. ※ clone.model() 메서드의 경우 가중치는 제외하고 구조만 복제한다.
model_A_clone = tf.keras.models.clone_model(model_A)
model_A_clone.set_weights(model_A.get_weights())
4) 작업 B를 위해 model_B_on_A 훈련
새로운 출력 층이 랜덤하게 초기화되어 있으므로 처음 몇 번의 에포크 동안 큰 오차를 만들 수 있으므로, 큰 오차 그레이디언트가 재사용된 가중치를 망치지 않도록 처음 몇 번의 에포크 동안 재사용된 층을 동결하고 새로운 층에게 적절한 가중치를 학습할 시간을 준다. 이를 위해 trainable 속성을 False로 지정하고 모델을 컴파일한다.
for layer in model_B_on_A.layers[:-1]:
layer.trainable = False
model_B_on_A.compile(loss='binary_crossentropy', optimizer=tf.keras.optimizers.SGD(learning_rate=0.001),
metrics=['accuracy'])
5) 재사용된 층을 작업 B에 맞게 미세 튜닝
몇 번의 에포크 동안 모델을 훈련 하고, 재사용된 층의 동결을 해제하고 작업 B에 맞게 재사용된 층을 세밀하게 튜닝하기 위해 훈련을 계속한다. 일반적으로 재사용된 층의 동결을 해제한 후에 학습률을 낮추는 것이 좋은데, 이렇게 하면 재사용된 가중치가 망가지는 것을 막아준다.
※ 층을 동결하거나 동결을 해제한 후에는 반드시 모델을 컴파일 해야 한다.
history = model_B_on_A.fit(X_train_B, y_train_B, epochs=4,
validation_data=(X_valid_B, y_valid_B))
for layer in model_B_on_A.layers[:-1]:
layer.trainable = True
optimizer = tf.keras.optimizers.SGD(learning_rate=0.001)
model_B_on_A.compile(loss='binary_crossentropy', optimizer=optimizer,
metrics=['accuracy'])
history = model_B_on_A.fit(X_train_B, y_train_B, epochs=16,
validation_data=(X_valid_B, y_valid_B))
6) 최종 점수 확인
model_B_on_A.evaluate(X_test_B, y_test_B)
▶ 이 모델의 테스트 정확도는 91.25% 이다.
전이 학습은 작은 완전 연결 네트워크에서는 잘 작동하지 않는데, 아마도 작은 네트워크는 패턴 수를 적게 학습하고 완전 연결 네트워크는 특정 패턴을 학습하기 때문 일 것이다. 전이 학습은 조금 더 일반적인 특성을 감지하는 경향이 있는 심층 합성곱 신경망에서 더 잘 작동한다.
2. 비지도 사전 훈련
풀어야 할 문제가 복잡하고 재사용할 수 있는 비슷한 모델이 없으며 레이블된 훈련 데이터가 적을 때는 비지도 사전 훈련이 좋은 선택이 될 수 있다. 요즘에는 일반적으로 한 번에 전체 비지도 학습 모델을 훈련하고 RBM 대신 오토인코더나 GAN을 사용한다.
[RBM, 오토인코더, GAN]
◆ RBM (Restricted Boltzmann Machine, 제한된 볼츠만 머신)
1) 개념
RBM은 비지도 학습을 위한 생성 모델(generative model)로, 에너지 기반 모델(Energy-Based Model)의 일종이다.
두 층으로 구성된 신경망으로, 가시층(Visible Layer)과 은닉층(Hidden Layer) 사이의 연결만 존재하며, 동일 층 내의 노드는 연결되지 않은 제한된 구조이다.
2) 구조
- 가시층: 입력 데이터를 표현하는 층.
- 은닉층: 입력 데이터의 숨겨진 특성을 학습하는 층.
3) 작동 방식
확률적 모델로 동작하며, 각 뉴런은 활성화될 확률을 계산하며, 에너지 함수(Energy Function)를 통해 입력 데이터와 은닉층 노드 간의 상관관계를 학습한다. CD 알고리즘(Contrastive Divergence)을 사용하여 파라미터를 업데이트한다.
4) 특징
- 특징 추출, 차원 축소, 이상 탐지에 사용.
- 딥러닝 초창기에는 심층 신경망을 초기화하는 데 사용되었으나, 최근에는 활용도가 줄어들었다.
5) 적용 분야
- 협업 필터링(추천 시스템).
- 특징 추출 및 차원 축소.
- 비지도 학습 기반 데이터 재구성.
◆ Autoencoder (오토인코더)
1) 개념
Autoencoder는 비지도 학습으로 데이터를 효율적으로 인코딩하는 데 사용되는 신경망이며, 입력 데이터를 압축(인코딩)하고 다시 복원(디코딩)하여 원본과 유사한 출력을 생성하는 모델이이다.
2) 구조
- 입력층(Input Layer) → 은닉층(Hidden Layer) → 출력층(Output Layer)으로 구성.
- 인코더(Encoder): 데이터를 저차원 잠재 공간(Latent Space)으로 압축.
- 디코더(Decoder): 잠재 공간에서 원본 데이터를 복원.
3) 학습 목표
- 입력 데이터와 출력 데이터의 차이(손실 함수, 보통 MSE)를 최소화.
4) 유형
- Vanilla Autoencoder: 기본적인 구조.
- Sparse Autoencoder: 은닉층의 일부 뉴런만 활성화되도록 제한.
- Denoising Autoencoder: 입력 데이터에 노이즈를 추가해 학습, 더 강인한 모델 생성.
- Variational Autoencoder (VAE): 잠재 공간에서 확률 분포를 학습, 생성 모델로 활용.
5) 적용 분야
- 데이터 차원 축소 및 시각화.
- 이상 탐지.
- 노이즈 제거(이미지, 음성 등).
- 생성 모델: VAE를 활용해 새로운 데이터를 생성.
◆ GAN (Generative Adversarial Network, 생성적 적대 신경망)
1) 개념
GAN은 두 개의 신경망인 생성자(Generator)와 판별자(Discriminator)가 경쟁하며 학습하는 생성 모델이다.
생성자는 가짜 데이터를 만들어내고, 판별자는 데이터가 진짜인지 가짜인지 구분한한다.
2) 구조
- 생성자(Generator): 랜덤 노이즈를 입력으로 받아 실제 데이터와 유사한 데이터를 생성.
- 판별자(Discriminator): 입력 데이터가 실제 데이터인지, 생성자가 만든 가짜 데이터인지 구분.
- 두 네트워크는 적대적 학습(adversarial training)을 통해 서로 발전.
3) 학습 과정
- 생성자는 판별자를 속일 수 있는 데이터를 생성하려고 노력.
- 판별자는 생성자가 만든 데이터를 진짜와 구분하려고 노력.
- 학습이 진행될수록 생성자는 더 진짜 같은 데이터를 만들고, 판별자는 더 정교하게 구분.
4) 손실 함수
- 교차 엔트로피 손실 또는 **JS 발산(Jensen-Shannon Divergence)**를 활용하여 두 네트워크를 동시에 학습.
5) 유형
- DCGAN: CNN 기반 GAN으로 이미지 생성에 특화.
- CycleGAN: 이미지 간 스타일 변환 (예: 낮↔밤, 여름↔겨울).
- StyleGAN: 고해상도 이미지 생성.
- WGAN: 학습 안정성을 개선한 GAN.
6) 적용 분야
- 이미지 생성 (예: 얼굴 생성, 애니메이션 스타일 변환).
- 데이터 증강.
- 비디오 생성 및 예측.
- 텍스트-이미지 변환(예: 텍스트 설명으로 이미지 생성).
2-1. 보조 작업에서 사전 훈련
레이블된 훈련 데이터가 많지 않다면 마지막 선택 사항은 레이블된 훈련 데이터를 쉽게 얻거나 생성할 수 있는 보조 작업에서 첫 번째 신경망을 훈련하는 것이다. 그리고 이 신경망의 하위 층을 실제 작업을 위해 재사용한다. 첫 번째 신경망의 하위 층은 두 번째 신경망에 재사용될 수 있는 특성 추출기를 학습하게 된다.
다음 내용
[출처]
핸즈 온 머신러닝
고등학생을 위한 인공신경망과 딥러닝
딥 러닝을 이용한 자연어 처리 입문
IBM
https://iambeginnerdeveloper.tistory.com/188
https://post.naver.com/my.naver?memberNo=26040503
https://jaylala.tistory.com
'[파이썬 Projects] > <파이썬 딥러닝, 신경망>' 카테고리의 다른 글
[딥러닝] 텐서플로를 사용한 사용자 정의 모델과 훈련 (0) | 2024.11.24 |
---|---|
[딥러닝] 심층 신경망 훈련 (1) | 2024.11.24 |
[딥러닝] 심층 신경망 훈련 - 1 (0) | 2024.11.23 |
[딥러닝] 신경망 하이퍼파라미터 튜닝하기 (1) | 2024.11.21 |
[딥러닝] 케라스로 다층 퍼셉트론 구현하기 - 3 (1) | 2024.11.20 |