【问题标题】:Reproduce normalization by tensorflow to keras通过 tensorflow 将归一化重现到 keras
【发布时间】:2020-09-27 06:25:24
【问题描述】:

实际上我正在尝试在 keras 上重现 tensorflow 模型,我对这个主题真的很陌生。 我想重现这些行

embedding = tf.layers.conv2d(conv6, 128, (16, 16), padding='VALID', name='embedding')
embedding = tf.reshape(embedding, (-1, 128))
embedding = embedding - tf.reduce_min(embedding, keepdims =True)
z_n = embedding/tf.reduce_max(embedding, keepdims =True)

我的实际代码是:

def conv_conv_pool(n_filters,
                   name,
                   pool=True,
                   activation=tf.nn.relu, padding='same', filters=(3,3)):
    """{Conv -> BN -> RELU}x2 -> {Pool, optional}
    Args:
        input_ (4-D Tensor): (batch_size, H, W, C)
        n_filters (list): number of filters [int, int]
        training (1-D Tensor): Boolean Tensor
        name (str): name postfix
        pool (bool): If True, MaxPool2D
        activation: Activaion functions
    Returns:
        net: output of the Convolution operations
        pool (optional): output of the max pooling operations
    """
    net = Sequential()
    for i, F in enumerate(n_filters):
        conv = Conv2D(
            filters = F,
            kernel_size = (3,3),
            padding = 'same',
            )
        net.add(conv)
        batch_norm = BatchNormalization()
        net.add(batch_norm)
        net.add(Activation('relu'))

    if pool is False:
        return net

    pool = Conv2D(
        filters = F,
        kernel_size = (3,3),
        strides = (2,2),
        padding = 'same',  
        )
    net.add(pool)
    batch_norm = BatchNormalization()
    net.add(batch_norm)
    net.add(Activation('relu'))
    return net


def model_keras():
    model = Sequential()
    model.add(conv_conv_pool(n_filters = [8, 8], name="1"))
    model.add(conv_conv_pool([32, 32], name="2"))
    model.add(conv_conv_pool([32, 32], name="3"))
    model.add(conv_conv_pool([64, 64], name="4"))
    model.add(conv_conv_pool([64, 64], name="5"))
    model.add(conv_conv_pool([128, 128], name="6", pool=False))
    return model

标准化应该在第 6 层之后。

我正在考虑使用 lambda 层,这是否正确?是的话应该怎么写?

【问题讨论】:

  • 为了更好地解释我的情况。实际上我正在 Keras 上写一个序列(这里是代码)` def model_keras(): model = Sequential() model.add(conv_conv_pool(n_filters = [8, 8], name="1")) model.add( conv_conv_pool([32, 32], name="2")) model.add(conv_conv_pool([32, 32], name="3")) model.add(conv_conv_pool([64, 64], name="4 ")) model.add(conv_conv_pool([64, 64], name="5")) model.add(conv_conv_pool([128, 128], name="6", pool=False)) `我想要在名为“6”的层上进行操作,但我不太清楚该怎么做
  • 请在编辑问题上方插入您的代码。如果可能的话,还报告什么是 conv_conv_pool
  • 好的,谢谢,现在很清楚了……您引用的规范化接收来自卷积层(4d 形状)的输入,然后尝试返回 2d 形状。这是正确的吗?是你要找的吗?还是在输出中保持 al 4d 更好?
  • @MarcoCerliani 是的,我想通过 4d 到 2d 进行重塑
  • @MarcoCerliani 非常感谢你,我要试试并告诉你

标签: python tensorflow keras normalization


【解决方案1】:

我使用您在 Lambda 层中引入的规范化。我还进行了更正(最小值和最大值是在同一个输入上计算的,而不是一个在输入上,另一个在转换上),但您也可以更改它。 norm_original 标准化 4D 输入,在所有通道上计算最小值和最大值,并尝试返回具有固定数量特征的 2D 输出,这将产生错误,因为您正在修改批量维度

def norm_original(inp):

    embedding = tf.reshape(inp, (-1, inp.shape[-1]))
    embedding = embedding - tf.reduce_min(inp)
    embedding = embedding / tf.reduce_max(inp)

    return embedding

inp = Input((28,28,3))
x = Conv2D(128, 3, padding='same')(inp)
x = Lambda(norm_original)(x)

m = Model(inp, x)
m.compile('adam', 'mse')
m.summary()

X = np.random.uniform(0,1, (10,28,28,3))
y = np.random.uniform(0,1, (10,128))

m.fit(X,y, epochs=3) # error

为了避免这个错误,我提出了两种可能性。我还进行了更改以按通道操作规范化(我保留它更合适),但您也可以修改它。

1) 您可以使用 min/max 对 4D 输入进行归一化,然后将输出展平,将所有内容放在最后一个维度上。此解决方案不会交替批次暗淡

def norm(inp):
    ## this function operate normalization by channels
    embedding = inp - tf.reduce_min(inp, keepdims=True, axis=[0,1,2])
    embedding = embedding / tf.reduce_max(inp, keepdims=True, axis=[0,1,2])

    return embedding

inp = Input((28,28,3))
x = Conv2D(128, 3, padding='same')(inp)
x = Lambda(norm)(x)
x = Flatten()(x)
x = Dense(128, activation='relu')(x)

m = Model(inp, x)
m.compile('adam', 'mse')

X = np.random.uniform(0,1, (10,28,28,3))
y = np.random.uniform(0,1, (10,128))

m.fit(X,y, epochs=3)

2) 您可以使用 GlobalPooling 层来减少 4D 维度并重新生成 2D 形状,同时保留特征维度

inp = Input((28,28,3))
x = Conv2D(128, 3, padding='same')(inp)
x = Lambda(norm)(x)
x = GlobalMaxPool2D()(x) # u can also use GlobalAveragePooling2D

m = Model(inp, x)
m.compile('adam', 'mse')

X = np.random.uniform(0,1, (10,28,28,3))
y = np.random.uniform(0,1, (10,128))

m.fit(X,y, epochs=3)

【讨论】:

    【解决方案2】:

    如果你想使用 keras layer api,你可以创建一个自定义层,你可以在这里找到文档如何做 https://www.tensorflow.org/guide/keras/custom_layers_and_models, 你应该以这样的方式结束:

    class NormalizationLayer(layers.Layer):
    
      def __init__(self, filters=128):
        super(NormalizationLayer, self).__init__()
        self.filters = filters
    
      def call(self, inputs):
        embedding = tf.keras.layers.conv2d(inputs, self.filters, (16, 16), padding='VALID', 
                name='embedding')
        embedding = tf.keras.layers.reshape(embedding, (-1, self.filters))
        embedding = embedding - tf.math.reduce_min(embedding, keepdims =True)
        z_n = embedding/tf.math.reduce_max(embedding, keepdims =True)
        return zn
    

    【讨论】:

      【解决方案3】:

      我相信您想切换到使用 keras 作为 API 的 tensorflow 2。你需要安装/升级到 tensorflow 2,然后你可以试试这个:

      import tensorflow as tf
      
      embedding = tf.keras.layers.conv2d(conv6, 128, (16, 16), padding='VALID', 
                  name='embedding')
      embedding = tf.keras.layers.reshape(embedding, (-1, 128))
      embedding = embedding - tf.math.reduce_min(embedding, keepdims =True)
      z_n = embedding/tf.math.reduce_max(embedding, keepdims =True)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-12-23
        • 1970-01-01
        • 2017-01-09
        • 2021-11-03
        • 2021-05-24
        • 1970-01-01
        • 2021-07-26
        相关资源
        最近更新 更多