220911

AIVILLAIN·2022년 9월 11일
0

오공완

목록 보기
5/25

Sequential 모델을 넘어서 케라스의 함수형 API

지금까지는 모든 신경망을 Sequential 모델을 사용하여 만듬
Sequential 모델은 네트워크의 입력과 출력이 하나라고 가정
층을 차례대로 쌓아 구성
많은 경우에는 이런 가정이 적절
하지만 일부 네트워크는 개별 입력이 여러 개 필요하거나 출력이 여러 개 필요
층을 차례대로 쌓지 않고 층 사이를 연결하여 그래프처럼 만드는 네트워크도 있음

다양한 입력 소스에서 전달된 데이터를 다른 종류의 신경망 층을 사용하여 처리하고 합침
ex) 중고 의류 시장 가격 예측 모델
사용자가 제공하는 메타데이터 (의류 브랜드, 연도 등) 사용자가 제공한 텍스트 설명, 제품 사진 등

메타데이터만 있다면 이를 원-핫 인코딩 후 완전 연결 네트워크를 사용하여 가격을 예측할 수 있음
텍스트 설명만 있다면 RNN이나 1D ConvNet 사용 가능
이미지만 있다면 2D ConvNet을 사용할 수 있음
간단한 방법은 3개의 모델을 따로 훈련하고 각 예측을 가중 평균하는 것
모델에서 추출한 정보가 중복된다면 이 방식은 최적이 아닐 것
가능한 모든 종류의 입력 데이터를 동시에 사용해서 정확한 하나의 모델을 학습하는 것이 더 나은 방법

어떤 작업은 입력 데이터에서 여러 개의 타깃 속성을 예측해야 하는 경우
ex) 소설, 짧은 글이 있을 때 자동으로 장르별로 분류 및 글을 쓴 대략의 시대를 예측
2개의 모델을 따로 훈련할 수 있음
장르를 위한 모델(분류)과 시대를 위한 모델(회귀)
이 속성들은 통계적으로 독립적이지 않기 때문에 동시에 장르와 시대를 함께 예측하도록 학습해야 좋은 모델을 만들 수 있음 (2개의 출력)
장르와 시대 사이의 상관관계 때문에 소설의 시대를 알면 장르의 공간에서 정확하고 풍부한 표현을 학습하는 데 도움이 됨

최근 개발된 많은 신경망 구조는 선형적이지 않은 네트워크 토폴로지가 필요 (인셉션 계열의 네트워크)
※ 토폴로지 : 컴퓨터 네트워크의 요소들(링크, 노드 등)을 물리적으로 연결해 놓은 것 또는 방식

모델에 잔차 연결을 추가하는 경향도 있음 (ResNet 계열의 네트워크)
하위 층의 출력 텐서를 상위 층의 출력 텐서에 더해서 아래층의 표현이 네트워크 위쪽으로 흘러갈 수 있도록
하위 층에서 학습된 정보가 데이터 처리 과정에서 손실되는 것을 방지
여러 경우에 다중 입력 모델, 다중 출력 모델, 그래프 구조를 띤 모델이 필요하지만 케라스의 Sequential 클래스를 사용해서는 만들 수 없음
케라스에는 훨씬 더 일반적이고 유연한 다른 방법인 함수형 API가 있음

함수형 API 소개


함수형 API에서는 직접 텐서들의 입출력을 다룸
함수처럼 층을 사용하여 텐서를 입력받고 출력함
관련되지 않은 입력과 출력으로 모델을 만들면 RuntimeError가 발생
Model 객체를 사용한 컴파일, 훈련, 평가 API는 Sequential 클래스와 같음

다중 입력 모델


함수형 API는 다중 입력 모델을 만드는 데 사용 가능
서로 다른 입력 가지를 합치기 위해 여러 텐서를 연결할 수 있는 층을 사용
텐서를 더하거나 이어 붙이는 식 (keras.layers.add, keras.layers.concatenate)

pydot install 문제 해결법

