LSTM网络在TensorFlow中的收敛问题

我正在尝试在一个长时间序列中检测微事件。为此,我将训练一个LSTM网络。

数据。 每个时间样本的输入是11个不同的特征,这些特征经过某种程度的归一化以适应0-1范围。输出将是两个类别之一。

批处理。 由于存在巨大的类别不平衡,我将数据提取为每批60个时间样本,其中至少有5个始终属于类别1,其余属于类别2。这样,类别不平衡从150:1减少到约12:1。然后,我随机化了所有批次的顺序。

模型。 我尝试训练一个LSTM,初始配置为3个不同的单元和5个延迟步骤。我期望微事件至少在3个时间步长的序列中出现。

问题: 当我尝试训练网络时,它会很快收敛到认为所有样本都属于多数类。当我实现加权损失函数时,在某个阈值处,它会转而认为所有样本都属于少数类。我怀疑(尽管不是专家)我的LSTM单元没有学习,或者我的配置有问题?

以下是我实现的代码。我希望有人能告诉我

  • 我的实现是否正确?
  • 导致这种行为的其他可能原因是什么?

ar_model.py

import numpy as npimport tensorflow as tffrom tensorflow.models.rnn import rnnimport ar_configconfig = ar_config.get_config()class ARModel(object):    def __init__(self, is_training=False, config=None):        # Config        if config is None:            config = ar_config.get_config()        # Placeholders        self._features = tf.placeholder(tf.float32, [None, config.num_features], name='ModelInput')        self._targets = tf.placeholder(tf.float32, [None, config.num_classes], name='ModelOutput')        # Hidden layer        with tf.variable_scope('lstm') as scope:            lstm_cell = tf.nn.rnn_cell.BasicLSTMCell(config.num_hidden, forget_bias=0.0)            cell = tf.nn.rnn_cell.MultiRNNCell([lstm_cell] * config.num_delays)            self._initial_state = cell.zero_state(config.batch_size, dtype=tf.float32)            outputs, state = rnn.rnn(cell, [self._features], dtype=tf.float32)        # Output layer        output = outputs[-1]        softmax_w = tf.get_variable('softmax_w', [config.num_hidden, config.num_classes], tf.float32)        softmax_b = tf.get_variable('softmax_b', [config.num_classes], tf.float32)        logits = tf.matmul(output, softmax_w) + softmax_b        # Evaluate        ratio = (60.00 / 5.00)        class_weights = tf.constant([ratio, 1 - ratio])        weighted_logits = tf.mul(logits, class_weights)        loss = tf.nn.softmax_cross_entropy_with_logits(weighted_logits, self._targets)        self._cost = cost = tf.reduce_mean(loss)        self._predict = tf.argmax(tf.nn.softmax(logits), 1)        self._correct = tf.equal(tf.argmax(logits, 1), tf.argmax(self._targets, 1))        self._accuracy = tf.reduce_mean(tf.cast(self._correct, tf.float32))        self._final_state = state        if not is_training:            return        # Optimize        optimizer = tf.train.AdamOptimizer()        self._train_op = optimizer.minimize(cost)    @property    def features(self):        return self._features    @property    def targets(self):        return self._targets    @property    def cost(self):        return self._cost    @property    def accuracy(self):        return self._accuracy    @property    def train_op(self):        return self._train_op    @property    def predict(self):        return self._predict    @property    def initial_state(self):        return self._initial_state    @property    def final_state(self):        return self._final_state

ar_train.py

