TF/keras 子类在 Eager Execution 中完美运行,没有它会引发大量无法追踪的错误?

Posted

技术标签:

【中文标题】TF/keras 子类在 Eager Execution 中完美运行,没有它会引发大量无法追踪的错误?【英文标题】:TF/keras subclass works perfectly in Eager Execution, and throws a massive untraceable error without it? 【发布时间】:2019-09-20 20:48:29 【问题描述】:

我从keras.io 学会了编写自定义层。这里是:

class modrelu(Layer):
    def __init__(self, **kwargs):
        super(modrelu, self).__init__(**kwargs)

    def build(self, input_shape):
        print(input_shape)
        self.b = self.add_weight(name='brad', shape=(input_shape[0][1],), initializer='uniform',
                                      trainable=True)
        super(modrelu, self).build(input_shape)  # Be sure to call this at the end

    def call(self, x):
        assert isinstance(x, list)
        ip_r, ip_i = x
        comp= tf.complex(ip_r, ip_i) 
        ABS= tf.math.abs(comp)
        ANG= tf.math.angle(comp)

        ABS= tf.nn.relu( self.b + ABS) 

        op_i=  ABS * tf.sin(ANG) #K.dot ??
        op_r= ABS * tf.cos(ANG)
        return [op_r, op_i]

    def compute_output_shape(self, input_shape):
        assert isinstance(input_shape, list)
        shape_a, shape_b = input_shape
        return [shape_a, shape_b]


act= modrelu()
a=tf.constant(np.array([[1,2], [4,4]]), dtype='float32')
b=tf.constant(np.array([[3,4], [5, -1]]), dtype='float32')
act([a,b])

在 Eager 执行中运行时,我得到了不错的输出。如果没有这种模式,我会遇到非常奇怪的错误,我什至无法追踪到它的开始位置,它在另一个世界。这里是:

----------------------------------- ---------------------------- TypeError Traceback(最近一次调用 最后的) ~\AppData\Local\conda\conda\envs\py36\lib\site-packages\tensorflow\python\framework\tensor_util.py 在 make_tensor_proto(值,dtype,形状,verify_shape) 526 尝试: --> 527 str_values = [compat.as_bytes(x) for x in proto_values] 528 除了类型错误:

~\AppData\Local\conda\conda\envs\py36\lib\site-packages\tensorflow\python\framework\tensor_util.py 在 (.0) 526 尝试: --> 527 str_values = [compat.as_bytes(x) for x in proto_values] 528 除了类型错误:

~\AppData\Local\conda\conda\envs\py36\lib\site-packages\tensorflow\python\util\compat.py 在 as_bytes(bytes_or_text, 编码) 60 raise TypeError('期望的二进制或 unicode 字符串,得到 %r' % ---> 61 (bytes_or_text,)) 62

TypeError:预期的二进制或 unicode 字符串,得到 Dimension(2)

在处理上述异常的过程中,又发生了一个异常:

TypeError Traceback(最近调用 最后)在 2 a=tf.constant(np.array([[1,2], [4,4]]), dtype='float32') 3 b=tf.constant(np.array([[3,4], [5, -1]]), dtype='float32') ----> 4 幕([a,b])

~\AppData\Local\conda\conda\envs\py36\lib\site-packages\tensorflow\python\keras\engine\base_layer.py 在调用(自我、输入、*args、**kwargs) 744 # 用户手动覆盖了我们需要的构建方法吗 745#构建它。 --> 746 self.build(input_shapes) 747 # 我们必须设置 self.built 因为用户定义的构建函数不是 第748章

in build(self, input_shape) 7 打印(输入形状) 8 self.b = self.add_weight(name='brad', shape=(input_shape[0][1],), initializer='uniform', ----> 9 可训练=真) 10 # self.b= K.variable(value=np.random.rand(input_shape[0][1])-0.5, dtype='float32') # 11 super(modrelu, self).build(input_shape) # 一定要在最后调用这个

~\AppData\Local\conda\conda\envs\py36\lib\site-packages\tensorflow\python\keras\engine\base_layer.py 在 add_weight(self, name, shape, dtype, initializer, regularizer, 可训练、约束、分区器、use_resource、同步、 聚合,**kwargs) 607个集合=集合, 608同步=同步, --> 609 聚合=聚合) 610 backend.track_variable(变量) 第611章

~\AppData\Local\conda\conda\envs\py36\lib\site-packages\tensorflow\python\training\checkpointable\base.py 在 _add_variable_with_custom_getter(self, name, shape, dtype, 初始化器、getter、覆盖、**kwargs_for_getter) 第637章 第638章 --> 639 **kwargs_for_getter) 640 641 # 如果我们设置了一个初始化器并且变量处理了它,跟踪将不会

