Без опису

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745
  1. # Csar Fdez, UdL, 2025
  2. # Changes from v1: Normalization
  3. # IN v1, each failure type has its own normalization pars (mean and stdevs)
  4. # In v2, mean and stdev is the same for all data
  5. # v3.py trains the models looping in TIME_STEPS (4,8,12,16,20,24,....) finding the optimal Threshold factor
  6. import pandas as pd
  7. import matplotlib.pyplot as plt
  8. import datetime
  9. import numpy as np
  10. import keras
  11. import os.path
  12. from keras import layers
  13. from optparse import OptionParser
  14. import copy
  15. import pickle
  16. parser = OptionParser()
  17. parser.add_option("-t", "--train", dest="train", help="Trains the models (false)", default=False, action="store_true")
  18. parser.add_option("-o", "--optimizetf", dest="optimizetf", help="Optimzes Threshold Factor (false)", default=False, action="store_true")
  19. parser.add_option("-n", "--timesteps", dest="timesteps", help="TIME STEPS ", default=12)
  20. parser.add_option("-f", "--thresholdfactor", dest="TF", help="Threshold Factor ", default=1.4)
  21. (options, args) = parser.parse_args()
  22. # data files arrays. Index:
  23. # 0. No failure
  24. # 1. Blocked evaporator
  25. # 2. Full Blocked condenser
  26. # 3. Partial Blocked condenser
  27. # 4 Fan condenser not working
  28. # 5. Open door
  29. NumberOfFailures=4 # So far, we have only data for the first 4 types of failures
  30. datafiles=[]
  31. for i in range(NumberOfFailures+1):
  32. datafiles.append([])
  33. # Next set of ddata corresponds to Freezer, SP=-26
  34. datafiles[0]=['2024-08-07_5_','2024-08-08_5_','2025-01-25_5_','2025-01-26_5_','2025-01-27_5_','2025-01-28_5_']
  35. datafiles[1]=['2024-12-11_5_', '2024-12-12_5_','2024-12-13_5_','2024-12-14_5_','2024-12-15_5_']
  36. #datafiles[1]=['2024-12-17_5_','2024-12-16_5_','2024-12-11_5_', '2024-12-12_5_','2024-12-13_5_','2024-12-14_5_','2024-12-15_5_'] # This have transitions
  37. datafiles[2]=['2024-12-18_5_','2024-12-19_5_']
  38. datafiles[3]=['2024-12-21_5_','2024-12-22_5_','2024-12-23_5_','2024-12-24_5_','2024-12-25_5_','2024-12-26_5_']
  39. datafiles[4]=['2024-12-28_5_','2024-12-29_5_','2024-12-30_5_','2024-12-31_5_','2025-01-01_5_']
  40. #datafiles[4]=['2024-12-27_5_','2024-12-28_5_','2024-12-29_5_','2024-12-30_5_','2024-12-31_5_','2025-01-01_5_'] # This have transitions
  41. #datafiles[4]=[]
  42. # Features suggested by Xavier
  43. # Care with 'tc s3' because on datafiles[0] is always nulll
  44. # Seems to be incoropored in new tests
  45. #r1s5 supply air flow temperature
  46. #r1s1 inlet evaporator temperature
  47. #r1s4 condenser outlet
  48. # VAriables r1s4 and pa1 apiii may not exists in cloud controlers
  49. features=['r1 s1','r1 s4','r1 s5','pa1 apiii']
  50. features=['r1 s1','r1 s4','r1 s5']
  51. featureNames={}
  52. featureNames['r1 s1']='$T_{evap}$'
  53. featureNames['r1 s4']='$T_{cond}$'
  54. featureNames['r1 s5']='$T_{air}$'
  55. featureNames['pa1 apiii']='$P_{elec}$'
  56. unitNames={}
  57. unitNames['r1 s1']='$(^{o}C)$'
  58. unitNames['r1 s4']='$(^{o}C)$'
  59. unitNames['r1 s5']='$(^{o}C)$'
  60. unitNames['pa1 apiii']='$(W)$'
  61. #features=['r1 s1','r1 s2','r1 s3','r1 s4','r1 s5','r1 s6','r1 s7','r1 s8','r1 s9','r1 s10','r2 s1','r2 s2','r2 s3','r2 s4','r2 s5','r2 s6','r2 s7','r2 s8','r2 s9','pa1 apiii','tc s1','tc s2']
  62. #features=['r2 s2', 'tc s1','r1 s10','r1 s6','r2 s8']
  63. NumFeatures=len(features)
  64. df_list=[]
  65. for i in range(NumberOfFailures+1):
  66. df_list.append([])
  67. for i in range(NumberOfFailures+1):
  68. dftemp=[]
  69. for f in datafiles[i]:
  70. print(" ", f)
  71. #df1 = pd.read_csv('./data/'+f+'.csv', parse_dates=['datetime'], dayfirst=True, index_col='datetime')
  72. df1 = pd.read_csv('./data/'+f+'.csv')
  73. dftemp.append(df1)
  74. df_list[i]=pd.concat(dftemp)
  75. # subsampled to 5' = 30 * 10"
  76. # We consider smaples every 5' because in production, we will only have data at this frequency
  77. subsamplingrate=30
  78. dataframe=[]
  79. for i in range(NumberOfFailures+1):
  80. dataframe.append([])
  81. for i in range(NumberOfFailures+1):
  82. datalength=df_list[i].shape[0]
  83. dataframe[i]=df_list[i].iloc[range(0,datalength,subsamplingrate)][features]
  84. dataframe[i].reset_index(inplace=True,drop=True)
  85. dataframe[i].dropna(inplace=True)
  86. # Train data is first 2/3 of data
  87. # Test data is: last 1/3 of data
  88. dataTrain=[]
  89. dataTest=[]
  90. for i in range(NumberOfFailures+1):
  91. dataTrain.append(dataframe[i].values[0:int(dataframe[i].shape[0]*2/3),:])
  92. dataTest.append(dataframe[i].values[int(dataframe[i].shape[0]*2/3):,:])
  93. # Calculate means and stdev
  94. a=dataTrain[0]
  95. for i in range(1,NumberOfFailures+1):
  96. a=np.vstack((a,dataTrain[i]))
  97. means=a.mean(axis=0)
  98. stdevs=a.std(axis=0)
  99. def normalize2(train,test):
  100. return( (train-means)/stdevs, (test-means)/stdevs )
  101. dataTrainNorm=[]
  102. dataTestNorm=[]
  103. for i in range(NumberOfFailures+1):
  104. dataTrainNorm.append([])
  105. dataTestNorm.append([])
  106. for i in range(NumberOfFailures+1):
  107. (dataTrainNorm[i],dataTestNorm[i])=normalize2(dataTrain[i],dataTest[i])
  108. def plotData():
  109. fig, axes = plt.subplots(
  110. nrows=NumberOfFailures+1, ncols=2, figsize=(15, 20), dpi=80, facecolor="w", edgecolor="k",sharex=True
  111. )
  112. for i in range(NumberOfFailures+1):
  113. axes[i][0].plot(np.concatenate((dataTrainNorm[i][:,0],dataTestNorm[i][:,0])),label="Fail "+str(i)+", feature 0")
  114. axes[i][1].plot(np.concatenate((dataTrainNorm[i][:,1],dataTestNorm[i][:,1])),label="Fail "+str(i)+", feature 1")
  115. #axes[1].legend()
  116. #axes[0].set_ylabel(features[0])
  117. #axes[1].set_ylabel(features[1])
  118. plt.show()
  119. #plotData()
  120. #exit(0)
  121. NumFilters=64
  122. KernelSize=7
  123. DropOut=0.2
  124. ThresholdFactor=1.4
  125. def create_sequences(values, time_steps):
  126. output = []
  127. for i in range(len(values) - time_steps + 1):
  128. output.append(values[i : (i + time_steps)])
  129. return np.stack(output)
  130. def AtLeastOneTrue(x):
  131. for i in range(NumFeatures):
  132. if x[i]:
  133. return True
  134. return False
  135. def anomalyMetric(th,ts,testList): # first of list is non failure data
  136. # FP, TP: false/true positive
  137. # TN, FN: true/false negative
  138. # Sensitivity (recall): probab failure detection if data is fail: TP/(TP+FN)
  139. # Specificity: true negative ratio given data is OK: TN/(TN+FP)
  140. # Accuracy: Rate of correct predictions: (TN+TP)/(TN+TP+FP+FN)
  141. # Precision: Rate of positive results: TP/(TP+FP)
  142. # F1-score: predictive performance measure: 2*Precision*Sensitity/(Precision+Sensitity)
  143. # F2-score: predictive performance measure: 2*Specificity*Sensitity/(Specificity+Sensitity)
  144. x_test = create_sequences(testList[0],ts)
  145. x_test_pred = model.predict(x_test)
  146. test_mae_loss = np.mean(np.abs(x_test_pred - x_test), axis=1)
  147. anomalies = test_mae_loss > th
  148. count=0
  149. for i in range(anomalies.shape[0]):
  150. if AtLeastOneTrue(anomalies[i]):
  151. count+=1
  152. FP=count
  153. TN=anomalies.shape[0]-count
  154. count=0
  155. TP=np.zeros((NumberOfFailures))
  156. FN=np.zeros((NumberOfFailures))
  157. Sensitivity=np.zeros((NumberOfFailures))
  158. Precision=np.zeros((NumberOfFailures))
  159. for i in range(1,len(testList)):
  160. x_test = create_sequences(testList[i],ts)
  161. x_test_pred = model.predict(x_test)
  162. test_mae_loss = np.mean(np.abs(x_test_pred - x_test), axis=1)
  163. anomalies = test_mae_loss > th
  164. count=0
  165. for j in range(anomalies.shape[0]):
  166. if AtLeastOneTrue(anomalies[j]):
  167. count+=1
  168. TP[i-1] = count
  169. FN[i-1] = anomalies.shape[0]-count
  170. Sensitivity[i-1]=TP[i-1]/(TP[i-1]+FN[i-1])
  171. Precision[i-1]=TP[i-1]/(TP[i-1]+FP)
  172. GlobalSensitivity=TP.sum()/(TP.sum()+FN.sum())
  173. Specificity=TN/(TN+FP)
  174. Accuracy=(TN+TP.sum())/(TN+TP.sum()+FP+FN.sum())
  175. GlobalPrecision=TP.sum()/(TP.sum()+FP)
  176. F1Score= 2*GlobalPrecision*GlobalSensitivity/(GlobalPrecision+GlobalSensitivity)
  177. F2Score = 2*Specificity*GlobalSensitivity/(Specificity+GlobalSensitivity)
  178. print("Sensitivity: ",Sensitivity)
  179. print("Global Sensitivity: ",GlobalSensitivity)
  180. #print("Precision: ",Precision)
  181. #print("Global Precision: ",GlobalPrecision)
  182. print("Specifity: ",Specificity)
  183. #print("Accuracy: ",Accuracy)
  184. #print("F1Score: ",F1Score)
  185. print("F2Score: ",F2Score)
  186. #print("FP: ",FP)
  187. #return Sensitivity+Specifity
  188. return F2Score
  189. FScoreHash={}
  190. threshold={}
  191. def getFScore(timestep,datalist):
  192. FScoreHash[timestep]=[]
  193. # plots FSCore as a function of Threshold Factor
  194. tf=0.3
  195. while tf<8:
  196. th=threshold[timestep]*tf
  197. r=anomalyMetric(th,timestep,datalist)
  198. FScoreHash[timestep].append([tf,r])
  199. if tf<2:
  200. tf+=0.1
  201. else:
  202. tf+=0.5
  203. def plotFScore(FS):
  204. plt.rcParams.update({'font.size': 16})
  205. fig, axes = plt.subplots(nrows=1, ncols=1, figsize=(14, 10), dpi=80, facecolor="w", edgecolor="k")
  206. for k in FS.keys():
  207. ar=np.array((FS[k]))
  208. axes.plot(ar[:,0],ar[:,1],label="$ns=$"+str(k),linewidth=3)
  209. axes.set_xlabel("Threshold factor ($TF$)")
  210. axes.set_ylabel("FScore")
  211. axes.legend()
  212. axes.grid()
  213. s='['
  214. for i in range(len(features)):
  215. s+=featureNames[features[i]]
  216. if i < len(features)-1:
  217. s+=', '
  218. s+=']'
  219. plt.title(s)
  220. plt.show()
  221. def listToString(l):
  222. r=''
  223. for i in l:
  224. r+=str(i)
  225. return(r.replace(' ',''))
  226. if options.train:
  227. for timesteps in range(4,21,4):
  228. x_train=[]
  229. for i in range(NumberOfFailures+1):
  230. x_train.append(create_sequences(dataTrainNorm[i],timesteps))
  231. model = keras.Sequential(
  232. [
  233. layers.Input(shape=(x_train[0].shape[1], x_train[0].shape[2])),
  234. layers.Conv1D(
  235. filters=NumFilters,
  236. kernel_size=KernelSize,
  237. padding="same",
  238. strides=2,
  239. activation="relu",
  240. ),
  241. layers.Dropout(rate=DropOut),
  242. layers.Conv1D(
  243. filters=int(NumFilters/2),
  244. kernel_size=KernelSize,
  245. padding="same",
  246. strides=2,
  247. activation="relu",
  248. ),
  249. layers.Conv1DTranspose(
  250. filters=int(NumFilters/2),
  251. kernel_size=KernelSize,
  252. padding="same",
  253. strides=2,
  254. activation="relu",
  255. ),
  256. layers.Dropout(rate=DropOut),
  257. layers.Conv1DTranspose(
  258. filters=NumFilters,
  259. kernel_size=KernelSize,
  260. padding="same",
  261. strides=2,
  262. activation="relu",
  263. ),
  264. layers.Conv1DTranspose(filters=x_train[i].shape[2], kernel_size=KernelSize, padding="same"),
  265. ]
  266. )
  267. model.compile(optimizer=keras.optimizers.Adam(learning_rate=0.001), loss="mse")
  268. model.summary()
  269. path_checkpoint="model_noclass_v2_"+str(timesteps)+listToString(features)+"_checkpoint.weights.h5"
  270. es_callback=keras.callbacks.EarlyStopping(monitor="val_loss", min_delta=0, patience=15)
  271. modelckpt_callback=keras.callbacks.ModelCheckpoint( monitor="val_loss", filepath=path_checkpoint, verbose=1, save_weights_only=True, save_best_only=True,)
  272. history=model.fit( x_train[0], x_train[0], epochs=400, batch_size=128, validation_split=0.3, callbacks=[ es_callback, modelckpt_callback ],)
  273. x_train_pred=model.predict(x_train[0])
  274. train_mae_loss=np.mean(np.abs(x_train_pred - x_train[0]), axis=1)
  275. threshold[timesteps]=np.max(train_mae_loss,axis=0)
  276. file = open('threshold'+listToString(features)+'.pk', 'wb')
  277. pickle.dump(threshold, file)
  278. file.close()
  279. exit(0)
  280. else:
  281. file = open('threshold'+listToString(features)+'.pk', 'rb')
  282. threshold=pickle.load(file)
  283. file.close()
  284. x_train=[]
  285. for i in range(NumberOfFailures+1):
  286. x_train.append(create_sequences(dataTrainNorm[i],int(options.timesteps)))
  287. model = keras.Sequential(
  288. [
  289. layers.Input(shape=(x_train[0].shape[1], x_train[0].shape[2])),
  290. layers.Conv1D(
  291. filters=NumFilters,
  292. kernel_size=KernelSize,
  293. padding="same",
  294. strides=2,
  295. activation="relu",
  296. ),
  297. layers.Dropout(rate=DropOut),
  298. layers.Conv1D(
  299. filters=int(NumFilters/2),
  300. kernel_size=KernelSize,
  301. padding="same",
  302. strides=2,
  303. activation="relu",
  304. ),
  305. layers.Conv1DTranspose(
  306. filters=int(NumFilters/2),
  307. kernel_size=KernelSize,
  308. padding="same",
  309. strides=2,
  310. activation="relu",
  311. ),
  312. layers.Dropout(rate=DropOut),
  313. layers.Conv1DTranspose(
  314. filters=NumFilters,
  315. kernel_size=KernelSize,
  316. padding="same",
  317. strides=2,
  318. activation="relu",
  319. ),
  320. layers.Conv1DTranspose(filters=x_train[i].shape[2], kernel_size=KernelSize, padding="same"),
  321. ]
  322. )
  323. model.compile(optimizer=keras.optimizers.Adam(learning_rate=0.001), loss="mse")
  324. model.summary()
  325. if options.optimizetf:
  326. for timesteps in range(4,21,4):
  327. path_checkpoint="model_noclass_v2_"+str(timesteps)+listToString(features)+"_checkpoint.weights.h5"
  328. es_callback=keras.callbacks.EarlyStopping(monitor="val_loss", min_delta=0, patience=15)
  329. modelckpt_callback=keras.callbacks.ModelCheckpoint( monitor="val_loss", filepath=path_checkpoint, verbose=1, save_weights_only=True, save_best_only=True,)
  330. model.load_weights(path_checkpoint)
  331. getFScore(timesteps,[dataTestNorm[0],dataTrainNorm[1],dataTrainNorm[2],dataTrainNorm[3],dataTrainNorm[4]])
  332. file = open('FScore'+listToString(features)+'.pk', 'wb')
  333. pickle.dump(FScoreHash, file)
  334. file.close()
  335. path_checkpoint="model_noclass_v2_"+str(options.timesteps)+listToString(features)+"_checkpoint.weights.h5"
  336. es_callback=keras.callbacks.EarlyStopping(monitor="val_loss", min_delta=0, patience=15)
  337. modelckpt_callback=keras.callbacks.ModelCheckpoint( monitor="val_loss", filepath=path_checkpoint, verbose=1, save_weights_only=True, save_best_only=True,)
  338. model.load_weights(path_checkpoint)
  339. file = open('FScore'+listToString(features)+'.pk', 'rb')
  340. FS=pickle.load(file)
  341. file.close()
  342. #plotFScore(FS)
  343. #exit(0)
  344. TIME_STEPS=int(options.timesteps)
  345. # 1st scenario. Detect only anomaly. Later, we will classiffy it
  346. # Test data= testnormal + testfail1 + testtail2 + testfail3 + testfail4 + testnormal
  347. #d=np.vstack((dataTestNorm[0],dataTestNorm[1],dataTestNorm[2],dataTestNorm[3],dataTestNorm[4],dataTestNorm[0]))
  348. # For Failure data, we can use Train data becasue not used for training and includes the firsts samples
  349. #datalist=[dataTestNorm[0],dataTrainNorm[1],dataTrainNorm[2],dataTrainNorm[3],dataTrainNorm[4]]
  350. datalist=[dataTestNorm[0],dataTestNorm[1],dataTestNorm[2],dataTestNorm[3],dataTestNorm[4]]
  351. d=np.vstack((datalist))
  352. x_test = create_sequences(d,int(options.timesteps))
  353. x_test_pred = model.predict(x_test)
  354. test_mae_loss = np.mean(np.abs(x_test_pred - x_test), axis=1)
  355. # Define ranges for plotting in different colors
  356. testRanges=[]
  357. r=0
  358. for i in range(len(datalist)):
  359. testRanges.append([r,r+datalist[i].shape[0]])
  360. r+=datalist[i].shape[0]
  361. #r=dataTestNorm[0].shape[0]
  362. #testRanges.append([0,r])
  363. #for i in range(1,NumberOfFailures+1):
  364. # rnext=r+dataTrainNorm[i].shape[0]
  365. # testRanges.append([r,rnext] )
  366. # r=rnext
  367. # Drop the last TIME_STEPS for plotting
  368. testRanges[NumberOfFailures][1]=testRanges[NumberOfFailures][1]-TIME_STEPS
  369. anomalies = test_mae_loss > threshold[int(options.timesteps)]*float(options.TF)
  370. anomalous_data_indices = []
  371. for i in range(anomalies.shape[0]):
  372. if AtLeastOneTrue(anomalies[i]):
  373. #if anomalies[i][0] or anomalies[i][1] or anomalies[i][2] or anomalies[i][3]:
  374. anomalous_data_indices.append(i)
  375. # Let's plot some features
  376. colorline=['violet','lightcoral','cyan','lime','grey']
  377. colordot=['darkviolet','red','blue','green','black']
  378. #featuresToPlot=['r1 s1','r1 s2','r1 s3','pa1 apiii']
  379. featuresToPlot=features
  380. indexesToPlot=[]
  381. for i in featuresToPlot:
  382. indexesToPlot.append(features.index(i))
  383. def plotData3():
  384. NumFeaturesToPlot=len(indexesToPlot)
  385. plt.rcParams.update({'font.size': 16})
  386. fig, axes = plt.subplots(
  387. nrows=NumFeaturesToPlot, ncols=1, figsize=(15, 10), dpi=80, facecolor="w", edgecolor="k",sharex=True
  388. )
  389. for i in range(NumFeaturesToPlot):
  390. init=0
  391. end=testRanges[0][1]
  392. axes[i].plot(range(init,end),x_test[testRanges[0][0]:testRanges[0][1],0,indexesToPlot[i]]*stdevs[i]+means[i],label="No fail")
  393. init=end
  394. end+=(testRanges[1][1]-testRanges[1][0])
  395. for j in range(1,NumberOfFailures+1):
  396. axes[i].plot(range(init,end),x_test[testRanges[j][0]:testRanges[j][1],0,indexesToPlot[i]]*stdevs[i]+means[i],label="Fail type "+str(j), color=colorline[j-1])
  397. if j<NumberOfFailures:
  398. init=end
  399. end+=(testRanges[j+1][1]-testRanges[j+1][0])
  400. x=[]
  401. y=[]
  402. for k in anomalous_data_indices:
  403. if (k+TIME_STEPS)<x_test.shape[0]:
  404. x.append(k+TIME_STEPS)
  405. y.append(x_test[k+TIME_STEPS,0,indexesToPlot[i]]*stdevs[i]+means[i])
  406. axes[i].plot(x,y ,color='grey',marker='.',linewidth=0,label="Fail detection" )
  407. if i==(NumFeatures-1):
  408. axes[i].legend(loc='right')
  409. s=''
  410. s+=featureNames[features[indexesToPlot[i]]]
  411. s+=' '+unitNames[features[indexesToPlot[i]]]
  412. axes[i].set_ylabel(s)
  413. axes[i].grid()
  414. axes[NumFeaturesToPlot-1].set_xlabel("Sample number")
  415. plt.show()
  416. anomalyMetric(threshold[int(options.timesteps)]*float(options.TF), int(options.timesteps),datalist)
  417. #plotData3()
  418. def plotData5():
  419. model1 = keras.Sequential(
  420. [
  421. layers.Input(shape=(4, 3)),
  422. layers.Conv1D(
  423. filters=NumFilters,
  424. kernel_size=KernelSize,
  425. padding="same",
  426. strides=2,
  427. activation="relu",
  428. ),
  429. layers.Dropout(rate=DropOut),
  430. layers.Conv1D(
  431. filters=int(NumFilters/2),
  432. kernel_size=KernelSize,
  433. padding="same",
  434. strides=2,
  435. activation="relu",
  436. ),
  437. layers.Conv1DTranspose(
  438. filters=int(NumFilters/2),
  439. kernel_size=KernelSize,
  440. padding="same",
  441. strides=2,
  442. activation="relu",
  443. ),
  444. layers.Dropout(rate=DropOut),
  445. layers.Conv1DTranspose(
  446. filters=NumFilters,
  447. kernel_size=KernelSize,
  448. padding="same",
  449. strides=2,
  450. activation="relu",
  451. ),
  452. layers.Conv1DTranspose(filters=3, kernel_size=KernelSize, padding="same"),
  453. ]
  454. )
  455. model1.compile(optimizer=keras.optimizers.Adam(learning_rate=0.001), loss="mse")
  456. model1.summary()
  457. path_checkpoint="model_noclass_v2_"+str(4)+listToString(features)+"_checkpoint.weights.h5"
  458. es_callback=keras.callbacks.EarlyStopping(monitor="val_loss", min_delta=0, patience=15)
  459. modelckpt_callback=keras.callbacks.ModelCheckpoint( monitor="val_loss", filepath=path_checkpoint, verbose=1, save_weights_only=True, save_best_only=True,)
  460. model1.load_weights(path_checkpoint)
  461. model2 = keras.Sequential(
  462. [
  463. layers.Input(shape=(20, 3)),
  464. layers.Conv1D(
  465. filters=NumFilters,
  466. kernel_size=KernelSize,
  467. padding="same",
  468. strides=2,
  469. activation="relu",
  470. ),
  471. layers.Dropout(rate=DropOut),
  472. layers.Conv1D(
  473. filters=int(NumFilters/2),
  474. kernel_size=KernelSize,
  475. padding="same",
  476. strides=2,
  477. activation="relu",
  478. ),
  479. layers.Conv1DTranspose(
  480. filters=int(NumFilters/2),
  481. kernel_size=KernelSize,
  482. padding="same",
  483. strides=2,
  484. activation="relu",
  485. ),
  486. layers.Dropout(rate=DropOut),
  487. layers.Conv1DTranspose(
  488. filters=NumFilters,
  489. kernel_size=KernelSize,
  490. padding="same",
  491. strides=2,
  492. activation="relu",
  493. ),
  494. layers.Conv1DTranspose(filters=3, kernel_size=KernelSize, padding="same"),
  495. ]
  496. )
  497. model2.compile(optimizer=keras.optimizers.Adam(learning_rate=0.001), loss="mse")
  498. model2.summary()
  499. path_checkpoint="model_noclass_v2_"+str(20)+listToString(features)+"_checkpoint.weights.h5"
  500. es_callback=keras.callbacks.EarlyStopping(monitor="val_loss", min_delta=0, patience=15)
  501. modelckpt_callback=keras.callbacks.ModelCheckpoint( monitor="val_loss", filepath=path_checkpoint, verbose=1, save_weights_only=True, save_best_only=True,)
  502. model2.load_weights(path_checkpoint)
  503. datalist=[dataTestNorm[0],dataTestNorm[3],dataTestNorm[2],dataTestNorm[1],dataTestNorm[4]]
  504. d=np.vstack((datalist))
  505. x_test = create_sequences(d,4)
  506. x_test_pred = model1.predict(x_test)
  507. test_mae_loss = np.mean(np.abs(x_test_pred - x_test), axis=1)
  508. testRanges=[]
  509. TIME_STEPS=4
  510. r=0
  511. for i in range(len(datalist)):
  512. testRanges.append([r,r+datalist[i].shape[0]])
  513. r+=datalist[i].shape[0]
  514. testRanges[NumberOfFailures][1]=testRanges[NumberOfFailures][1]-TIME_STEPS
  515. anomalies = test_mae_loss > threshold[4]*float(options.TF)
  516. anomalous_data_indices = []
  517. for i in range(anomalies.shape[0]):
  518. if AtLeastOneTrue(anomalies[i]):
  519. anomalous_data_indices.append(i)
  520. plt.rcParams.update({'font.size': 16})
  521. fig, axes = plt.subplots(
  522. nrows=2, ncols=1, figsize=(15, 7), dpi=80, facecolor="w", edgecolor="k" , sharex=True
  523. )
  524. for i in range(1):
  525. init=0
  526. end=testRanges[0][1]
  527. axes[i].plot(range(init,end),x_test[testRanges[0][0]:testRanges[0][1],0,indexesToPlot[i]]*stdevs[i]+means[i],label="No fail")
  528. init=end
  529. end+=(testRanges[1][1]-testRanges[1][0])
  530. for j in range(1,NumberOfFailures+1):
  531. axes[i].plot(range(init,end),x_test[testRanges[j][0]:testRanges[j][1],0,indexesToPlot[i]]*stdevs[i]+means[i],label="Fail type "+str(j), color=colorline[j-1])
  532. if j<NumberOfFailures:
  533. init=end
  534. end+=(testRanges[j+1][1]-testRanges[j+1][0])
  535. x=[]
  536. y=[]
  537. for k in anomalous_data_indices:
  538. if (k+TIME_STEPS)<x_test.shape[0]:
  539. x.append(k+TIME_STEPS)
  540. y.append(x_test[k+TIME_STEPS,0,indexesToPlot[i]]*stdevs[i]+means[i])
  541. axes[i].plot(x,y ,color='grey',marker='.',linewidth=0,label="Fail detection" )
  542. if i==(NumFeatures-1):
  543. axes[i].legend(loc='right')
  544. s=''
  545. s+=featureNames[features[indexesToPlot[i]]]
  546. s+=' '+unitNames[features[indexesToPlot[i]]]
  547. axes[i].set_ylabel(s)
  548. axes[i].grid()
  549. x_test = create_sequences(d,20)
  550. x_test_pred = model2.predict(x_test)
  551. test_mae_loss = np.mean(np.abs(x_test_pred - x_test), axis=1)
  552. testRanges=[]
  553. r=0
  554. TIME_STEPS=20
  555. for i in range(len(datalist)):
  556. testRanges.append([r,r+datalist[i].shape[0]])
  557. r+=datalist[i].shape[0]
  558. testRanges[NumberOfFailures][1]=testRanges[NumberOfFailures][1]-TIME_STEPS
  559. anomalies = test_mae_loss > threshold[20]*float(options.TF)
  560. anomalous_data_indices = []
  561. for i in range(anomalies.shape[0]):
  562. if AtLeastOneTrue(anomalies[i]):
  563. anomalous_data_indices.append(i)
  564. print(testRanges)
  565. for i in range(1):
  566. init=0
  567. end=testRanges[0][1]
  568. axes[i+1].plot(range(init,end),x_test[testRanges[0][0]:testRanges[0][1],0,indexesToPlot[i]]*stdevs[i]+means[i],label="No fail")
  569. init=end
  570. end+=(testRanges[1][1]-testRanges[1][0])
  571. for j in range(1,NumberOfFailures+1):
  572. if j==1:
  573. axes[i+1].plot(range(init,end),x_test[testRanges[j][0]:testRanges[j][1],0,indexesToPlot[i]]*stdevs[i]+means[i],label="Fail type 3", color=colorline[j-1])
  574. else:
  575. axes[i+1].plot(range(init,end),x_test[testRanges[j][0]:testRanges[j][1],0,indexesToPlot[i]]*stdevs[i]+means[i], color=colorline[j-1])
  576. if j<NumberOfFailures:
  577. init=end
  578. end+=(testRanges[j+1][1]-testRanges[j+1][0])
  579. x=[]
  580. y=[]
  581. for k in anomalous_data_indices:
  582. if (k+TIME_STEPS)<x_test.shape[0]:
  583. x.append(k+TIME_STEPS)
  584. y.append(x_test[k+TIME_STEPS,0,indexesToPlot[i]]*stdevs[i]+means[i])
  585. axes[i+1].plot(x,y ,color='grey',marker='.',linewidth=0,label="Fail detection" )
  586. if i==0:
  587. axes[i+1].legend(loc='right')
  588. s=''
  589. s+=featureNames[features[indexesToPlot[i]]]
  590. s+=' '+unitNames[features[indexesToPlot[i]]]
  591. axes[i+1].set_ylabel(s)
  592. axes[i+1].grid()
  593. axes[0].set_xlim(460,480)
  594. axes[1].set_xlim(460,480)
  595. axes[0].set_title('$ns=4$')
  596. axes[1].set_title('$ns=20$')
  597. axes[1].set_xlabel("Sample number")
  598. plt.show()
  599. plotData5()
  600. exit(0)
  601. # 2nd scenario. Detect only anomaly. Later, we will classiffy it
  602. # Test data= testnormal + testfail1 + testtail2 + testfail3 + testfail4 + testnormal
  603. #d=np.vstack((dataTestNorm[0],dataTestNorm[1],dataTestNorm[2],dataTestNorm[3],dataTestNorm[4],dataTestNorm[0]))
  604. num=100
  605. d=np.vstack((dataTestNorm[0][0:num,:],dataTestNorm[1][0:num,:],dataTestNorm[0][num:2*num,:],dataTestNorm[2][70:70+num,:],dataTestNorm[0][2*num-90:3*num-90,:],dataTestNorm[3][50:num+50,:],dataTestNorm[0][150:150+num,:],dataTestNorm[4][0:num+TIME_STEPS,:]))
  606. x_test = create_sequences(d,int(options.timesteps))
  607. x_test_pred = model.predict(x_test)
  608. test_mae_loss = np.mean(np.abs(x_test_pred - x_test), axis=1)
  609. anomalies = test_mae_loss > threshold[int(options.timesteps)]*float(options.TF)
  610. anomalous_data_indices = []
  611. for i in range(anomalies.shape[0]):
  612. if AtLeastOneTrue(anomalies[i]):
  613. #if anomalies[i][0] or anomalies[i][1] or anomalies[i][2] or anomalies[i][3]:
  614. anomalous_data_indices.append(i)
  615. def plotData4():
  616. NumFeaturesToPlot=len(indexesToPlot)
  617. plt.rcParams.update({'font.size': 16})
  618. fig, axes = plt.subplots(
  619. nrows=NumFeaturesToPlot, ncols=1, figsize=(15, 10), dpi=80, facecolor="w", edgecolor="k",sharex=True
  620. )
  621. for i in range(NumFeaturesToPlot):
  622. for j in range(1,NumberOfFailures+1):
  623. if j==1:
  624. axes[i].plot(range((j-1)*2*num,(j-1)*2*num+num),x_test[(j-1)*2*num:(j-1)*2*num+num,0,indexesToPlot[i]],label="No fail", color='C0')
  625. else:
  626. axes[i].plot(range((j-1)*2*num,(j-1)*2*num+num),x_test[(j-1)*2*num:(j-1)*2*num+num,0,indexesToPlot[i]], color='C0')
  627. axes[i].plot(range(j*2*num-num,j*2*num),x_test[j*2*num-num:j*2*num,0,indexesToPlot[i]],label="File type "+str(j),color=colorline[j-1])
  628. x=[]
  629. y=[]
  630. for k in anomalous_data_indices:
  631. if (k+TIME_STEPS)<x_test.shape[0]:
  632. x.append(k+TIME_STEPS)
  633. y.append(x_test[k+TIME_STEPS,0,indexesToPlot[i]])
  634. axes[i].plot(x,y ,color='grey',marker='.',linewidth=0,label="Fail detection" )
  635. if i==0:
  636. axes[i].legend(bbox_to_anchor=(0.9, 0.4))
  637. s=''
  638. s+=featureNames[features[indexesToPlot[i]]]
  639. axes[i].set_ylabel(s)
  640. axes[i].grid()
  641. axes[NumFeaturesToPlot-1].set_xlabel("Sample number")
  642. plt.show()
  643. plotData4()

Powered by TurnKey Linux.