Keras Connected Convolutional Layers: формат данных, необходимый на каждом слое Conv

Используя подключенные последовательные слои Conv2D в Keras, нужно ли мне устанавливать 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)

Заранее спасибо за помощь.


person benbotto    schedule 16.05.2018    source источник


Ответы (1)


Он нужен вам в каждом слое, или вы можете установить его в конфигурационном файле keras:

  • Линукс: ~/.keras/keras.json
  • Окна: C:\users\<yourusername>\.keras\keras.json

Но, честно говоря, вам лучше поменять местами оси ваших данных, так как другие функции keras, как правило, всегда работают на последней оси. Таким образом, наличие каналов на последней оси может сэкономить вам много дополнительной работы.

Чтобы изменить свои данные:

np.moveaxis(data,1,-1)
person Daniel Möller    schedule 16.05.2018
comment
Спасибо. Я думал о повороте оси (на самом деле в соответствии с одним из ваших ответов на чужой вопрос!), но в случае с кодом, над которым я сейчас работаю, это добавляет сложности в другом месте. В любом случае, еще раз спасибо за помощь. - person benbotto; 16.05.2018
comment
@Danial Möller, мне трудно отображать изображение после того, как его ось поменялась местами, так как размер одного изображения станет (84,4). Нужно ли мне вернуться к исходному формату для отображения изображения? - person iamkk; 18.02.2021
comment
@iamkk, насколько мне известно, наиболее распространенные библиотеки, отображающие изображения, используют каналы в последнюю очередь. Они принимают (x, y, 4) в качестве входной формы, как и стандарт Keras. - person Daniel Möller; 18.02.2021