非常简单的Keras二进制分类不起作用

时间:2018-09-24 15:27:46

标签: python keras

有人可以解释为什么以下代码仅实现约50%的分类准确度吗?

我正在尝试将20个项目的列表分为0或1。这些列表全是5s或全是6s。

import numpy as np
import keras
from sklearn.model_selection import train_test_split

positive_samples = [[5]*20]*100
negative_samples = [[6]*20]*100

x_list = np.array(positive_samples+negative_samples, dtype=np.float32)
y_list = np.array([1]*len(positive_samples)+[0]*len(negative_samples), dtype=np.float32)

x_train, x_test, y_train, y_test = train_test_split(x_list, y_list, test_size=0.20, random_state=42)

y_train = keras.utils.to_categorical(y_train, 2)
y_test = keras.utils.to_categorical(y_test, 2)

model = keras.models.Sequential()
model.add(keras.layers.Dense(10, input_dim=x_train.shape[1], kernel_initializer='normal', activation='relu'))
model.add(keras.layers.Dense(5, kernel_initializer='normal', activation='relu'))
model.add(keras.layers.Dense(2, kernel_initializer='normal', activation='sigmoid'))

model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])

model.fit(x_train, y_train, batch_size=10, epochs=20, verbose=2, validation_data=(x_test, y_test))
print (model.evaluate(x_test, y_test, verbose=0))

2 个答案:

答案 0 :(得分:1)

由于最后一个输出层每个样本具有2个值,因此您需要使用softmax激活而不是sigmoid

此外,这意味着无法使用binary_crossentropy,而您必须使用categorical_crossentropy

我还通过除以最大值(x_list)来归一化数据集6

x_list /= x_list.max()

此外,您还需要通过在shuffle=True中传递train_test_split来改组数据集。

import numpy as np
import keras
from sklearn.model_selection import train_test_split

positive_samples = [[5]*20]*100
negative_samples = [[6]*20]*100

x_list = np.array(positive_samples+negative_samples, dtype=np.float32)
y_list = np.array([1]*len(positive_samples)+[0]*len(negative_samples), dtype=np.float32)

x_list /= x_list.max()

x_train, x_test, y_train, y_test = train_test_split(x_list, y_list, test_size=0.20, shuffle=True, random_state=42)

y_train = keras.utils.to_categorical(y_train, 2)
y_test = keras.utils.to_categorical(y_test, 2)

model = keras.models.Sequential()
model.add(keras.layers.Dense(10, input_dim=x_train.shape[1], kernel_initializer='normal', activation='relu'))
model.add(keras.layers.Dense(5, kernel_initializer='normal', activation='relu'))
model.add(keras.layers.Dense(2, kernel_initializer='normal', activation='softmax'))

model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])

model.fit(x_train, y_train, batch_size=10, epochs=100, verbose=2, validation_data=(x_test, y_test))
print (model.evaluate(x_test, y_test, verbose=0))

只有在有1输出时,输出中的S型激活才有意义,其中输出值在[0, 1]范围内,表示实例为1的可能性。

对于2(或更多)输出神经元,有必要对归一化为1的概率进行归一化,因此我们使用softmax层。

答案 1 :(得分:1)

在将数据馈送到网络之前,应该对数据进行规范化,通常可以通过将值更改为0和1或-1和1之间的值来完成。

positive_samples = [[1]*20]*100
negative_samples = [[-1]*20]*100

有效,或者模型可以更改为:

model = keras.models.Sequential()
model.add(BatchNormalization())
model.add(keras.layers.Dense(10, kernel_initializer='normal', activation='relu'))
model.add(keras.layers.Dense(5, kernel_initializer='normal', activation='relu'))
model.add(keras.layers.Dense(2, kernel_initializer='normal', activation='sigmoid'))