代码之家  ›  专栏  ›  技术社区  ›  benbotto

Keras连接的卷积层:每个Conv层上需要的数据格式

  •  0
  • benbotto  · 技术社区  · 6 年前

    使用已连接的连续 Conv2D Keras中的图层,是否需要设置 data_format 每一层,还是第一层?我的数据是NCHW(频道优先)格式。

    为了提供一些上下文,我有一个由多个连接的 Conv2D 层层叠叠。我的图像是:

    • 灰度;
    • 84x84像素;
    • 堆叠4个,以便每个样本都有速度指示(即,一个样本由4个序列图像组成,我对这些样本的批次进行训练)。

    换句话说,每个样品的形状 (4, 84, 84) .这是我的模型,它是一个Deep-q网络实现:

    import numpy as np
    import tensorflow as tf
    
    '''
     ' Huber loss: https://en.wikipedia.org/wiki/Huber_loss
    '''
    def huber_loss(y_true, y_pred):
      error = y_true - y_pred
      cond  = tf.keras.backend.abs(error) < 1.0
    
      squared_loss = 0.5 * tf.keras.backend.square(error)
      linear_loss  = tf.keras.backend.abs(error) - 0.5
    
      return tf.where(cond, squared_loss, linear_loss)
    
    '''
     ' Importance Sampling weighted huber loss.
    '''
    def huber_loss_mean_weighted(y_true, y_pred, is_weights):
      error = huber_loss(y_true, y_pred)
    
      return tf.keras.backend.mean(error * is_weights)
    
    
    # The observation input.
    in_obs = tf.keras.layers.Input(shape=(4, 84, 84))
    
    # The importance sampling weights are used with the custom loss function,
    # and correct for the non-uniform distribution of the samples.
    in_is_weights = tf.keras.layers.Input(shape=(1,))
    
    # Expectations when training (the output is qualities for actions).
    in_actual = tf.keras.layers.Input(shape=(4,))
    
    # Normalize the observation to the range of [0, 1].
    norm = tf.keras.layers.Lambda(lambda x: x / 255.0)(in_obs)
    
    # Convolutional layers per the Nature paper on DQN.
    conv1 = tf.keras.layers.Conv2D(filters=32, kernel_size=8, strides=4,
      activation="relu", data_format="channels_first")(norm)
    conv2 = tf.keras.layers.Conv2D(filters=64, kernel_size=4, strides=2,
      activation="relu", data_format="channels_first")(conv1)
    conv3 = tf.keras.layers.Conv2D(filters=64, kernel_size=3, strides=1,
      activation="relu", data_format="channels_first")(conv2)
    
    # Flatten, and move to the fully-connected part of the network.
    flatten = tf.keras.layers.Flatten()(conv3)
    dense1  = tf.keras.layers.Dense(512, activation="relu")(flatten)
    
    # Output prediction.
    out_pred = tf.keras.layers.Dense(4, activation="linear")(dense1)
    
    # Using Adam optimizer, RMSProp's successor.
    opt = tf.keras.optimizers.Adam(lr=5e-5, decay=0.0)
    
    # This network is used for training.
    train_network = tf.keras.models.Model(
      inputs=[in_obs, in_actual, in_is_weights],
      outputs=out_pred)
    
    # The custom loss, which is Huber Loss weighted by IS weights.
    train_network.add_loss(
      huber_loss_mean_weighted(out_pred, in_actual, in_is_weights))
    
    train_network.compile(optimizer=opt, loss=None)
    

    提前感谢您的帮助。

    1 回复  |  直到 6 年前
        1
  •  1
  •   Daniel Möller    6 年前

    您在每一层都需要它,也可以在keras配置文件中进行设置:

    • Linux: ~/.keras/keras.json
    • 窗户: C:\users\<yourusername>\.keras\keras.json

    但老实说,您应该更好地从数据中交换轴,因为其他keras函数往往总是在最后一个轴上工作。因此,在最后一个轴上设置通道可以节省大量额外工作。

    要更改数据,请执行以下操作:

    np.moveaxis(data,1,-1)