【问题标题】:Tensorflow Layers API CNN parameters wont change during trainingTensorflow Layers API CNN 参数在训练期间不会改变
【发布时间】:2017-12-21 04:22:47
【问题描述】:

我是 Tensorflow 的新手,所以这个问题可能真的很傻。

我一直在尝试使用 Tensorflow 为 MNIST 手写数字数据集编写一个简单的 CNN。问题是优化器没有更新参数(由 Tensorboard 摘要监控)。
Graph 看起来不错,尽管 Layers API 创建的范围看起来很奇怪。梯度是从每一层计算出来的。 请帮忙!

我正在使用来自这里的训练数据:http://yann.lecun.com/exdb/mnist/

这里是代码

import tensorflow as tf

DATA = 'train-images.idx3-ubyte'
LABELS = 'train-labels.idx1-ubyte'
NUM_EPOCHS = 2
BATCH_SIZE = 15
#Data definition
data_queue = tf.train.string_input_producer([DATA,])
label_queue = tf.train.string_input_producer([LABELS,])

reader_data = tf.FixedLengthRecordReader(record_bytes=28*28, header_bytes = 16)
reader_labels = tf.FixedLengthRecordReader(record_bytes=1, header_bytes = 8)

(_,data_rec) = reader_data.read(data_queue)
(_,label_rec) = reader_labels.read(label_queue)

image = tf.decode_raw(data_rec, tf.uint8)
image = tf.reshape(image, [28, 28, 1])
label = tf.decode_raw(label_rec, tf.uint8)
label = tf.reshape(label, [1])

image_batch, label_batch = tf.train.shuffle_batch([image, label],
                                                 batch_size=BATCH_SIZE,
                                                 capacity=100,
                                                 min_after_dequeue = 30)
#Layers definition
conv = tf.layers.conv2d(
  inputs=tf.cast(image_batch, tf.float32),
  filters=15,
  kernel_size=[5,5],
  padding='same',
  activation=tf.nn.relu)

conv1 = tf.layers.conv2d(
  inputs=conv,
  filters=15,
  kernel_size=[3,3],
  padding='same',
  activation=tf.nn.relu)

pool_flat = tf.reshape(conv1, [BATCH_SIZE, -1])

dense1 = tf.layers.dense(inputs=pool_flat, units=30, activation=tf.nn.relu)

output = tf.nn.softmax(tf.layers.dense(inputs=dense1, units=10))

#train operation definition
onehot_labels = tf.one_hot(indices=tf.cast(tf.reshape(label_batch,[-1]), tf.int32), depth=10)

loss = tf.losses.softmax_cross_entropy(onehot_labels=onehot_labels,
                                       logits=output)

global_step = tf.Variable(0,name='global_step',trainable=False)
train_op = tf.train.GradientDescentOptimizer(0.05).minimize(loss, global_step = global_step)

#Summaries definition

for var in tf.get_collection(tf.GraphKeys.GLOBAL_VARIABLES, scope='conv2d'):
    tf.summary.histogram(var.name, var)
for var in tf.get_collection(tf.GraphKeys.GLOBAL_VARIABLES, scope='conv2d_1'):
    tf.summary.histogram(var.name, var)
for var in tf.get_collection(tf.GraphKeys.GLOBAL_VARIABLES, scope='dense'):
    tf.summary.histogram(var.name, var)
for var in tf.get_collection(tf.GraphKeys.GLOBAL_VARIABLES, scope='dense_1'):
    tf.summary.histogram(var.name, var)
tf.summary.image("inp", image_batch, max_outputs =1)
loss_summary = tf.summary.scalar("loss", loss)
summaries = tf.summary.merge_all()

#init
sess = tf.Session()
summary_writer = tf.summary.FileWriter('log_simple_stats', sess.graph)
coord = tf.train.Coordinator()
threads = tf.train.start_queue_runners(coord=coord, sess=sess)
sess.run(tf.global_variables_initializer())

#loop
for i in range((60000*NUM_EPOCHS)//BATCH_SIZE):
    sess.run(train_op)
    if(i%100):
        merged = sess.run(summaries)
        summary_writer.add_summary(merged, i)


coord.request_stop()
coord.join(threads)

编辑 自定义层给出相同的结果。

自定义层定义:

def convol(input, inp, outp, name="conv"):
    with tf.name_scope(name):
        w = tf.Variable(tf.truncated_normal([5, 5, inp, outp], stddev=0.1),name="W")
        b = tf.Variable(tf.constant(0.1, shape=[outp]), name="B")
        filtered = tf.nn.conv2d(input, w, strides=[1,1,1,1], padding="SAME", name="conv2d")
        activation = tf.nn.relu(features=(filtered+b), name="activation")
        tf.summary.histogram(name=w.name, values=w)
        tf.summary.histogram(name=b.name, values=b)
        tf.summary.histogram(name=activation.name, values=activation)
        return activation

def dense(input, inp, outp, name="dense"):
    with tf.name_scope(name):
        w = tf.Variable(tf.truncated_normal([inp, outp], stddev=0.1), name="W")
        b = tf.Variable(tf.constant(0.1, shape=[outp]), name="B")
        act = tf.matmul(input, w) + b
        tf.summary.histogram(name=w.name, values=w)
        tf.summary.histogram(name=b.name, values=b)
        tf.summary.histogram(name="activation", values=act)
        return act

编辑:

因此,在处理了 tf 中的这个和 MNIST 示例一段时间后,我注意到没有学习权重。我处理数据读取的方式搞砸了梯度计算。我刚刚将读取 MNIST 数据集的类录制到我的代码中,它可以 100% 工作,无需对参数进行任何调整。

【问题讨论】:

    标签: python tensorflow


    【解决方案1】:

    我的 convnet 也遇到了同样的问题,对我来说,原因很简单:

    • 迭代次数不足:更改可能需要很长时间才能显现(数万次迭代)
    • 模型变得复杂:大幅减少第一次测试的过滤器数量,然后慢慢增加它们以适应您的用例,以确保它不是别的东西。

    为了更好地调试,尝试使用 Tensorboard 可视化您的过滤器,这个要点对我帮助很大:

    https://gist.github.com/kukuruza/03731dc494603ceab0c5

    您的任何一种方法(tf.layers 和手动创建的变量)都应该正确连接到train_op,所以我认为这没有什么问题。

    【讨论】:

    • 感谢您的回答!我会尝试用小参数运行它,但我怀疑情况并非如此。这是传递给 train_op 的 1.8 个数据时代(100000 次运行),它实际上并没有改变任何东西。 graph_from_tensorboard
    猜你喜欢
    • 2018-04-13
    • 2022-01-19
    • 2018-12-08
    • 2017-06-17
    • 2017-08-24
    • 2019-12-07
    • 2018-08-03
    • 2017-01-08
    • 2019-05-07
    相关资源
    最近更新 更多