我正在tf中编程一个模型。keras和运行模型。训练集上的evaluate()通常会产生约96%的准确率。我对测试集的评估通常很接近,大约93%。然而,当我手动预测时,模型通常不准确。这是我的代码:
import tensorflow as tf
from tensorflow.keras import layers
import numpy as np
import pandas as pd
!git clone https://github.com/DanorRon/data
%cd data
!ls
batch_size = 100
epochs = 15
alpha = 0.001
lambda_ = 0.001
h1 = 50
train = 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.values
y_train = y_train.values
x_test = x_test.values
y_test = y_test.values
nb_classes = 10
targets = y_train.reshape(-1)
y_train_onehot = np.eye(nb_classes)[targets]
nb_classes = 10
targets = 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/15
49999/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]
模型的输出。predict\u类:
[9 9 0 ... 5 0 5]
打印输出(y\U测试):
[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/255
x_test = x_test.values/255
也不清楚为什么你要求一个784单元的层,因为这实际上是NN的第二层(第一层由input_shape
参数隐式设置-请参阅Keras Sequential模型输入层),它当然不需要为您的784输入特性中的每一个包含一个单元。
更新(评论后):
但为什么MSE对于分类毫无意义?
这是一个理论问题,不完全适合SO;粗略地说,这与我们不使用线性回归进行分类的原因相同——我们使用逻辑回归,两种方法之间的实际区别正是函数损失。Andrew Ng在Coursera广受欢迎的机器学习课程中很好地解释了这一点——参见他的第6.1讲——逻辑回归|YouTube分类(解释从大约3:00开始),以及第4.2节为什么不使用线性回归[进行分类]?(强烈推荐并免费提供)教科书Hastie、Tibshirani和同事的《统计学习导论》。
MSE确实提供了很高的精度,为什么这不重要呢?
如今,几乎任何你扔给MNIST的东西都会“起作用”,这当然既不能使它正确,也不能成为要求更高的数据集的好方法。。。
更新2:
每当我使用交叉熵运行时,准确率只是在10%左右摆动
抱歉,无法复制该行为。。。以Keras MNIST MLP为例,使用您模型的简化版本,即:
model = Sequential()
model.add(Dense(784, activation='linear', input_shape=(784,)))
model.add(Dense(50, activation='relu'))
model.add(Dense(num_classes, activation='softmax'))
model.compile(loss='categorical_crossentropy',
optimizer=SGD(),
metrics=['accuracy'])
仅经过5个阶段,我们就很容易获得约92%的验证准确率:
history = model.fit(x_train, y_train,
batch_size=128,
epochs=5,
verbose=1,
validation_data=(x_test, y_test))
Train on 60000 samples, validate on 10000 samples
Epoch 1/10
60000/60000 [==============================] - 4s - loss: 0.8974 - acc: 0.7801 - val_loss: 0.4650 - val_acc: 0.8823
Epoch 2/10
60000/60000 [==============================] - 4s - loss: 0.4236 - acc: 0.8868 - val_loss: 0.3582 - val_acc: 0.9034
Epoch 3/10
60000/60000 [==============================] - 4s - loss: 0.3572 - acc: 0.9009 - val_loss: 0.3228 - val_acc: 0.9099
Epoch 4/10
60000/60000 [==============================] - 4s - loss: 0.3263 - acc: 0.9082 - val_loss: 0.3024 - val_acc: 0.9156
Epoch 5/10
60000/60000 [==============================] - 4s - loss: 0.3061 - acc: 0.9132 - val_loss: 0.2845 - val_acc: 0.9196
请注意第一个密集层的激活='linear'
,这相当于不指定任何内容,就像在您的情况下一样(正如我所说,实际上您向MNIST抛出的所有内容都将“起作用”)。。。
最后建议:尝试将模型修改为:
model = tf.keras.Sequential()
model.add(layers.Dense(784, activation = 'relu',input_shape=(784,)))
model.add(layers.Dense(h1, activation='relu'))
model.add(layers.Dense(10, activation='softmax'))
为了使用更好的(也是默认的)“glorot\u uniform”
初始值设定项,并删除kernel\u正则化器
参数(它们可能是任何问题的原因-始终从简单开始!)。。。
我理解经典例子的问题 但我无法说服自己以下是有效的还是无效的 我知道'foo(i)'和'i'的求值顺序是不确定的,但是'评估'到底是什么意思?也就是说bar的第二个参数总是42,或者'i'的当前值可以在foo改变它之前被传入吗?
校验者: @飓风 @小瑶 @FAME @v 翻译者: @小瑶 @片刻 @那伊抹微笑 有 3 种不同的 API 用于评估模型预测的质量: Estimator score method(估计器得分的方法): Estimators(估计器)有一个 score(得分) 方法,为其解决的问题提供了默认的 evaluation criterion (评估标准)。 在这个页面上没有相关讨论,但是在每个 esti
问题内容: 我知道Java在这种情况下具有智能/惰性评估: 但是关于: 即使返回true 也被调用? 问题答案: 在Java(和其他类似C的语言)中,这称为 短路评估 。* 是的,在第二个示例中总是被调用。也就是说,除非编译器/ JVM可以确定它没有可观察到的副作用,否则在这种情况下它可以选择进行优化,但是无论如何您都不会注意到它们之间的差异。 两者截然不同; 前者本质上是一种优化技术,而第二种则
本文向大家介绍接口测试质量评估标准是什么?相关面试题,主要包含被问及接口测试质量评估标准是什么?时的应答技巧和注意事项,需要的朋友参考一下 接口表现与接口文档的一致性 请求参数:必选和非必选、长度、字符类型、为空、缺失、组合、重复 返回数据:正常和异常
问题内容: 我想知道JavaScript是否具有C#中的&&运算符之类的“短路”评估。如果没有,我想知道是否有一种合理的解决方法可以采用。 问题答案: 是的,JavaScript具有“短路”评估。
问题内容: 给出以下代码: 如果返回,php解释器是否还会检查以后的条件,例如? 如果是这样,那么为什么它在不需要时会做额外的工作呢? 问题答案: 是的,PHP解释器是“惰性”的,这意味着它将尽可能少地进行比较以评估条件。 如果要验证,请尝试以下操作: