【问题标题】:Randomly select layer in tensorflow model在张量流模型中随机选择层
【发布时间】:2021-12-28 12:28:22
【问题描述】:

我想在我的网络中使用具有特定概率的不同层。层是以下类。

class plus1(keras.layers.Layer):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
    def call(self, X):
        return X + 1    
    def compute_output_shape(self, batch_input_shape):
        return batch_input_shape

class plus2(keras.layers.Layer):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
    def call(self, X):
        return X + 2
    def compute_output_shape(self, batch_input_shape):
        return batch_input_shape

class plus3(keras.layers.Layer):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
    def call(self, X):
        return X + 3
    def compute_output_shape(self, batch_input_shape):
        return batch_input_shape

网络如下图。

def f1():
    return plus1()
def f2():
    return plus2()
def f3():
    return plus3()

def simple_model(input_num):
    input_layer = Input(input_num)
    rand = tf.random.uniform((1,), minval=0, maxval=3, dtype=tf.int32)
    r = tf.switch_case(rand[0], branch_fns={0: f1, 1: f2, 2: f3})
    res = r(input_layer)
    model = Model(inputs=input_layer, outputs=res)
    return model

model = simple_model([1,])

每次我运行下面的代码时,我都会得到相同的输出,但我预计会有不同的输出。 有什么方法可以实现吗?

model.predict([1])
>>> array([[4.]], dtype=float32)

【问题讨论】:

  • 你的 Tensorflow 版本是什么?我用 Tensorflow 2.4.1 测试了你的代码,脚本按预期运行。
  • 使用simple_model 函数构建模型时会选择随机层。模型建立后,它的层不再改变,这就是为什么model.predict([1]) 总是返回相同的输出。如果您希望 model.predict([1]) 返回不同的输出,您需要每次都重新构建模型。即你需要运行model = simple_model([1, ]); model.predict([1]) 而不仅仅是model.predict([1])
  • 我不想每次都重建模型。那么你的意思是没有任何方法可以让模型在每批中选择不同的功能/层? @FlaviaGiammarino

标签: python tensorflow keras layer


【解决方案1】:

这与我面临的问题相同,但我没有找到解决方案。所以我实现了不同的网络,然后从它们的输出中随机选择。

【讨论】:

    【解决方案2】:

    我一直在处理同样的问题:我有一个层列表,我需要在每次迭代时从中随机选择。 tf.switch_case() 给了我你描述的同样的问题。

    无论出于何种原因,而且我没有足够的背景深度来告诉你为什么(我的 tf.switch_case 实现以一种不相关的方式存在错误完全有可能),这段代码对我有用:

    def random_layer(layers, image_tensor):
    """
    Selects and executes a random layer chosen from a list
    """
    to_use = tf.random.uniform(shape=[], maxval=len(layers), dtype=tf.int32)
    out = image_tensor
    
    for i, layer in enumerate(layers):
        # out is either image_tensor or the actual output, *but*
        # since we can't break this loop, when it matches it will become the actual output
        # and any further calls will return that value
        
        def _match():
            # tf.print("using {}".format(layer))
            return layer(out, training=True)
        out = tf.cond(to_use==i, _match, lambda: out)
        
    return out 
    

    (请注意,我使用本地函数只是为了验证随机性。)然后我传入:

    NOISE_LAYERS = [tf.keras.layers.GaussianNoise(stddev=.1),
                   tf.keras.layers.GaussianNoise(stddev=.2),
                   tf.keras.layers.GaussianNoise(stddev=.3),
                   tf.keras.layers.GaussianNoise(stddev=.4)]
    

    (这是数据集准备的一部分,我希望图像包含不同数量的噪声。)

    【讨论】:

    • 嗨,欢迎来到 SO!您能否根据他们的代码展示如何将您的解决方案应用于 OP 的情况?例如,将他们代码中的 tf.switch_case(...) 语句替换为可以工作的内容(或在必要时进行更多更改)。目前,很难将您的答案的想法转移到他们的情况
    猜你喜欢
    • 1970-01-01
    • 2018-07-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-12
    • 2021-09-08
    • 1970-01-01
    • 2020-03-20
    相关资源
    最近更新 更多