keras v1.2.2 与 keras v2+ 的奇怪行为(准确性存在巨大差异)
Strange behavior of keras v1.2.2 vs. keras v2+ (HUGE differences in accuracy)
今天我 运行 了解了 Keras 的一些非常 st运行ge 行为。 当我尝试使用简单模型对 iris 数据集进行 class化 运行 时,keras 版本 1.2.2 给我 +- 95% 的准确度,而 keras 版本的2.0+ 为每个训练示例预测相同的 class(导致准确度为 +- 35%,因为有三种类型的虹膜)。唯一让我的模型预测 +-95% 准确度的事情是将 keras 降级到 2.0 以下的版本:
我认为是Keras的问题,因为我已经尝试了以下的东西,都没有什么区别;
- 在最后一层切换激活函数(从 Sigmoid 到 softmax)。
- 切换后端(Theano 和 Tensorflow 的性能大致相同)。
- 使用 运行dom 种子。
- 改变隐藏层中的神经元数量(我在这个简单模型中只有 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
如果您将 nb_epoch
更改为 epochs
,(所有其他条件完全相同),我已经设法找出问题所在,模型再次预测得非常好,在 keras 2 中也是如此。我不知道这是预期行为还是错误。
在 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'))
今天我 运行 了解了 Keras 的一些非常 st运行ge 行为。 当我尝试使用简单模型对 iris 数据集进行 class化 运行 时,keras 版本 1.2.2 给我 +- 95% 的准确度,而 keras 版本的2.0+ 为每个训练示例预测相同的 class(导致准确度为 +- 35%,因为有三种类型的虹膜)。唯一让我的模型预测 +-95% 准确度的事情是将 keras 降级到 2.0 以下的版本:
我认为是Keras的问题,因为我已经尝试了以下的东西,都没有什么区别;
- 在最后一层切换激活函数(从 Sigmoid 到 softmax)。
- 切换后端(Theano 和 Tensorflow 的性能大致相同)。
- 使用 运行dom 种子。
- 改变隐藏层中的神经元数量(我在这个简单模型中只有 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
如果您将 nb_epoch
更改为 epochs
,(所有其他条件完全相同),我已经设法找出问题所在,模型再次预测得非常好,在 keras 2 中也是如此。我不知道这是预期行为还是错误。
在 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'))