Нема описа

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

Powered by TurnKey Linux.