Keras模型根本不学习
Posted
技术标签:
【中文标题】Keras模型根本不学习【英文标题】:Keras model doesn't learn at all 【发布时间】:2019-05-21 09:55:03 【问题描述】:我的模型权重(我将它们输出到weights_before.txt
和weights_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
(结果),将这两个按行拆分为test
和validation
集。
将这些集合转换为 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 + TensorFlow 开发一个复杂深度学习模型