8wDlpd.png
8wDFp9.png
8wDEOx.png
8wDMfH.png
8wDKte.png

在 for 循环内训练多个 Keras 模型时速度很慢

Akshat Sharma 2月前

21 0

我在 for 循环中训练了几个 Keras 模型。当火车启动时,每个 epoch 大约需要 280 毫秒。但随着火车的运行,每个 epoch 大约持续 3 秒。我尝试使用以下方法解决这个问题

我正在循环内训练几个 Keras 模型 for 。当火车启动时,每个时期大约需要 280ms 。但随着火车的行驶,每个时期持续大约 3s 来解决这个问题 clear_session() ,但没有任何变化。我也曾尝试在模型完成时删除它 .fit 并使用 gc.collect() ,但都不起作用。

这是我的代码:

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')

以下是一些训练时间的输出:

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

知道是什么原因导致了这个问题吗?这是内存泄漏问题吗?我知道代码写得不好/根本没有优化,所以任何帮助都会非常感激。

帖子版权声明 1、本帖标题:在 for 循环内训练多个 Keras 模型时速度很慢
    本站网址:http://xjnalaquan.com/
2、本网站的资源部分来源于网络,如有侵权,请联系站长进行删除处理。
3、会员发帖仅代表会员个人观点,并不代表本站赞同其观点和对其真实性负责。
4、本站一律禁止以任何方式发布或转载任何违法的相关信息,访客发现请向站长举报
5、站长邮箱:yeweds@126.com 除非注明,本帖由Akshat Sharma在本站《tensorflow》版块原创发布, 转载请注明出处!
最新回复 (0)
返回
作者最近主题: