Python Numba可用于划分Keras层的子类吗?

Python Numba可用于划分Keras层的子类吗?,python,tensorflow,keras,numba,Python,Tensorflow,Keras,Numba,我知道麻木。然而,在我的例子中,我试图将一个层子类化,所以这个解决方案对我不起作用 将numpy导入为np 进口麻木 导入tensorflow作为tf @numba.jit(nopython=True) def func(参数,输入): 返回参数*输入**2 @numba.jit(nopython=True) def gradfunc(参数,输入): 返回输入**2 @自定义梯度 def func_tf(参数,输入): p=参数numpy() i=input.numpy() def梯度(dy):

我知道麻木。然而,在我的例子中,我试图将一个
层子类化,所以这个解决方案对我不起作用

将numpy导入为np
进口麻木
导入tensorflow作为tf
@numba.jit(nopython=True)
def func(参数,输入):
返回参数*输入**2
@numba.jit(nopython=True)
def gradfunc(参数,输入):
返回输入**2
@自定义梯度
def func_tf(参数,输入):
p=参数numpy()
i=input.numpy()
def梯度(dy):
返回tf.numpy_函数(gradfunc,(p,i),tf.float32),2*p*i
返回tf.numpy_函数(func,(p,i),tf.float32),grad
myLayer类(tf.keras.layers.Layer):
定义初始化(自):
super()。\uuuu init\uuuuu()
def构建(自我,输入_形状):
self.param=自加重量(“param”)
def呼叫(自我,输入):
返回函数(self.param,输入)
myModel类(tf.keras.Model):
def uuu init uuuu(自,num_层):
super()。\uuuuu init\uuuuuuu(名称=“”)
self.\u layers=[myLayer()用于范围内的(num\u layers)]
def调用(自、输入张量):
对于自身中的层。\u层:
输入张量=图层(输入张量)
返回输入张量
模型=我的模型(3)

打印(型号(1.5))#编辑:如果您将
params
input
直接传递到以下位置,而不是在
tf_func
中使用
.numpy()
,则您的代码应该可以工作:

@tf.custom\u梯度
def func_tf(参数,输入):
param=tf。将_转换为_张量(param)
输入=tf。将_转换为_张量(输入)
def梯度(dy):
返回tf.numpy_函数(gradfunc,(param,input),tf.float32),2*param*input
返回tf.numpy_函数(func,(param,input),tf.float32),grad
存在的原因是严格要求对象,因此如果直接使用
params
,它将是从
myLayer
传递的变量,它将无法按预期工作

出于某种原因,代码在此之后仍然给出了一个关于形状的错误。我将
参数
权重的形状更改为
[1,1]
:

self.param=self.add_weight(“param”,shape=[1,1])

您可以通过
run_early=True
强制Keras使用渴望模式(即不使用)进行培训:

model.compile(
optimizer=tf.keras.optimizers.Adam(),
损失=损失,
指标=[损失],
热切地奔跑(正确)

的确如此(谢谢你的建议),但这至少会使训练速度减慢10倍@Ziofil是的,这并不让我感到惊讶。。。不幸的是,没有太多的方法可以解决这个问题,如果你想将NumPy/Numba代码整合到训练中,你需要急切地运行。。。另一种选择是将Numba代码移植到TensorFlow,我不知道这在您的情况下是否可行(可能是TensorFlow实现比Numba慢)。但原则上,它应该可以在Keras和TF的内部实现:如果一个人将op定义为一个具有自己自定义梯度的黑盒,那么它在计算图中应该是“可插入的”,就像…@Ziofil Wait,我刚刚意识到,为什么你在代码中使用
.numpy()
?在
func_tf
中不需要
p
i
,应该使用
param
input
。这将允许将代码包装到
tf.函数中。嗯,
input
作为一个值传递,但是
param
作为一个张量传递,因此如果我不使用
.numpy()
,它将不起作用。。。(除非我遗漏了什么)