【问题标题】:Strange behavior of keras v1.2.2 vs. keras v2+ (HUGE differences in accuracy)keras v1.2.2 与 keras v2+ 的奇怪行为(准确性差异巨大)
【发布时间】:2019-12-21 06:21:38
【问题描述】:

今天我遇到了 Keras 的一些非常奇怪的行为。 当我尝试使用简单模型在 iris 数据集上运行分类时,keras 版本 1.2.2 给了我 +- 95% 的准确率,而 keras 版本 2.0+ 为每个训练示例预测相同的类(导致精度为 +- 35%,因为存在三种类型的虹膜)。使我的模型预测 +-95% 准确度的唯一因素是将 keras 降级到 2.0 以下的版本:

我认为是Keras的问题,因为我尝试了以下的东西,都没有影响;

  • 在最后一层切换激活函数(从 Sigmoid 到 softmax)。
  • 切换后端(Theano 和 Tensorflow 的性能大致相同)。
  • 使用随机种子。
  • 改变隐藏层中的神经元数量(我在这个简单模型中只有 1 个隐藏层)。
  • 切换损失函数。

由于模型非常简单并且可以独立运行(您只需要易于获取的 iris.csv 数据集),因此我决定包含整个代码;

import pandas as pd
from keras.models import Sequential
from keras.layers import Dense
from keras.wrappers.scikit_learn import KerasClassifier
from keras.utils import np_utils
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import KFold
from sklearn.preprocessing import LabelEncoder

#Load data
data_frame = pd.read_csv("iris.csv", header=None)
data_set = data_frame.values
X = data_set[:, 0:4].astype(float)
Y = data_set[:, 4]

#Encode class values as integers
encoder = LabelEncoder()
encoder.fit(Y)
encoded_Y = encoder.transform(Y)

# convert integers to dummy variables (i.e. one hot encoded)
dummy_y = np_utils.to_categorical(encoded_Y)

def baseline_model():
    #Create & Compile model
    model = Sequential()
    model.add(Dense(8, input_dim=4, init='normal', activation='relu'))
    model.add(Dense(3, init='normal', activation='sigmoid'))
    model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
    return model

#Create Wrapper For Neural Network Model For Use in scikit-learn
estimator = KerasClassifier(build_fn=baseline_model, nb_epoch=200, batch_size=5, verbose=0)

#Create kfolds-cross validation
kfold = KFold(n_splits=10, shuffle=True)

#Evaluate our model (Estimator) on dataset (X and dummy_y) using a 10-fold cross-validation procedure (kfold).
results = cross_val_score(estimator, X, dummy_y, cv=kfold)
print("Accuracy: {:2f}% ({:2f}%)".format(results.mean()*100, results.std()*100))

如果有人想在这里复制错误是我用来观察问题的依赖项:

numpy=1.16.4
pandas=0.25.0
sk-learn=0.21.2
theano=1.0.4
tensorflow=1.14.0

【问题讨论】:

  • 输出层中的activation='sigmoid' 看起来非常可疑,它当然不应该存在(应该是softmax);你确定你在 Keras 1.2 上的“好”结果伴随着同样的激活吗?另外,应该避免使用init='normal' - 你应该离开default(至少在Keras 2中)glorot_uniform
  • 我都试过了;问题仍然存在......我真的认为这是 Keras 的问题或我的环境中的某些依赖项。只有我不知道从哪里开始寻找

标签: python tensorflow keras neural-network theano


【解决方案1】:

在 Keras 2.0 中,许多参数更改了名称,有兼容层来保持工作,但不知何故,它在使用 KerasClassifier 时不适用。

在这部分代码中:

estimator = KerasClassifier(build_fn=baseline_model, nb_epoch=200, batch_size=5, verbose=0)

您使用的是旧名称 nb_epoch,而不是现代名称 epochs。默认值为epochs=1,这意味着您的模型只训练了一个时期,产生的预测质量非常低。

还要注意这里:

model.add(Dense(3, init='normal', activation='sigmoid'))

您应该使用softmax 激活而不是sigmoid,因为您使用的是分类交叉熵损失:

model.add(Dense(3, init='normal', activation='softmax'))

【讨论】:

    【解决方案2】:

    如果您将nb_epoch 更改为epochs,我已经设法隔离了这个问题,(所有其他条件都完全相同)该模型再次预测得非常好,在 keras 2 中也是如此。我不知道这是预期的行为还是错误。

    【讨论】:

    • 这不是错误,model.fit 中的参数在 Keras 2 中从 nb_epoch 更改为 epochs。还要注意使用 sigmoid 激活进行多类分类是错误的,你应该为此使用 softmax。
    猜你喜欢
    • 2020-04-15
    • 2017-12-03
    • 2019-03-25
    • 1970-01-01
    • 2019-02-03
    • 2020-05-31
    • 1970-01-01
    • 2019-08-29
    • 1970-01-01
    相关资源
    最近更新 更多