[英]@tf.function( input_signature ) on an object's method defined outside of a class scope
Say I have a Custom Layer
:假设我有一个
Custom Layer
:
class Custom_Layer(keras.layers.Layer):
def __init__(self, **kwargs):
self.w_0 = tf.Variable(tf.random_uniform_initializer(),trainable=True)
self.b_0 = tf.Variable(tf.zeros_initializer(),trainable=True)
....
def call(self, inputs):
output = A_Method(self, inputs)
return output
def A_Method(self, TensorA):
....
return something
if I want to decorate @tf.function(with input_signature)
to A_Method
to control tracing如果我想将
@tf.function(with input_signature)
装饰为A_Method
以控制跟踪
@tf.function(input_signature=[???, tf.TensorSpec(shape=None)])
def A_Method(self, TensorA):
....
return something
what spec should i put for self
?我应该为
self
设定什么规格? I tried putting tf.TensorSpec
but it raised an error我尝试放置
tf.TensorSpec
但出现错误
___Updated the question___:
Im quite new to tensorflow sorry if the code is weird or doesnt make sense.我对 tensorflow 很陌生,如果代码很奇怪或没有意义,我深表歉意。 the reason I do this is I found RNN took a long time for first epoch to get started, I dont know if this custom layer can do something alike but is taking less time.
我这样做的原因是我发现 RNN 花了很长时间才开始第一个纪元,我不知道这个自定义层是否可以做类似的事情但花费的时间更少。 but ultimately I believe the slow initialize time is because of tensorflow
retracing repeatedly even on same input_spec - input_shape
.但最终我相信缓慢的初始化时间是因为 tensorflow
retracing repeatedly even on same input_spec - input_shape
。 I use this layer repeatedly as,我反复使用这一层,
input_layer = Input(shape=( X_.shape[1],X_.shape[2]), name='input')
for loop :
Hard_Code_RNN_Layer(input_layer[:,:, slicing])
then I ran .experimental_get_tracing_count()
count is 300 which really shouldn't be above 10, thats why I wanted to take this method out def Mimic_RNN(self, step_input, step_state)
remove it from the class
and try giving it an input_signature. remove it from the class
我.experimental_get_tracing_count()
def Mimic_RNN(self, step_input, step_state)
Please see below:请看下面:
def Initialize_Variable(input_dim, units):
w_init = tf.random_normal_initializer()
b_init = tf.zeros_initializer()
w_0 = tf.Variable(initial_value=w_init(shape=(input_dim, units)))
b_0 = tf.Variable(initial_value=b_init(shape=(units)))
return w_0, b_0
def Initialize_One_Variable(input_dim, units):
w_init = tf.random_uniform_initializer()
R_kernal = tf.Variable(initial_value=w_init(shape=(input_dim, units)))
return R_kernal
class Hard_Code_RNN_Layer(keras.layers.Layer):
def __init__(self, input_tuple, Sequencee=True, **kwargs):
super(Hard_Code_RNN_Layer, self).__init__()
input_shape, units = input_tuple
self.Hidden_Size = (int)(input_shape * 0.85)
self.inputshape = input_shape
self.units = units
self.thiseq = Sequencee
self.Uz = Initialize_One_Variable(self.Hidden_Size, self.Hidden_Size)
self.Ur = Initialize_One_Variable(self.Hidden_Size, self.Hidden_Size)
self.w_hz, self.b_hz = Initialize_Variable(self.units, self.Hidden_Size)
self.w_out, self.b_out = Initialize_Variable(self.Hidden_Size,self.units)
self.w_0, self.b_0 = Initialize_Variable(self.inputshape,self.units)
def get_config(self):
cfg = super().get_config()
return cfg
def Layer_Method(inputs, w_h, b_h):
return tf.matmul(inputs, w_h) + b_h
def Mimic_RNN(self, step_input, step_state): <-----------input_signature_this
x__j = self.Layer_Method(step_input, self.w_0, self.b_0)
r = tf.sigmoid(tf.matmul(step_state, self.Ur))
z = tf.sigmoid(tf.matmul(step_state, self.Uz))
h__ = tf.nn.relu(tf.matmul(x__j, self.w_hz) + tf.multiply(r, step_state) + self.b_hz)
h = (1-z) * h__ + z * step_state
output__ = tf.nn.relu(tf.matmul(h, self.w_out) + self.b_out)
return output__, h
def call(self, inputs):
unstack = tf.unstack(inputs, axis=1)
out1, hiddd = self.Mimic_RNN(step_input=unstack[0], step_state=tf.zeros_like(unstack[0][:,0:self.Hidden_Size]))
out2, hiddd = self.Mimic_RNN(step_input=unstack[1], step_state=hiddd)
out3, hiddd = self.Mimic_RNN(step_input=unstack[2], step_state=hiddd)
if(self.thiseq):
return tf.stack([out1, out2, out3], axis =1 )
else:
return out3
You actually can use input_signature
with class methods.您实际上可以将
input_signature
与 class 方法一起使用。 The initial self
parameter simply needs to be ignored in the input signature specification, so you just provide the tf.TensorSpec
for the other parameters.在输入签名规范中只需忽略初始
self
参数,因此您只需为其他参数提供tf.TensorSpec
。
For example:例如:
import tensorflow as tf
class MyClass:
@tf.function(input_signature=(tf.TensorSpec([None], tf.float32),
tf.TensorSpec([None], tf.float32)))
def my_method(self, a, b):
return a + b
tf.print(MyClass().my_method([1, 2, 3], [4]))
# 5, 6, 7
If you specify an input signature, all inputs to the python function must be convertible to Tensor
.如果您指定输入签名,则 python function 的所有输入都必须可转换为
Tensor
。 self
in that case, holds the reference to the instance on which the method is called on, and cannot be convertible as a Tensor.在这种情况下,
self
持有对调用该方法的实例的引用,并且不能转换为张量。 You just can't specify an input_signature
on your A_method
function.您只是不能在
A_method
input_signature
上指定 input_signature。
However, it is still possible to decorate a method from a class, because TensorFlow will detect if the function to decorate is a method, and if that's the case, will automatically remove the self
argument.但是,仍然可以从 class 装饰方法,因为 TensorFlow 将检测 function 是否是一种方法,如果是这种情况,将自动删除
self
参数。 You can check the source code :您可以查看源代码:
if self._is_method:
# Remove `self`: default arguments shouldn't be matched to it.
# TODO(b/127938157): Should this error out if there is no arg to
# be removed?
args = fullargspec.args[1:]
It's worth noting that if a method is defined outside of the class, then this check will fail.值得注意的是,如果在 class 之外定义了方法,则此检查将失败。 (The check relies on the
ismethod
function from the standard library inspect
module). (检查依赖于标准库
inspect
模块中的ismethod
)。 As self
is not convertible to a Tensor, the decorated method will throw an error when called.由于
self
不能转换为 Tensor,因此被修饰的方法在调用时会抛出错误。
It's not best practice to define a method outside of the class definition: it makes the code harder to read, and harder to use.在 class 定义之外定义方法并不是最佳实践:它使代码更难阅读,也更难使用。 You can give a look to that question for more details: Define a method outside of class definition?
您可以查看该问题以获取更多详细信息: 在 class 定义之外定义方法? .
. The python way of reusing logic between classes is either to use inheritance, or to define a function that does not depend on the attributes of the object (or where those attributes are passed as argument to the function).
The python way of reusing logic between classes is either to use inheritance, or to define a function that does not depend on the attributes of the object (or where those attributes are passed as argument to the function).
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.