如何使用maclaurin系列扩展2dim阵列?

2024-04-19 16:43:38 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图将像素向量输入到卷积神经网络(CNN),其中像素向量来自图像数据,如cifar-10数据集。在将像素向量输入CNN之前,我需要用maclaurin系列扩展像素向量。关键是,我知道了如何用一维展开张量,但无法用一维展开张量>;2.有谁能告诉我如何将一维张量的麦克劳林级数应用于一维以上的张量?在TensorFlow或Keras中是否有任何启发式方法来实现这一点?有什么想法吗

CNN上的麦克劳林系列节目:

我找到了用麦克劳林级数展开一维张量的方法。下面是如何抓取实现的外观:

def cnn_taylor(input_dim, approx_order=2):
    x = Input((input_dim,))
    def pwr(x, approx_order):
        x = x[..., None] 
        x = tf.tile(x, multiples=[1, 1, approx_order + 1])
        pw = tf.range(0, approx_order + 1, dtype=tf.float32) 
        x_p = tf.pow(x, pw) 
        x_p = x_p[..., None]
        return x_p

    x_p = Lambda(lambda x: pwr(x, approx_order))(x)
    h = Dense(1, use_bias=False)(x_p)  
    def cumu_sum(h):
        h = tf.squeeze(h, axis=-1)  
        s = tf.cumsum(h, axis=-1) 
        s = s[..., None] 
        return s
    S = Lambda(cumu_sum)(h)

所以以上的实现是关于如何用一维张量用泰勒展开来展开CNN的一个草图编码尝试。我想知道如何用多维数组(即dim=3)对张量做同样的事情

如果我想用泰勒展开法以2的近似阶展开CNN,其中输入是来自RGB图像的像素向量,我如何在TensorFlow中轻松实现这一点?有什么想法吗?谢谢


Tags: 数据方法图像noneinputtftensorflowdef
1条回答
网友
1楼 · 发布于 2024-04-19 16:43:38

如果我理解正确,所提供的计算图中的每个x只是一个标量(像素的一个通道)。在这种情况下,为了将变换应用于每个像素,您可以:

  1. 将来自卷积层的4D(b, h, w, c)输入展平为(b, h*w*c)形状的张量
  2. 将变换应用于生成的张量
  3. 撤消重塑以获得形状为(b,h,w,c)`的4D张量,其“泰勒展开”已按元素应用

这可以通过以下方式实现:

shape_cnn = h.shape  # Shape=(bs, h, w, c)
flat_dim = h.shape[1] * h.shape[2] * h.shape[3]
h = tf.reshape(h, (-1, flat_dim))
taylor_model = taylor_expansion_network(input_dim=flat_dim, max_pow=approx_order)
h = taylor_model(h)
h = tf.reshape(h, (-1, shape_cnn[1], shape_cnn[2], shape_cnn[3]))

注意:我从this answer借用了函数taylor_expansion_network


更新:我仍然不清楚最终目标,但这次更新可能使我们更接近预期的输出。我修改了taylor_expansion_network,将管道的第一部分应用于形状(width, height, nb_channels=3)的RGB图像,返回形状(width, height, nb_channels=3, max_pow+1)的张量:

def taylor_expansion_network_2(width, height, nb_channels=3, max_pow=2):
    input_dim = width * height * nb_channels

    x = Input((width, height, nb_channels,))
    h = tf.reshape(x, (-1, input_dim))

    # Raise input x_i to power p_i for each i in [0, max_pow].
    def raise_power(x, max_pow):
        x_ = x[..., None]  # Shape=(batch_size, input_dim, 1)
        x_ = tf.tile(x_, multiples=[1, 1, max_pow + 1])  # Shape=(batch_size, input_dim, max_pow+1)
        pows = tf.range(0, max_pow + 1, dtype=tf.float32)  # Shape=(max_pow+1,)
        x_p = tf.pow(x_, pows)  # Shape=(batch_size, input_dim, max_pow+1)
        return x_p

    h = raise_power(h, max_pow)

    # Compute s_i for each i in [0, max_pow]
    h = tf.cumsum(h, axis=-1)  # Shape=(batch_size, input_dim, max_pow+1)

    # Get the input format back
    h = tf.reshape(h, (-1, width, height, nb_channels, max_pow+1))  # Shape=(batch_size, w, h, nb_channels, max_pow+1)

    # Return Taylor expansion model
    model = Model(inputs=x, outputs=h)
    model.summary()
    return model

在这个修改后的模型中,管道的最后一步,即每个iw_i * s_i之和不适用。现在,您可以以任何方式使用生成的(width, height, nb_channels=3, max_pow+1)形张量

相关问题 更多 >