为什么我的深度学习模型会预测非常相似但错误的值

问题描述

因此,过去我做了一些非常基础的监督学习,并决定尝试进行预测性维护,并且由于我是本学科的新手,因此决定观看万维网上的一些教程。经过几个小时的学习,我遇到了这个特定的教程(在下面向下链接),其中使用了来自NASA的数据集(在下面向下链接),该数据集具有来自多个不同引擎的多个值。我进行预测性维护的主要目标是预测某些对象何时会发生故障,因此我们可以通过进行最终维修来查明并避免它。

问题在于,在本教程中,他没有建立模型也不向其提供数据,因此我决定尝试一下,但是尽管准确性接近90%,但结果还是很糟糕。它们不好的原因是,正如本教程所建议的那样,我创建了一个名为RUL(剩余有用寿命)的变量,该变量根据“ RUL”的数量为1或0(小于20则为1,否则为1)。 0)。 RUL是根据循环数进行计算的,因此每个引擎都从循环1开始,其RUL是它达到的最大循环数减去循环数,因此在下一个循环(2)中,RUL将是max_cycle-2。 如果这样做对您有意义,我提前致歉。在下面,您可以找到本教程中提供的所有代码以及我的模型和尝试。

import matplotlib
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from sklearn.model_selection import train_test_split
from keras.models import Sequential
from keras.layers import Dense,Flatten


# http://ti.arc.nasa.gov/c/6/
path = r"C:\Users\Ginger Bread\Desktop\archive\CMAPSSData\train_FD001.txt"
raw_data = pd.read_csv(path,sep=' ',header=None)
print(raw_data.head())

# Changing the label name
raw_data = raw_data[[f for f in range(0,26)]]
raw_data.columns = ['ID','Cycle','OpSet1','OpSet2','OpSet3','SensorMeasure1','SensorMeasure2','SensorMeasure3','SensorMeasure4','SensorMeasure5','SensorMeasure6','SensorMeasure7','SensorMeasure8','SensorMeasure9','SensorMeasure10','SensorMeasure11','SensorMeasure12','SensorMeasure13','SensorMeasure14','SensorMeasure15','SensorMeasure16','SensorMeasure17','SensorMeasure18','SensorMeasure19','SensorMeasure20','SensorMeasure21']
print(raw_data)

# Checking what is the max number of Cycles for each id engine
max_cycles_df = raw_data.groupby(['ID'],sort=False)['Cycle'].max().reset_index().rename(columns={'Cycle':'MaxCycleID'})
print(max_cycles_df.head())

# merge back to original dataset
FD001_df = pd.merge(raw_data,max_cycles_df,how='inner',on='ID')
FD001_df['RUL'] = FD001_df['MaxCycleID'] - FD001_df['Cycle']
print(FD001_df)
print(FD001_df[['Cycle','RUL']])


print('Shape:',FD001_df.shape)
print(list(FD001_df))

# create outcome variable
print(len(FD001_df[FD001_df['RUL'] == 0]))

# plot them
one_engine = []
for i,r in FD001_df.iterrows():
    rul = r['RUL']
    one_engine.append(rul)
    if rul == 0:
        plt.plot(one_engine)
        one_engine = []
plt.show()

# Write to file
FD001_df.to_csv('NASA_Full_FD001.csv',index=None)

# Create a smaller data set for classification
pred_maint_data = FD001_df[['Cycle','RUL']]
print(pred_maint_data.head())


# Create a binary outcome - we'll assume 20 days
# Percent of time RUL at 0
pt0 = len(pred_maint_data[pred_maint_data['RUL'] == 0])/len(pred_maint_data) * 100
print('Percent of time RUL at 0:',np.round(pt0,2),'%')

# create outcome variable of 1 or 0
pred_maint_data['RUL'] = [1 if out < 20 else 0 for out in pred_maint_data['RUL']]

pt0 = np.mean(pred_maint_data['RUL']) * 100
print('Percent of time RUL at 0:','%')
print(pred_maint_data['RUL'].value_counts())

# save to file
pred_maint_data.to_csv('NASA_20_Cycles_Failure_FD001.csv',index=None)

# End of the tutorial Code
# Below this comment,the code was made by me

# Getting the data from a csv file and dividing it into train and test sets

data = pd.read_csv("NASA_20_Cycles_Failure_FD001.csv")