~\AppData\Local\conda\conda\envs\py36\lib\site-packages\tensorflow\python\keras\engine\base_layer.py 在 make_variable(name, shape, dtype, initializer, partition_info, 可训练、缓存设备、验证形状、约束、使用资源、 集合、同步、聚合、分区器)1975 收藏=收藏,1976 同步=同步, -> 1977年聚合=聚合)1978年返回v 1979年

~\AppData\Local\conda\conda\envs\py36\lib\site-packages\tensorflow\python\ops\variables.py 在 调用(cls, *args, **kwargs) 181 def 调用(cls,*args,**kwargs): 182 如果 cls 是变量 V1: --> 183 返回 cls._variable_v1_call(*args, **kwargs) 184 elif cls 是变量: 185 返回 cls._variable_v2_call(*args, **kwargs)

~\AppData\Local\conda\conda\envs\py36\lib\site-packages\tensorflow\python\ops\variables.py 在_variable_v1_call(cls,initial_value,可训练,集合, validate_shape,caching_device,名称,variable_def,dtype, 预期形状,import_scope,约束,use_resource, 同步、聚合) 第144章 145同步=同步, --> 146 聚合=聚合) 147 148 def_variable_v2_call(cls,

~\AppData\Local\conda\conda\envs\py36\lib\site-packages\tensorflow\python\ops\variables.py 在 (**kwargs) 123 聚合=VariableAggregation.NONE): 124 """调用变量类。用于强制签名。""" --> 125 previous_getter = lambda **kwargs: default_variable_creator(None, **kwargs) 126 for getter in ops.get_default_graph()._variable_creator_stack: # pylint: 禁用=受保护的访问 127 previous_getter = _make_getter(getter, previous_getter)

~\AppData\Local\conda\conda\envs\py36\lib\site-packages\tensorflow\python\ops\variable_scope.py 在 default_variable_creator(next_creator, **kwargs) 2435 缓存设备=缓存设备,名称=名称,数据类型=数据类型,2436 约束=约束,变量定义=变量定义, -> 2437 import_scope=import_scope) 2438 else: 2439 返回变量.RefVariable(

~\AppData\Local\conda\conda\envs\py36\lib\site-packages\tensorflow\python\ops\variables.py 在 调用(cls, *args, **kwargs) 185 返回 cls._variable_v2_call(*args, **kwargs) 186 其他: --> 187 return super(VariableMetaclass, cls).call(*args, **kwargs) 188 189

~\AppData\Local\conda\conda\envs\py36\lib\site-packages\tensorflow\python\ops\resource_variable_ops.py 在 init(self, initial_value, trainable, collections, validate_shape,caching_device,名称,dtype,variable_def, 进口范围,约束) 第295章 第296章 --> 297 约束=约束) 298 299 # pylint:禁用=未使用的参数

~\AppData\Local\conda\conda\envs\py36\lib\site-packages\tensorflow\python\ops\resource_variable_ops.py 在 _init_from_args(self, initial_value, trainable, collections, validate_shape、caching_device、名称、dtype、约束) 407 与 ops.name_scope("Initializer"), ops.device(None): 第408章 --> 409 initial_value() if init_from_fn else initial_value, 410 名称=“初始值”,dtype=dtype) 411 self._handle = eager_safe_variable_handle(

~\AppData\Local\conda\conda\envs\py36\lib\site-packages\tensorflow\python\keras\engine\base_layer.py in () 1957 初始化器 = 初始化器(dtype=dtype) 1958 init_val = lambda:初始化程序(# pylint: 禁用=g-long-lambda -> 1959 形状,dtype=dtype,partition_info=partition_info) 1960 variable_dtype = dtype.base_dtype 1961 if use_resource 是无:

~\AppData\Local\conda\conda\envs\py36\lib\site-packages\tensorflow\python\ops\init_ops.py 在调用中(self、shape、dtype、partition_info) 第253章 第254章 --> 255 形状,self.minval,self.maxval,dtype,seed=self.seed) 256 257 def get_config(自我):

~\AppData\Local\conda\conda\envs\py36\lib\site-packages\tensorflow\python\ops\random_ops.py 在 random_uniform(形状,minval,maxval,dtype,种子,名称) 233 最大值 = 1 234 以 ops.name_scope(name, "random_uniform", [shape, minval, maxval]) 作为名称: --> 235 形状 = _ShapeTensor(形状) 第236章 237 maxval = ops.convert_to_tensor(maxval, dtype=dtype, name="max")

~\AppData\Local\conda\conda\envs\py36\lib\site-packages\tensorflow\python\ops\random_ops.py 在 _ShapeTensor(形状) 其他 42 条: 43 dtype = 无 ---> 44 返回 ops.convert_to_tensor(shape, dtype=dtype, name="shape") 45 46

~\AppData\Local\conda\conda\envs\py36\lib\site-packages\tensorflow\python\framework\ops.py 在 convert_to_tensor(值,dtype,名称,preferred_dtype)1048 名称=名称,1049 首选_dtype=preferred_dtype, -> 1050 as_ref=False) 1051 1052

