【问题标题】:Tensorflow: How to set the learning rate in log scale and some Tensorflow questionsTensorflow:如何设置对数尺度的学习率和一些 Tensorflow 问题
【发布时间】:2018-05-06 00:16:58
【问题描述】:

我是一名深度学习和 Tensorflow 初学者,我正在尝试使用 Tensorflow 在 paper 中实现该算法。本文使用 Matconvnet+Matlab 来实现,我很好奇 Tensorflow 是否有等效的功能来实现相同的东西。论文说:

使用 Xavier 方法 [14] 初始化网络参数。我们使用了 l2 惩罚下的四个小波子带的回归损失,并通过使用随机梯度下降 (SGD) 对所提出的网络进行了训练。正则化参数 (λ) 为 0.0001,动量为 0.9。学习率设置为 10-1 到 10-4,在每个 epoch 以对数规模减小。

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

初始化变量正态分布
stddev=sqrt(2/(filter_size*filter_size*num_filters)

第一季度。我应该如何初始化变量?下面的代码是否正确?

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

本文没有详细解释如何构造损失函数。我找不到等效的 Tensorflow 函数来设置对数刻度的学习率(仅限 exponential_decay)。我理解MomentumOptimizer 相当于带有动量的随机梯度下降。

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

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

我按照website 编写了下面的代码。假设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 初学者,我在这里和那里复制粘贴代码,所以如果可以的话,请随时纠正它;)

【问题讨论】:

  • 您使用的是哪个 TF 和 Python 版本?
  • @MaxB 我使用的是 TF 1.40 和 Python 2.7.14 或 3.6.3

标签: python tensorflow deep-learning deep-residual-networks


【解决方案1】:

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

没错(尽管缺少左括号)。如果要重用变量,您还可以查看tf.get_variable

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

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

编辑:查看另一个答案,使用 staircase=True 参数!

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

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

【讨论】:

  • 实际上我没有使用变量logits,也不知道应该如何将它与labelspred 关联起来构造第一个损失函数。请您建议如何修改这两行?
  • 感谢您使用tf.train.piecewise_constant 的建议。请问你能告诉我如何使用这个函数来设置log scale中的训练率吗?
【解决方案2】:

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)

优化器 = tf.train.AdamOptimizer(learning_rate=learning_rate_node).minimize(loss)

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

一开始,你还没有写“pred”到“image”转换到这个消息(根据论文,你需要应用减法和IDWT来获得最终图像)。

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

pred = 模型()

pred = tf.matmul(pred, weights) + 偏差

logits = tf.nn.softmax(pred)

损失 = tf.reduce_mean(tf.abs(logits - 标签))

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

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

pred = 模型()

pred = tf.matmul(image, weights) + 偏差

logits = tf.nn.softmax(pred)

image = apply_IDWT("X : input", logits) # 这将应用 IDWT(x_label - y_label)

loss = tf.reduce_mean(tf.abs(图像 - 标签))

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

pred = 模型()

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) # 这将应用 IDWT(x_label - y_label)

损失 = tf.reduce_mean(tf.abs(logits - 标签))

此损失函数将为您提供基本的训练能力。但是,这是 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))

【讨论】:

  • 根据论文,model() 函数应该有很多转换。根据 tensorflow 教程,每个 conv 都应使用权重进行过滤。所以我们应该有一个权重列表。我们是否应该在 model() 中返回权重并使用它们来计算损失函数?另外,我没有看到正则化是如何应用于损失函数的(我猜应该和这个website类似)。最后,如果可能的话,我想根据论文实现对数刻度。是否可以定义自定义学习率?
  • 您不会将损失应用于权重。您将损失应用于输出。损失完全定义为(你得到的输出 - 你应该得到的)。正则化是完全不同的事情。首先考虑了解损失函数。然后,跳到正则化会更有意义。
  • 你好像迷失在了纸上。考虑遵循取得成功的路线图: 训练一个网络,不考虑论文的现状,确保一切正常并且 nn 学习输出(当前不应该学习)然后,搜索如何对权重参数应用正则化(有很多解释它)然后,搜索对数尺度学习率。最后两个步骤是将输出细化为增强。不解决第一个,后两个没有意义。
  • 是的,我迷路了,因为我是初学者,感谢您指出路线图。如果您可以将上述描述放入代码中并逐步解释我应该如何构建损失,如何应用正则化,在对数尺度上设置学习率并使用优化器来设置学习率并最小化,那将非常有帮助亏损。我问我们是否应该对损失应用权重的原因是我在谷歌上搜索了很多代码,看到其中一些是这样做的。我的理解是我们使用这些权重(用于 conv2d)来创建模型,因此在损失中评估它们确实有意义
  • 还有一件事是该论文确实提到了 L2 损失和正则化,所以我不认为 website 将正则化用于损失是错误的。请你看看这个网站,看看它是否有意义?
【解决方案3】:

其他答案非常详细且很有帮助。这是一个代码示例,它使用占位符以对数尺度衰减学习率。 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

【讨论】:

  • 抱歉我的数学不好。请您解释一下为什么learning_rate /= 2 表示对数尺度的衰减学习率?
  • @chesschi 推理类似于为什么在二叉搜索树中的搜索是 O(log2(N)) - 你将搜索空间减半。例如,假设您开始时的学习率为 32,那么在 5 个 epoch 之后,您的学习率将是 32/2/2/2/2/2 = 1,并且 log2(32) = 5。如果您绘制 log (lr) 以 2 为底,以 2 为底,这将是一条直线。你可以选择任何你喜欢的基础并除以它。
  • 因此,如果您以对数比例绘制衰减图,它应该看起来像向上凹(具有负斜率)而不是向下凹且具有负斜率 (curve description)?
  • 在对数尺度下,它将是一条带负斜率的直线。
  • 我理解在对数刻度的数学中它会是一条直线。但是你是如何告诉 Tensorflow 在对数尺度上解释学习率的(就像learning_rate /= 2 一样简单)?我很困惑,所以这个问题听起来很傻。
猜你喜欢
  • 2016-04-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-26
相关资源
最近更新 更多