Python 神经网络在玩具数据集上失败

Python 神经网络在玩具数据集上失败,python,machine-learning,neural-network,keras,classification,Python,Machine Learning,Neural Network,Keras,Classification,我创建了以下玩具数据集: 我试图用keras中的神经网络预测课程: model = Sequential() model.add(Dense(units=2, activation='sigmoid', input_shape= (nr_feats,))) model.add(Dense(units=nr_classes, activation='softmax')) model.compile(loss='categorical_crossentropy', o

我创建了以下玩具数据集:

我试图用keras中的神经网络预测课程:

model = Sequential()
model.add(Dense(units=2, activation='sigmoid', input_shape= (nr_feats,)))
model.add(Dense(units=nr_classes, activation='softmax'))

model.compile(loss='categorical_crossentropy',
              optimizer='adam',
              metrics=['accuracy'])
nr_专长
nr_等级
设置为2。 神经网络只能以50%的准确度预测所有1或所有2。使用Logistic回归可以得到100%的准确率

我找不到这里出了什么问题

如果你很快想尝试一些东西,我已经上传了一个到github的

编辑1

我大幅增加了历元的数量,精度最终开始从历元72的0.5提高到历元98的1.0。 对于这样一个简单的数据集,这似乎仍然非常缓慢

我知道最好使用一个带乙状结肠激活的单输出神经元,但更重要的是,我想了解为什么它不适用于两个输出神经元和softmax激活

我按如下方式预处理我的数据帧:

from sklearn.preprocessing import LabelEncoder

x_train = df_train.iloc[:,0:-1].values
y_train = df_train.iloc[:, -1]

nr_feats = x_train.shape[1]
nr_classes = y_train.nunique()

label_enc = LabelEncoder()
label_enc.fit(y_train)

y_train = keras.utils.to_categorical(label_enc.transform(y_train), nr_classes)
培训和评价:

model.fit(x_train, y_train, epochs=500, batch_size=32, verbose=True)
accuracy_score(model.predict_classes(x_train),  df_train.iloc[:, -1].values)
编辑2


在将输出层更改为具有sigmoid激活的单个神经元并使用modesitt建议的
二进制交叉熵
损失后,200个历元的准确度仍保持在0.5,100个历元后收敛到1.0

问题是您的标签是
1
2
,而不是0和1。Keras在看到
2
时不会引发错误,但无法预测
2


从所有y值中减去1。作为旁注,在深度学习中,使用1个
神经元
乙状结肠
进行二元分类(0或1)与使用
softmax
的2个类比较是很常见的。最后,使用
binary\u crossentropy
解决二进制分类问题的损失。

注意:如果你想知道真正的原因,请阅读我答案末尾的“更新”部分。在这种情况下,我提到的另外两个原因仅在学习率设置为低值(小于
1e-3
)时有效


我整理了一些代码。它和你的非常相似,但我只是稍微清洗了一下,让它更简单。如您所见,我使用了一个密集层,其中一个单元的最后一层具有
sigmoid
激活功能,只需将优化器从
adam
更改为
rmsprop
(这并不重要,如果您愿意,可以使用
adam
):

将numpy导入为np
随机输入
#生成具有两个特征的随机数据
n_样本=200
n_专长=2
cls0=np.random.uniform(低=0.2,高=0.4,大小=(n_样本,n_专长))
cls1=np.random.uniform(低=0.5,高=0.7,大小=(n个样本,n个专长))
x_列=np.连接((cls0,cls1))
y_序列=np.串联((np.零((n_样本,)),np.一((n_样本,))
#洗牌数据,因为所有负片(即“0”类)都是第一位的
#然后是所有积极因素(即“1类”)
指数=np.arange(x_列形状[0])
np.random.shuffle(索引)
x_列=x_列[指数]
y_列=y_列[指数]
从keras.models导入顺序
从keras.layers导入稠密
模型=顺序()
添加(密集型(2,激活='sigmoid',输入形状=(n_专长,))
model.add(密集型(1,激活='sigmoid'))
model.compile(loss='binary\u crossentropy',
优化器='rmsprop',
指标=[‘准确度’])
model.summary()
model.fit(x_序列,y_序列,历代数=5,批量大小=32,详细度=True)
以下是输出:

层(类型)输出形状参数
=================================================================
密集型_25(密集型)(无,2)6
_________________________________________________________________
致密(致密)(无,1)3
=================================================================
总参数:9
可培训参数:9
不可训练参数:0
_________________________________________________________________
纪元1/5
400/400[============================================================]0秒966us/步-损耗:0.7013-加速度:0.5000
纪元2/5
400/400[===================================================-0s143us/步-损耗:0.6998-加速度:0.5000
纪元3/5
400/400[================================================]0秒137us/步-损耗:0.6986-加速度:0.5000
纪元4/5
400/400[=============================================]0秒149秒/步-损耗:0.6975-加速度:0.5000
纪元5/5
400/400[================================================]秒132us/步-损耗:0.6966-加速度:0.5000
正如你所看到的,准确度从50%一直没有提高。如果将历代的数量增加到50,会怎么样

层(类型)输出形状参数
=================================================================
致密(致密)(无,2)6
_________________________________________________________________
致密(致密)(无,1)3
=================================================================
总参数:9
可培训参数:9
不可训练参数:0
_________________________________________________________________
纪元1/50
400/400[======================================================-0s 1ms/步-损耗:0.6925-加速度:0.5000
纪元2/50
400/400[=========================================================]秒136us/步-损耗:0.6902-附件:0.5000
纪元3/50
400/400[============================================================]0秒133us/步-损耗:0.6884-acc:0.5000
纪元4/50
400/400[======================================================-0s 160us/步-损耗:0.6866-加速度:0.5000
纪元5/50
400/400[=========================================================-0s140us/步-损耗:0.6848-加速度:0.5000
纪元6/50
400/400[================================================]0秒168us/步-损耗:0.6832-加速度:0.5000
纪元7/50
400/400[============================================================]0秒154us/步-损耗:0.6817-加速度:0.5000
纪元8/50
400/400[============================================================]0s 146us/步-损耗:0.6802-加速度:0.5000
纪元9/50
400/400[===============================================================]0秒161us/步-损耗:0.6789-加速度:0.5000
第一纪元