123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161 |
- # 变分自编码器
- from keras.models import Model
- from keras.layers import Dense, Input, Lambda
- from keras.losses import mse, binary_crossentropy
- from keras.utils import plot_model
- import keras.backend as K
- import pandas as pd
- from random import shuffle
- from sklearn.preprocessing import StandardScaler
- import numpy as np
- import tensorflow.keras as keras
- import datetime
- import matplotlib.pyplot as plt
- from keras.layers import Input, Dense, Lambda
- from matplotlib.pyplot import MultipleLocator
- from keras import losses
- data_set=pd.read_feather('data_set_sp.feather')
- #打乱并切分训练集测试集
- def shuffle_data(dataset_faults):
- sn_fau=list(set(dataset_faults['sn']))
- shuffle(sn_fau)
- newtrain=dataset_faults[dataset_faults['sn'].isin(sn_fau[:int(0.8*len(sn_fau))])]
- newtest=dataset_faults[dataset_faults['sn'].isin(sn_fau[int(0.8*len(sn_fau)):])]
- newtrain.reset_index(drop=True,inplace=True)
- newtest.reset_index(drop=True,inplace=True)
- return newtrain,newtest
- #训练集数据标准化
- def scaler_train(train):
- Xtrain=train.drop(['time','sn','split'],axis=1)
- Xsc_colnames=list(Xtrain.columns)
- scaler=StandardScaler()
- scaler.fit(Xtrain) #保存train_sc的均值和标准差
- Xsc=scaler.transform(np.array(Xtrain))
- Xsc=pd.DataFrame(Xsc)
- Xsc.columns=Xsc_colnames
- Xsc['split']=train['split'].values
- return Xsc,scaler
- #测试集数据标准化
- def scaler_test_train(test,scaler):
- Xtest=test.drop(['time','sn','split'],axis=1)
- Xsc_colnames=list(Xtest.columns)
- Xtsc=scaler.transform(np.array(Xtest))
- Xtsc=pd.DataFrame(Xtsc)
- Xtsc.columns=Xsc_colnames
- Xtsc['split']=test['split'].values
- return Xtsc
- train,test=shuffle_data(data_set)
- Xsc,scaler = scaler_train(train)
- Xtsc = scaler_test_train(test,scaler)
- #时间窗口划分
- def create_dataset(data_set,time_steps): #X为dataframe,y为serie
- a=[]
- aa=np.empty(shape=[0,3])
- #index=pd.DataFrame()
- List_n_split=data_set['split'].drop_duplicates()
- for k in List_n_split:
- dataset=data_set[data_set['split']==k]
- #datatrain=data_train[data_train['split']==k]
- if len(dataset)>time_steps:
- dataset=dataset.reset_index(drop=True)
- dataset=dataset.drop(['split'],axis=1)
- dataX= []
- #index_step=[]
- for i in list(range(0,len(dataset)-60,60))[:-1]:
- v1 = dataset.iloc[i:(i+time_steps)].values
- dataX.append(v1)
- #index_step.append(i)
- #dataset3=dataset.iloc[:len(dataset)-time_steps]
- #newdatatrain=datatrain[:len(dataset3)]
- dataX2=np.array(dataX)
- a.append(dataX2)
- #index=index.append(newdatatrain)
- if len(a)>0:
- aa=np.vstack(a)
- #index.reset_index(drop=True,inplace=True)
- return aa
- aa = create_dataset(Xsc,time_steps=120)
- bb = create_dataset(Xtsc,time_steps=120)
- def sampling(args):
- # 再参数化采样
- z_mean, z_log_var = args[0],args[1]
- batch = K.shape(z_mean)[0]
- dim = K.int_shape(z_mean)[1]
- #epsilon = K.random_normal(shape=(batch, dim))
- epsilon = K.random_normal(shape=(batch, dim,args[2]))
- return z_mean + K.exp(0.5 * z_log_var) * epsilon
- def get_loss(args):
- """
- 自定义损失函数
- x:原始样本
- xr: 重构样本
- m: 编码器隐变量z均值
- v: 编码器隐变量z方差的对数
- """
- x, xr, m, v = args
- dim = K.int_shape(x)[-1]
- print(dim)
- re_loss = dim * binary_crossentropy(x, xr) # 重构正确性度量
- kl_loss = 1 + v - K.square(m) - K.exp(v) # d维向量,隐变量z维度为d
- kl_loss = - 0.5 * K.sum(kl_loss, axis=-1) # kl散度,罚项
- print(re_loss)
- print(kl_loss)
- #vae_loss = K.mean(re_loss + kl_loss)
- vae_loss =re_loss + kl_loss
- print(vae_loss)
- return vae_loss
- # def get_loss(x, x_decoded_mean):
- # #my tips:logloss
- # xent_loss = input_dim * losses.binary_crossentropy(x, x_decoded_mean)
- # #my tips:see paper's appendix B
- # kl_loss = - 0.5 * K.sum(1 + z_log_var - K.square(z_mean) - K.exp(z_log_var), axis=-1)
- # return xent_loss + kl_loss
- # 模型训练参数
- batch_size = 128
- epochs = 10
- # 模型结构参数
- input_dim = aa.shape[2] # 输入图像为28*28
- latent_dim = 10 # 潜在因子z的维度
- # 构建编码器(推断网络)
- #inputs = Input(shape=(input_dim,))
- inputs = Input(shape=(aa.shape[1],aa.shape[2]))
- encode_h = Dense(20, activation='relu')(inputs)
- z_mean = Dense(latent_dim, activation='relu')(encode_h)
- z_log_var = Dense(latent_dim, activation='relu')(encode_h) # log(sigma^2)
- z_sample = Lambda(sampling, output_shape=([latent_dim]))([z_mean, z_log_var,latent_dim]) # 采样
- print(z_sample)
- encoder = Model(inputs, [z_mean, z_log_var, z_sample]) # 编码器输出结果为3层
- # 构建解码器(生成网络)
- inputs_decoder = Input(shape=(aa.shape[1],latent_dim))
- print(inputs_decoder)
- decode_h = Dense(20, activation='relu')(inputs_decoder)
- x_mean_decoded = Dense(input_dim, activation='sigmoid')(decode_h)
- decoder = Model(inputs_decoder, x_mean_decoded)
- # 构建VAE模型
- x_decoded = decoder(encoder(inputs)[2])
- print(x_decoded)
- outputs = Lambda(get_loss)([inputs, x_decoded, z_mean, z_log_var]) # 模型直接输出损失函数值
- #outputs = Lambda(get_loss)(inputs_decoder, x_mean_decoded) # 模型直接输出损失函数值
- #decoder.compile(optimizer='rmsprop', loss=get_loss)
- vae_model = Model(inputs, outputs)
- vae_model.compile(optimizer='adam', loss=lambda y_true, y_pred: y_pred)
- vae_model.fit(aa, aa,shuffle=True,epochs=epochs,verbose=2,batch_size=batch_size)
- encoded_imgs = encoder.predict(bb)[2]
- decoded_imgs = decoder.predict(encoded_imgs)
|