I am training several Keras models inside a for
loop. When the train starts, each epoch takes around 280ms
. But as trains go on, each epoch lasts around 3s
. I have tried to solve this problem using clear_session(), but nothing changed. I also have tried to delete the model when it finishes the .fit
and also use gc.collect()
, but none worked.
Here is my code:
import os
import time
import pandas as pd
import tensorflow as tf
import numpy as np
import unicodedata
from keras.models import Sequential
from keras.layers import InputLayer
from keras.layers import Conv1D
from keras.layers import MaxPooling1D
from keras.layers import Flatten
from keras.layers import Dense
from keras.callbacks import ModelCheckpoint
from keras.callbacks import EarlyStopping
import keras.backend as K
from openpyxl.styles import PatternFill
class vazao:
def __init__(self, modelo='M1', rede='Conv1D', opcao=4):
self.dir_usuario = os.getcwd()
self.tipo = 'VAZAO'
self.caminho_vazao = f'{self.dir_usuario}\{self.tipo}'
self.caminho_deck_ons_dados_abertos = f'{self.caminho_vazao}\DECK_ONS_DADOS_ABERTOS\'
self.caminho_deck_ons_sintegre = f'{self.caminho_vazao}\DECK_ONS_SINTEGRE'
self.caminho_psats = f'{self.caminho_deck_ons_sintegre}\PSATS\'
self.caminho_psats_previsao = f'{self.caminho_deck_ons_sintegre}\PSATS_PREVISAO\'
self.caminho_resultados_previsao = f'{self.dir_usuario}\RESULTADOS PREVISAO\{self.tipo}'
self.caminho_deck_dessem_destino = f'{self.dir_usuario}\RESULTADOS PREVISAO\DECK_DESSEM'
self.df_reservatorios = pd.read_excel(f'{self.caminho_deck_ons_dados_abertos}\RESERVATORIOS.xlsx')
renomear_postos = {'EMBORCAÇÃO':'EMBORCACAO', 'C.BRANCO-1':'CAPIM BRANC1', 'C.BRANCO-2':'CAPIM BRANC2', 'SÃO SIMÃO':'SAO SIMAO', 'TRÊS MARIAS': 'TRES MARIAS',
'B. BONITA': 'BARRA BONITA', 'PROMISSÃO':'PROMISSAO', 'N. AVANHANDAVA':'NAVANHANDAVA', 'TAQUARUÇU':'TAQUARUCU', 'TRÊS IRMÃOS':'TRES IRMAOS',
'PORTO PRIMAVERA':'P. PRIMAVERA', 'M. MORAES':'M. DE MORAES', 'CORUMBA':'CORUMBA I', 'SERRA DA MESA':'SERRA MESA', 'SANTO ANTONIO':'STO ANTONIO',
'PEIXE ANGICAL':'PEIXE ANGIC', 'NILO PEÇANHA':'NILO PECANHA', 'PEREIRA PASSOS':'P. PASSOS', 'SANTA CECILIA':'STA CECILIA', 'C. DOURADA':'CACH.DOURADA',
'PORTO ESTRELA':'P. ESTRELA', 'G. B. MUNHOZ':'G.B. MUNHOZ', 'G. P. SOUZA':'G.P. SOUZA', 'SANTA CLARA-PR':'STA CLARA PR', 'FUNDÃO':'FUNDAO', 'SALTO SANTIAGO':'SLT.SANTIAGO',
'ITÁ':'ITA', 'PONTE DE PEDRA':'PONTE PEDRA', 'P. AFONSO 1,2,3':'P.AFONSO 123', 'P. AFONSO 4':'P.AFONSO 4', 'BOA ESPERANÇA':'B. ESPERANCA',
'PEDRA DO CAVALO':'P. CAVALO', 'COARACY NUNES':'COARACY NUNE', 'CACHOEIRA CALDEIRAO':'CACH.CALDEIR', 'STA.CLARA-MG':'STA CLARA MG', 'SUIÇA':'SUICA',
'S.R.VERDINHO':'SLT VERDINHO', 'QUEBRA QUEIXO':'QUEBRA QUEIX', 'CORUMBA-3':'CORUMBA III', 'CORUMBA-4':'CORUMBA IV', 'B.COQUEIROS':'B. COQUEIROS',
'FOZ DO RIO CLARO':'FOZ R. CLARO', 'S.DO FACÃO':'SERRA FACAO', 'PASSO SAO JOAO':'PASSO S JOAO', 'STO ANTONIO DO JARI':'STO ANT JARI',
'FERREIRA GOMES':'FERREIRA GOM', 'GUILM. AMORIM':'GUILMAN-AMOR', 'SALTO GRANDE CM': 'SALTO GRANDE', 'SALTO GRANDE CS': 'L.N. GARCEZ'}
remover_postos = ['ITAPARICA', 'MOXOTO', 'P.AFONSO 123', 'P.AFONSO 4', 'XINGO',
'STA CECILIA', 'ITUTINGA', 'FONTES', 'P. PASSOS', 'NILO PECANHA',
'SIMPLICIO', 'SANTONIO CM', 'P. ESTRELA', 'BELO MONTE', 'ITIQUIRA II',
'HENRY BORDEN', 'CANASTRA', 'SUICA']
self.df_reservatorios['nom_reservatorio'].replace(renomear_postos, inplace=True)
self.df_reservatorios = self.df_reservatorios[~self.df_reservatorios['nom_reservatorio'].isin(remover_postos)]
self.df_reservatorios.loc[self.df_reservatorios['nom_reservatorio'] == 'SUICA', 'cod_resplanejamento'] = 145
df_reservatorios = self.df_reservatorios.copy()
df_reservatorios = df_reservatorios[['nom_reservatorio', 'nom_bacia','nom_rio','val_latitude','val_longitude']]
self.df_config = pd.read_excel(f'{self.caminho_deck_ons_sintegre}\Configuracao.xlsx')
lista_df = []
arquivos = os.listdir(self.caminho_deck_ons_dados_abertos)
for arquivo in arquivos:
if 'DADOS' in arquivo:
df_ano = pd.read_csv(f'{self.caminho_deck_ons_dados_abertos}{arquivo}', sep=';', index_col=None, header=0)
lista_df.append(df_ano)
self.df_vazao = pd.concat(lista_df, axis=0, ignore_index=True)
self.df_vazao['id_subsistema'].replace(to_replace='SE', value='SECO', inplace=True)
self.df_vazao['nom_reservatorio'].replace(renomear_postos, inplace=True)
ultimo_ano = pd.to_datetime(self.df_vazao['din_instante']).dt.year.max()
self.df_vazao_ultimo_ano_completo = self.df_vazao[pd.to_datetime(self.df_vazao['din_instante']).dt.year == ultimo_ano]
self.df_vazao_ultimo_ano_completo = self.df_vazao_ultimo_ano_completo[~self.df_vazao_ultimo_ano_completo['nom_reservatorio'].isin(remover_postos)]
self.df_vazao_ultimo_ano_completo.loc[self.df_vazao_ultimo_ano_completo['nom_reservatorio'] == 'SUICA', 'cod_usina'] = 145
self.dic_par_postos_jusante_montante = {
'DARDANELOS': '',
'SAMUEL': '',
'PORTO ESTRELA': 'SALTO GRANDE CM',
'ESPORA': '',
'BILLINGS': 'GUARAPIRANGA',
'GUARAPIRANGA': '',
'SOBRADINHO': 'TRES MARIAS',
'BALBINA': '',
'STO ANTONIO DO JARI': '',
'COARACY NUNES': 'CACHOEIRA CALDEIRAO',
'FERREIRA GOMES':'COARACY NUNES',
}
self.modelo = modelo
self.rede = rede
self.opcao = opcao
self.lista_subs = ['SECO', 'S', 'NE', 'N']
self.lista_horizontes = ['dM1', 'dM2', 'dM3', 'dM4', 'dM5', 'dM6', 'dM7', 'dM8', 'dM9']
# self.lista_horizontes = ['dM1', 'dM9']
self.lista_modelos = ['M1', 'M3']
self.lista_redes = ['Conv1D', 'MLP']
self.lista_modelos_previ_precipit = ['ECMWF', 'ETA40', 'GEFS']
self.associacoes_df = pd.read_csv(f'{self.caminho_vazao}\associacoes_usina_posto.csv')
self.df_precipitacoes = pd.read_csv(f'{self.caminho_vazao}\precipitacoes.csv')
self.df_correlacao_reservatorio_psat = pd.read_csv(f'{self.caminho_vazao}\correlacao_usina_psat.csv')
def consulta_postos_em_bacias(self, subs, bacia):
caminho = f'{self.caminho_vazao}\SUBS_{subs}\{bacia}'
pastas = os.listdir(caminho)
return pastas
def treinamento(self, tela = False, pb = 0, progresso = 'text', subs='', bacia='', reservatorio='', epocas=500, es=250, num_inic=10, erro=''):
def remover_acentos(texto):
texto_sem_acento = ''.join(c for c in unicodedata.normalize('NFD', texto) if unicodedata.category(c) != 'Mn')
texto_sem_acento = texto_sem_acento.replace(' ', '_')
texto_sem_acento = texto_sem_acento.replace(',','.')
return texto_sem_acento
def conv1d():
nome_rede = f'{subs}_{bacia}_{reservatorio}_{self.modelo}_{self.rede}_{horizonte}_inicializacao_{inicializacao}'
nome_rede = remover_acentos(nome_rede)
# K.clear_session() # DID NOT WORK
rede_conv1d = Sequential(name=nome_rede)
rede_conv1d.add(InputLayer((timesteps, input_dim), name='Camada_Entrada'))
rede_conv1d.add(Conv1D(filters=64, kernel_size=4, activation=funcao, name='Camada_Conv_1'))
rede_conv1d.add(MaxPooling1D(pool_size=1))
rede_conv1d.add(Conv1D(filters=64, kernel_size=4, activation=funcao, name='Camada_Conv_2'))
rede_conv1d.add(MaxPooling1D(pool_size=1))
rede_conv1d.add(Flatten())
rede_conv1d.add(Dense(units=72, activation=funcao, name='Dense_1'))
rede_conv1d.add(Dense(units=neuronios_saida, activation=funcao, name='Camada_Saida'))
return rede_conv1d
tf.config.set_visible_devices([], 'GPU') # Disable GPU
input_dim = 1
val_size = 0.2
amostras_antes = 15
# amostras_depois = 1
funcao = 'tanh'
inicializacoes = num_inic
if self.opcao == 1:
pass
elif self.opcao == 2:
pass
elif self.opcao == 3:
reservatorios_na_bacia = self.consulta_postos_em_bacias(subs=subs, bacia=bacia)
for reservatorio in reservatorios_na_bacia:
df_treinamento = pd.read_csv(f'{self.caminho_vazao}\SUBS_{subs}\{bacia}\{reservatorio}\{reservatorio}_Dados_Treinamento_Norm.csv', index_col='din_instante')
diretorio_result_treinamento = f'{self.caminho_vazao}\SUBS_{subs}\{bacia}\{reservatorio}\AGREGADO\Resultados Treinamento'
diretorio_elia = f'{self.caminho_vazao}\SUBS_{subs}\{bacia}\{reservatorio}\AGREGADO\ELIA'
if not os.path.exists(diretorio_result_treinamento):
os.makedirs(diretorio_result_treinamento)
if not os.path.exists(diretorio_elia):
os.makedirs(diretorio_elia)
if len(df_treinamento) != 0:
writer = pd.ExcelWriter(f'{diretorio_result_treinamento}\{subs}_{bacia}_{reservatorio}_MSE_{self.modelo}_{self.rede}.xlsx')
writer_loss = pd.ExcelWriter(f'{diretorio_result_treinamento}\{subs}_{bacia}_{reservatorio}_Treinamento_{self.modelo}_{self.rede}.xlsx')
for horizonte in self.lista_horizontes:
horiz = int(horizonte[-1])
x_train = []
y_train = []
if self.modelo == 'M1':
for i in range(0, len(df_treinamento), 1):
final_x = i + amostras_antes
final_y = final_x + horiz
if final_y > len(df_treinamento):
break
previsor_vazao = df_treinamento['val_vazaoincremental'][i:final_x]
previsor_sen = pd.Series(df_treinamento['Seno'].loc[df_treinamento.index[final_y-1]])
previsor_cos = pd.Series(df_treinamento['Cosseno'].loc[df_treinamento.index[final_y-1]])
previsor_concat = pd.concat([previsor_vazao,
previsor_sen,
previsor_cos]).values
x_train.append(previsor_concat)
y_train.append(df_treinamento['val_vazaoincremental'][final_y - 1])
else:
melhor_lag_pearson = self.df_correlacao_reservatorio_psat.loc[self.df_correlacao_reservatorio_psat['nom_reservatorio'] == reservatorio, 'melhor_lag'].values[0]
if -melhor_lag_pearson > amostras_antes:
for i in range(-melhor_lag_pearson-amostras_antes, len(df_treinamento), 1):
final_x = i + amostras_antes
final_y = final_x + horiz
if final_y > len(df_treinamento):
break
previsor_vazao = df_treinamento['val_vazaoincremental'][i:final_x]
previsor_precipitacao = pd.Series(df_treinamento['precipitacao'].loc[df_treinamento.index[final_y + melhor_lag_pearson - 1]])
previsor_sen = pd.Series(df_treinamento['Seno'].loc[df_treinamento.index[final_y - 1]])
previsor_cos = pd.Series(df_treinamento['Cosseno'].loc[df_treinamento.index[final_y - 1]])
previsor_concat = pd.concat([previsor_vazao,
previsor_precipitacao,
previsor_sen,
previsor_cos]).values
x_train.append(previsor_concat)
y_train.append(df_treinamento['val_vazaoincremental'][final_y - 1])
else:
for i in range(0, len(df_treinamento), 1):
final_x = i + amostras_antes
final_y = final_x + horiz
if final_y > len(df_treinamento):
break
previsor_vazao = df_treinamento['val_vazaoincremental'][i:final_x]
previsor_precipitacao = pd.Series(df_treinamento['precipitacao'].loc[df_treinamento.index[final_y + melhor_lag_pearson - 1]])
previsor_sen = pd.Series(df_treinamento['Seno'].loc[df_treinamento.index[final_y - 1]])
previsor_cos = pd.Series(df_treinamento['Cosseno'].loc[df_treinamento.index[final_y - 1]])
previsor_concat = pd.concat([previsor_vazao,
previsor_precipitacao,
previsor_sen,
previsor_cos]).values
x_train.append(previsor_concat)
y_train.append(df_treinamento['val_vazaoincremental'][final_y - 1])
x_train = np.array(x_train)
y_train = np.array(y_train)
y_train = np.reshape(y_train, (y_train.shape[0], 1))
df_mse_train = pd.DataFrame(index=pd.RangeIndex(inicializacoes), columns=['mse treinamento'])
df_mse_val = pd.DataFrame(index=pd.RangeIndex(inicializacoes), columns=['mse validação'])
df_tempo = pd.DataFrame(index=pd.RangeIndex(inicializacoes), columns=['tempo (minutos)'])
df_melhor_epoca = pd.DataFrame(index=pd.RangeIndex(inicializacoes), columns=['melhor época'])
df_earlystop = pd.DataFrame(index=pd.RangeIndex(inicializacoes), columns=['época parou'])
num_amostras = x_train.shape[0]
timesteps = x_train.shape[1]
x_train = x_train.reshape(num_amostras, timesteps, input_dim)
melhor_historico = None
menor_loss_validacao = float('inf')
neuronios_saida = y_train.shape[1]
for inicializacao in range(inicializacoes):
if self.rede == 'Conv1D':
rede_ = conv1d()
rede_.compile(optimizer='adam', loss='mean_squared_error')
cp = ModelCheckpoint(
filepath=f'{diretorio_elia}\{subs}_{bacia}_{reservatorio}_{self.modelo}_{self.rede}_{horizonte}_inicializacao_{inicializacao}.hdf5',
monitor='val_loss',
verbose=1,
save_best_only=True,
mode='min')
earlystop = EarlyStopping(monitor='val_loss',
patience=es,
verbose=1,
mode='min',
restore_best_weights=True)
t = time.time()
treinando = rede_.fit(x_train, y_train, batch_size=32,
epochs=epocas, verbose=2,
callbacks=[cp, earlystop],
validation_split=val_size, shuffle=True)
tempo_modelo = round((time.time() - t) / 60, 4)
# del rede_ # DID NOT WORK
# gc.collect() # DID NOT WORK
tempo_modelo = round((time.time() - t) / 60, 4)
menor_loss_validacao_inicializacao = min(treinando.history['val_loss'])
if menor_loss_validacao_inicializacao < menor_loss_validacao:
menor_loss_validacao = menor_loss_validacao_inicializacao
melhor_historico = treinando.history
df_mse_train.iloc[inicializacao] = treinando.history['loss'][np.argmin(treinando.history['val_loss'])]
df_mse_val.iloc[inicializacao] = min(treinando.history['val_loss'])
df_tempo.iloc[inicializacao] = tempo_modelo
df_melhor_epoca.iloc[inicializacao] = np.argmin(treinando.history['val_loss'])
df_earlystop.iloc[inicializacao] = earlystop.stopped_epoch
df_loss = pd.DataFrame.from_dict(melhor_historico)
df_loss.index.names = ['Época']
df_loss.to_excel(writer_loss, sheet_name=f'{horizonte}', index=True)
df_mse_train.loc['Media'] = df_mse_train.mean()
df_mse_train.loc['Desv_Pad'] = df_mse_train.std(ddof=0)
df_mse_val.loc['Media'] = df_mse_val.mean()
df_mse_val.loc['Desv_Pad'] = df_mse_val.std(ddof=0)
df_tempo.loc['Total (minutos)'] = df_tempo.sum()
melhor_inicializacao = np.argmin(df_mse_val[:-2])
linha_excel = melhor_inicializacao + 3
df_resultados = pd.concat([df_mse_train, df_mse_val, df_earlystop, df_melhor_epoca, df_tempo], axis=1)
df_resultados.index.names = ['Inicialização']
df_resultados.to_excel(writer, sheet_name=f'{horizonte}', index=True, startrow=1)
aba = writer.sheets[f'{horizonte}']
# Color best initialization
for col_num in range(1, aba.max_column + 1):
cell = aba.cell(row=linha_excel, column=col_num)
fill = PatternFill(start_color="00FF00", end_color="00FF00", fill_type="solid")
cell.fill = fill
for inicializacao in range(inicializacoes):
if inicializacao != melhor_inicializacao:
if os.path.exists(f'{diretorio_elia}\{subs}_{bacia}_{reservatorio}_{self.modelo}_{self.rede}_{horizonte}_inicializacao_{inicializacao}.hdf5'):
os.remove(f'{diretorio_elia}\{subs}_{bacia}_{reservatorio}_{self.modelo}_{self.rede}_{horizonte}_inicializacao_{inicializacao}.hdf5')
else:
print('Arquivo não existe')
else:
nome_antigo = f'{diretorio_elia}\{subs}_{bacia}_{reservatorio}_{self.modelo}_{self.rede}_{horizonte}_inicializacao_{inicializacao}.hdf5'
nome_novo = f'{diretorio_elia}\{subs}_{bacia}_{reservatorio}_{self.modelo}_{self.rede}_{horizonte}.hdf5'
if os.path.exists(nome_novo):
os.remove(nome_novo)
os.rename(nome_antigo, nome_novo)
else:
os.rename(nome_antigo, nome_novo)
writer._save()
writer_loss._save()
else:
pass
return None
if __name__ == "__main__":
vazao(modelo='M1', rede='Conv1D', opcao=3).treinamento(subs='SECO', bacia='SAO FRANCISCO')
Any ideas what is causing this issue? Is this a memory leak problem? I am aware that the code is poorly written/not optimized at all, so any help will be trully appreactiated.