입력이 2개인 모델 훈련 방법은?
넘파이 배열의 리스트를 주입하거나 입력 이름과 넘파이 배열로 이루어진 딕셔너리를 모델의 입력으로 주입
두 번째 방식은 입력 이름을 설정했을 때 사용 가능

다중 출력 모델


네트워크 출력마다 다른 손실 함수 지정
compile 메서드에 리스트나 딕셔너리를 사용하여 출력마다 다른 손실 지정 가능
계산된 손실 값은 전체 손실 하나로 더해지고 훈련 과정을 통해 최소화

손실 값이 많이 불균형하면 모델이 개별 손실이 가장 큰 작업에 치우쳐 표현을 최적화
다른 작업들이 손해를 입음
이를 위해 손실 값이 최종 손실에 기여하는 수준을 지정할 수 있음
손실값의 스케일이 다를 때 유용
회귀 작업의 손실 MSE 값, 성별 분류 작업에 사용되는 크로스 엔트로피 손실 크로스엔트로피 값 0.1 등
균형을 맞추려면 크로스엔트로피 손실에 가중치 10, MSE 손실에 가중치 0.25를 줄 수 있음

층으로 구성된 비순환 유향 그래프


내부 토폴로지가 복잡한 네트워크도 만들 수 있음
비순환 유향 그래프도 만들 수 있음
그래프로 구현된 몇 개의 신경망 컴포넌트가 널리 사용됨
가장 유명한 2개는 인셉션 모듈과 잔차 연결

인셉션 모듈

합성곱 신경망에서 인기 있는 네트워크 구조
네트워크 안의 네트워크 구조에서 영감을 받음
나란히 분리된 가지를 따라 모듈을 쌓아 독립된 작은 네트워크처럼 구성
네트워크가 따로따로 공간 특성과 채널 방향의 특성을 학습하도록 도움
한꺼번에 학습하는 것보다 효과가 더 높음

※ 1x1 합성곱의 목적

추출된 패치가 하나의 타일을 이루어졌을 때
모든 타일 벡터를 하나의 Dense 층에 통과시키는 것과 동일
입력 텐서의 채널 정보를 혼합한 특성을 계산
공간 방향으로는 정보를 섞지 않음
채널 방향의 특성 학습, 공간 방향의 특성 학습은 분리하는 데 도움을 줌
채널이 공간 방향으로 상관관계가 크고 채널 간에는 독립적이라고 가정하면 납득할 만한 전략

잔차 연결 (residual connection)

엑셉션을 포함하여 2015년 이후 등장한 많은 네트워크 구조에 있는 그래프 형태의 네트워크 컴포넌트
대규모 딥러닝 모델에서 흔히 나타나는 그래디언트 소실, 표현 병목을 해결
일반적으로 10개 층 이상을 가진 모델에 잔차 연결을 추가하면 도움이 됨
하위 층의 출력을 상위 층의 입력으로 사용
하위 층의 출력이 상위 층의 활성화 출력에 연결되는 것이 아니고 더해짐
두 출력의 크기가 동일해야 함
크기가 다르다면 선형 변환을 사용하여 하위 층의 활성화 출력을 목표 크기로 변환해야 함
(활성화 함수가 없는 Dense 등)

※ 딥러닝의 표현 병목

Sequential 모델에서 표현 학습을 위한 층은 다른 층 위에 연달아 놓임
이전 층의 활성화 출력 정보만을 사용
어떤 층이 너무 작으면 이 활성화 출력에 얼마나 많은 정보를 채울 수 있느냐에 모델 성능이 좌우됨
하위 층의 정보를 다시 주입하는 잔차 연결은 손실된 정보에 대한 이슈를 어느 정도 해결할 수 있음

※ 딥러닝의 그래디언트 소실 문제

