【问题标题】:Changing the scale of a tensor in tensorflow在张量流中改变张量的尺度
【发布时间】:2016-11-17 12:07:26
【问题描述】:

对不起,如果我搞砸了标题,我不知道如何表达这个。无论如何,我有一组值的张量,但我想确保张量中的每个元素的范围都在 0 到 255 之间,(或者 0 到 1 也可以)。但是,我不想像 softmax 那样让所有值加起来为 1 或 255,我只想缩小这些值。

有什么办法吗?

谢谢!

【问题讨论】:

    标签: python tensorflow conv-neural-network


    【解决方案1】:

    sigmoid(tensor) * 255 应该这样做。

    【讨论】:

      【解决方案2】:

      您正在尝试规范化数据。一个经典的归一化公式是这样的:

      normalize_value = (value − min_value) / (max_value − min_value)
      

      tensorflow 上的实现如下所示:

      tensor = tf.div(
         tf.subtract(
            tensor, 
            tf.reduce_min(tensor)
         ), 
         tf.subtract(
            tf.reduce_max(tensor), 
            tf.reduce_min(tensor)
         )
      )
      

      张量的所有值都在 0 和 1 之间。

      重要提示:确保张量具有浮点/双精度值,否则输出张量将只有零和一。如果您有一个整数张量,请先调用它:

      tensor = tf.to_float(tensor)
      

      更新:从 tensorflow 2 开始,tf.to_float() 已弃用,而应使用 tf.cast()

      tensor = tf.cast(tensor, dtype=tf.float32) # or any other tf.dtype, that is precise enough
      

      【讨论】:

      • 还要确保取小值中的最大值(即 epsilon=1e-12)和分母以避免 div 被零。 (val - min_val) / max((max_val - min_val), epsilon)
      • 当 val==max==min (val - min_val + epsilon) / max((max_val - min_val), 2*epsilon) 时,分子加上 epsilon,分母加上 2*epsilon 得到 0.5
      【解决方案3】:

      根据维基百科中的feature scaling,您还可以尝试缩放到单位长度:

      可以使用这段代码来实现:

      In [3]: a = tf.constant([2.0, 4.0, 6.0, 1.0, 0])                                                                                                                                                                     
      In [4]: b = a / tf.norm(a)
      In [5]: b.eval()
      Out[5]: array([ 0.26490647,  0.52981293,  0.79471946,  0.13245323,  0.        ], dtype=float32)
      

      【讨论】:

      • 只是补充一点,这个规范的实现被称为 L2 规范。它计算为向量平方值之和的平方根。
      【解决方案4】:

      在某些情况下,您需要分别对每个图像进行归一化 - 例如,每个图像都有噪声的对抗性数据集。假设输入具有典型大小 Batch x YDim x XDim x Channels,以下根据每个图像自己的最小值和最大值对每个图像进行归一化:

          cast_input = tf.cast(inputs,dtype=tf.float32)     # e.g. MNIST is integer
          input_min = tf.reduce_min(cast_input,axis=[1,2])  # result B x C
          input_max = tf.reduce_max(cast_input,axis=[1,2])
          ex_min = tf.expand_dims(input_min,axis=1)         #  put back inner dimensions
          ex_max = tf.expand_dims(input_max,axis=1)
          ex_min = tf.expand_dims(ex_min,axis=1)            # one at a time - better way?
          ex_max = tf.expand_dims(ex_max,axis=1)            # Now Bx1x1xC
          input_range = tf.subtract(ex_max, ex_min)
          floored = tf.subtract(cast_input,ex_min)          # broadcast
          scale_input = tf.divide(floored,input_range)
      

      我想像在 Numpy 中一样将维度扩展为一个短的维度,但 tf.expand_dims 似乎一次只接受一个维度 - 在这里接受建议。谢谢!

      【讨论】:

        【解决方案5】:

        让输入为

        X = tf.constant([[0.65,0.61, 0.59, 0.62, 0.6 ],[0.25,0.31, 0.89, 0.52, 0.6 ]])
        

        我们可以定义一个缩放函数

        def rescale(X, a=0, b=1):
          repeat = X.shape[1]
          xmin = tf.repeat(tf.reshape(tf.math.reduce_min(X, axis=1), shape=[-1,1]), repeats=repeat, axis=1)
          xmax = tf.repeat(tf.reshape(tf.math.reduce_max(X, axis=1), shape=[-1,1]), repeats=repeat, axis=1)
          X = (X - xmin) / (xmax-xmin)
          return X * (b - a) + a
        

        这会在 [0,1] 范围内输出 X

        >>rescale(X)
        
        <tf.Tensor: shape=(2, 5), dtype=float32, numpy=
        array([[1.        , 0.333334  , 0.        , 0.5000005 , 0.16666749],
               [0.        , 0.09375001, 1.        , 0.42187497, 0.54687506]],
              dtype=float32)>
        

        在 [0, 255] 范围内缩放

        >> rescale(X, 0, 255) 
        <tf.Tensor: shape=(2, 5), dtype=float32, numpy=
        array([[255.      ,  85.00017 ,   0.      , 127.50012 ,  42.50021 ],
               [  0.      ,  23.906252, 255.      , 107.57812 , 139.45314 ]],
              dtype=float32)>
        
        

        【讨论】:

          【解决方案6】:

          如果您希望最大值是 0-1 范围的有效上限并且有一个有意义的零,那么使用这个:

          import tensorflow as tf
          tensor = tf.constant([0, 1, 5, 10])
          tensor = tf.divide(tensor, tf.reduce_max(tensor))
          tf.print(tensor)
          

          会导致:

          [0 0.1 0.5 1]
          

          【讨论】:

            猜你喜欢
            • 2021-12-08
            • 1970-01-01
            • 1970-01-01
            • 2021-07-03
            • 1970-01-01
            • 2018-04-18
            • 1970-01-01
            • 1970-01-01
            • 2016-08-20
            相关资源
            最近更新 更多