python - Keras的predict()返回比evaluate()更好的准确度

标签 python numpy tensorflow machine-learning keras

我使用 Keras 设置了一个模型,然后在包含 3 个记录的数据集上对其进行训练,最后使用评估()和预测()测试了生成的模型,对这两个函数使用相同的测试集(测试集具有100 条记录,并且没有任何训练集的记录(考虑到两个数据集的大小)。 该数据集由 5 个文件组成,其中 4 个文件代表不同的温度传感器,每分钟收集 60 个测量值(每行包含 60 个测量值),而最后一个文件包含我想要预测的类标签(特别是, 3 类:3、20 或 100)。

这是我正在使用的模型:

n_sensors, t_periods = 4, 60

model = Sequential()

model.add(Conv1D(100, 6, activation='relu', input_shape=(t_periods, n_sensors)))

model.add(Conv1D(100, 6, activation='relu'))

model.add(MaxPooling1D(3))

model.add(Conv1D(160, 6, activation='relu'))

model.add(Conv1D(160, 6, activation='relu'))

model.add(GlobalAveragePooling1D())

model.add(Dropout(0.5))

model.add(Dense(3, activation='softmax'))

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

我训练的: self.model.fit(X_train, y_train, batch_size=3, epochs=5, verbose=1)

然后我使用评估: self.model.evaluate(x_test, y_test, verbose=1)

并预测:

predictions = self.model.predict(data)
result = np.where(predictions[0] == np.amax(predictions[0]))
if result[0][0] == 0:
    return '3'
elif result[0][0] == 1:
    return '20'
else:
    return '100'
对于每个预测的类别,我将其与实际标签进行比较,然后计算正确的猜测/总示例,这应该相当于评估()函数的准确性。代码如下:

correct = 0
for profile in self.profile_file: #profile_file is an opened file
    ts1 = self.ts1_file.readline()
    ts2 = self.ts2_file.readline()
    ts3 = self.ts3_file.readline()
    ts4 = self.ts4_file.readline()
    data = ts1, ts2, ts3, ts4
    test_data = self.dl.transform(data) # see the last block of code I posted
    prediction = self.model.predict(test_data)
    if prediction == label:
       correct += 1
acc = correct / 100 # 100 is the number of total examples

提供给evaluate()的数据取自此函数:

label = pd.read_csv(os.path.join(self.testDir, 'profile.txt'), sep='\t', header=None)
label = np_utils.to_categorical(label[0].factorize()[0])
data = [os.path.join(self.testDir,'TS2.txt'),os.path.join(self.testDir, 'TS1.txt'),os.path.join(self.testDir,'TS3.txt'),os.path.join(self.testDir, 'TS4.txt')]
df = pd.DataFrame()
for txt in data:
    read_df = pd.read_csv(txt, sep='\t', header=None)
    df = df.append(read_df)
df = df.apply(self.__predict_scale)
df = df.sort_index().values.reshape(-1,4,60).transpose(0,2,1)
return df, label

虽然提供给 Predict() 的数据是从另一个数据中获取的:

df = pd.DataFrame()
for txt in data: # data 
    read_df = pd.read_csv(StringIO(txt), sep='\t', header=None)
    df = df.append(read_df)
df = df.apply(self.__predict_scale)
df = df.sort_index().values.reshape(-1,4,60).transpose(0,2,1)
return df

evaluate() 和predict() 产生的准确度总是不同的:特别是,我注意到的最大差异是evaluate() 的准确度为78%,而predict() 的准确度为95%。这两个函数之间的唯一区别是,我让predict()一次处理一个示例,而evaluate()一次处理整个数据集,但它应该不会产生任何差异。怎么可能?

更新1:看来问题在于我如何准备数据。在使用 Predict() 的情况下,我使用我发布的最后一段代码一次仅转换每个文件中的一行,而在提供评估()时,我使用报告的其他函数转换整个文件。为什么应该有所不同?在我看来,我正在应用完全相同的转换,唯一的区别在于转换的行数。

最佳答案

这个问题已经得到解答here

当您评估模型时,由于您的损失函数是 categorical_crossentropy,因此 metrics=['accuracy'] 会计算 categorical_accuracy。

但是预测的默认设置为binary_accuracy。

因此,本质上,您正在使用评估来计算分类准确性,并使用预测来计算二进制准确性。这就是它们如此不同的原因。

categorical_accuracy和binary_accuracy之间的区别在于,categorical_accuracy检查所有输出是否与您的y_test匹配,而binary_accuracy检查您的每个输出是否与您的y_test匹配。

示例(单行):

prediction = [0,0,1,1,0]
y_test = [0,0,0,1,0]

categorical_accuracy = 0% 

由于 1 个输出与 categorical_accuracy 不匹配,因此 categorical_accuracy 为 0

binary_accuracy = 80% 

即使 1 个输出与其余 80% 的输出不匹配,因此准确度为 80%

关于python - Keras的predict()返回比evaluate()更好的准确度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57862459/

相关文章:

python - 从 CSV 文件构建列表列表

python - 如何使用 keras 将数组 reshape 为 3d

Python re.findall 正则表达式和文本处理

tensorflow - 在使用 seq2seq 时,tf.nn.dynamic_rnn 如何处理不同长度的输入?

Python Beautiful Soup 网页抓取特定数字

python - 为什么 np.float ('nan' ) 会导致字典出现问题,但 math.nan 不会?

python - 将数据点分成簇并取每个簇的平均值

python - 使用 == 比较 numpy 数组的规则是什么?

python - 不平衡数据和加权交叉熵

python - keras 'multi output' 中 'raw' 与 'flow_from_dataframe' 之间的区别 0x104567910