본문 바로가기

Heute lerne ich/AI

[엘리스] 모델 학습 및 서비스

<1> 모델 학습

 

01 Background

Tensorflow : google, 강력한 시각화

Pytorch : facebook, 데이터 처리, 모델의 구현

→ tensorflow 사용

Tensorflow : session을 단위로 실행 코드를 작성하고 수동으로 모델을 구현

Keras: 공식 api (2.0 버전부터)

과적합 : 모델이 데이터의 일반적인 특징이 아닌 학습 데이터에만 특화되어 학습

  • 데이터의 수나 다양성이 부족할 때
  • 데이터에 비해 모델이 너무 클 때
  • 너무 많은 epoch를 학습했을 때 ↔ 너무 적은 epoch를 학습하면 과소적합(underfitting)

과적합을 막기 위한 방법

  • 데이터를 늘린다 ⇒ best!
  • 과적합이 일어나기 전에 학습을 정지함 (Early Stop)
  • 데이터 증강 (Data augmentation) : 같은 데이터도 반전시키거나 약간 변형해서 입력, 적은 수의 데이터를 이용하여 좀 더 일반적인 특징을 학습하도록 유도

02 Fit 함수

fit(

x=학습 세트의 입력 데이터,

y=학습 세트의 입력 데이터를 넣었을 때 정답 값,

batch_size: 한 번에 입력할 데이터의 수,

epochs=학습 데이터를 몇 번 학습할 것인지,

steps_per_epoch: 한 epoch은 몇 번의 입력을 수행하는지(none설정시 batch_size에 따라 자동으로 설정).

verbose=학습 과정을 출력하는 방법(0: 출력X, 1: 진행 바 표시, 2: 진행바 표시X, 수치 정보만)

validation_data=검증 데이터 셋, 현재 epoch의 성능을 평가하기 위해 사용,

validation_freq=검증하는 주기, 1(기본값): 매 epoch마다 검증,

shuffle: 학습 데이터를 섞을지 여부, True, False(검증 데이터는 섞지 않음)

validation_batch_size: 한번 입력에 입력할 데이터의 수,

validation_steps: 한번 검증할 때 데이터 입력의 횟수,

class_weight: 클래스별 반영 정도, 데이터 불균형 해결하는 방법, 적은 수의 클래스에 더 많은 관심을 기울이는 개념, 딕셔녀리 문제를 형태로 전달.

workers, use_multiprocessing: 병렬 처리를 위한 인수들(generator를 사용하는 경우에만 사용),

callbacks=다른 코드의 인수로 함수를 넘겨주면, 그 코드가 필요에 따라 실행하는 함수

)

validation_batch+size * validation_steps = 검증 데이터의 수

batch_size * steps_per+epoch = 학습 데이터의 수


03 콜백함수

keras.callbacks.Callback 을 상속받아서 클래스 정의

on_train_end(self, logs=None) : 학습이 종료될 때 호출

class MYCallback(keras.callbacks.Callback):
	def on_epoch_end(self, epoch, logs=None):
		keys = list(logs.keys())
		print("End epoch {} of training: got log keys: {}".format(epoch, keys))

model.fit( ... , callbacks = [MyCallback()])

내장 콜백함수: EarlyStopping, ModelCheckpoint, TensorBoard 등

  • Earlystopping: 과적합이 발생하는 Epoch을 감지하고 자동으로 학습을 종료
tf.keras.callbacks.EarlyStopping(
	monitor='val_loss', min_delta=0, patience=0, verbose=0,
	mode='auto', baseline=None, restore_best_weights=False
)
#moniotr : 검사할 수치의 이름, mode : 원하는 방향, min(loss, error), max(정확도)
  • ModelCheckPoint: 일정 주기마다 모델이나 모델의 가중치를 자동으로 저장, 과적합이 발생했을 때 처음부터 수행하지 않고 중간부터 다시 학습이 가능
tf.keras.callbacks.ModelCheckpoint(
	filepath, monitor='val_loss', verbose=0, save_best_only=False,
	save_weights_only=False, mode='auto', save_freq='epoch',
	options=None, **kwargs
)
#save_best_only: 가장 좋은 버전만 저장 
#true -> 성능이 가장 좋은 버전만 남기고 나머지 체크포인트 삭제
#false -> 모든 버전을 저장

#save_weights_only: 모델의 가중치의 값만 저장
#true -> 학습 진행 상황, 모델의 구조에 대한 데이터를 빼고 저장

#filepath: 체크 포인트를 저장할 디렉토리
#고정된 문자열을 전달하면 하나의 디렉토리에 계속 저장 -> epoch에 따라 이름을 다르게 하도록 설정
#filepath = 'checkpoints/cp-{epoch:04d}.ckpt' 포멧 문자열 사용

04 TensorBoard

모델의 정보를 시각화하는 Tensorboard를 사용할 수 있도록 로그를 기록

장점 : 원격에서 실시간으로 모델의 학습정보 파악 가능, 간단하게 callback 추가, 원격에서 활용 가능

사용 과정 : callback에서 Tensorboard 콜백 함수를 추가하여 로그 디렉토리에 기록을 저장, 모듈을 실행하여 로그 디렉토리의 로그를 웹페이지로 호스트, 웹 페이지에 출력된 정보들을 보고 학습 과정을 모니터링

콜백 함수의 인자

log_dir: 로그를 저장할 경로

update_freq: 저장하는 주기

  • ‘epoch’ : 한 epoch마다 기록을 저장
  • ‘batch’ : batch마다 기록을 저장(학습 속도가 느려짐)
