Структурирование проекта Keras для достижения воспроизводимых результатов в GPU - PullRequest
1 голос
/ 16 марта 2019

Я пишу оболочку tenorflow.Keras для выполнения экспериментов ML.

Мне нужна моя инфраструктура, чтобы иметь возможность выполнять эксперимент, как указано в файле конфигурации yaml, и параллельно работать в графическом процессоре.

Тогда мне нужна гарантия, что, если я снова проведу эксперимент, я получу, если не те же самые результаты, что-то достаточно близкое.

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

# Set up random seeds
random.seed(seed)
np.random.seed(seed)
tf.set_random_seed(seed)

Этого оказалось недостаточно.

Я выполнил одну и ту же конфигурацию 4 раза и составил графикрезультаты:

enter image description here

Как видите, результаты сильно различаются в зависимости от пробежек.

Как настроить тренировкув Керасе, чтобы убедиться, что я получаю достаточно похожие результаты при обучении в GPU?Это вообще возможно?

Полный учебный сценарий можно найти здесь .

Некоторые из моих коллег используют просто чистый TF , и ихрезультаты кажутся намного более последовательными.Более того, они, похоже, не вызывают какой-либо случайности, кроме как для того, чтобы разделить поезд и валидацию всегда одинаково.

Ответы [ 2 ]

2 голосов
/ 20 июля 2019

Keras + Tensorflow.

Шаг 1, отключите графический процессор.

import os
os.environ["CUDA_DEVICE_ORDER"] = "PCI_BUS_ID"
os.environ["CUDA_VISIBLE_DEVICES"] = ""

Шаг 2, запустите те библиотеки, которые включены в ваш код, скажем «tenorflow, numpy, random».

import tensorflow as tf
import numpy as np
import random as rn

sd = 1 # Here sd means seed.
np.random.seed(sd)
rn.seed(sd)
os.environ['PYTHONHASHSEED']=str(sd)

from keras import backend as K
config = tf.ConfigProto(intra_op_parallelism_threads=1,inter_op_parallelism_threads=1)
tf.set_random_seed(sd)
sess = tf.Session(graph=tf.get_default_graph(), config=config)
K.set_session(sess)

Убедитесь, что эти два фрагмента кода включены в начало вашего кода, тогда результат будет воспроизводимым.

0 голосов
/ 16 марта 2019

Попробуйте добавить начальные параметры в инициализаторы весов / смещений.Просто чтобы добавить больше деталей к комментарию Александра Эйбекова.

Tensorflow имеет два уровня графа случайных начальных чисел и уровень операции.Если вы используете более одного графика, вам нужно указать seed в каждом.Вы можете переопределить начальный уровень графика с помощью операционного уровня, установив начальный параметр в функции.И вы можете заставить две функции даже из разных графиков выводить одно и то же значение, если установлено одинаковое начальное число.Рассмотрим этот пример:

g1 = tf.Graph()
with g1.as_default():
    tf.set_random_seed(1)
    a = tf.get_variable('a', shape=(1,), initializer=tf.keras.initializers.glorot_normal())
    b = tf.get_variable('b', shape=(1,), initializer=tf.keras.initializers.glorot_normal(seed=2))
with tf.Session(graph=g1) as sess:
    sess.run(tf.global_variables_initializer())
    print(sess.run(a)) 
    print(sess.run(b))
g2 = tf.Graph()
with g2.as_default():
    a1 = tf.get_variable('a1', shape=(1,), initializer=tf.keras.initializers.glorot_normal(seed=1))

with tf.Session(graph=g2) as sess:
    sess.run(tf.global_variables_initializer())
    print(sess.run(a1))

В этом примере вывод a совпадает с a1, но b отличается.

...