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: Как создать функцию потерь, описанную выше?
Ваша функция потерь выглядит правильно.