train = data.drop(['RUL','Cycle'],axis=1)
test = data['RUL']
X_train,X_test,y_train,y_test = train_test_split(train,test,test_size=0.2,random_state=2)
print("HERE")
print(X_train)
print("HERE2")
print(y_train)

# Model
model = Sequential()
model.add(Dense(4,init='uniform',input_shape=(4,),activation='relu'))
model.add(Dense(16,activation='relu'))
model.add(Dense(32,activation='relu'))
model.add(Dense(1,activation='sigmoid'))
# Compile model
model.compile(loss='mean_squared_error',optimizer='adam',metrics=['accuracy'])
# Fit the model
history = model.fit(X_train,epochs=3,verbose=1,validation_split=0.2,shuffle=True)

score = model.evaluate(X_test,y_test,verbose=2)
print(score)

print(history.history.keys())

plt.plot(history.history['val_acc'],label='train')
plt.plot(history.history['val_loss'],label='loss')
plt.legend()
plt.show()

# Seeing the predictions
predictions = model.predict(X_test)

print("Predictions")
for i in predictions:
    print(i)
    if i >= 0.5:
        print("ALELUIA")
print("Real values")
for u in y_test:
    print(u)

当值不等于20时,我尝试将RUL的数量更改为1,并且精度也发生了变化,但是预测最终仍几乎是相同的,这使得预测值四舍五入为全0或全1在下面,我将输入每个预测的结果以及实际值(y_test)。

注意:在转换为1或0后,我可能应该将RUL列的名称更改为“ needs fixing”。

