Tensorflow: как установить скорость обучения в логарифмическом масштабе и некоторые вопросы Tensorflow

Я начинающий Tensorflow, и я пытаюсь реализовать алгоритм в этой статье, используя Tensorflow. Эта статья использует Matconvnet+Matlab для его реализации, и мне любопытно, имеет ли Tensorflow эквивалентные функции для достижения того же самого. В документе сказано:

Параметры сети были инициализированы с использованием метода Ксавье [14]. Мы использовали регрессионные потери в четырех вейвлет-поддиапазонах под штрафом l2, и предложенная сеть была обучена с использованием стохастического градиентного спуска (SGD). Параметр регуляризации (λ) составлял 0,0001, а импульс составлял 0,9. Скорость обучения была установлена ​​от 10-1 до 10-4, которая была уменьшена в логарифмическом масштабе в каждую эпоху.

В этой статье используются вейвлет-преобразование (WT) и метод остаточного обучения (где остаточное изображение = WT(HR) - WT(HR'), а HR' используется для обучения). Метод Ксавье предлагает инициализировать нормальное распределение переменных с

stddev=sqrt(2/(filter_size*filter_size*num_filters)

Q1. Как я должен инициализировать переменные? Правильный ли приведенный ниже код?

weights = tf.Variable(tf.random_normal[img_size, img_size, 1, num_filters], stddev=stddev)

Эта статья не объясняет, как построить функцию потерь в деталях. Я не могу найти эквивалентную функцию Tensorflow для установки скорости обучения в логарифмическом масштабе (только exponential_decay). я понимаю MomentumOptimizer эквивалентно стохастическому градиентному спуску с импульсом.

Q2: можно ли установить скорость обучения в логарифмическом масштабе?

Q3: Как создать функцию потерь, описанную выше?

Я следил за этим сайтом, чтобы написать код ниже. Предположим, что функция model() возвращает сеть, упомянутую в этой статье, и lamda=0.0001,

inputs = tf.placeholder(tf.float32, shape=[None, patch_size, patch_size, num_channels])
labels = tf.placeholder(tf.float32, [None, patch_size, patch_size, num_channels])

# get the model output and weights for each conv
pred, weights = model()

# define loss function
loss = tf.nn.softmax_cross_entropy_with_logits_v2(labels=labels, logits=pred)

for weight in weights:
    regularizers += tf.nn.l2_loss(weight)

loss = tf.reduce_mean(loss + 0.0001 * regularizers)

learning_rate = tf.train.exponential_decay(???) # Not sure if we can have custom learning rate for log scale
optimizer = tf.train.MomentumOptimizer(learning_rate, momentum).minimize(loss, global_step)

ПРИМЕЧАНИЕ: Поскольку я начинающий, изучающий Tensorflow, я копирую и вставляю код здесь и там, поэтому, пожалуйста, исправляйте его, если можете;)

3 ответа

Решение

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

import tensorflow as tf

import numpy as np


# data simulation
N = 10000
D = 10
x = np.random.rand(N, D)
w = np.random.rand(D,1)
y = np.dot(x, w)

print y.shape

#modeling
batch_size = 100
tni = tf.truncated_normal_initializer()
X = tf.placeholder(tf.float32, [batch_size, D])
Y = tf.placeholder(tf.float32, [batch_size,1])
W = tf.get_variable("w", shape=[D,1], initializer=tni)
B = tf.zeros([1])

lr = tf.placeholder(tf.float32)

pred = tf.add(tf.matmul(X,W), B)
print pred.shape
mse = tf.reduce_sum(tf.losses.mean_squared_error(Y, pred))
opt = tf.train.MomentumOptimizer(lr, 0.9)

train_op = opt.minimize(mse)

learning_rate = 0.0001

do_train = True
acc_err = 0.0
sess = tf.Session()
sess.run(tf.global_variables_initializer())
while do_train:
  for i in range (100000):
     if i > 0 and i % N == 0:
       # epoch done, decrease learning rate by 2
       learning_rate /= 2
       print "Epoch completed. LR =", learning_rate

     idx = i/batch_size + i%batch_size
     f = {X:x[idx:idx+batch_size,:], Y:y[idx:idx+batch_size,:], lr: learning_rate}
     _, err = sess.run([train_op, mse], feed_dict = f)
     acc_err += err
     if i%5000 == 0:
       print "Average error = {}".format(acc_err/5000)
       acc_err = 0.0

Q1. Как я должен инициализировать переменные? Правильный ли приведенный ниже код?

Используйте tf.get_variable или переключитесь на slim (он выполняет инициализацию автоматически за вас). пример

Q2: можно ли установить скорость обучения в логарифмическом масштабе?

Вы можете, но вам это нужно? Это не первое, что вам нужно решить в этой сети. Пожалуйста, проверьте № 3

Однако для справки используйте следующие обозначения.

learning_rate_node = tf.train.exponential_decay (learning_rate = 0,001, decay_steps=10000, decay_rate=0,98, лестница = True)

optimizer = tf.train.AdamOptimizer (learning_rate = learning_rate_node).minimize (потеря)

Q3: Как создать функцию потерь, описанную выше?

Во-первых, вы не записали преобразование "pred" в "image" в это сообщение (на основе бумаги вам нужно применить вычитание и IDWT для получения окончательного изображения).

Здесь есть одна проблема, логиты должны быть рассчитаны на основе данных вашей этикетки. т.е. если вы будете использовать помеченные данные как "Y: Label", вам нужно написать

пред = модель ()

pred = tf.matmul (пред, веса) + смещения

logits = tf.nn.softmax(пред)

loss = tf.reduce_mean (tf.abs (логиты - метки))

Это даст вам вывод Y: Метка для использования

Если помеченные изображения в вашем наборе данных не содержат шума, в этом случае вам необходимо выполнить следующее:

пред = модель ()

pred = tf.matmul (изображение, вес) + смещения

logits = tf.nn.softmax(пред)

image = apply_IDWT ("X: input", logits) # это будет применять IDWT (x_label - y_label)

loss = tf.reduce_mean (tf.abs (изображение - метки))

Логиты - это выход вашей сети. Вы будете использовать это как результат, чтобы вычислить остальное. Вместо matmul вы можете добавить сюда слой conv2d без нормализации партии и функции активации и установить количество выходных объектов равным 4. Пример:

пред = модель ()

pred = slim.conv2d (pred, 4, [3, 3], активации_fn= нет, заполнение = "ЖЕ", область действия = "вывод")

logits = tf.nn.softmax(пред)

image = apply_IDWT ("X: input", logits) # это будет применять IDWT (x_label - y_label)

loss = tf.reduce_mean (tf.abs (логиты - метки))

Эта функция потери даст вам базовые возможности обучения. Тем не менее, это расстояние L1, и оно может страдать от некоторых проблем ( проверьте). Подумайте о следующей ситуации

Допустим, у вас есть следующий массив в качестве вывода [10, 10, 10, 0, 0], и вы пытаетесь достичь [10, 10, 10, 10, 10]. В этом случае ваша потеря составляет 20 (10 + 10). Тем не менее, у вас есть 3/5 успеха. Кроме того, это может указывать на некоторый наряд.

Для этого же случая рассмотрим следующий вывод [6, 6, 6, 6, 6]. У него все еще есть потеря 20 (4 + 4 + 4 + 4 + 4). Однако всякий раз, когда вы применяете порог 5, вы можете добиться успеха 5/5. Следовательно, это тот случай, который мы хотим.

Если вы используете потерю L2, для первого случая вы получите 10^2 + 10^2 = 200 в качестве вывода потерь. Во втором случае вы получите 4^2 * 5 = 80. Следовательно, оптимизатор попытается убежать от #1 как можно быстрее для достижения глобального успеха, а не полного успеха одних выходов и полного отказа других. Вы можете применить функцию потерь, как это для этого.

tf.reduce_mean (tf.nn.l2_loss (logits - изображение))

Кроме того, вы можете проверить функцию перекрестной потери энтропии. (это применяет softmax внутри, не применяйте softmax дважды)

tf.reduce_mean (tf.nn.softmax_cross_entropy_with_logits (пред., изображение))

Q1. Как я должен инициализировать переменные? Правильный ли приведенный ниже код?

Это правильно (хотя и отсутствует открывающая скобка). Вы также можете посмотреть в tf.get_variable если переменные будут использоваться повторно.

Q2: можно ли установить скорость обучения в логарифмическом масштабе?

Экспоненциальный спад снижает скорость обучения на каждом этапе. Я думаю, что вы хотите tf.train.piecewise_constantи установить границы в каждую эпоху.

РЕДАКТИРОВАТЬ: Посмотрите на другой ответ, используйтеstaircase=Trueаргумент!

Q3: Как создать функцию потерь, описанную выше?

Ваша функция потерь выглядит правильно.

Другие вопросы по тегам