import osfrom datetime import datetimeimport numpy as npimport tensorflow as tffrom tensorflow.python.platform import gfileimport ar_networkimport ar_configimport ar_readerconfig = ar_config.get_config()def main(argv=None):    if gfile.Exists(config.train_dir):        gfile.DeleteRecursively(config.train_dir)        gfile.MakeDirs(config.train_dir)    train()def train():    train_data = ar_reader.ArousalData(config.train_data, num_steps=config.max_steps)    test_data = ar_reader.ArousalData(config.test_data, num_steps=config.max_steps)    with tf.Graph().as_default(), tf.Session() as session, tf.device('/cpu:0'):        initializer = tf.random_uniform_initializer(minval=-0.1, maxval=0.1)        with tf.variable_scope('model', reuse=False, initializer=initializer):            m = ar_network.ARModel(is_training=True)            s = tf.train.Saver(tf.all_variables())        tf.initialize_all_variables().run()        for batch_input, batch_target in train_data:            step = train_data.iter_steps            dict = {                m.features: batch_input,                m.targets: batch_target            }            session.run(m.train_op, feed_dict=dict)            state, cost, accuracy = session.run([m.final_state, m.cost, m.accuracy], feed_dict=dict)            if not step % 10:                test_input, test_target = test_data.next()                test_accuracy = session.run(m.accuracy, feed_dict={                    m.features: test_input,                    m.targets: test_target                })                now = datetime.now().time()                print ('%s | Iter %4d | Loss= %.5f | Train= %.5f | Test= %.3f' % (now, step, cost, accuracy, test_accuracy))            if not step % 1000:                destination = os.path.join(config.train_dir, 'ar_model.ckpt')                s.save(session, destination)if __name__ == '__main__':    tf.app.run()

ar_config.py

class Config(object):    # Directories    train_dir = '...'    ckpt_dir = '...'    train_data = '...'    test_data = '...'    # Data    num_features = 13    num_classes = 2    batch_size = 60    # Model    num_hidden = 3    num_delays = 5    # Training    max_steps = 100000def get_config():    return Config()

更新后的架构:

# Placeholdersself._features = tf.placeholder(tf.float32, [None, config.num_features, config.num_delays], name='ModelInput')self._targets = tf.placeholder(tf.float32, [None, config.num_output], name='ModelOutput')# Weightsweights = {    'hidden': tf.get_variable('w_hidden', [config.num_features, config.num_hidden], tf.float32),    'out': tf.get_variable('w_out', [config.num_hidden, config.num_classes], tf.float32)}biases = {    'hidden': tf.get_variable('b_hidden', [config.num_hidden], tf.float32),    'out': tf.get_variable('b_out', [config.num_classes], tf.float32)}#Layer inwith tf.variable_scope('input_hidden') as scope:    inputs = self._features    inputs = tf.transpose(inputs, perm=[2, 0, 1])  # (BatchSize,NumFeatures,TimeSteps) -> (TimeSteps,BatchSize,NumFeatures)    inputs = tf.reshape(inputs, shape=[-1, config.num_features]) # (TimeSteps,BatchSize,NumFeatures -> (TimeSteps*BatchSize,NumFeatures)    inputs = tf.add(tf.matmul(inputs, weights['hidden']), biases['hidden'])#Layer hiddenwith tf.variable_scope('hidden_hidden') as scope:    inputs = tf.split(0, config.num_delays, inputs) # -> n_steps * (batchsize, features)    cell = tf.nn.rnn_cell.BasicLSTMCell(config.num_hidden, forget_bias=0.0)    self._initial_state = cell.zero_state(config.batch_size, dtype=tf.float32)    outputs, state = rnn.rnn(cell, inputs, dtype=tf.float32)#Layer outwith tf.variable_scope('hidden_output') as scope:    output = outputs[-1]    logits = tf.add(tf.matmul(output, weights['out']), biases['out'])

回答:

Related Posts

L1-L2正则化的不同系数

我想对网络的权重同时应用L1和L2正则化。然而,我找不…

使用scikit-learn的无监督方法将列表分类成不同组别,有没有办法?

我有一系列实例,每个实例都有一份列表,代表它所遵循的不…

f1_score metric in lightgbm

我想使用自定义指标f1_score来训练一个lgb模型…

通过相关系数矩阵进行特征选择

我在测试不同的算法时,如逻辑回归、高斯朴素贝叶斯、随机…

可以将机器学习库用于流式输入和输出吗?

已关闭。此问题需要更加聚焦。目前不接受回答。 想要改进…

在TensorFlow中,queue.dequeue_up_to()方法的用途是什么?

我对这个方法感到非常困惑,特别是当我发现这个令人费解的…

发表回复

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