Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/tensorflow/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Apache spark 在pyspark UDF中使用tensorflow.keras模型会产生pickle错误_Apache Spark_Tensorflow_Keras_Pyspark_User Defined Functions - Fatal编程技术网

Apache spark 在pyspark UDF中使用tensorflow.keras模型会产生pickle错误

Apache spark 在pyspark UDF中使用tensorflow.keras模型会产生pickle错误,apache-spark,tensorflow,keras,pyspark,user-defined-functions,Apache Spark,Tensorflow,Keras,Pyspark,User Defined Functions,我想在pysark pandas_udf中使用tensorflow.keras模型。但是,在将模型发送给工作程序之前序列化模型时,我会收到一个pickle错误。我不确定我正在使用最好的方法来执行我想要的,因此我将公开一个最小但完整的示例 套餐: tensorflow-2.2.0(但所有以前的版本也会触发错误) pyspark-2.4.5 进口声明如下: 将熊猫作为pd导入 将numpy作为np导入 从tensorflow.keras.models导入顺序 从tensorflow.keras.

我想在pysark pandas_udf中使用tensorflow.keras模型。但是,在将模型发送给工作程序之前序列化模型时,我会收到一个pickle错误。我不确定我正在使用最好的方法来执行我想要的,因此我将公开一个最小但完整的示例

套餐:

  • tensorflow-2.2.0(但所有以前的版本也会触发错误)
  • pyspark-2.4.5
进口声明如下:

将熊猫作为pd导入
将numpy作为np导入
从tensorflow.keras.models导入顺序
从tensorflow.keras.layers导入稠密
从pyspark.sql导入SparkSession,函数为F,类型为T
Pyspark UDF是一种新的UDF:

def计算输出自定义项(模型):
“模型预测的udf”
@F.pandas_udf(T.DoubleType(),F.PandasUDFType.SCALAR)
def计算输出(输入1、输入2、输入3):
pdf=pd.DataFrame({
“input1”:input1,
“输入2”:输入2,
“input3”:inputs3
})
pdf['predicted_output']=model.predict(pdf.values)
返回pdf['predicted_output']
返回计算输出
主要代码:

#模型参数
权重=np.数组([[0.5]、[0.4]、[0.3])
偏差=np.数组([1.25])
激活='线性'
输入尺寸,输出尺寸=权重.shape
#初始化模型
模型=顺序()
层=密集(输出尺寸,输入尺寸=输入尺寸,激活=激活)
模型。添加(图层)
层。设置权重([权重,偏差])
#初始化Spark会话
spark=SparkSession.builder.appName('test').getOrCreate()
#使用输入和运行模型创建数据流
pdf=pd.DataFrame({
“input1”:np.random.randn(200),
“input2”:np.random.randn(200),
“input3”:np.random.randn(200)
})
pdf['predicted_output']=model.predicted(pdf['input1','input2','input3'].值)
#使用输入创建spark df,并使用udf运行模型
sdf=spark.createDataFrame(pdf)
sdf=sdf.withColumn('predicted\u output','compute\u output\u udf(model)('input1','input2','input3'))
sdf.limit(5.show)()
调用计算输出udf(模型)时会触发此错误:

PicklingError: Could not serialize object: TypeError: can't pickle _thread.RLock objects
我发现这是关于酸洗keras模型的,并在tensorflow.keras上进行了尝试,但当在UDF中调用模型的预测函数时,我得到了以下错误(因此序列化工作正常,但非序列化不正常?)

有人知道如何继续吗?提前谢谢你


PS:注意,我没有直接使用keras库中的模型,因为我周期性地出现另一个错误,解决它似乎更困难。但是,该模型的序列化不会像tensorflow.keras模型那样产生错误。

因此,如果我们使用该解决方案直接在tensorflow.keras.models.model类中扩展getstatesetstate方法,然后,工人无法取消序列化模型,因为他们没有该类的扩展

然后,解决方案是使用本文建议的包装器类

类ModelWrapperPickable:
定义初始化(自我,模型):
self.model=model
定义获取状态(自身):
模型_str=''
将tempfile.NamedTemporaryFile(后缀='.hdf5',delete=True)作为fd:
tensorflow.keras.models.save_model(self.model,fd.name,overwrite=True)
model_str=fd.read()
d={'model_str':model_str}
返回d
定义设置状态(自身、状态):
将tempfile.NamedTemporaryFile(后缀='.hdf5',delete=True)作为fd:
写入(状态['model_str'])
fd.flush()
self.model=tensorflow.keras.models.load\u model(fd.name)
UDF变成:

def compute_output_pandas_udf(模型包装器):
“模型预测的udf”
@F.pandas_udf(T.DoubleType(),F.PandasUDFType.SCALAR)
def计算输出(输入1、输入2、输入3):
pdf=pd.DataFrame({
“input1”:input1,
“输入2”:输入2,
“input3”:inputs3
})
pdf['predicted_output']=model_wrapper.model.predict(pdf.values)
返回pdf['predicted_output']
返回计算输出
以及主要代码:

#模型参数
权重=np.数组([[0.5]、[0.4]、[0.3])
偏差=np.数组([1.25])
激活='线性'
输入尺寸,输出尺寸=权重.shape
#初始化keras模型
模型=顺序()
层=密集(输出尺寸,输入尺寸=输入尺寸,激活=激活)
模型。添加(图层)
层。设置权重([权重,偏差])
#初始化模型包装器
model_wrapper=ModelWrapperPickable(model)
#初始化Spark会话
spark=SparkSession.builder.appName('test').getOrCreate()
#使用输入和运行模型创建数据流
pdf=pd.DataFrame({
“input1”:np.random.randn(200),
“input2”:np.random.randn(200),
“input3”:np.random.randn(200)
})
pdf['predicted_output']=model_wrapper.model.predicted(pdf['input1','input2','input3'].values)
#使用输入创建spark df,并使用udf运行模型
sdf=spark.createDataFrame(pdf)
sdf=sdf.withColumn('predicted\u output','compute\u output\u pandas\u udf(model\u wrapper)('input1','input2','input3'))
sdf.limit(5.show)()
AttributeError: 'Sequential' object has no attribute '_distribution_strategy'