我有这个损失函数:
loss_main = tf.reduce_mean(
tf.nn.softmax_cross_entropy_with_logits(train_logits, train['labels']),
name='loss_main',
)
train_logits
由如下构建的管道定义:
def build_logit_pipeline(data, include_dropout):
# X --> *W1 --> +b1 --> relu --> *W2 --> +b2 ... --> softmax etc...
pipeline = data
for i in xrange(len(layer_sizes) - 1):
last = i == len(layer_sizes) - 2
with tf.name_scope("linear%d" % i):
pipeline = tf.matmul(pipeline, weights[i])
pipeline = tf.add(pipeline, biases[i])
if not last:
# insert relu after every one before the last
with tf.name_scope("relu%d" % i):
pipeline = getattr(tf.nn, arg('act-func'))(pipeline)
if include_dropout and not arg('no-dropout'):
pipeline = tf.nn.dropout(pipeline, 0.5, name='dropout')
return pipeline
、和layer_sizes
的构造如下:weights
biases
def make_weight(from_, to, name=None):
return tf.Variable(tf.truncated_normal([from_, to], stddev=0.5), name=name)
def make_bias(to, name=None):
return tf.Variable(tf.truncated_normal([to], stddev=0.5), name=name)
layer_sizes = [dataset.image_size**2] + arg('layers') + [dataset.num_classes]
with tf.name_scope("parameters"):
with tf.name_scope("weights"):
weights = [make_weight(layer_sizes[i], layer_sizes[i+1], name="weights_%d" % i)
for i in xrange(len(layer_sizes) - 1)]
with tf.name_scope("biases"):
biases = [make_bias(layer_sizes[i + 1], name="biases_%d" % i)
for i in xrange(len(layer_sizes) - 1)]
如果arg('act-func')
是 relu,那么如果我构建一个长链 relu - 就像arg('layers')
是一样[750, 750, 750, 750, 750, 750]
- 那么我的损失函数是巨大的:
Global step: 0
Batch loss function: 28593700.000000
如果我有一个较短的 relus 链 -arg('layers')
只是说[750]
- 那么损失函数会更小:
Global step: 0
Batch loss function: 96.377831
我的问题是:为什么损失函数如此不同?据我了解,logits 的输出是 softmax 以产生概率分布。然后根据这个概率分布确定单热标签的交叉熵。为什么更改我拥有的 relus 数量会更改此功能?我认为每个网络在开始时都应该是同样错误的——大约是随机的——因此损失永远不会变得太大。
请注意,此损失函数不包含任何 l2 损失,因此增加的权重和偏差数量不会解释这一点。
使用arg('act-func')
astanh
相反,这种损失的增加不会发生 - 它保持大致相同,正如我所期望的那样。