我使用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'
对于每个预测的类,我将使用实际的标签来对付它,然后计算正确的猜测/总计示例,这些示例应等同于validate()函数的准确性。这是代码:
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
从以下函数获取馈给评价()的数据:
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()的工作,而valuate()一次处理了整个数据集,但不会有任何区别。怎么会这样?
更新1:似乎问题出在我准备数据的方式上。在使用predict()的情况下,我使用我发布的最后代码块一次仅对每个文件转换一行,而在馈送evaluate()时,我使用报告的其他函数对整个文件进行了转换。为什么要与众不同?在我看来,我正在应用完全相同的转换,唯一的区别是转换的行数。
最佳答案
这个问题已经被回答here
评估模型时会发生什么,因为损失函数是categorical_crossentropy,所以metrics=['accuracy']
会计算categorical_accuracy。
但是predict的默认设置为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不匹配为0
binary_accuracy = 80%
,即使1个输出与其他80%的输出都不匹配也是如此,因此准确性为80%
关于python - Keras预报()比评估()返回更好的准确性,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57862459/