Как перезагрузить модуль ТОЛЬКО, если он НЕ был загружен только выполняющимся в данный момент скриптом - PullRequest
0 голосов
/ 09 января 2019

У меня есть скрипт, который я использую для инициализации и обучения нейронной сети с Keras, поэтому я инициализировал случайные начальные числа для 100% воспроизводимых результатов обучения, когда тестирую и оптимизирую свой код. Тем временем я также использовал функцию importlib.reload () для перезагрузки всех своих пользовательских модулей, которые я изменяю по мере разработки. Но проблема в том, что моя случайная последовательность может отличаться в первый раз, когда я вызываю скрипт в сеансе ipython, по сравнению с последующим временем. Я нашел решение (см. Ниже), но оно кажется довольно элегантным и жестким. Мне интересно, есть ли более эффективный или более питонический способ. Или, может быть, мне следует совершенно иначе обращаться со случайными семенами?

import sys
modulesUnderDevelopment = ['common_config', 'cnn_tools', 'prep_dataset'] 
moduleShorthand = ['cc', 'ct', 'pd']
reloadTracker = dict()
#record which modules have not yet been imported, before we do any importing.  
for moduleName, shorthand in zip(modulesUnderDevelopment, moduleShorthand):
    reloadTracker[moduleName] = {'imported':moduleName in sys.modules, 'shorthand': shorthand}

#import modules.  Anything that's already been imported won't be imported by these lines,
# so any randomness that occurs during import will NOT occur if the module was 
# already imported.  HOWEVER, if the module has not been imported, any randomness 
# in the module import will be executed.
print('imports are beginning')
import common_config as cc
import cnn_tools as ct
import prep_dataset as pd
print('imports are ending')

import importlib
#now reload the key modules that I'm optimizing and regularly changing.  These reloads will
# ALWAYS happen, so the randomness in them will always be executed.  
print('reloads are beginning')
for key, item in reloadTracker.items():
    if not item['imported']:
        continue
    if key == 'common_config':
        importlib.reload(cc)
    elif key == 'cnn_tools':
        importlib.reload(ct)
    elif key == 'prep_dataset':
        importlib.reload(pd)
print('reloads are complete')

Между тем, мои модули содержат такой код:

## prep_dataset ##
import numpy as np
print('starting prep_dataset -- {}'.format(np.random.random()))

## cnn_tools ##
import numpy as np
print('starting cnn_tools -- {}'.format(np.random.random()))

В первый раз, когда я запускаю ipython и запускаю этот скрипт, он печатает это:

imports are beginning
starting cnn_tools -- 0.5507979025745755
Using TensorFlow backend.
starting prep_dataset -- 0.7081478226181048
imports are ending
reloads are beginning
reloads are complete

В последующие времена он печатает это:

imports are beginning
imports are ending
reloads are beginning
starting cnn_tools -- 0.5507979025745755
starting prep_dataset -- 0.7081478226181048
reloads are complete

Так что это решает мою проблему - поток случайных чисел одинаков оба раза. Но это кажется очень неуклюжим ... И наоборот, если я не прохожу все эти проблемы и просто импортирую, а затем перезагружаюсь, я получаю РАЗНЫЕ результаты при первом запуске сценария - 2 дополнительных случайных числа из потока.

starting cnn_tools -- 0.5507979025745755
Using TensorFlow backend.
starting prep_dataset -- 0.7081478226181048
reloads are beginning
starting cnn_tools -- 0.2909047389129443
starting prep_dataset -- 0.510827605197663
reloads are complete
...