我在 tf.keras 中编写了一个模型,在训练集上运行 model.evaluate() 通常会得到大约 96% 的准确率。在测试集上的评估结果通常也很接近,大约是 93%。然而,当我手动进行预测时,模型的预测通常不准确。这是我使用的代码:
import tensorflow as tffrom tensorflow.keras import layersimport numpy as npimport pandas as pd!git clone https://github.com/DanorRon/data%cd data!lsbatch_size = 100epochs = 15alpha = 0.001lambda_ = 0.001h1 = 50train = pd.read_csv('/content/data/mnist_train.csv.zip')test = pd.read_csv('/content/data/mnist_test.csv.zip')train = train.loc['1':'5000', :]test = test.loc['1':'2000', :]train = train.sample(frac=1).reset_index(drop=True)test = test.sample(frac=1).reset_index(drop=True)x_train = train.loc[:, '1x1':'28x28']y_train = train.loc[:, 'label']x_test = test.loc[:, '1x1':'28x28']y_test = test.loc[:, 'label']x_train = x_train.valuesy_train = y_train.valuesx_test = x_test.valuesy_test = y_test.valuesnb_classes = 10targets = y_train.reshape(-1)y_train_onehot = np.eye(nb_classes)[targets]nb_classes = 10targets = y_test.reshape(-1)y_test_onehot = np.eye(nb_classes)[targets]model = tf.keras.Sequential()model.add(layers.Dense(784, input_shape=(784,), kernel_initializer='random_uniform', bias_initializer='zeros'))model.add(layers.Dense(h1, activation='relu', kernel_regularizer=tf.keras.regularizers.l2(lambda_), kernel_initializer='random_uniform', bias_initializer='zeros'))model.add(layers.Dense(10, activation='softmax', kernel_regularizer=tf.keras.regularizers.l2(lambda_), kernel_initializer='random_uniform', bias_initializer='zeros'))model.compile(optimizer='SGD', loss = 'mse', metrics = ['categorical_accuracy'])model.fit(x_train, y_train_onehot, epochs=epochs, batch_size=batch_size)model.evaluate(x_test, y_test_onehot, batch_size=batch_size)prediction = model.predict_classes(x_test)print(prediction)print(y_test[1:])
我听说很多人遇到这个问题时,通常是数据输入的问题。但在这里我看不出数据输入有什么问题,因为它几乎总是预测错误(错误率和你随机预测的期望值差不多)。我该如何解决这个问题呢?
编辑:以下是具体结果:
最后一次训练步骤:
Epoch 15/1549999/49999 [==============================] - 3s 70us/sample - loss: 0.0309 - categorical_accuracy: 0.9615
评估输出:
2000/2000 [==============================] - 0s 54us/sample - loss: 0.0352 - categorical_accuracy: 0.9310[0.03524150168523192, 0.931]
来自 model.predict_classes 的输出:
[9 9 0 ... 5 0 5]
来自 print(y_test) 的输出:
[9 0 0 7 6 8 5 1 3 2 4 1 4 5 8 4 9 2 4]
回答:
首先,你的损失函数选择错误:你处于多类分类设置中,而你使用的是适合回归而非分类的损失函数(MSE)。
请将模型编译改为:
model.compile(loss='categorical_crossentropy', optimizer='SGD', metrics=['accuracy'])
参见 Keras 的 MNIST MLP 示例 以确认,并查看我在 当损失为均方误差(MSE)时,Keras 中定义准确率的函数是什么? 的回答以获取更多细节(尽管这里你实际上遇到了相反的问题,即在分类设置中使用了回归损失)。
此外,不清楚你使用的 MNIST 变体是否已经标准化;如果没有,你应该自己进行标准化:
x_train = x_train.values/255x_test = x_test.values/255
也不清楚你为什么需要一个 784 单元的层,因为这实际上是你神经网络的第二层(第一层是由 input_shape
参数隐式设置的 – 参见 Keras Sequential 模型输入层),并且它肯定不需要为你 784 个输入特征中的每一个都包含一个单元。