[Python] Excessively increased training time for multiple Keras Conv1d networks within a for...

Discussão em 'Python' iniciado por Stack, Dezembro 19, 2024.

  1. Stack

    Stack Membro Participativo

    I am training several Keras models inside a for loop. Check the following 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')


    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 some sugestions i found, like 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.

    This increase in training time only happens if i use the Conv1D network. If i use the MLP, the training time is constant at around 90ms and does not increase. What is happening here? What is causing this increase in training time for the Conv1D? Any ideas how to fix this?

    Here some examples:

    At the very start:

    Epoch 3: val_loss improved from 0.00015 to 0.00007, saving model to C:\Users\ldsp_\SIPREDVS\VAZAO\SUBS_SECO\SAO FRANCISCO\QUEIMADO\AGREGADO\ELIA\SECO_SAO FRANCISCO_QUEIMADO_M1_Conv1D_dM1_inicializacao_0.hdf5
    164/164 - 0s - loss: 3.6645e-04 - val_loss: 7.4710e-05 - 284ms/epoch - 2ms/step
    Epoch 4/500

    After 10 minutes of training:

    Epoch 392: val_loss did not improve from 0.00005
    164/164 - 0s - loss: 2.2052e-04 - val_loss: 7.2596e-05 - 318ms/epoch - 2ms/step
    Epoch 393/500


    After 40 minutes of training:

    Epoch 13: val_loss improved from 0.00025 to 0.00022, saving model to C:\Users\ldsp_\SIPREDVS\VAZAO\SUBS_SECO\SAO FRANCISCO\QUEIMADO\AGREGADO\ELIA\SECO_SAO FRANCISCO_QUEIMADO_M1_Conv1D_dM2_inicializacao_5.hdf5
    164/164 - 0s - loss: 6.5353e-04 - val_loss: 2.2064e-04 - 450ms/epoch - 3ms/step
    Epoch 14/500

    Continue reading...

Compartilhe esta Página