DDD*_*DDD 8 python numpy machine-learning keras tensorflow
我使用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'])
Run Code Online (Sandbox Code Playgroud)
我训练的:
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'
Run Code Online (Sandbox Code Playgroud)
对于每个预测的类,我将使用实际的标签来对付它,然后计算正确的猜测/总计示例,这些示例应等效于评估()函数的准确性。这是代码:
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
Run Code Online (Sandbox Code Playgroud)
从此函数获取提供给评价()的数据:
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
Run Code Online (Sandbox Code Playgroud)
馈送给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
Run Code Online (Sandbox Code Playgroud)
由Evaluate()和predict()产生的精度始终是不同的:特别是,我注意到的最大差异是,Evaluate()的精度为78%,而predict()的精度为95%。这两个函数之间的唯一区别是,我使一次一次在一个示例上运行了predict(),而evaluate()一次处理了整个数据集,但不会有任何区别。怎么会这样?
更新1:似乎问题出在我如何准备数据。在使用predict()的情况下,我使用我发布的最后一个代码块一次只转换每个文件中的一行,而在馈送evaluate()时,我使用报告的其他函数来转换整个文件。为什么要与众不同?在我看来,我正在应用完全相同的转换,唯一的区别是转换的行数。
这个问题已经在这里得到回答
当您评估模型时会发生什么,因为您的损失函数是 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%
Run Code Online (Sandbox Code Playgroud)
由于 1 个输出与 categorical_accuracy 不匹配,因此为 0
binary_accuracy = 80%
Run Code Online (Sandbox Code Playgroud)
即使 1 个输出与其余 80% 的输出不匹配,但仍匹配,因此准确度为 80%
归档时间: |
|
查看次数: |
311 次 |
最近记录: |