【问题标题】:Get randomly weighted averages between samples in a batch, with arbitrary sample shape获得批次中样本之间的随机加权平均值,具有任意样本形状
【发布时间】:2020-03-21 05:17:06
【问题描述】:

基本上,我想要一个this custom Keras layer 的实现:

class RandomWeightedAverage(_Merge):
    """Provides a (random) weighted average between real and generated image samples"""
    def _merge_function(self, inputs):
        alpha = K.random_uniform((32, 1, 1, 1))
        return (alpha * inputs[0]) + ((1 - alpha) * inputs[1])

但具有任意批量大小且不依赖于数据的形状。该层的目的是通过取每对样本的平均值来合并两个批次,但随机加权每个平均值。该实施的问题是:

  1. 它的硬编码批量大小为 32。在我的模型中,批量大小当前在我创建层时没有定义。我可以更改它,以便更早地定义批量大小,但我真的不希望这样做。
  2. If 假设批次中的每个样本都是 rank-3 张量,因为它最初是用于图像的。我将在模型中使用两种类型的数据,其中一种是形状为 (28, 28, 1) 的图像,另一种是形状为 (100,) 的向量。我宁愿不做两个RandomWeightedAverage 层实现。

我怎样才能制作一个random_uniform 形状为[batch_size] + [1] * rank_of_samples 的张量?或者,更抽象地说,是否有另一种方法可以通过对每对样本进行随机加权平均来实现合并两个批次的相同目标?

我尝试过的事情:

  1. alpha = K.random_uniform(K.shape(inputs[0])[0])
    
    任何那种都行不通,因为两个张量必须是相同的秩才能相乘,即使它们的形状不完全相同。例如,(32,)(32, 28, 28, 1) 形状的张量不能相乘,但 (32, 1, 1, 1)(32, 28, 28, 1) 可以。
  2. in_shape = K.shape(inputs[0])
    shape = K.concatenate([in_shape[0], K.ones_like(in_shape[1:], dtype='int32')], axis=0)
    alpha = K.random_uniform(shape)
    
    不起作用,给出稍微令人困惑的错误:
    ValueError: Can't concatenate scalars (use tf.stack instead) for 'random_weighted_average_1/concat' (op: 'ConcatV2') with input shapes: [], [3], [].
    
  3. in_shape = K.shape(inputs[0])
    shape = K.ones_like(in_shape, dtype='int32')
    shape[0] = in_shape[0]
    alpha = K.random_uniform(shape)
    
    不起作用,给出错误:
    TypeError: 'Tensor' object does not support item assignment
    

Keras 2.3.0、TF 1.14.0

【问题讨论】:

    标签: tensorflow keras tensor


    【解决方案1】:

    事实证明,我与尝试 #2 很接近。在问题的代码中,in_shape[0] 是一个标量,我试图将它与K.ones_like(in_shape[1:], dtype='int32') 连接起来,这是一个向量。只需将in_shape[0] 更改为in_shape[0:1] 就足以修复错误并成功编译我的模型。

    最终代码:

    class RandomWeightedAverage(layers.merge._Merge):
        """Provides a (random) weighted average between real and generated image samples"""
        def _merge_function(self, inputs):
            in_shape = K.shape(inputs[0])
            shape = K.concatenate([in_shape[0:1], K.ones_like(in_shape[1:], dtype='int32')], axis=0)
            alpha = K.random_uniform(shape)
            return (alpha * inputs[0]) + ((1 - alpha) * inputs[1])
    

    我不确定这是不是最好的方法,但至少它似乎有效。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-10
      • 2012-10-14
      • 2022-12-17
      • 2019-04-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-02
      相关资源
      最近更新 更多