TensorFlow动态RNN无法训练

问题陈述


我在Linux RedHat 7.3上使用TensorFlow v1.0.1尝试训练一个动态RNN(在Windows 7上也有相同的问题),无论我尝试什么方法,每个epoch的训练和验证错误都完全相同,即我的权重没有更新。

我非常感谢您能提供的任何帮助。

示例


我尝试将这个问题简化为一个最小的示例来展示我的问题,但即使是最小的示例仍然相当大。我主要基于这个gist来构建网络结构。

网络定义

import functoolsimport numpy as npimport tensorflow as tfdef lazy_property(function):    attribute = '_' + function.__name__    @property    @functools.wraps(function)    def wrapper(self):        if not hasattr(self, attribute):            setattr(self, attribute, function(self))        return getattr(self, attribute)    return wrapperclass MyNetwork:    """    定义用于标记时间序列的RNN的类。    """    def __init__(self, data, target, num_hidden=64):        self.data = data        self.target = target        self._num_hidden = num_hidden        self._num_steps = int(self.target.get_shape()[1])        self._num_classes = int(self.target.get_shape()[2])        self._weight_and_bias()  # 创建权重和偏置张量        self.prediction        self.error        self.optimize    @lazy_property    def prediction(self):        """定义循环神经网络的预测方案。"""        # 动态LSTM。        network = tf.contrib.rnn.BasicLSTMCell(self._num_hidden)        output, _ = tf.nn.dynamic_rnn(network, data, dtype=tf.float32)        # 展平并对所有时间步应用相同的权重。        output = tf.reshape(output, [-1, self._num_hidden])        prediction = tf.nn.softmax(tf.matmul(output, self.weight) + self.bias)        prediction = tf.reshape(prediction,                                [-1, self._num_steps, self._num_classes])        return prediction    @lazy_property    def cost(self):        """定义网络的成本函数。"""        cross_entropy = -tf.reduce_sum(self.target * tf.log(self.prediction),                                       axis=[1, 2])        cross_entropy = tf.reduce_mean(cross_entropy)        return cross_entropy    @lazy_property    def optimize(self):        """定义优化方案。"""        learning_rate = 0.003        optimizer = tf.train.RMSPropOptimizer(learning_rate)        return optimizer.minimize(self.cost)    @lazy_property    def error(self):        """定义预测误差的度量。"""        mistakes = tf.not_equal(tf.argmax(self.target, 2),                                tf.argmax(self.prediction, 2))        return tf.reduce_mean(tf.cast(mistakes, tf.float32))    def _weight_and_bias(self):        """返回输出层适当大小的权重和偏置张量。"""        self.weight = tf.Variable(tf.truncated_normal(                                         [self._num_hidden, self._num_classes],                                         mean=0.0,                                         stddev=0.01,                                         dtype=tf.float32))        self.bias = tf.Variable(tf.constant(0.1, shape=[self._num_classes]))

训练

这是我的训练过程。all_data类只是保存我的数据和标签,并使用批量生成器类在调用all_data.train.next()all_data.train_labels.next()时输出用于训练的批次。您可以使用任何喜欢的批量生成方案进行重现,如果您认为这相关,我可以添加代码;我觉得这已经太长了。

tf.reset_default_graph()data = tf.placeholder(tf.float32,                      [None, all_data.num_steps, all_data.num_features])target = tf.placeholder(tf.float32,                        [None, all_data.num_steps, all_data.num_outputs])model = MyNetwork(data, target, NUM_HIDDEN)print('正在训练模型...')with tf.Session() as sess:    sess.run(tf.global_variables_initializer())    print('已初始化。')    for epoch in range(3):        print('Epoch {} |'.format(epoch), end='', flush=True)        for step in range(all_data.train_size // BATCH_SIZE):            # 生成下一个训练批次并训练。            d = all_data.train.next()            t = all_data.train_labels.next()            sess.run(model.optimize,                     feed_dict={data: d, target: t})            # 定期更新用户。            if step % summary_frequency == 0:                print('.', end='', flush=True)        # 在每个epoch结束时显示训练和验证错误。        print('|', flush=True)        train_error = sess.run(model.error,                               feed_dict={data: d, target: t})        valid_error = sess.run(model.error,                               feed_dict={                                   data: all_data.valid,                                   target: all_data.valid_labels                                   })        print('训练错误: {}%'.format(100 * train_error))        print('验证错误: {}%'.format(100 * valid_error))    # 在一切完成后检查测试错误。    test_error = sess.run(model.error,                          feed_dict={                              data: all_data.test,                              target: all_data.test_labels                              })    print('训练{}个epoch后的测试错误: {}%'.format(epoch + 1, 100 * test_error))

对于一个简单的示例,我生成了随机数据和标签,其中数据的形状为[num_samples, num_steps, num_features],每个样本都与整个事物相关联的单个标签:

data = np.random.rand(5000, 1000, 2)labels = np.random.randint(low=0, high=2, size=[5000])

然后我将我的标签转换为one-hot向量,并对它们进行平铺处理,使得生成的labels张量与data张量大小相同。


回答:

Related Posts

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注