tensorboard_callback = tf.keras.callbacks.TensorBoard(log_dir="./logs")
model.fit(x_train, y_train, epochs=2, callbacks=[tensorboard_callback])
#fit함수에 콜백 함수 추가

#명렬줄에서 tensorboard를 실행
#--logdir에 저장한 디렉토리 경로를 전달
tensorboard --logdir=path_to_your_logs

<2> 모델 서비스

 

01 모델 저장하고 불러오기

모델의 구성요소 - 모델의 구조, 가중치 값, compile 정보

  1. 모델의 구조 : 레이어의 종류와 형태, 입력값의 형태
  2. 가중치 값 : 모델의 학습은 loss값이 낮아지도록 가중치의 값을 수정하는 과정, 같은 모델도 가중치 값에 따라 성능이 달라짐
  3. compile정보 : optimizer의 종류, learning rate(lr), 사용한 loss function 정보

텐서플로우 모델의 저장 형식

-H5 형식 : 과거 Keras에서 사용하던 저장 방식, 모델의 구조와 가중치를 포함하는 정보들을 저장, 사용자 정의 레이어와 손실함수는 저장하지 않음

-SavedModel: 최근(?) 사용하는 tensorflow 표준 저장 형식

모델의 구조와 가중치를 포함한 정보들을 저장, 사용자 정의 레이어와 손실함수까지 모두 저장

model.fit(x,y)
#모델 저장
model.save("my_model") #.h5사용시 형식 바뀌어 저장

#저장된 모델 사용
loaded_model = keras.models.load_model("my_model")

*이어서 학습하기 : savedModel은 모델의 모든 정보를 저장하고 불러오는 방식, 불러온 모델을 그대로 학습을 마저 진행(initial_epoch과 epoch을 조절하여 이어서 학습을 진행)

model.compile(...)
model.fit(x,y)
model.save("my_model")

loaded_model = keras.models.load_model("my_model")
#지시한 시점의 compile정보와 학습 상태까지 불러옴
#다시 compile X, 바로 이어서 학습 가능
#21부터 40epoch
loaded_model.fit(x,y, initial_epoch = 20, epochs = 40)

*체크 포인트 불러오기 : checkpoint 콜백 함수의 인수 중 save_weights_only를 false로 설정, 원하는 epoch의 체크포인트 경로를 전달, initial_epoch과 epoch을 조절하여 이어서 학습을 진행

loaded_model = keras.models.load_model("checkpoints/cp-0020.ckpt")
loaded_model.fit(x,y,initial_epoch = 20, epochs = 40)

만약 save_weights_only가 true면 가중치만 저장되기 때문에 다시 처음부터 해야 함


02 모델 서비스 방법

자바스크립트를 이용한 모델 서비스

  • Tensorflow.js (자바스크립트 tensorflow 라이브러리) : 브라우저 또는 node.js에서 학습된 모델을 사용 가능
  • Tensorflow.js에서 사용하는 과정 : 모델의 학습을 tensorflow에서 진행, python에서 학습된 모델을 tensorflow.js에 맞는 형식으로 변환, tensorflow에서 모델의 동작을 js로 작성하여 서비스
  1. Tensorflow.js 형식으로 변환하는 방법
import tensorflowjs as tfjs
def train(...) :
model = keras.models.Sequential()
model.compile(...)
model.fit(...)

tfjs.converters.save_keras_model(model, target_dir)

2. Tensorflowjs로 변환한 모델 사용 방법

import * as tf from '@tensorflow/tfjs';
const model = await tf.loadLayersModel('<https://foo.bar/tfjs_artifacts/model.json>');
//model.json 파일의 url을 제공하여 모델 로드

const example = tf.fromPixels(webcamElement)
const prediction = model.predcit(example)

 3. Flask에서 서비스하기

//학습된 모델을 불러오기 : SavedModel 형식의 모델을 로드
if __name__ = '__main__:
	model = tf.keras.models.load_model("my_model");
	app.run(host='localhost', port = 8080)

//모델의 사용은 그대로 predict를 사용
res = model.predict([inputdata]) //리스트로 묶어서

03 서버 안정화 처리

딥러닝 모델 서비스는 처리 시간도 길고, gpu를 병렬적으로 사용하기 위한 처리가 필요함 ⇒ 서비스 안정화가 필요함. 사용자의 요청을 거절하더라도 서비스가 종료되지 않도록 자원관리가 필요, 서버의 연산 성능, 처리 중인 작업의 수를 고려한 설계가 요구됨

 

⇒ 실행 가능한 작업 제한

비교적 쉽게 구현이 가능하나 사용자가 작업을 예약하는 등의 처리가 어렵고, 무거운 모델은 오래걸리며 대규모 서비스에 적용하기는 부적절함

 

⇒ 작업 큐를 이용한 비동기 처리 : 사용자와 상호작용을 관리하는 메인 프로세스와 작업을 처리하는 worker 프로세스를 분리, 각 프로세스는 큐를 이용하여 상호작용함

작업 큐를 이용한 비동기 처리 구현의 예

 

*사진 출처 : 엘리스 코딩

 

장점 : worker 프로세스가 오류로 종료되어도 웹 서비스는 계속 동장, 딥러닝 모델의 가중치 업데이트는 worker 프로세스만 수정하면 반영되는 등

사용자의 로그인 정보와 작업을 매칭 → 사용자가 처리를 요청하고 브라우저를 닫아도 진행상황이 유지되고 결과를 받을 수 있음. 요금을 부담하여 우선순위 조정, 더 큰 이미지 요청도 가능함

 

 

*다만 2021년 자료라 최신 버전이 아닌게 아쉽다

AI는 금방 트랜드가 바뀌어버려 다른 방법도 많이 생겼을 것 같은데 ..!