~\AppData\Local\conda\conda\envs\py36\lib\site-packages\tensorflow\python\framework\ops.py 在 internal_convert_to_tensor(value, dtype, name, as_ref, preferred_dtype, ctx) 1144 1145 如果 ret 为无: -> 1146 ret = conversion_func(value, dtype=dtype, name=name, as_ref=as_ref) 1147 1148 如果 ret 未实现:

~\AppData\Local\conda\conda\envs\py36\lib\site-packages\tensorflow\python\framework\constant_op.py 在 _constant_tensor_conversion_function(v, dtype, name, as_ref) 227 as_ref=假): 第228章 --> 229 返回常量(v, dtype=dtype, name=name) 230 231

~\AppData\Local\conda\conda\envs\py36\lib\site-packages\tensorflow\python\framework\constant_op.py 在常量(值,dtype,形状,名称,verify_shape) 第206章 第207章 --> 208 值,dtype=dtype,shape=shape,verify_shape=verify_shape)) 第209章 210 const_tensor = g.create_op(

~\AppData\Local\conda\conda\envs\py36\lib\site-packages\tensorflow\python\framework\tensor_util.py 在 make_tensor_proto(值,dtype,形状,verify_shape) 529 raise TypeError("未能将 %s 类型的对象转换为张量。" 530 “内容:%s。考虑将元素转换为” --> 531“支持的类型。” %(类型(值),值)) 第532章 第533章

TypeError:无法将类型对象转换为张量。 内容:(维度(2),)。考虑将元素转换为受支持的 输入。

【问题讨论】:

【参考方案1】:

您正在成为TensorShape 实例。如果执行不急,您可以使用as_list() 属性将其转换为 Python 列表:

if tf.executing_eagerly():
    shape = (input_shape[0][1], )
else:
    shape = (input_shape[0].as_list()[1], )

在你的代码中会是这样的:

import tensorflow as tf
from tensorflow.keras.layers import Layer
import numpy as np

class modrelu(Layer):
    def __init__(self, **kwargs):
        super(modrelu, self).__init__(**kwargs)

    def build(self, input_shape):
        if tf.executing_eagerly():
            shape = (input_shape[0][1])
        else:
            shape = (input_shape[0].as_list()[1], )
        self.b = self.add_weight(name='brad',
                                 shape=shape,
                                 initializer='uniform',
                                 trainable=True)
        super(modrelu, self).build(input_shape)  # Be sure to call this at the end

    def call(self, x):
        assert isinstance(x, list)
        ip_r, ip_i = x
        comp = tf.complex(ip_r, ip_i) 
        ABS = tf.math.abs(comp)
        ANG = tf.math.angle(comp)
        ABS = tf.nn.relu( self.b + ABS) 
        op_i =  ABS * tf.sin(ANG) #K.dot ??
        op_r = ABS * tf.cos(ANG)
        return [op_r, op_i]

    def compute_output_shape(self, input_shape):
        assert isinstance(input_shape, list)
        shape_a, shape_b = input_shape
        return [shape_a, shape_b]

act = modrelu()
a = tf.constant(np.array([[1,2], [4,4]]), dtype='float32')
b = tf.constant(np.array([[3,4], [5, -1]]), dtype='float32')
act([a,b])
# [<tf.Tensor 'modrelu_6/mul_1:0' shape=(2, 2) dtype=float32>,
#  <tf.Tensor 'modrelu_6/mul:0' shape=(2, 2) dtype=float32>]

【讨论】:

好吧,那是天才。但是,为什么 keras.io 网站没有显示呢?我从字面上复制了他的例子!这里,这里的第二个例子:keras.io/layers/writing-your-own-keras-layers 您的示例有点不同,因为您要覆盖 compute_output_shape() 方法。 default implementation 在计算 compute_output_shape() 中的形状时同时处理急切模式和图形模式的情况。 啊啊,你的意思是我修改了那个方法....是的,我做了。我明白了。我真的不知道该怎么感谢你。你真是个天才。

以上是关于TF/keras 子类在 Eager Execution 中完美运行,没有它会引发大量无法追踪的错误?的主要内容,如果未能解决你的问题,请参考以下文章

使用 Tensorflow.keras 组织项目。应该是 tf.keras.Model 的一个子类吗?

AttributeError: Tensor.op 在启用 Eager Execution 时毫无意义

tf.keras 和 tf.python.keras 有啥区别?

如何在 Tensorflow 中从 tf.keras 导入 keras?

不能将tf.keras.optimizer与tf.keras.models.sequential一起使用

使用 [:, :, 0] 的 TF2 / Keras 切片张量