猿问

如何自定义 Keras 图层名称并使其自动递增 layer.name

我目前正在尝试使用名称为自定义激活的多个图层cust_sig。但是当我尝试编译模型时,我得到一个 ValueError ,因为多个层具有相同的 name cust_sig。我知道我可以手动更改每个图层的名称,但想知道是否可以_1, _2, ...像对内置图层一样自动添加到名称中。可以在下面找到模型定义。


# Creating a model

from tensorflow.python.keras import keras

from tensorflow.python.keras.models import Model

from tensorflow.python.keras.layers import Dense


# Custom activation function

from tensorflow.python.keras.layers import Activation

from tensorflow.python.keras import backend as K

from keras.utils.generic_utils import get_custom_objects


def custom_activation(x):

    return (K.sigmoid(x) * 5) - 1


get_custom_objects().update({'custom_activation': Activation(custom_activation)})


data_format = 'channels_first'


spec_input = keras.layers.Input(shape=(1, 3, 256), name='spec')

x = keras.layers.Flatten(data_format)(spec_input)


for layer in range(3):

  x = Dense(512)(x)

  x = Activation('custom_activation', name='cust_sig')(x)


out = Dense(256, activation="sigmoid", name='out')(x)

model = Model(inputs=spec_input, outputs=out)

错误信息如下所示


Traceback (most recent call last):

  File "/home/xyz/anaconda3/envs/ctf/lib/python3.7/site-packages/tensorflow/python/training/tracking/base.py", line 457, in _method_wrapper

    result = method(self, *args, **kwargs)

  File "/home/xyz/anaconda3/envs/ctf/lib/python3.7/site-packages/tensorflow/python/keras/engine/network.py", line 315, in _init_graph_network

    self.inputs, self.outputs)

  File "/home/xyz/anaconda3/envs/ctf/lib/python3.7/site-packages/tensorflow/python/keras/engine/network.py", line 1861, in _map_graph_network

    str(all_names.count(name)) + ' times in the model. '

ValueError: The name "cust_sig" is used 3 times in the model. All layer names should be unique.



MMTTMM
浏览 262回答 3
3回答

哔哔one

下面应该做:def custom_activation(x):    return (K.sigmoid(x) * 5) - 1class CustSig(Layer):    def __init__(self, my_activation, **kwargs):        super(CustSig, self).__init__(**kwargs)        self.supports_masking = True        self.activation = my_activation    def call(self, inputs):        return self.activation(inputs)    def get_config(self):        config = {'activation': activations.serialize(self.activation)}        base_config = super(Activation, self).get_config()        return dict(list(base_config.items()) + list(config.items()))    def compute_output_shape(self, input_shape):        return input_shape说明:从源代码来看,自动命名的工作原理如下:if not name:  self._name = backend.unique_object_name(      generic_utils.to_snake_case(self.__class__.__name__),      zero_based=zero_based)else:  self._name = name检查 Keras 图是否存在与您定义的对象同名的对象 - 如果存在,则继续递增 1,直到没有匹配项。问题是,您不能指定name=,因为这消除了上述条件的自动命名。唯一的解决方法可能是使用所需的名称作为类名定义您自己的自定义激活层,如上所示,其表现如下:ipt = Input(shape=(1, 3, 256), name='spec')x   = Flatten('channels_last')(ipt)for _ in range(3):    x   = Dense(512)(x)    x   = CustSig(custom_activation)(x)out = Dense(256, activation='sigmoid', name='out')(x)model = Model(ipt, out)print(model.layers[3].name)print(model.layers[5].name)print(model.layers[7].name)cust_sigcust_sig_1cust_sig_2

ITMISS

如果您查看Layerclass的源代码,您可以找到决定层名称的这些行。if not name:    prefix = self.__class__.__name__    name = _to_snake_case(prefix) + '_' + str(K.get_uid(prefix))self.name = nameK.get_uid(prefix)将从图中获取唯一 ID,这就是您看到activation_1,的原因activation_2。如果你想对你的自定义激活函数有同样的效果,更好的方法是定义你自己的继承自Layer.class MyAct(Layer):    def __init__(self):        super().__init__()    def call(self, inputs):        return (K.sigmoid(inputs) * 5) - 1 spec_input = Input(shape=(10,10))x = Flatten()(spec_input)for layer in range(3):    x = Dense(512)(x)    x = MyAct()(x)model = Model(spec_input, x)model.summary()输出# Layer (type)                 Output Shape              Param #   # =================================================================# input_1 (InputLayer)         (None, 10, 10)            0         # _________________________________________________________________# flatten_1 (Flatten)          (None, 100)               0         # _________________________________________________________________# dense_1 (Dense)              (None, 512)               51712     # _________________________________________________________________# my_act_1 (MyAct)             (None, 512)               0         # _________________________________________________________________# dense_2 (Dense)              (None, 512)               262656    # _________________________________________________________________# my_act_2 (MyAct)             (None, 512)               0         # _________________________________________________________________# dense_3 (Dense)              (None, 512)               262656    # _________________________________________________________________# my_act_3 (MyAct)             (None, 512)               0         # =================================================================# Total params: 577,024# Trainable params: 577,024# Non-trainable params: 0

红颜莎娜

如果要specific_name多次使用数字后缀,请使用以下命令:tf.get_default_graph().unique_name("specific_name")或者tf.compat.v1.get_default_graph().unique_name("specific_name")在你的情况下:...for layer in range(3):  x = Dense(512)(x)  x = Activation('custom_activation', name=tf.get_default_graph().unique_name("cust_sig"))(x)...
随时随地看视频慕课网APP

相关分类

Python
我要回答