Python ValueError:tf.function-decorated函数试图在非第一次调用时创建变量

Python ValueError:tf.function-decorated函数试图在非第一次调用时创建变量,python,tensorflow,machine-learning,keras,tensorflow2.0,Python,Tensorflow,Machine Learning,Keras,Tensorflow2.0,我有一个用tensorflow 2中的模型子类API编写的模型。它包含一个自定义层。问题是,在自定义层中,我需要在运行时将输入张量的通道号发送到Conv2D层。请参阅下面的代码: 自定义层 导入tensorflow作为tf AuxNettf.keras.layers.layers类: def _初始__自身,比率=8: superAuxNet,自初始化__ 自身比率=比率 self.avg=tf.keras.layers.globalaveragepoolg2d self.max=tf.kera

我有一个用tensorflow 2中的模型子类API编写的模型。它包含一个自定义层。问题是,在自定义层中,我需要在运行时将输入张量的通道号发送到Conv2D层。请参阅下面的代码:

自定义层

导入tensorflow作为tf AuxNettf.keras.layers.layers类: def _初始__自身,比率=8: superAuxNet,自初始化__ 自身比率=比率 self.avg=tf.keras.layers.globalaveragepoolg2d self.max=tf.keras.layers.globalMapooling2D def callself,输入: 平均值=自我平均值 max=self.maxinputs 平均值=tf.keras.layers.reforme1,1,平均值形状[1]平均值 最大值=tf.keras.layers.Reforme1,1,最大形状[1]最大值 警觉的----------- input\u shape=inputs.get\u shape.as\u列表 _,h,w,通道=输入形状 conv1a=tf.keras.layers.Conv2Dchannels,内核大小=1, 步幅=1,padding='same',使用_bias=True, 激活=tf.nn.reluavg conv1b=tf.keras.layers.Conv2Dchannels,内核大小=1,步幅=1, padding='same',使用_bias=True, 激活=tf.nn.relumax 返回tf.nn.sigmoidconv1a+conv1b 整个模型

净重级、克瑞斯级、型号: 定义初始自身,尺寸: 超级网,自我初始化__ self.base=tf.keras.layers.Conv2D124,3,1 self.gap=tf.keras.layers.globalaveragepoolg2d self.aux=AuxNet初始化自定义层 self.density=tf.keras.layers.Dense128,激活=tf.nn.relu self.out=tf.keras.layers.Dense10,激活='softmax' def callself,输入张量,training=False: x=自基输入张量 在输入张量上使用自定义图层 aux=self.auxx*x x=self.gapaux x=自我。性别 返回self.outx 如您所见,AuxNet类包含Conv2D层及其输入通道的过滤器大小。输入只是模型类的输入,网络。在模型类中初始化自定义层时,我无法设置其Conv2D层的通道号。所以,我在这里所做的是,我在AuxNet层的调用方法中计算这个Conv2D的通道号,我认为这是一个糟糕的做法

这个问题带来了运行时问题。我无法在图形模式下编译模型类,而是强制启用渴望模式

将numpy作为np导入 导入tensorflow作为tf 从tensorflow.keras.models导入模型 从tensorflow.keras.layers导入稠密、全局平均池2D、辍学 x_列,y_列,x_测试,y_测试=tf.keras.datasets.cifar10.load_数据 列车组/数据 x_列=x_列。A类型为'float32'/255 列车组/目标 y列车=tf.keras.utils.to_categoricaly_列车,数量=10类 型号=Net32,32,3 tf.config.run_函数-------- model.compile 损失=tf.keras.loss.CategoricalCross熵, metrics=tf.keras.metrics.CategoricalAccuracy, 优化器=tf.keras.optimizers.Adam 适合 model.fitx\u系列,y\u系列,批量大小=128,历代数=1 这很有效,但训练速度很慢。但是,如果不这样做,则会出现以下错误:

ValueError:tf.function-decorated函数试图在非第一次调用时创建变量

无需启用急切模式的任何解决方法?如何有效地将所需参数传递到此自定义层?在这种情况下,我不必在调用方法中计算通道深度。

基本上,我需要了解如何在自定义层中定义内置层。建议所有层都应该初始化uuu init_uuu方法。但我们需要未知张量的通道深度,并根据该值设置过滤器数量。然而,在构建方法中,我们可以很容易地做到这一点

AuxNettf.keras.layers.layers类: def _初始__自身,比率=8: superAuxNet,自初始化__ 自身比率=比率 self.avg=tf.keras.layers.globalaveragepoolg2d self.max=tf.keras.layers.globalMapooling2D def buildself,输入_形状: self.conv1=tf.keras.layers.Conv2Dinput_形状[-1], 内核大小=1,步幅=1,padding='same', 使用_bias=True,激活=tf.nn.relu self.conv2=tf.keras.layers.conv2Input_形状[-1], 内核大小=1,步幅=1,padding='same', 使用_bias=True,激活=tf.nn.relu superAuxNet,self.buildinput\u形状 def callself,输入: 平均值=自我平均值 max=self.maxinputs 平均值=tf.keras.layers.reforme1,1,平均值形状[1]平均值 最大值=tf.keras.layers.Reforme1,1,最大形状[1]最大值 conv1a=self.conv1avg conv1b=self.conv2max 返回tf.nn.sigmoidconv1a+conv1b 解决了的 基本上,我需要了解如何在自定义层中定义内置层。建议所有层都应该初始化uuu init_uuu方法。但我们需要未知张量的通道深度,并根据该值设置过滤器数量。然而,在构建方法中,我们可以很容易地做到这一点

AuxNettf.keras.layers.layers类: def _初始__自身,比率=8: superAuxNet,自初始化__ 自身比率=比率 self.avg=tf.keras.layers.globalaveragepoolg2d self.max=tf.keras.layers.globalMapooling2D def buildself,输入_形状: self.conv1=tf.keras.layers.Conv2Dinput_形状[-1], 内核大小=1,步幅=1,padding='same', 使用_bias=True,激活=tf.nn.relu self.conv2=tf.keras.layers.conv2Input_形状[-1], 内核大小=1,步幅=1,padding='same', 使用_bias=True,激活=tf.nn.relu superAuxNet,self.buildinput\u形状 def callself,输入: 平均值=自我平均值 max=self.maxinputs 平均值=tf.keras.layers.reforme1,1,平均值形状[1]平均值 最大值=tf.keras.layers.Reforme1,1,最大形状[1]最大值 conv1a=self.conv1avg conv1b=self.conv2max 返回tf.nn.sigmoidconv1a+conv1b
不知道你在这里想做什么。目前,您的模型在每次调用时都会创建新的卷积层,即每次训练迭代,这毫无意义,并且由于每次都重置变量,因此训练不可能进行。我想您可能想了解如何创建自定义图层,例如,或。特别是,看看如何在构建方法中创建变量。这是一个主要任务的玩具演示。不过,谢谢你的指点。我将仔细阅读这份文件@它解决了xdurch0问题。谢谢我不知道你想在这里做什么。目前,您的模型在每次调用时都会创建新的卷积层,即每次训练迭代,这毫无意义,并且由于每次都重置变量,因此训练不可能进行。我想您可能想了解如何创建自定义图层,例如,或。特别是,看看如何在构建方法中创建变量。这是一个主要任务的玩具演示。不过,谢谢你的指点。我将仔细阅读这份文件@它解决了xdurch0问题。谢谢除息的