12장 텐서플로를 사용한 사용자 정의 모델과 훈련
텐서플로란?
텐서플로는 강력한 수치 계산용 라이브러리입니다.
케라스가 고수준의 API를 제공하지만 더 높은 자유도를 위해서 저수준 파이썬 API를 사용할 수 있습니다.
이제 텐서를 직접 다루어 봅시다.
텐서
- 상수 텐서: tf.constant()
- shape과 dtype을 가진다.
- 모든 종류의 텐서 연산이 가능하다.
- 텐서의 값을 바꿀 수 없다.
- mean, sum, max 함수를 reduce_mean, reduce_sum, reduce_max와 같이 사용한다.
- GPU 커널(연산 구현)이 원소가 추가된 순서를 고려하지 않는 리듀스 알고리즘을 사용하기 때문이다.
- 어떠한 타입변환도 자동으로 수행하지 않는다.
- tf.cast() 함수를 사용한다.
- 변수 텐서: tf.Variable()
- 텐서의 내용을 바꿀 수 있다.
- 상수텐서와 동일한 연산을 지원한다.
- assign() 함수를 사용해서 변숫값을 바꿀 수 있다.
- 단, 직접 수정은 안됩니다.
- 다른 데이터 구조
- 희소텐서(tf.SparseTensor)
- 텐서 배열(tf.TensorArray)
- 래그드 텐서(tf.RaggedTensor)
- 문자열 텐서(바이트 문자열)
- 집합
- 큐
커스텀 모델과 훈련 알고리즘
- 커스텀 로스 함수
- tf.keras.losses.Loss 클래스를 상속하고 get_config() 메서드를 구현하여 모델 저장 후 불러올 때 로스 함수에서 사용된 인자 또한 불러올 수 있습니다.
- init(), call() 메서드로 인자를 받고 로스를 계산하여 반환합니다.
- get_config(): 모델을 저장할 때 로스 함수에서 사용된 인자를 저장하여 불러올 때 사용합니다.
- 딕셔너리 언패킹 연산자 **
- param= { ‘a’: 1, ‘b’: 2}; func(**param)은 func(a=1, b=2)와 같습니다.
- 커스텀 함수가 저장을 필요한 파라미터를 가지고 있거나 가중치를 저장해야 한다면 적절한 클래스를 상속해서 구현해야 한다.
- 커스텀 지표
- 평균을 통해서 구할 수 없고 정밀도와 같이 배치마다 업데이트가 필요한 지표를 스트리밍 지표 라 한다.
- 구현하기 위해선 Metric 클래스를 상속하여 구현해야 한다.
- 커스텀 층
- 여러 입력이 주어질 때 하나의 튜플로 만들어서 층에 전달해야 합니다.
- 훈련과 테스트에서 다르게 동작하는 층이라면 call() 메서드에 training 매개변수를 추가하여 훈련인지 테스트인지 결정합니다.
- 모델 내부 구조에 기반한 손실과 지표
- 보조 출력에 대한 손실을 계산하여 학습에 사용하고 지표로 출력하기 위해서는
- 모델 클래스의 call() 메서드 안에 self.add_loss로 손실을 추가하고 self.add_metric을 사용해서 지표 출력을 구현가능 합니다.
- 보조 출력에 대한 손실을 계산하여 학습에 사용하고 지표로 출력하기 위해서는
- 자동미분으로 그레디언트 계산하기
- tf.GradientTape()을 사용해서 그레디언트를 계산할 수 있습니다.
- gradient() 메서드를 통해서 계산할 수 있고 변수가 포함된 연산에 대해서만 계산 가능합니다.
- 만약 변수가 아닌 입력에 대해 그레디언트 계산을 강제하고 싶다면 watch() 함수를 사용할 수 있습니다.
- 그레디언트를 전파하고 싶지 않은 부분에 대해서는 tf.stop_gradient() 함수를 사용합니다.
- 수치적으로 안정적이지 않은 함수의 그레디언트를 계산할 때
- @tf.custom_gradient 데코레이터를 사용하고 함수 결과와 그레디언트를 모두 반환해야 합니다.
- tf.GradientTape()을 사용해서 그레디언트를 계산할 수 있습니다.
- 사용자 정의 훈련 반복
- y_pred = model(X_batch, training=True): 예측 생성하기
- loss = tf.reduce_mean(loss_fn(y_batch, y_pred)): 손실 계산하기
- gradients = tape.gradient(loss, model.trainable_variables): 그레디언트 계산하기
- optimizer.apply_gradient(zip(gradients, model.trainable_variables)): 가중치 업데이트 하기
자동 그래프 생성
- 파이썬 함수에 @tf.function 데코레이터를 사용하면 텐서플로 함수가 만들어집니다.
- 계산 그래프를 최적화하여 연산을 효율적으로 진행합니다.
- 텐서로 결과를 반환합니다.
- tf.function을 호출할 때 jit_compile=True로 설정하면 XLA를 사용하여 해당 그래프를 위한 전용커널을 컴파일하며 이는 연산을 융합하는 결과를 갖고 속도가 빨라지며 메모리를 적게 사용합니다.
- 케라스는 자동으로 커스텀 함수를 텐서플로 함수로 변환하여 사용합니다.
- 텐서플로 함수는 입력크기와 데이터 타입에 맞춰 매번 새로운 그래프를 생성합니다.
- 텐서를 입력으로 받는 경우 동일한 타입이라면 그래프를 재사용합니다.
- 하지만 파이썬 값을 입력으로 받는 경우 동일한 타입이라도 새로운 그래프를 만들어 메모리가 많이 사용됩니다.
- 오토그래프
- 파이썬 함수의 코드를 분석하여 모든 제어문을 텐서플로 연산으로 바꾸고 업그레이드 버전을 만듭니다.
- 트레이싱
- 오토그래프로 생성된 업그레이드 함수를 입력에 대한 심볼릭 텐서를 사용해 호출하고 해당 함수는 그래프 모드로 실행됩니다.
- 이때 노드와 화살표를 통해 단순화된 최종 그래프를 만듭니다.
12장 내용에 대해서 정리해보았습니다. 텐서플로에 대한 기초적인 내용으로 2권이 시작되고 이후 컴퓨터 비전, 자연어 처리와 같은 내용이 이어집니다.
총평
이제 머신러닝, 딥러닝에 관심을 갖고 배워 나가고 싶은 분에게 알맞은 책입니다. 책 중간중간 글로 설명한 내용을 실제 파이썬 코드를 통해 설명해 주는 점이 실제 코드를 작성할 때 도움이 됩니다.
또한 캐글을 입문하시는 분에게도 추천합니다. 캐글에서 자주 다루는 tabular data에는 신경망보다 머신러닝 방법으로 접근하는 것이 더 높은 성능을 가져옵니다. 실제 대회 상위권 해결 방법을 살펴보았을 때 lightbgm, xgboost와 같은 방법이 많이 보입니다. 책의 1권에서 이러한 머신러닝에 대해서 자세하게 설명해주고 있습니다.
하지만 새롭게 출시되는 논문에 관심이 있고 논문을 코드로 구현하고 싶은 분에게는 추천하지 않습니다. 논문의 구현은 파이토치로 제공되는 경우가 대부분이며 이 경우 텐서플로보다 파이토치를 먼저 학습하는 것이 우선일 수 있습니다.
'AI&ML > 학습 정리' 카테고리의 다른 글
[Paper-review]RAGAS: Automated Evaluation of Retrieval Augmented Generation (0) | 2024.07.02 |
---|---|
langchain quickstart 따라하기 (0) | 2024.05.03 |
[Paper-review]Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks (0) | 2024.04.10 |
f1-score에 대해서 알아보자(2) (0) | 2023.12.07 |
f1-score에 대해서 알아보자(1) (0) | 2023.12.07 |