1D сверточная сеть, дающая постоянный выход - PullRequest
0 голосов
/ 22 мая 2019

Я хочу использовать 1D сверточную нейронную сеть для регрессии.

У меня около 1500 тренировочных образцов, каждый из которых имеет 40 функций.Я тренируюсь партиями по 200-300 образцов.

Я не уверен, правильно ли настроен код.Каждая входная выборка, по сути, является одномерным вектором с 40 элементами, поэтому в первом слое свертки я хочу, чтобы каждый фильтр проходил по длине каждого вектора (независимо) в обучающей партии.Правильно ли я настроил ширину, высоту, каналы и т. Д., Чтобы добиться этого?

Мой код:

width = 40
channels = 1
n_outputs = 1

X = tf.placeholder(tf.float32, shape=[None, width], name="X")
X_reshaped = tf.reshape(X, shape=[-1, width, channels])
y = tf.placeholder(tf.float32, shape=[None, channels], name="y")
y_reshaped = tf.reshape(y, shape=[-1, channels])
training = tf.placeholder_with_default(False, shape=(), name='training')

with tf.name_scope("cnn"):
    conv1 = tf.layers.conv1d(X_reshaped, filters=24, kernel_size=4,
                             strides=2, padding='same', activation=tf.nn.relu, name="conv1")

    pool1 = tf.layers.average_pooling1d(conv1, pool_size=2, strides=2, padding='same')

    conv2 = tf.layers.conv1d(pool1, filters=32, kernel_size=2,
                             strides=2, padding='same', activation=tf.nn.relu, name="conv2")

    pool2 = tf.layers.average_pooling1d(conv2, pool_size=2, strides=2, padding='same')

    flat = tf.layers.flatten(pool2, name='flatten')

    drop = tf.layers.dropout(flat, rate=0.3, training=training)

    output = tf.layers.dense(drop, n_outputs, activation=tf.nn.tanh, name="fully_connected")

with tf.name_scope("loss"):
    loss = tf.reduce_mean(tf.square(y_reshaped - output))

initial_learning_rate = 0.01
decay_steps = 1000
decay_rate = 0.1 

with tf.name_scope("train"):
   global_step = tf.Variable(0, trainable=False, name="global_step")
    learning_rate = tf.train.exponential_decay(initial_learning_rate, global_step, decay_steps, decay_rate)
    optimizer = tf.train.RMSPropOptimizer(learning_rate, momentum=0.9)
    training_op = optimizer.minimize(loss, global_step=global_step)

Я масштабирую 40 входных функций до диапазона [0.0, 1.0].Другими словами, мой тензор 'X' содержит образцы вдоль строк, причем столбцы являются различными элементами.Я масштабирую каждый столбец до диапазона [0.0, 1.0].

Поскольку я использую выходной слой с одним нейроном с активацией tanh (который имеет выход в диапазоне [-1.0: 1.0]:

  • во время обучения я масштабирую предиктор (y) до диапазона [-1: 0, 1.0]
  • при использовании обученной сети для генерации прогнозов, я должен изменить масштабирование, чтобы получить «реальное»«значения (поскольку прогнозируемые значения имеют диапазон [-1,0, 1,0])

Является ли этот подход правильным?

Выход из сети практически идентичен для всех тестовых образцов.это указывает на проблему с весами? Я пытался установить "kernel_initializer = 'he_normal'" в слоях свертки, но это не помогло.

При использовании многослойного персептрона на этом же наборе данных мне нужно былоиспользуйте пакетную нормализацию, в противном случае обучение завершится неудачно. Есть ли что-то похожее для сверточных сетей?

1 Ответ

0 голосов
/ 23 мая 2019

Использование функции активации в конце выходного слоя в задаче регрессии не является обычной практикой.Активации используются в задачах классификации, и даже в этом случае сигмоид (для бинарной классификации) или softmax (для мультиклассовой классификации) обычно предпочтительнее.

Я вижу, что вы используете потерю MSE, которая является правильным выбором для регрессиино ваше масштабирование ввода и вывода не соответствует предположению нейронных сетей (вход и выход поступают из нормального распределения: среднее: 0, стандартное: 1), поэтому люди обычно выполняют z-нормализацию (вычитают среднее и делят на стандартное) на входах и выходах перед тренировкой.

...