Tensorflow:如何设置对数尺度的学习率和一些 Tensorflow 问题

Tensorflow: How to set the learning rate in log scale and some Tensorflow questions

我是一名深度学习和 Tensorflow 初学者,我正在尝试使用 Tensorflow 实现此 paper 中的算法。本文使用Matconvnet+Matlab实现,好奇Tensorflow有没有等价的功能来实现同样的事情。论文说:

The network parameters were initialized using the Xavier method [14]. We used the regression loss across four wavelet subbands under l2 penalty and the proposed network was trained by using the stochastic gradient descent (SGD). The regularization parameter (λ) was 0.0001 and the momentum was 0.9. The learning rate was set from 10−1 to 10−4 which was reduced in log scale at each epoch.

本文采用小波变换(WT)和残差学习方法(其中残差图像=WT​​(HR) - WT(HR'),HR'用于训练)。 Xavier 方法建议用

初始化变量正态分布
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:如何创建上述损失函数?

我按照这个website写了下面的代码。假设model()函数returns本文提到的网络和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)

注意:因为我是一个深度 learning/Tensorflow 初学者,所以我在这里和那里复制粘贴代码,所以如果可以的话请随时更正 ;)

Q1。我应该如何初始化变量?下面的代码正确吗?

正确(虽然缺少左括号)。如果要重用变量,您还可以查看 tf.get_variable

Q2:是否可以设置对数尺度的学习率?

指数衰减会降低每一步的学习率。我想你想要的是 tf.train.piecewise_constant,并在每个 epoch 设置边界。

编辑:查看其他答案,使用 staircase=True 参数!

Q3:如何创建上述损失函数?

你的损失函数看起来是正确的。

Q1。我应该如何初始化变量?下面的代码正确吗?

使用 tf.get_variable 或切换到 slim(它会自动为您进行初始化)。 example

Q2:是否可以设置对数刻度的学习率?

可以,但你需要吗?这不是您需要在此网络中解决的第一件事。请检查#3

但是,仅供参考,请使用以下符号。

learning_rate_node = tf.train.exponential_decay(learning_rate=0.001, decay_steps=10000, decay_rate=0.98, staircase=True)

optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate_node).minimize(loss)

Q3:如何创建上述损失函数?

一开始,你还没有写"pred"到"image"的转换(根据论文需要做减法和IDWT得到最终图像)。

这里有一个问题,logits必须根据你的标签数据来计算。即,如果您将标记数据用作 "Y : Label",则需要编写

pred = model()

pred = tf.matmul(pred, weights) + biases

logits = tf.nn.softmax(pred)

loss = tf.reduce_mean(tf.abs(logits - labels))

这将为您提供 Y 的输出:要使用的标签

如果你的数据集的标记图像是去噪图像,在这种情况下你需要遵循这个:

pred = model()

pred = tf.matmul(image, weights) + biases

logits = tf.nn.softmax(pred)

image = apply_IDWT("X : input", logits) # this will apply IDWT(x_label - y_label)

loss = tf.reduce_mean(tf.abs(image - labels))

Logits 是网络的输出。您将使用这个结果来计算其余部分。您可以在此处添加一个 conv2d 层而不是 matmul,而无需批归一化和激活函数,并将输出特征数设置为 4。示例:

pred = model()

pred = slim.conv2d(pred, 4, [3, 3], activation_fn=None, padding='SAME', scope='output')

logits = tf.nn.softmax(pred)

image = apply_IDWT("X : input", logits) # this will apply IDWT(x_label - y_label)

loss = tf.reduce_mean(tf.abs(logits - labels))

这个损失函数会给你基本的训练能力。但是,这是 L1 距离,可能会遇到一些问题 (check)。思考以下情况

假设您将以下数组作为输出 [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 - image))

或者,您可以检查交叉熵损失函数。 (它内部确实应用了softmax,不要两次应用softmax)

tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(pred, image))

其他回答很详细,很有帮助。下面是一个代码示例,它使用占位符来降低对数尺度的学习率。 HTH.

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