Predictions
[0.1050983]
[0.10404325]
[0.10555065]
[0.10555321]
[0.10344189]
[0.10533005]
[0.10478833]
[0.1051653]
[0.10526326]
[0.10516419]
[0.1038975]
[0.10515215]
[0.10531015]
[0.10511505]
[0.10518976]
[0.1050439]
[0.1051843]
[0.10559492]
[0.10387661]
[0.10374805]
[0.10509399]
[0.10515141]
[0.10521074]
[0.1052593]
[0.10540438]
[0.10533711]
[0.10501852]
[0.10463601]
[0.10503829]
[0.10521385]
[0.10441336]
[0.105217]
[0.10531073]
[0.10491394]
[0.10537319]
[0.10523231]
[0.10557146]
[0.1047653]
[0.10525884]
[0.10500285]
[0.10505348]
[0.10541109]
[0.10533073]
[0.10517488]
[0.1050622]
[0.10527248]
[0.1051841]
[0.10544233]
[0.10554202]
[0.10465073]
[0.10464738]
[0.10524271]
[0.10522015]
[0.10502062]
[0.10546359]
[0.10409129]
[0.10522158]
[0.1051973]
[0.10548837]
[0.10525122]
[0.10466116]
[0.10534483]
[0.10547991]
[0.10514109]
[0.10531491]
[0.10518854]
[0.10496807]
[0.10505583]
[0.10516969]
[0.10521539]
[0.10524863]
[0.10527457]
[0.10532214]
[0.10324776]
[0.10544115]
[0.10540842]
[0.10515314]
[0.10515888]
[0.10483669]
[0.10501605]
[0.104861]
[0.10495911]
[0.10525009]
[0.10529111]
[0.10487738]
[0.10509273]
[0.10518468]
[0.10503055]
[0.10417407]
[0.10479013]
[0.10534652]
[0.10522777]
[0.10319146]
[0.10549013]
[0.10530148]
[0.10484377]
[0.10440563]
[0.10472738]
[0.10502187]
[0.10525076]
[0.10510702]
[0.10532416]
[0.10381923]
[0.1054415]
[0.1054302]
[0.10558783]
[0.10514364]
[0.10523658]
[0.10515053]
[0.10526689]
[0.10520654]
[0.10515639]
[0.10531743]
[0.10403327]
[0.10531391]
[0.10477831]
[0.10548837]
[0.10522526]
[0.10505868]
[0.10418756]
[0.1053642]
[0.10524843]
[0.10497409]
[0.10368675]
[0.10495283]
[0.10515259]
[0.10517113]
[0.1049794]
[0.10523032]
[0.10518576]
[0.1050372]
[0.10507836]
[0.10503409]
[0.10540656]
[0.10431397]
[0.10471103]
[0.10531015]
[0.10523356]
[0.10539803]
[0.10527551]
[0.10513147]
[0.10511173]
[0.10527663]
[0.10504944]
[0.10528576]
[0.10536461]
[0.10493658]
[0.10516817]
[0.10531207]
[0.10546369]
[0.10419846]
[0.10411397]
[0.10465484]
[0.10431477]
[0.10501323]
[0.10528364]
[0.10537661]
[0.10482613]
[0.10522176]
[0.10495919]
[0.10519546]
[0.10520439]
[0.10508794]
[0.10462283]
[0.10532165]
[0.10358283]
[0.10522396]
[0.105164]
[0.10544351]
[0.10536326]
[0.10539526]
[0.10498454]
[0.10327268]
[0.10522733]
[0.10537484]
[0.10505765]
[0.10524735]
[0.10499822]
[0.10508626]
[0.10388456]
[0.1051572]
[0.10503815]
[0.10507942]
[0.10505755]
[0.10536408]
[0.105366]
[0.10546079]
[0.10522104]
[0.10485433]
[0.10520129]
[0.10539605]
[0.10529195]
[0.10493235]
[0.10515185]
[0.10532335]
[0.10540719]
[0.10522908]
[0.10535663]
[0.10558803]
[0.10517517]
[0.10549721]
[0.10537575]
[0.10507962]
[0.10530768]
[0.10452699]
[0.10524847]
[0.10516036]
[0.10510545]
[0.10540862]
[0.10508175]
[0.10522414]
[0.10484162]
[0.10526936]
[0.10518522]
[0.10485084]
[0.10538556]
[0.10537019]
[0.10549224]
[0.10515653]
[0.10519943]
[0.10512082]
[0.10544203]
[0.10487756]
[0.10497619]
[0.10518141]
[0.10533778]
[0.10509621]
[0.10531738]
[0.10505059]
[0.10514385]
[0.10523034]
[0.10531139]
[0.10385931]
[0.1056235]
[0.10516278]
[0.10499334]
[0.10527273]
[0.10524946]
[0.10525396]
[0.10490155]
[0.10441212]
[0.10487241]
[0.10538799]
[0.1049312]
[0.10491467]
[0.10517243]
[0.10535877]
[0.10543416]
[0.10509314]
[0.1049196]
[0.10501852]
Real values
0
0
0
0
1
0
0
0
0
0
0
0
0
0
0
0
0
0
1
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
1
1
0
0
0
0
0
0
0
0
1
0
0
1
0
0
0
0
0
0
0
0
0
0
0
0
1
0
0
0
0
0
0
0
0
0
0
0
0
0
0
1
0
1
0
0
0
0
0
0
0
0
0
1
0
0
1
0
0
0
0
0
0
0
1
0
0
0
0
0
0
0
0
0
1
0
0
0
0
0
0
1
0
0
1
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
1
0
0
0
0
0
1
0
1
0
0
0
0
0
0
1
0
0
0
0
0
1
1
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
1
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
1
0
0
0
0
0
1
0
0
0
0
0
0
0
0
0
1
0
0
0
0
0
1
0
1
0
0
0
0
0
0
0
0
0
0

如您所见,它始终为我提供接近0的数字,这使该模型似乎具有较高的准确性,因为y_test中有很多0,但在最重要的一个(告诉我什么时候为1)中却失败了发动机需要修理!如果您知道发生了什么并想帮助我,我将非常感激!

谢谢。

注2:所显示的预测和y_test值的数量急剧减少,以适应正文。

有用的链接

Youtube Video - Tutorial

Raw Code - Tutorial

Dataset - NASA

版本:

Windows 10 Keras 2.2.0 Tensorflow 1.12.0

解决方法

目前,您正在使用'mean_squared_error'损失。当您尝试预测模拟数字时,MSE非常有用。但是,这里的基本事实是二进制预测:0或1。在这种情况下,您应该尝试预测类别,而不是真实值。为此,您需要binary cross-entropy。因此,将loss='mean_squared_error'更改为loss='binary_crossentropy'

此外,似乎您可能没有对它进行足够长时间的培训,并且批处理量太大。如果您未在model.fit中指定批处理大小,那么我相信它默认为等于整个数据集的批处理大小。这意味着模型的参数每个时期仅更新一次。目前,您已将其设置为仅训练3个纪元。我要尝试的下一件事是将批处理大小设置为32,然后将其运行更多的时期,例如可能是10到100,具体取决于数据集的大小。所以你应该有类似的东西

history = model.fit(X_train,y_train,epochs=30,batch_size=32,...