역전파는 출력 손실에서 얻은 피드백 신호를 하위 층에 전파
피드백 신호가 깊이 쌓인 층을 통과하여 전파되면 신호가 아주 작아지거나 완전히 사라질 수 있음
그래디언트 소실 문제
심층 신경망과 긴 시퀀스를 처리하는 순환 신경망에서 모두 나타남
순환 신경망에서 LSTM 층이 이 문제를 해결하기 위한 방식을 사용
잔차 연결은 피드 포워드 심층 신경망에서 비슷한 역할을 하고, 좀 더 단순함
주 네트워크 층에 나란히 단순한 선형 정보를 실어 날라 그래디언트가 깊게 쌓은 층을 통과하여 전파하도록 도와줌

층 가중치 공유


함수형 API는 층 객체를 여러 번 재사용할 수 있음
층 객체를 두 번 호출하면 새로운 층 객체를 만들지 않고 각 호출에 동일한 가중치 재사용
공유 가지를 가진 모델을 만들 수 있음
같은 가중치를 공유하고 같은 연산을 수행
같은 표현을 공유하고 이런 표현을 다른 입력에서 함께 학습
두 문장 사이의 의미가 비슷한지 측정하는 모델 가정
2개의 입력(비교할 문장), 0과 1 사이 점수 출력
대화 시스템에서 자연어 질의에 대한 중복 제거를 포함하는 많은 애플리케이션에서 유용하게 사용 가능
두 입력 시퀀스가 바뀔 수 있음
의미가 비슷하다는 것은 대칭적인 관계 (A에서 B에 대한 유사도 == B에서 A 에 대한 유사도)
각 입력 문장을 처리하는 2개의 독립된 모델을 학습하는 것은 이치에 맞지 않음
대신 하나의 LSTM 층으로 양쪽을 모두 처리하는 것이 좋음
이 LSTM 층의 표현은 두 입력에 대해 함께 학습됨 (샴 LSTM, 공유 LSTM)

층과 모델


함수형 API에서는 모델을 층처럼 사용할 수 있음
입력 텐서로 모델을 호출해서 출력 텐서를 얻을 수 있음
모델 객체를 호출할 때 모델의 가중치가 재사용됨
층 객체나 모델 객체나 객체를 호출하는 것은 항상 그 객체가 가진 학습된 표현을 재사용
듀얼 카메라에서 입력을 받는 비전 모델 가정
왼쪽 카메라와 오른쪽 카메라에서 시각적 특징을 추출하여 합치기 위해 2개의 독립된 모델을 사용할 필요가 없음
저수준처리 과정이 공유될 수 있음
가중치가 같고 동일한 표현을 공유하는 층을 사용

케라스 콜백과 텐서보드를 사용한 딥러닝 모델 검사와 모니터링

훈련하는 동안 모델 내부에서 일어나는 일을 조사하고 제어하는 방법
model.fit(), model.fit_generator()로 수십번의 에포크를 실행하는 것은 종이 비행기를 날리는 것과 비슷
손을 떠나면 경로와 착륙 지점을 제어할 방법이 없음

콜백을 사용하여 모델의 훈련 과정 제어


최적의 검증 손실을 위해 얼마나 많은 에포크가 필요한지 알 수 없음
좋은 처리 방법은 검증 손실이 더이상 향상되지 않을 때 훈련을 멈추는 것
케라스 콜백을 사용하여 구현 가능
콜백은 모델의 fit() 메서드가 호출될 때 전달되는 객체
훈련하는 동안 모델은 여러 지점에서 콜백을 호출
콜백은 모델의 상태와 성능에 대한 모든 정보에 접근하고 훈련 중지, 모델 저장, 가중치 적재 또는 모델 상태 변경 등 처리 가능

  • 모델 체크포인트 저장 : 특정 지점에서 모델의 가중치 저장
  • 조기 종료 : 검증 손실이 더 이상 향상되지 않을 때 훈련을 중지
  • 훈련하는 동안 하이퍼파라미터 값을 동적으로 조정 (옵티마이저의 학습률 등)
  • 훈련과 검증 지표를 로그에 기록하거나 모델이 학습한 표현이 업데이트 될 때마다 시각화 (progress bar 등)

ModelCheckpoint와 EarlyStopping
EarlyStopping 콜백은 정해진 에포크 동안 모니터링 지표가 향상되지 않을 때 훈련 중지 가능
과대적합이 시작되자마자 훈련 중지 가능
에포크 횟수를 줄여 다시 모델을 훈련할 필요가 없음
일반적으로 훈련하는 동안 모델을 계속 저장하는 ModelCheckpoint와 함께 사용

ReduceLROnPlateau
검증 손실이 향상되지 않을 때 학습률을 작게 할 수 있음
손실 곡선이 평탄할 때 학습률을 작게 하거나 크게 하면 훈련 도중 지역 최솟값(local minimum)에서 효과적으로 빠져나올 수 있음

자신만의 콜백 만들기
내장 콜백에서 제공하지 않는 특수 행동이 훈련 도중 필요하면 자신만의 콜백 생성 가능
keras.callbacks.Callback 클래스를 상속받아 구현
호출될 여러 지점을 나타내기 위해 약속된 메서드 구현
on_epoch_begin
on_epoch_end
on_batch_begin
on_batch_end
on_train_begin
on_train_end
logs 매개변수와 함께 호출됨
이전 배치, 에포크에 대한 훈련과 검증 측정값이 담겨 있는 딕셔너리가 전달됨
추가 참조 가능 속성

  • self.model : 콜백 호출하는 모델 객체
  • self.validation_data : fit() 메서드에 전달된 검증 데이터

ex) 매 에포크 끝에서 검증 세트의 첫 번째 샘플로 모델에 있는 모든 층의 활성화 출력을 계산하여 디스크에 저장하는 커스텀 콜백

텐서플로의 시각화 프레임워크 텐서보드


모델이 얼마나 잘 작동하는지 가능한 많은 정보를 얻는 것
실험 결과에 대한 처리
텐서플로 백엔드로 케라스를 설정한 경우 케라스 모델에서 사용 가능
훈련 모델의 내부에서 일어나는 모든 것을 시각적으로 모니터링할 수 있도록 돕는 것
모델의 최종 손실 외 더 많은 정보를 모니터링하면 모델 작동에 대한 명확한 그림을 그릴 수 있음

  • 훈련하는 동안 측정 지표를 시각적으로 모니터링
  • 모델 구조 시각화
  • 활성화 출력과 그래디언트의 히스토그램을 그림
  • 3D로 임베딩 표현

모델의 성능을 최대로 끌어올리기

단순히 작동만 하는 모델이 필요하다면 이런저런 구조를 시도해 보아도 충분
작동하는 수준을 넘어 아주 잘 작동하는 최고의 모델

고급 구조 패턴


잔차 연결 외 꼭 알아야 할 디자인 패턴이 추가로 존재
정규화,깊이별 분리 합성곱
고성능 심층 컨브넷을 만들 때 유용

배치 정규화

정규화는 머신러닝 모델에 주입되는 샘플들을 균일하게 만드는 광범위한 방법
모델이 학습하고 새로운 데이터에 잘 일반화되도록 도움
데이터에서 평균을 빼서 데이터를 원점에 맞추고 표준 편차로 나누어 분산을 1로 만듬
정규 분포를 따른다고 가정하고 조정한 것

데이터 정규화는 네트워크에서 일어나는 모든 변환 후에도 고려되어야 함
Dense나 Conv2D 층에 들어가는 데이터ㄴ의 평균이 0이고 분산이 1이더라도 출력되는 데이터가 동일한 분포를 가질 것이라고 기대하기 어려움

훈련하는 동안 평균과 분산에 대한 지수 이동 평균을 내부에 유지, 평균과 분산이 바뀌더라도 이에 적응하여 데이터를 정규화
그래디언트의 전파를 도움
ResNet50, Inceptvion V3, Exception 등
BatchNormalization 층은 일반적으로 합성곱이나 완젼 연결 층 다음에 사용

