Проблема с установкой нескольких последовательных моделей keras в одном скрипте python

#python #tensorflow #keras

#python #tensorflow #keras

Вопрос:

Пожалуйста, смотрите Суть здесь для полного кода. В этом вопросе я вставил то, что я считаю важной частью кода внизу.

Сначала я создаю набор данных, как показано в [2], который состоит из 2 объектов ( x и y ) и 3 меток ( grey , blue и orange ). Затем я создаю 4 последовательные модели keras с идентичной структурой слоев, оптимизатором, функцией потерь и т. Д. Наконец, я вызываю fit каждую модель и строю результирующие показатели, показанные в [3] . Как вы можете видеть, все модели работают по-разному, и мне интересно, почему? Я заблокировал случайное начальное значение, поэтому каждый раз, когда я запускаю этот скрипт, я получаю точно такой же результат.

В этом примере модели имеют идентичные структуры, поэтому я ожидаю, что графики метрик будут идентичными. В конце концов, я хотел бы варьировать количество слоев, размер слоя, функцию потерь и т. Д. Между моделями, Чтобы увидеть его эффекты, но это не представляется возможным в этой настройке. Я неправильно подхожу к этому?

Интересно отметить, что при установке значения batch_size 32 этот эффект не так заметен, но он все еще присутствует и воспроизводится (см. [4] ).

Данные

Показатели

Метрики с batch_size = 32

 # ---- MAKE MODELS ---- #
NUMBER_OF_MODELS = 4
models = []
for i in range(NUMBER_OF_MODELS):
    model = keras.models.Sequential(name=f'{i}')

    model.add(keras.layers.Dense(8, activation='relu', input_shape=df_train['features'].values.shape[-1:]))
    model.add(keras.layers.Dense(3, activation='softmax'))

    model.compile(optimizer=keras.optimizers.Adam(),
                  loss=keras.losses.CategoricalCrossentropy(),
                  metrics=[keras.metrics.CategoricalAccuracy()])

    model.summary()
    models.append(model)
# --------------------- #

# ---- TRAIN MODELS ---- #
histories = []
for model in models:
    with tf.device('/cpu:0'):
        history = model.fit(x=df_train['features'].values, y=df_train['labels'].values,
                            validation_data=(df_val['features'].values, df_val['labels'].values),
                            batch_size=512, epochs=100, verbose=0)
        histories.append(history)
# ---------------------- #
 

Ответ №1:

вам просто нужно устанавливать начальное значение каждый раз, когда вы определяете и подгоняете модель

следуя вашему коду, я сворачиваю все в этих строках:

 NUMBER_OF_MODELS = 4
models = []
histories = []

for i in range(NUMBER_OF_MODELS):

    set_seed_TF2(33)

    model = keras.models.Sequential(name=f'{i}')

    model.add(keras.layers.Dense(8, activation='relu', input_shape=df_train['features'].values.shape[-1:]))
    model.add(keras.layers.Dense(3, activation='softmax'))

    model.compile(optimizer=keras.optimizers.Adam(),
                  loss=keras.losses.CategoricalCrossentropy(),
                  metrics=[keras.metrics.CategoricalAccuracy()])
    
    with tf.device('/cpu:0'):
        
        history = model.fit(x=df_train['features'].values, y=df_train['labels'].values,
                            validation_data=(df_val['features'].values, df_val['labels'].values),
                            batch_size=512, epochs=100, verbose=0)
        histories.append(history)
        
    models.append(model)
 

волшебная функция set_seed_TF2

 def set_seed_TF2(seed):
    
    tf.random.set_seed(seed)
    os.environ['PYTHONHASHSEED'] = str(seed)
    np.random.seed(seed)
    random.seed(seed)
 

это должно вызываться каждый раз, когда вы инициализируете модель и подгоняете

имея это в виду, вы можете каждый раз создавать одни и те же показатели / прогнозы:

введите описание изображения здесь

вот работающий ноутбук: https://colab.research.google.com/drive/1nHEDI6d3LsRPQUXGiTOYfNOfw954Pu-H?usp=sharing

это работает только для процессора

Комментарии:

1. О’кей, это интересно! Почему это так происходит? Нужно ли вам делать это вот так последовательно? Итак, set_seed -> compile -> fit , последовательно для каждой модели? Или можно сначала скомпилировать все модели в одном цикле, а затем поместить все модели в другой цикл?

2. каждый раз, когда вы инициализируете модель, генерируются новые случайные веса, как и при любой случайной операции в python. наверняка в таком порядке работает. если вы хотите сначала скомпилировать, а затем подогнать, вы можете попробовать… но в цикле компиляции я предлагаю делать set_seed (X)-> compile, а в цикле подгонки set_seed (X)-> fit каждый раз, когда вы вычисляете компиляцию / подгонку (как в примере, который я предоставил u) … не забудьте проголосовать и принять его 😉

3. Но начальные значения уже были установлены в начале. Являются ли они каким-то образом недействительными при инициализации модели keras?

4. если вы выполните: np.random.seed(0); X = np.random.uniform(0,1,10); Y = np.random.uniform(0,1,10)… X отличается от Y, это та же логика