Python 火花上的Keras/Tensorflow可再现结果

Python 火花上的Keras/Tensorflow可再现结果,python,apache-spark,tensorflow,keras,multiprocessing,Python,Apache Spark,Tensorflow,Keras,Multiprocessing,我正在Spark集群上运行一个带有Keras的python程序(我在深层神经网络上执行网格搜索),我想确保我的结果是可复制的 我的Spark cluster通过运行以下.sh脚本点燃: SPARK_HOME=/u/users/******/spark-2.3.0 \ Q_CORE_LOC=/u/users/******/q-core \ ENV=local \ HIVE_HOME=/usr/hdp/current/hive-client \ SPARK2_HOME=/u/users/******

我正在Spark集群上运行一个带有Keras的python程序(我在深层神经网络上执行网格搜索),我想确保我的结果是可复制的

我的Spark cluster通过运行以下
.sh
脚本点燃:

SPARK_HOME=/u/users/******/spark-2.3.0 \
Q_CORE_LOC=/u/users/******/q-core \
ENV=local \
HIVE_HOME=/usr/hdp/current/hive-client \
SPARK2_HOME=/u/users/******/spark-2.3.0 \
HADOOP_CONF_DIR=/etc/hadoop/conf \
HIVE_CONF_DIR=/etc/hive/conf \
HDFS_PREFIX=hdfs:// \
PYTHONPATH=/u/users/******/q-core/python-lib:/u/users/******/three-queues/python-lib:/u/users/******/pyenv/prod_python_libs/lib/python2.7/site-packages/:$PYTHON_PATH \
YARN_HOME=/usr/hdp/current/hadoop-yarn-client \
SPARK_DIST_CLASSPATH=$(hadoop classpath):$(yarn classpath):/etc/hive/conf/hive-site.xml \
PYSPARK_PYTHON=/usr/bin/python2.7 \
QQQ_LOC=/u/users/******/three-queues \
spark-submit \
--master yarn 'dnn_grid_search.py' \
--executor-memory 10g \
--num-executors 8 \
--executor-cores 10 \
--conf spark.port.maxRetries=80 \
--conf spark.dynamicAllocation.enabled=False \
--conf spark.default.parallelism=6000 \
--conf spark.sql.shuffle.partitions=6000 \
--principal ************************ \
--queue default \
--name lets_get_starting \
--keytab /u/users/******/.******.keytab \
--driver-memory 10g
通过在我的
bash
shell上运行
nohup./spark\u python\u shell.sh>output.log&
,我点燃了spark集群,并运行了我的python Keras脚本(参见上文
spark submit\--master warn'dnn\u grid\u search.py'

为了确保结果的可再现性,我尝试在笔记本电脑的CPU上成功地实现了这一点,以获得可再现的结果(另请参见我对StackOverflow的回答:,):

但是,通过包含部分
(5)
,我很确定程序没有正常运行,因为我在其中包含的一些
print
语句没有在
output.log
文件中打印任何内容

具体而言,我创建了一个非常简单的自定义记分器函数,将此打印语句插入其中,以便查看网格搜索是否真正在运行:

def precision_recall(y_true, y_predict):

    # Print time
    from datetime import datetime
    time_now = datetime.utcnow()
    print('Grid Search time now:', time_now)

    from sklearn.metrics import precision_recall_fscore_support
    _, recall, _, _ = precision_recall_fscore_support(y_true, y_predict, average='binary')

    return  recall

from sklearn.metrics import make_scorer
custom_scorer = make_scorer(score_func=precision_recall, greater_is_better=True, needs_proba=False)

# Execute grid search
# Notice 'n_jobs=-1' for parallelizing the jobs (across the cluster)
from sklearn.model_selection import GridSearchCV
classifiers_grid = GridSearchCV(estimator=classifier, param_grid=parameters, scoring=custom_scorer, cv=5, n_jobs=-1)
classifiers_grid.fit(X, y)
但是,当我运行其他ML算法(随机森林等)时,自定义分数函数(
precision\u recall
)中的print语句正确地打印时间,然后当我使用Keras/Tensorflow及其种子系统和会话尝试打印时,没有打印任何内容


因此,我的问题是如何在Spark上使用Keras/Tensorflow获得可复制的结果?

据我所知,该代码没有使用Spark的执行器,只有驱动程序。@user6910411,我在Spark方面的经验不足,无法理解这到底意味着什么。我只想提两件事。首先,我首先使用超级按钮连接到edgenode,然后在这个用户的bash中运行
nohup
命令。其次,例如,当使用Xgboost进行网格搜索时,我可以在几个小时内获得50000个不同网格搜索组合的结果。因此,我的印象是我确实使用了执行器,但我可能错了。您共享的是一个简单的、非分布式的代码。即使您使用
spark submit
提交它,它也将保持不变-没有任何spark魔法可以将它变成分布式程序。当然,您的问题可能缺少一些重要的部分,您实际上使用Spark分布式原语来运行单个组件-如果是这种情况,请回答您的问题并将其包括在内,以便潜在客户的答案具有完整的图片。您似乎使用的每个库都有某种形式的Spark绑定(tensorframes、xgboost4j spark、spark deep learning、spark sklearn等等),但是,到目前为止,您共享的代码中没有任何内容建议您使用其中任何一种。最后,我强烈建议您关注特定场景—在分布式应用程序中处理RNG状态(如果它确实是分布式的)可能会非常复杂,尤其是在复杂的环境中,除此之外,还有其他非决定论的来源,这大大限制了您提供完全可复制结果的能力。
def precision_recall(y_true, y_predict):

    # Print time
    from datetime import datetime
    time_now = datetime.utcnow()
    print('Grid Search time now:', time_now)

    from sklearn.metrics import precision_recall_fscore_support
    _, recall, _, _ = precision_recall_fscore_support(y_true, y_predict, average='binary')

    return  recall

from sklearn.metrics import make_scorer
custom_scorer = make_scorer(score_func=precision_recall, greater_is_better=True, needs_proba=False)

# Execute grid search
# Notice 'n_jobs=-1' for parallelizing the jobs (across the cluster)
from sklearn.model_selection import GridSearchCV
classifiers_grid = GridSearchCV(estimator=classifier, param_grid=parameters, scoring=custom_scorer, cv=5, n_jobs=-1)
classifiers_grid.fit(X, y)