Keras模型根本不学习

Posted

技术标签:

【中文标题】Keras模型根本不学习【英文标题】:Keras model doesn't learn at all 【发布时间】:2019-05-21 09:55:03 【问题描述】:

我的模型权重(我将它们输出到weights_before.txtweights_after.txt)在训练前后完全相同,即训练没有改变任何东西,没有拟合发生。

我的数据是这样的(我基本上是想让模型预测特征的符号result如果特征为负则为0,如果为正则为1):

,feature,zerosColumn,result
0,-5,0,0
1,5,0,1
2,-3,0,0
3,5,0,1
4,3,0,1
5,3,0,1
6,-3,0,0
...

我的方法的简要总结:

    加载数据。 将其按列拆分为x(功能)和y(结果),将这两个按行拆分为testvalidation 集。 将这些集合转换为 TimeseriesGenerators(在这种情况下不是必需的,但我想让这个设置正常工作,我看不出有任何不应该这样做的原因)。 创建和编译简单的Sequential 模型,在其输出层使用少量Dense 层和softmax 激活,使用binary_crossentropy 作为损失函数。 训练模型...什么都没有发生!

完整代码如下:

import keras
import pandas as pd
import numpy as np

np.random.seed(570)

TIMESERIES_LENGTH = 1
TIMESERIES_SAMPLING_RATE = 1
TIMESERIES_BATCH_SIZE = 1024
TEST_SET_RATIO = 0.2  # the portion of total data to be used as test set
VALIDATION_SET_RATIO = 0.2  # the portion of total data to be used as validation set
RESULT_COLUMN_NAME = 'feature'
FEATURE_COLUMN_NAME = 'result'

def create_network(csv_path, save_model):
    before_file = open("weights_before.txt", "w")
    after_file = open("weights_after.txt", "w")

    data = pd.read_csv(csv_path)

    data[RESULT_COLUMN_NAME] = data[RESULT_COLUMN_NAME].shift(1)
    data = data.dropna()

    x = data.ix[:, 1:2]
    y = data.ix[:, 3]

    test_set_length = int(round(len(x) * TEST_SET_RATIO))
    validation_set_length = int(round(len(x) * VALIDATION_SET_RATIO))

    x_train_and_val = x[:-test_set_length]
    y_train_and_val = y[:-test_set_length]
    x_train = x_train_and_val[:-validation_set_length].values
    y_train = y_train_and_val[:-validation_set_length].values
    x_val = x_train_and_val[-validation_set_length:].values
    y_val = y_train_and_val[-validation_set_length:].values


    train_gen = keras.preprocessing.sequence.TimeseriesGenerator(
        x_train,
        y_train,
        length=TIMESERIES_LENGTH,
        sampling_rate=TIMESERIES_SAMPLING_RATE,
        batch_size=TIMESERIES_BATCH_SIZE
    )

    val_gen = keras.preprocessing.sequence.TimeseriesGenerator(
        x_val,
        y_val,
        length=TIMESERIES_LENGTH,
        sampling_rate=TIMESERIES_SAMPLING_RATE,
        batch_size=TIMESERIES_BATCH_SIZE
    )
    model = keras.models.Sequential()
    model.add(keras.layers.Dense(10, activation='relu', input_shape=(TIMESERIES_LENGTH, 1)))
    model.add(keras.layers.Dropout(0.2))
    model.add(keras.layers.Dense(10, activation='relu'))
    model.add(keras.layers.Dropout(0.2))
    model.add(keras.layers.Flatten())
    model.add(keras.layers.Dense(1, activation='softmax'))

    for item in model.get_weights():
        before_file.write("%s\n" % item)

    model.compile(
        loss=keras.losses.binary_crossentropy,
        optimizer="adam",
        metrics=[keras.metrics.binary_accuracy]
    )

    history = model.fit_generator(
        train_gen,
        epochs=10,
        verbose=1,
        validation_data=val_gen
    )

    for item in model.get_weights():
        after_file.write("%s\n" % item)

    before_file.close()
    after_file.close()

create_network("data/sign_data.csv", False)

你有什么想法吗?

【问题讨论】:

你的 sn-ps 看起来相当大,你能评论一下它们和/或从理论上解释你在做什么吗? 我已添加摘要。 问题不在于您的窗口长度 (length) 设置为 1 吗?您似乎没有提供太多可供学习的序列。 由于要预测的结果是前一个特征的符号,我认为窗口长度1就足够了。无论如何,我已经尝试了长度 10 和 100,问题仍然存在。恕我直言,窗口长度不是问题。 【参考方案1】:

问题是您使用softmax 作为最后一层的激活函数。本质上,softmax 对其输入进行归一化以使元素之和为 1。因此,如果你在只有一个单元的层上使用它(即Dense(1,...)),那么它总是会输出1。为了解决这个问题,将最后一层的激活函数更改为sigmoid,它输出一个在@范围内的值987654324@.

【讨论】:

以上是关于Keras模型根本不学习的主要内容,如果未能解决你的问题,请参考以下文章

如何重塑文本数据以适合 keras 中的 LSTM 模型

如何从零使用 Keras + TensorFlow 开发一个复杂深度学习模型

Keras 模型似乎不起作用

当输入形状不同时,keras 中的迁移学习

如何使用 Keras Function API 进行深度学习

Keras学习手册,Keras 模型-Sequential API