【问题标题】:Keras Connected Convolutional Layers: Data Format Needed on Every Conv LayerKeras 连接卷积层:每个卷积层所需的数据格式
【发布时间】:2018-05-17 16:58:03
【问题描述】:

在 Keras 中使用连接的、连续的 Conv2D 层,我需要在每一层上设置 data_format,还是只设置第一层?我的数据采用 NCHW(渠道优先)格式。

为了提供一些上下文,我有一个 Keras 网络,它由多个连续连接的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)

提前感谢您的帮助。

【问题讨论】:

    标签: keras convolutional-neural-network


    【解决方案1】:

    你在每一层都需要它,或者你可以在你的 keras 配置文件中设置它:

    • Linux:~/.keras/keras.json
    • 窗口:C:\users\&lt;yourusername&gt;\.keras\keras.json

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

    要更改您的数据:

    np.moveaxis(data,1,-1)
    

    【讨论】:

    • 谢谢。我考虑过滚动轴(实际上是根据您对别人问题的回答!),但就我目前正在处理的代码而言,这样做会增加其他地方的复杂性。无论如何,再次感谢您的帮助。
    • @Danial Möller,一旦图像的轴被交换,我很难显示图像,因为单个图像的尺寸将变为(84,4)。我是否需要切换回原始格式才能显示图像?
    • @iamkk,据我所知,显示图像的最常见库最后使用通道。它们将 (x, y, 4) 作为输入形状,就像 Keras 标准一样。
    猜你喜欢
    • 2018-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-13
    • 2021-11-09
    • 1970-01-01
    相关资源
    最近更新 更多