我使用 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/