Python Keras精度和实际精度正好相反

Python Keras精度和实际精度正好相反,python,machine-learning,keras,neural-network,artificial-intelligence,Python,Machine Learning,Keras,Neural Network,Artificial Intelligence,我正在学习神经网络,目前正在使用Keras库在CFAR-10数据集上实现对象分类。以下是我对Keras定义的神经网络的定义: # Define the model and train it model = Sequential() model.add(Dense(units = 60, input_dim = 1024, activation = 'relu')) model.add(Dense(units = 50, activation = 'relu')) model.add(Dense

我正在学习神经网络,目前正在使用Keras库在CFAR-10数据集上实现对象分类。以下是我对Keras定义的神经网络的定义:

# Define the model and train it
model = Sequential()

model.add(Dense(units = 60, input_dim = 1024, activation = 'relu'))
model.add(Dense(units = 50, activation = 'relu'))
model.add(Dense(units = 60, activation = 'relu'))
model.add(Dense(units = 70, activation = 'relu'))
model.add(Dense(units = 30, activation = 'relu'))
model.add(Dense(units = 10, activation = 'sigmoid'))

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

model.fit(X_train, y_train, epochs=50, batch_size=10000)
因此,我有一个输入层,输入尺寸为1024或(1024,)(每个32*32*3的图像首先转换为灰度,得到32*32的尺寸)、5个隐藏层和1个输出层,如上面代码中定义的

当我对我的模型进行50多个时代的训练时,我得到了
0.9
或90%的准确率。另外,当我使用测试数据集对其进行评估时,我得到了大约90%的准确率。以下是评估模型的代码行:

print (model.evaluate(X_test, y_test))
这将打印以下损失和准确性:

[1.611809492111206, 0.8999999761581421]
但是当我通过对每个测试数据图像进行预测来手动计算精度时,我得到了大约11%的精度(这几乎与随机进行预测的概率相同)。以下是我手动计算的代码:

wrong = 0

for x, y in zip(X_test, y_test):
  if not (np.argmax(model.predict(x.reshape(1, -1))) == np.argmax(y)):
    wrong += 1

print (wrong)
这打印出10000个错误预测中的9002个。那么我在这里错过了什么?为什么这两种精度正好相反(100-89=11%)?任何直观的解释都会有帮助!谢谢

编辑:

以下是我处理数据集的代码:

# Process the training and testing data and make in Neural Network comfortable

# convert given colored image to grayscale
def rgb2gray(rgb):
  return np.dot(rgb, [0.2989, 0.5870, 0.1140])

X_train, y_train, X_test, y_test = [], [], [], []

def process_batch(batch_path, is_test = False):
  batch = unpickle(batch_path)
  imgs = batch[b'data']
  labels = batch[b'labels']


  for img in imgs:
    img = img.reshape(3,32,32).transpose([1, 2, 0])
    img = rgb2gray(img)
    img = img.reshape(1, -1)
    if not is_test:
      X_train.append(img)
    else:
      X_test.append(img)

  for label in labels:
    if not is_test:
      y_train.append(label)
    else:
      y_test.append(label)

process_batch('cifar-10-batches-py/data_batch_1')
process_batch('cifar-10-batches-py/data_batch_2')
process_batch('cifar-10-batches-py/data_batch_3')
process_batch('cifar-10-batches-py/data_batch_4')
process_batch('cifar-10-batches-py/data_batch_5')

process_batch('cifar-10-batches-py/test_batch', True)

number_of_classes = 10
number_of_batches = 5
number_of_test_batch = 1

X_train = np.array(X_train).reshape(meta_data[b'num_cases_per_batch'] * number_of_batches, -1)
print ('Shape of training data: {0}'.format(X_train.shape))

# create labels to one hot format
y_train = np.array(y_train)

y_train = np.eye(number_of_classes)[y_train]
print ('Shape of training labels: {0}'.format(y_train.shape))


# Process testing data

X_test = np.array(X_test).reshape(meta_data[b'num_cases_per_batch'] * number_of_test_batch, -1)
print ('Shape of testing data: {0}'.format(X_test.shape))

# create labels to one hot format
y_test = np.array(y_test)

y_test = np.eye(number_of_classes)[y_test]
print ('Shape of testing labels: {0}'.format(y_test.shape))

发生这种情况的原因是由于您正在使用的损失函数。您使用的是二进制交叉熵,您应该使用分类交叉熵作为损失。二进制文件仅用于两个标签的问题,但由于CIFAR-10,这里有10个标签

当您显示精度度量时,它实际上会误导您,因为它显示的是二进制分类性能。解决方案是通过选择
categorical\u crossentropy
重新训练模型

这篇文章有更多的细节:

相关-这篇文章回答了一个不同的问题,但答案基本上是你的问题是什么:

编辑 你提到你的模型的准确率徘徊在10%左右,在你的评论中没有改善。在检查Colab笔记本时,当您更改为分类交叉熵时,您似乎没有对数据进行标准化。由于像素值最初是无符号8位整数,因此在创建训练集时,它会将值提升为浮点值,但由于数据的动态范围,神经网络很难学习正确的权重。当您尝试更新权重时,梯度非常小,基本上没有更新,因此网络的性能就像随机机会一样。解决方案是,在继续之前,只需将培训和测试数据集除以255即可:

X_train /= 255.0
X_test /= 255.0
这将转换数据,使动态范围从
[0255]
扩展到
[0,1]
。由于较小的动态范围,您的模型将更容易进行时间训练,这将有助于渐变传播,并且在规格化之前不会因为较大的比例而消失。由于原始模型规范有大量密集层,由于数据的动态范围,梯度更新很可能会消失,这就是最初性能较差的原因

当我运行你的笔记本时,我得到37%的准确率。这对于CIFAR-10来说并不意外,它只是一个完全连接/密集的网络。另外,当你现在运行你的笔记本时,错误例子的准确率和分数是匹配的

如果您想提高准确性,我有几个建议:

  • 实际上包括颜色信息。CIFAR-10中的每个物体都有不同的颜色轮廓,这有助于区分
  • 添加卷积层。我不确定您在学习中的位置,但卷积层有助于学习和提取图像中的正确特征,以便将最佳特征呈现给密集层,以便根据这些特征进行分类提高准确性。现在,您正在对原始像素进行分类,这是不可取的,因为它们可能有多嘈杂,或者由于不受约束的情况(旋转、平移、倾斜、缩放等)

  • 我想你是对的,我刚刚意识到了这一点,并对它进行了分类交叉熵训练,现在我得到了10%的准确率,这与我的计算相符。但是你知道为什么精确度太低吗?@Kaushal28请更新你的帖子,特别是你如何加载数据集,以及你如何重塑数据集,使其适合前馈密集型网络。谢谢!更新了问题。如果代码写得不好,请原谅,因为这是我第一次尝试训练神经网络和处理数据集。让我分享我的整个笔记本。谢谢所有的帮助!!