일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 자바 실습
- 정보처리기사필기
- 코딩테스트
- CSS
- 혼공머신
- 데이터입출력구현
- 파이썬라이브러리
- 파이썬
- pandas
- 연습문제
- SQL
- 텍스트마이닝
- 중학수학
- CNN
- 자바
- 중학1-1
- JSP/Servlet
- C++
- 컴퓨터구조
- 정수와유리수
- 정보처리기사실기
- 운영체제
- 영어공부
- numpy/pandas
- 딥러닝
- 데이터분석
- 데이터베이스
- 머신러닝
- html/css
- 컴퓨터비전
- Today
- Total
클라이언트/ 서버/ 엔지니어 "게임 개발자"를 향한 매일의 공부일지
케라스 8 - 복잡한 모델 생성 본문
여기서부터는 혼공책에서 공부하지 못했던 내용이라 잘 이해할 수 있을지 조금 걱정이 된다. 그래도 여기까지 왔다면 케라스에 대해 어느 정도 잘 이해한다는 증거이다. 이제 학습을 시작해 본다.
1. 함수형 API(Functonal API)
함수 형태로 딥러닝 모델을 정의하면 다양한 모델 구조를 구현할 수 있다. 여러 층을 시퀀스 형태로 연결하는 Sequential API와 다르게, Funtional API는 복잡한 구조의 모델을 정의할 수 있다.
이 그림과 같이 함수의 입력 매개변수를 여러 개 갖는 다중 입력, 함수의 return 값을 여러 개 갖는 다중 출력, 같은 레벨에 여러 개의 층을 배치하여 입력과 출력을 공유하는 구조도 가능하다.
다음 예제는 기존에 Sequential API로 구현한 mnist 분류기 모델을 함수형 API로 동일하게 구현한 코드다.
함수형 API를 사용하기 위해서는 먼저 Input 레이어를 정의한다. Input 레이어에 데이터의 입력 shape을 정의한다. 레이어마다 반환되는 출력 값을 변수에 저장한 뒤 다음 레이어의 입력으로 연결한다. 이렇게 여러 개의 레이어를 마치 체인 구조로 입출력을 계속 연결할 수 있다.
레이어마다 name 매개변수로 이름을 부여할 수 있다. 모델 인스턴스에 대하여 summary()로 요약 출력할 때이름이 함께 출력된다. 첫 Input 레이어로 시작하여 x4 변수는 마지막 출력층을 나타낸다.
이렇게 체인 방식으로 연결한 후에 tf.keras.Model()에 입력 레이어와 출력 레이어를 정의해 모델을 생성한다.
input 매개변수로 입력층인 input_layer를 지정하고 outputs 매개변수에 출력층을 지정해 주어 모델을 생성한다. 모델 인스턴스 생성 시 name 매개변수에 이름을 지정하면 해당 이름이 summary()에 출력된다.
지금까지는 summary()로 모델의 요약을 확인했다. 하지만 복잡한 구조를 갖는 모델을 생성할 때 summary()로는 모델의 구조도를 시각화하기 어렵다. 케라스의 유틸 패키지에서 제공하는 plot_model 모듈을 활용하여 모델의 구조도를 시각화할 수 있다.
plot_model()에 모델을 지정하면 구조도가 출력된다.
함수형 API로 생성한 모델도 Sequential API로 생성한 모델과 동일한 방식으로 훈련할 수 있다. 생성된 모델 인스턴스에 compile() 메서드로 모델을 컴파일하고 fit() 메서드로 모델을 훈련한다. 훈련이 완료된 뒤 evalutate() 메서드로 검증할 수 있다.
2. 모델 서브클래싱(Model Subclassing)
텐서플로 케라스는 Model 클래스를 제공하고, 이를 기반으로 딥러닝 모델을 구현하고 있다. 이 클래스를 직접 상속받아 사용자가 직접 서브클래스로 딥러닝 모델을 만들 수 있다.
이 방법은 파이썬 클래스 개념을 잘 이해하고 있다면 가장 추천하는 방법이다. 하지만 객체지향이나 파이썬 클래스의 개념이 부족하다면 굳이 Model Subclassing으로 모델을 구현하지 않아도 좋다. 함수형 API로 생성한 모델과의 성능 차이는 없다.
Model Subclassing으로 모델 인스턴스를 생성하기 위해서는 tf.keras.Model를 상속받아 생성하고자 하는 모델 클래스를 구현한다. 모델의 __init__() 함수에 레이어를 정의하고 레이어의 하이퍼파라미터를 정의한다.
call() 함수를 메서드 오버라이딩으로 구현한다. call() 메서드는 fit() 메서드가 호출되어 훈련하는 경우 호출될 함수다. call() 함수 내부에서는 모델의 입력부터 출력까지의 흐름, 즉 순전파를 정의하고 함수형 API와 같은 방식으로 모든 레이어를 체인처럼 연결한다. 마지막으로 최종 출력 값을 return한다.
tf.keras.Model을 상속받아 구현한 모델인 MyModel을 생성자로 인스턴스를 생성한다. 생성자로 객체를 생성해 저장한 mymodel 변수에 바로 summary()로 요약 출력하는 것은 불가하다. mymodel에 Input 레이어와 함께 shape을 정의해 주면 summary()로 모델의 요약을 확인할 수 있다.
Model Subclassing으로 생성된 모델의 훈련도 동일하게 compile() 메서드로 컴파일한 후 fit() 메서드로 훈련한다.
3. 서브클래싱 모델 파라미터를 활용한 생성
Model Subclassing으로 생성하는 장점은 생성자 파라미터로 모델 내부 레이어의 하이파파라미터를 지정할 수 있다는 점이다. 다음은 모델의 생성자 파라미터를 추가하여 동적으로 레이어의 유닛 개수를 초기화하는 예제이다.
모델의 생성자 파라미터로 기준이 되는 unit의 개수를 입력받아 Dense 레이어의 유닛 개수를 계산하여 설정한다.
이 코드 역시 오류가 발생해서 몇 가지 수정해 주었다. 정수형 나눗셈을 수행할 수 있도록 연산자를 추가했고, 입력 형태를 정의하는 함수도 추가했다.
그리고 처음에는 input 형태를 mymodel.build(input_shape=(None, 28, 28))게 정의했더니 Output Shape으로 표시되었다. shape에는 None을 넣어서는 안 되는 것 같다.
모델 생성자에 생성자 파라미터로 초기화하여 생성한 모델에 summary()로 요약한 결과를 확인해 보면 동적으로 설정한 레이어의 파라미터가 초기화되었음을 알 수 있다.
이렇게 생성한 모델도 동일하게 compile() 메서드로 컴파일 한 뒤 fit() 메서드로 훈련한다. 훈련이 완료된 뒤 모델 인스턴스의 evaluate() 메서드로 모델의 성능을 검증할 수 있다.
학습을 마치고
공부하는 시간이 다시 즐거워졌다. 벌써 한 단원이 끝났나 하는 아쉬움이 들기도 했다. 파이썬에 대한 기본 실력이 있다는 것도 감사하고 기뻤다. 그냥 공부를 하는 지금 이 순간이 너무나도 행복했다.
새로운 것들을 하나씩 배워가며 나의 실력이 향상되는 것을 보며 마음 깊은 데서 우러나는 만족감을 느꼈다.
그리고 하기 싫은 분야라고 해서 해볼 생각도 하지 않고 포기하는 일은 이제 하지 않기로 다짐했다. 머신러닝, 딥러닝 분야도 무척 재미있는 분야이고 세상에는 내가 알 수 없는 얼마나 많은 배울 거리가 있을지 생각하면 하루하루가 즐겁고 기대가 된다.
'인공지능 > 딥러닝' 카테고리의 다른 글
케라스 10 - 텐서플로 데이터셋 (0) | 2024.10.26 |
---|---|
케라스 9 - 사용자 정의 : 배치 및 자동 미분을 활용한 모델 훈련 (1) | 2024.10.26 |
케라스 7 - 모델 저장 및 불러오기 (0) | 2024.10.26 |
케라스 6 - 콜백(Callback) (0) | 2024.10.26 |
케라스 5 - 모델 세부 설정 (0) | 2024.10.26 |