깊이별 분리 합성곱

Conv2D를 대체하면서 더 가볍고 더 빠른 층 (SeparableConv2D)
입력 채널별로 따로따로 공간 방향 합성곱 수행
이후 점별 합성곱을 통해 출력 채널 합침
공간 특성 학습, 채널 방향 특성 학습을 분리하는 효과
입력에서 공간상 위치는 상관관계가 크지만 채널별로는 매우 독립적이라고 가정
모델 파라미터와 연산 수를 크게 줄여주기 때문에 작고 더 빠른 모델 만듬
작은 데이터로도 더 좋은 표현을 학습하고 성능이 더 높은 모델을 만듬
제한된 데이터로 작은 모델을 처음부터 훈련시킬 때 특히 더 중요

하이퍼파라미터 최적화

얼마나 많은 층, 얼마나 많은 유닛과 필터, 활성화 함수 종류, 드롭아웃 등 구조에 관련된 파라미터를 하이퍼파라미터라고 부름
경험 많은 머신 러닝 엔지니어와 연구자는 하이퍼파라미터에 따라 작동하는 것과 작동하지 않는 것에 대한 직관이 있음
공식적인 규칙은 없음
주어진 문제에서 최대의 성능을 얻고 싶다면 사람이 임의로 선택한 결정에 만족해서는 안됨
가능성 있는 구조를 탐색해서 실제 가장 높은 성능을 내는 것을 찾음

  • 일련의 하이퍼파라미터를 자동으로 선택
  • 선택된 하이퍼파라미터로 모델 만듬
  • 훈련 데이터에 학습하고 검증 데이터에서 최종 성능 측정
  • 다음으로 시도할 하이퍼파라미터를 선택
  • 이 과정을 반복
  • 마지막으로 테스트 데이터에서 성능 측정

주어진 하이퍼파라미터에서 얻은 검증 성능을 사용하여 다음 번에 시도할 하이퍼파라미터를 선택하는 알고리즘이 핵심
베이지안 최적화, 유전 알고리즘, 랜덤 탐색 등

모델의 가중치를 훈련하는 것은 비교적으로 쉬움
하이퍼파라미터를 업데이트하는 것은 어려움

  • 피드백 신호를 계산하는 것은 비용이 매우 많이 듬
    새로운 모델을 만들고 데이터셋을 사용하여 처음부터 다시 훈련해야 함
  • 하이퍼파라미터 공간은 일반적으로 분리되어 있는 결정들로 채워짐
    (연속적이지 않고 미분 가능하지 않음)
    하이퍼파라미터 공간에 경사 하강법을 사용할 수 없음
    경사 하강법보다 비효율적인 그래디언트-프리 최적화 기법을 사용해야 함

모델 앙상블

가장 좋은 결과를 얻을 수 있는 또 다른 강력한 기법
여러 개의 다른 모델의 예측을 합쳐서 더 좋은 예측을 만듬
아주 뛰어난 단일 모델보다 성능이 좋음

독립적으로 훈련된 다른 종류의 좋은 모델이 각기 다른 장점을 가지고 있다는 가정
각 모델은 예측을 만들기 위해 조금씩 다른 측면을 바라봄
데이터의 모든 면이 아닌 부분 특징
각자의 가정(고유한 모델 구조와 랜덤 가중치 초기화)을 이용하고 각자의 관점으로 이해
각 모델은 데이터의 일부분에 맞는 정답을 찾지만 완전한 정답은 아님
이들의 관점을 모으면 데이터를 훨씬 더 정확하게 묘사 가능

앙상블이 잘 작동하게 만드는 핵심은 분류기의 다양성
모든 모델이 같은 방향으로 편향되어 있다면 앙상블은 동일한 편향을 유지할 것
최대한 다르면서 좋은 모델을 앙상블
최상의 모델이 얼마나 좋은지보다 앙상블의 후보 모델이 얼마나 다양한지가 중요

profile
소신있는 오픈마인드

0개의 댓글