처음에는 학습데이터의 양이 메인 메모리의 한계를 넘어가면서 메모리를 증설했고 그 다음에는 학습데이터를 GPU에 옮기는 과정에서 GPU 메모리가 부족하여 batch_size를 줄여도 보았으나 다음과 같은 에러 메시지는 해결되지 않았다.
" InternalError: Failed copying input tensor from /job:localhost/replica:0/task:0/device:CPU:0 to /job:localhost/replica:0/task:0/device:GPU:0 in order to run _EagerConst: Dst tensor is not initialized."
확실하진 않지만 위와 같은 메시지 였던것 같다. CPU에서 다루던 데이터를 GPU로 옮기다가 사고가 나는 것 같다. 이치상으로 보면 batch_size를 줄이면 해결되어야 하는데 해결되지 않았고 어디서 다음과 같은 DataGenerator로 조금씩 데이터를 흘려 주면 된다고 했는데 나한테는 전혀 효과가 없었다.
class DataGenerator(Sequence):
def __init__(self, x_set, y_set, batch_size):
self.x, self.y = x_set, y_set
self.batch_size = batch_size
def __len__(self):
return int(np.ceil(len(self.x) / float(self.batch_size)))
def __getitem__(self, idx):
if idx == self.__len__() - 1:
batch_x = self.x[idx * self.batch_size : ]
batch_y = self.y[idx * self.batch_size : ]
else:
batch_x = self.x[idx * self.batch_size : (idx+1) * self.batch_size]
batch_y = self.y[idx * self.batch_size : (idx+1) * self.batch_size]
return batch_x, batch_y
train_gen = DataGenerator( X_train_split, y_train_split, batch_size)
test_gen = DataGenerator(X_val_split, y_val_split, batch_size)
history = self.model.fit(
train_gen,
validation_data=test_gen,
epochs=epochs,
callbacks=callbacks,
verbose=1
)
정확히 문제가 되는 지점이 학습 완료 후 평가하는 과정에서 사단이 나서 굉장히 열받는 상황이었다. 며칠을 걸려서 학습을 완료했는데 왜 평가할때 프로그램이 사망하냐구.
아무튼 좀 더 구글링을 해서 찾은 해결책은 학습기간 동안 최적의 모델을 파일형태로 저장하도록 하고 기존 모델을 제거해서 메모리 문제를 제거하는 방법을 시도해 보았다. 그리고 최적의 모델은 다시 파일에서 로딩하는 방식으로... 하지만 다음 명령어는 효과가 없었다.
del model
뭔가 cuda와 cuDNN 그리고 tensorflow의 backend 사이에 꼬여 있는 부분이 있는 것 같다. 여러 차례의 시도를 하여 각 tensorflow의 backend의 각세션을 학습 완료 후 재 초기화 하고 "del model"을 수행한다. 그리고 garbage collect을 통해 안쓰는 데이터를 메모리에서 해제한다. 그 결과 평가 단계로 수훨하게 넘어 갈 수 있었다. 그 기록을 여기에 남겨 둔다.
... 학습 완료 후...
# reset Keras Session
sess = tf.compat.v1.keras.backend.get_session()
tf.compat.v1.keras.backend.clear_session()
sess.close()
sess = tf.compat.v1.keras.backend.get_session()
del self.model # this is from global space - change this as you need
# use the same config as you used to create the session
config = tf.compat.v1.ConfigProto()
config.gpu_options.per_process_gpu_memory_fraction = 1
config.gpu_options.visible_device_list = "0"
tf.compat.v1.keras.backend.set_session(tf.compat.v1.Session(config=config))
import gc
gc.collect()
... 저장된 파일에서 self.model을 다시 로드한다...