小论文
This commit is contained in:
parent
d8746d192f
commit
564ba3f669
|
|
@ -0,0 +1,229 @@
|
|||
# -*- encoding:utf-8 -*-
|
||||
|
||||
'''
|
||||
@Author : dingjiawen
|
||||
@Date : 2023/6/14 14:56
|
||||
@Usage :
|
||||
@Desc : 测试所实现的LSTM
|
||||
'''
|
||||
|
||||
import tensorflow as tf
|
||||
import numpy as np
|
||||
from model.LSTM.DCTAttention_embed_LSTM import AttentionEmbedLSTMLayer as LSTMLayer
|
||||
# from model.LSTM.LSTM import LSTMLayer as LSTMLayer
|
||||
import matplotlib.pyplot as plt
|
||||
from keras.callbacks import EarlyStopping
|
||||
|
||||
from model.LossFunction.FTMSE import FTMSE
|
||||
import math
|
||||
from sklearn.metrics import mean_absolute_error, mean_squared_error
|
||||
from pylab import *
|
||||
|
||||
'''
|
||||
超参数设置:
|
||||
'''
|
||||
hidden_num = 10 # LSTM细胞个数
|
||||
feature = 10 # 一个点的维度
|
||||
batch_size = 32
|
||||
EPOCH = 1000
|
||||
unit = 512 # LSTM的维度
|
||||
predict_num = 50 # 预测个数
|
||||
model_name = "dctLSTM"
|
||||
save_name = r"self_{0}_hidden{1}_unit{2}_feature{3}_predict{4}.h5".format(model_name, hidden_num, unit, feature,
|
||||
predict_num)
|
||||
|
||||
|
||||
def getData(filter_num, dims):
|
||||
# 数据读入
|
||||
HI_merge_data_origin = np.load("../../2012轴承数据集预测挑战/HI_create/HI_merge_data.npy")
|
||||
|
||||
# plt.plot(HI_merge_data[0:1250, 1])
|
||||
# 去除掉退化特征不明显前面的点
|
||||
HI_merge_data = HI_merge_data_origin[0:1250, 1]
|
||||
|
||||
# plt.plot(HI_merge_data)
|
||||
# plt.show()
|
||||
(total_dims,) = HI_merge_data.shape
|
||||
|
||||
# # 将其分成重叠采样状态-滑动窗口函数
|
||||
predict_data = np.empty(shape=[total_dims - filter_num, filter_num])
|
||||
|
||||
# 重叠采样获取时间部和训练次数
|
||||
for dim in range(total_dims - filter_num):
|
||||
predict_data[dim] = HI_merge_data[dim:dim + filter_num]
|
||||
|
||||
train_label = predict_data[dims:, :]
|
||||
train_label_single = HI_merge_data[dims + filter_num - 1:-1]
|
||||
|
||||
# 再重叠采样获取一个点的维度
|
||||
'''train_data.shape:(sample,filter_num) -> (sample,filter_num,dims)'''
|
||||
|
||||
# # 将其分成重叠采样状态-滑动窗口函数
|
||||
train_data = np.empty(shape=[dims, total_dims - filter_num - dims, filter_num])
|
||||
|
||||
for dim in range(dims):
|
||||
train_data[dim] = predict_data[dim:total_dims - filter_num - dims + dim, :]
|
||||
|
||||
# 转置变成想要的数据 (dims,sample,filter_num) -> (sample,filter_num,dims)
|
||||
train_data = tf.transpose(train_data, [1, 2, 0])
|
||||
|
||||
# todo 解决模型保存时,query无法序列化的问题
|
||||
total_data = tf.cast(HI_merge_data, dtype=tf.float32)
|
||||
train_data = tf.cast(train_data, dtype=tf.float32)
|
||||
train_label = tf.cast(train_label, dtype=tf.float32)
|
||||
train_label_single = tf.cast(train_label_single, dtype=tf.float32)
|
||||
|
||||
print("total_data.shape:", total_data.shape)
|
||||
print("train_data.shape:", train_data.shape) # (20, 1200, 30)
|
||||
print("train_label.shape:", train_label.shape) # (20, 1200)
|
||||
print("train_label_single.shape:", train_label_single.shape)
|
||||
|
||||
# 所有的原始数据;所有的训练数据;所有的训练标签(预测一个序列);所有的训练标签(预测一个点)
|
||||
return total_data, train_data, train_label, train_label_single
|
||||
|
||||
|
||||
'''
|
||||
train_data.shape: (total_dims - filter_num - 1, filter_num,dims) :(570,600,30)
|
||||
predict_data.shape: (total_dims - filter_num, filter_num) :(571,600,30)
|
||||
train_label.shape: (total_dims - filter_num - 1, filter_num) :(570,600)
|
||||
'''
|
||||
|
||||
|
||||
def remove(train_data, train_label, batch_size):
|
||||
epoch, _, _ = train_data.shape
|
||||
size = int(epoch / batch_size)
|
||||
return train_data[:size * batch_size], train_label[:size * batch_size]
|
||||
|
||||
|
||||
'''
|
||||
train_data.shape: (1230, 10, 10)
|
||||
train_label.shape: (1230, 10)
|
||||
train_label_single.shape: (1230,)
|
||||
'''
|
||||
|
||||
|
||||
def splitValData(data, label, label_single, predict_num=50):
|
||||
sample, hidden, feature = data.shape
|
||||
|
||||
train_data = data[:sample - predict_num, :, :]
|
||||
val_data = data[sample - predict_num:, :, :]
|
||||
|
||||
train_label = label[:sample - predict_num, :]
|
||||
val_label = label[sample - predict_num:, :]
|
||||
|
||||
train_label_single = label_single[:sample - predict_num, ]
|
||||
val_label_single = label_single[sample - predict_num:, ]
|
||||
|
||||
return train_data, val_data, train_label, val_label, train_label_single, val_label_single
|
||||
|
||||
|
||||
def predict_model(filter_num, dims):
|
||||
input = tf.keras.Input(shape=[filter_num, dims])
|
||||
input = tf.cast(input, tf.float32)
|
||||
|
||||
#### 官方
|
||||
# LSTM = tf.keras.layers.LSTM(units=512, return_sequences=True)(input)
|
||||
# LSTM = tf.keras.layers.LSTM(units=256, return_sequences=False)(LSTM)
|
||||
|
||||
#### 自己
|
||||
# LSTM = tf.keras.layers.Conv1D(512, kernel_size=8, padding='same')(input)
|
||||
LSTM = LSTMLayer(units=512, return_sequences=True)(input)
|
||||
LSTM = LSTMLayer(units=256, return_sequences=False)(LSTM)
|
||||
|
||||
x = tf.keras.layers.Dense(128, activation="relu")(LSTM)
|
||||
x = tf.keras.layers.Dense(64, activation="relu")(x)
|
||||
x = tf.keras.layers.Dropout(0.2)(x)
|
||||
x = tf.keras.layers.BatchNormalization()(x)
|
||||
x = tf.keras.layers.Dense(32, activation="relu")(x)
|
||||
x = tf.keras.layers.Dropout(0.2)(x)
|
||||
x = tf.keras.layers.BatchNormalization()(x)
|
||||
x = tf.keras.layers.Dense(16, activation="relu")(x)
|
||||
output = tf.keras.layers.Dense(1, activation="relu", name='output')(x)
|
||||
|
||||
model = tf.keras.Model(inputs=input, outputs=output)
|
||||
return model
|
||||
|
||||
|
||||
def split_data(train_data, train_label):
|
||||
return train_data[:1150, :, :], train_label[:1150, :], train_data[-70:, :, :], train_label[-70:, :]
|
||||
|
||||
|
||||
# 仅使用预测出来的最新的一个点预测以后
|
||||
def predictOneByOne(newModel, train_data, predict_num=50):
|
||||
# 取出训练数据的最后一条
|
||||
each_predict_data = np.expand_dims(train_data[-1, :, :], axis=0)
|
||||
predicted_list = np.empty(shape=(predict_num, 1)) # (5,filter_num,30)
|
||||
# all_data = total_data # (1201,)
|
||||
for each_predict in range(predict_num):
|
||||
# predicted_data.shape : (1,1)
|
||||
predicted_data = newModel.predict(each_predict_data) # (batch_size,filer_num,1)
|
||||
predicted_list[each_predict] = predicted_data
|
||||
# (1,1) => (10,1)
|
||||
temp1 = np.transpose(np.concatenate([each_predict_data[:, 1:, -1], predicted_data], axis=1), [1, 0])
|
||||
|
||||
each_predict_data = np.expand_dims(
|
||||
np.concatenate([np.squeeze(each_predict_data[:, :, 1:], axis=0), temp1], axis=1), axis=0)
|
||||
|
||||
return predicted_list
|
||||
|
||||
|
||||
# 不使用预测的数据,直接使用已知的数据持续预测
|
||||
def predictByEveryData(trained_model: tf.keras.Model, predict_data):
|
||||
predicted_data = trained_model.predict(predict_data)
|
||||
predicted_data = np.concatenate([np.expand_dims(total_data[:hidden_num + feature, ], axis=1), predicted_data],
|
||||
axis=0)
|
||||
data = predictOneByOne(trained_model, predict_data)
|
||||
predicted_data = np.concatenate([predicted_data, data], axis=0)
|
||||
return predicted_data
|
||||
pass
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
# 数据读取
|
||||
# 数据读入 --> 所有的原始数据;所有的训练数据;所有的训练标签(预测一个序列);所有的训练标签(预测一个点)
|
||||
total_data, train_data, train_label, train_label_single = getData(hidden_num, feature)
|
||||
# 根据预测的点数划分训练集和测试集(验证集)
|
||||
train_data, val_data, train_label, val_label, train_label_single, val_label_single = splitValData(train_data,
|
||||
train_label,
|
||||
train_label_single,
|
||||
predict_num=predict_num)
|
||||
# # # #### TODO 训练
|
||||
model = predict_model(hidden_num, feature)
|
||||
checkpoint = tf.keras.callbacks.ModelCheckpoint(
|
||||
filepath=save_name,
|
||||
monitor='val_loss',
|
||||
verbose=2,
|
||||
save_best_only=True,
|
||||
mode='min')
|
||||
lr_scheduler = tf.keras.callbacks.ReduceLROnPlateau(monitor='val_loss', factor=0.2, patience=10, min_lr=0.001)
|
||||
|
||||
model.compile(optimizer=tf.optimizers.SGD(), loss=tf.losses.mse)
|
||||
model.summary()
|
||||
early_stop = EarlyStopping(monitor='val_loss', min_delta=0.0001, patience=20, mode='min', verbose=1)
|
||||
|
||||
history = model.fit(train_data, train_label_single, epochs=EPOCH, validation_data=(val_data, val_label_single),
|
||||
shuffle=True, verbose=1,
|
||||
callbacks=[checkpoint, lr_scheduler, early_stop])
|
||||
|
||||
#### TODO 测试
|
||||
|
||||
trained_model = tf.keras.models.load_model(save_name, custom_objects={'AttentionEmbedLSTMLayer': LSTMLayer})
|
||||
|
||||
# 使用已知的点进行预测
|
||||
print("开始预测")
|
||||
predicted_data = predictByEveryData(trained_model, train_data)
|
||||
# 使用预测的点持续预测
|
||||
# predicted_data = predictOneByOne(trained_model, total_data, train_data)
|
||||
|
||||
print("predicted_data:", predicted_data)
|
||||
print("predicted_data.shape:", predicted_data.shape)
|
||||
|
||||
plt.figure(1)
|
||||
plt.subplot(2, 1, 1)
|
||||
plt.plot(total_data)
|
||||
# plt.subplot(2, 1, 2)
|
||||
plt.plot(predicted_data)
|
||||
|
||||
# plt.scatter()
|
||||
|
||||
plt.show()
|
||||
|
|
@ -2,7 +2,11 @@
|
|||
# 线性循环单元(Linear Recurrent Unit)
|
||||
# tensorflow 1.15 + bert4keras 0.11.4 测试通过
|
||||
|
||||
from bert4keras.layers import *
|
||||
|
||||
from tensorflow.keras.layers import Layer,Dense
|
||||
import numpy as np
|
||||
import tensorflow as tf
|
||||
import tensorflow.keras.backend as K
|
||||
|
||||
|
||||
class LRU(Layer):
|
||||
|
|
@ -26,9 +30,9 @@ class LRU(Layer):
|
|||
self.unroll = unroll
|
||||
self.kernel_initializer = initializers.get(kernel_initializer)
|
||||
|
||||
@integerize_shape
|
||||
|
||||
def build(self, input_shape):
|
||||
super(LRU, self).build(input_shape)
|
||||
|
||||
hidden_size = input_shape[-1]
|
||||
self.i_dense = Dense(
|
||||
units=self.units * 2,
|
||||
|
|
@ -57,7 +61,7 @@ class LRU(Layer):
|
|||
name='params_log', shape=(3, self.units), initializer=initializer
|
||||
)
|
||||
|
||||
@recompute_grad
|
||||
|
||||
def call(self, inputs, mask=None):
|
||||
u = self.i_dense(inputs)
|
||||
params = K.exp(self.params_log)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,239 @@
|
|||
# -*- encoding:utf-8 -*-
|
||||
|
||||
'''
|
||||
@Author : dingjiawen
|
||||
@Date : 2023/6/14 14:56
|
||||
@Usage :
|
||||
@Desc : 测试所实现的LSTM
|
||||
'''
|
||||
|
||||
import tensorflow as tf
|
||||
import numpy as np
|
||||
from model.AdamRNN.AdamRNN import AdaRNN
|
||||
# from model.LSTM.LSTM import LSTMLayer as LSTMLayer
|
||||
import matplotlib.pyplot as plt
|
||||
from keras.callbacks import EarlyStopping
|
||||
|
||||
from model.LossFunction.FTMSE import FTMSE
|
||||
import math
|
||||
from sklearn.metrics import mean_absolute_error, mean_squared_error
|
||||
from pylab import *
|
||||
|
||||
'''
|
||||
超参数设置:
|
||||
'''
|
||||
hidden_num = 40 # LSTM细胞个数
|
||||
feature = 10 # 一个点的维度
|
||||
batch_size = 32
|
||||
EPOCH = 1000
|
||||
unit = 512 # LSTM的维度
|
||||
predict_num = 50 # 预测个数
|
||||
model_name = "adaRNN"
|
||||
save_name = r"self_{0}_hidden{1}_unit{2}_feature{3}_predict{4}.h5".format(model_name, hidden_num, unit, feature,
|
||||
predict_num)
|
||||
|
||||
|
||||
def standardization(data):
|
||||
mu = np.mean(data, axis=0)
|
||||
sigma = np.std(data, axis=0)
|
||||
return (data - mu) / sigma
|
||||
|
||||
|
||||
def normalization(data):
|
||||
_range = np.max(data) - np.min(data)
|
||||
return (data - np.min(data)) / _range
|
||||
|
||||
|
||||
# LSTM_cell的数目,维度,是否正则化
|
||||
def getData(filter_num, dims, if_norm: bool = False):
|
||||
# 数据读入
|
||||
HI_merge_data_origin = np.load("../../2012轴承数据集预测挑战/HI_create/HI_merge_data.npy")
|
||||
|
||||
# plt.plot(HI_merge_data[0:1250, 1])
|
||||
# 去除掉退化特征不明显前面的点
|
||||
HI_merge_data = HI_merge_data_origin[0:1250, 1]
|
||||
|
||||
# 是否正则化
|
||||
if if_norm:
|
||||
HI_merge_data = normalization(HI_merge_data)
|
||||
|
||||
# plt.plot(HI_merge_data)
|
||||
# plt.show()
|
||||
(total_dims,) = HI_merge_data.shape
|
||||
|
||||
# # 将其分成重叠采样状态-滑动窗口函数
|
||||
predict_data = np.empty(shape=[total_dims - filter_num, filter_num])
|
||||
|
||||
# 重叠采样获取时间部和训练次数
|
||||
for dim in range(total_dims - filter_num):
|
||||
predict_data[dim] = HI_merge_data[dim:dim + filter_num]
|
||||
|
||||
train_label = predict_data[dims:, :]
|
||||
train_label_single = HI_merge_data[dims + filter_num - 1:-1]
|
||||
|
||||
# 再重叠采样获取一个点的维度
|
||||
'''train_data.shape:(sample,filter_num) -> (sample,filter_num,dims)'''
|
||||
|
||||
# # 将其分成重叠采样状态-滑动窗口函数
|
||||
train_data = np.empty(shape=[dims, total_dims - filter_num - dims, filter_num])
|
||||
|
||||
for dim in range(dims):
|
||||
train_data[dim] = predict_data[dim:total_dims - filter_num - dims + dim, :]
|
||||
|
||||
# 转置变成想要的数据 (dims,sample,filter_num) -> (sample,filter_num,dims)
|
||||
train_data = tf.transpose(train_data, [1, 2, 0])
|
||||
|
||||
# todo 解决模型保存时,query无法序列化的问题
|
||||
total_data = tf.cast(HI_merge_data, dtype=tf.float32)
|
||||
train_data = tf.cast(train_data, dtype=tf.float32)
|
||||
train_label = tf.cast(train_label, dtype=tf.float32)
|
||||
train_label_single = tf.cast(train_label_single, dtype=tf.float32)
|
||||
|
||||
print("total_data.shape:", total_data.shape)
|
||||
print("train_data.shape:", train_data.shape) # (20, 1200, 30)
|
||||
print("train_label.shape:", train_label.shape) # (20, 1200)
|
||||
print("train_label_single.shape:", train_label_single.shape)
|
||||
|
||||
# 所有的原始数据;所有的训练数据;所有的训练标签(预测一个序列);所有的训练标签(预测一个点)
|
||||
return total_data, train_data, train_label, train_label_single
|
||||
|
||||
|
||||
'''
|
||||
train_data.shape: (total_dims - filter_num - 1, filter_num,dims) :(570,600,30)
|
||||
predict_data.shape: (total_dims - filter_num, filter_num) :(571,600,30)
|
||||
train_label.shape: (total_dims - filter_num - 1, filter_num) :(570,600)
|
||||
'''
|
||||
|
||||
|
||||
def remove(train_data, train_label, batch_size):
|
||||
epoch, _, _ = train_data.shape
|
||||
size = int(epoch / batch_size)
|
||||
return train_data[:size * batch_size], train_label[:size * batch_size]
|
||||
|
||||
|
||||
'''
|
||||
train_data.shape: (1230, 10, 10)
|
||||
train_label.shape: (1230, 10)
|
||||
train_label_single.shape: (1230,)
|
||||
'''
|
||||
|
||||
|
||||
def splitValData(data, label, label_single, predict_num=50):
|
||||
sample, hidden, feature = data.shape
|
||||
|
||||
train_data = data[:sample - predict_num, :, :]
|
||||
val_data = data[sample - predict_num:, :, :]
|
||||
|
||||
train_label = label[:sample - predict_num, :]
|
||||
val_label = label[sample - predict_num:, :]
|
||||
|
||||
train_label_single = label_single[:sample - predict_num, ]
|
||||
val_label_single = label_single[sample - predict_num:, ]
|
||||
|
||||
return train_data, val_data, train_label, val_label, train_label_single, val_label_single
|
||||
|
||||
|
||||
def predict_model(filter_num, dims):
|
||||
input = tf.keras.Input(shape=[filter_num, dims])
|
||||
input = tf.cast(input, tf.float32)
|
||||
|
||||
|
||||
|
||||
x = tf.keras.layers.Dense(128, activation="relu")(LSTM)
|
||||
x = tf.keras.layers.Dense(64, activation="relu")(x)
|
||||
x = tf.keras.layers.Dropout(0.2)(x)
|
||||
x = tf.keras.layers.BatchNormalization()(x)
|
||||
x = tf.keras.layers.Dense(32, activation="relu")(x)
|
||||
x = tf.keras.layers.Dropout(0.2)(x)
|
||||
x = tf.keras.layers.BatchNormalization()(x)
|
||||
x = tf.keras.layers.Dense(16, activation="relu")(x)
|
||||
output = tf.keras.layers.Dense(1, activation="relu", name='output')(x)
|
||||
|
||||
model = tf.keras.Model(inputs=input, outputs=output)
|
||||
return model
|
||||
|
||||
|
||||
def split_data(train_data, train_label):
|
||||
return train_data[:1150, :, :], train_label[:1150, :], train_data[-70:, :, :], train_label[-70:, :]
|
||||
|
||||
|
||||
# 仅使用预测出来的最新的一个点预测以后
|
||||
def predictOneByOne(newModel, train_data, predict_num=50):
|
||||
# 取出训练数据的最后一条
|
||||
each_predict_data = np.expand_dims(train_data[-1, :, :], axis=0)
|
||||
predicted_list = np.empty(shape=(predict_num, 1)) # (5,filter_num,30)
|
||||
# all_data = total_data # (1201,)
|
||||
for each_predict in range(predict_num):
|
||||
# predicted_data.shape : (1,1)
|
||||
predicted_data = newModel.predict(each_predict_data) # (batch_size,filer_num,1)
|
||||
predicted_list[each_predict] = predicted_data
|
||||
# (1,1) => (10,1)
|
||||
temp1 = np.transpose(np.concatenate([each_predict_data[:, 1:, -1], predicted_data], axis=1), [1, 0])
|
||||
|
||||
each_predict_data = np.expand_dims(
|
||||
np.concatenate([np.squeeze(each_predict_data[:, :, 1:], axis=0), temp1], axis=1), axis=0)
|
||||
|
||||
return predicted_list
|
||||
|
||||
|
||||
# 不使用预测的数据,直接使用已知的数据持续预测
|
||||
def predictByEveryData(trained_model: tf.keras.Model, predict_data):
|
||||
predicted_data = trained_model.predict(predict_data)
|
||||
predicted_data = np.concatenate([np.expand_dims(total_data[:hidden_num + feature, ], axis=1), predicted_data],
|
||||
axis=0)
|
||||
data = predictOneByOne(trained_model, predict_data)
|
||||
predicted_data = np.concatenate([predicted_data, data], axis=0)
|
||||
return predicted_data
|
||||
pass
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
# 数据读取
|
||||
# 数据读入 --> 所有的原始数据;所有的训练数据;所有的训练标签(预测一个序列);所有的训练标签(预测一个点)
|
||||
total_data, train_data, train_label, train_label_single = getData(hidden_num, feature)
|
||||
# 根据预测的点数划分训练集和测试集(验证集)
|
||||
train_data, val_data, train_label, val_label, train_label_single, val_label_single = splitValData(train_data,
|
||||
train_label,
|
||||
train_label_single,
|
||||
predict_num=predict_num)
|
||||
# # # #### TODO 训练
|
||||
model = predict_model(hidden_num, feature)
|
||||
checkpoint = tf.keras.callbacks.ModelCheckpoint(
|
||||
filepath=save_name,
|
||||
monitor='val_loss',
|
||||
verbose=2,
|
||||
save_best_only=True,
|
||||
mode='min')
|
||||
lr_scheduler = tf.keras.callbacks.ReduceLROnPlateau(monitor='val_loss', factor=0.2, patience=10, min_lr=0.0001)
|
||||
|
||||
model.compile(optimizer=tf.optimizers.SGD(), loss=tf.losses.mse)
|
||||
|
||||
model.summary()
|
||||
early_stop = EarlyStopping(monitor='val_loss', min_delta=0.0001, patience=20, mode='min', verbose=1)
|
||||
|
||||
history = model.fit(train_data, train_label_single, epochs=EPOCH, validation_data=(val_data, val_label_single),
|
||||
shuffle=True, verbose=1,
|
||||
callbacks=[checkpoint, lr_scheduler, early_stop])
|
||||
|
||||
#### TODO 测试
|
||||
|
||||
trained_model = tf.keras.models.load_model(save_name, custom_objects={'AttentionEmbedLSTMLayer': LSTMLayer})
|
||||
|
||||
# 使用已知的点进行预测
|
||||
print("开始预测")
|
||||
predicted_data = predictByEveryData(trained_model, train_data)
|
||||
# 使用预测的点持续预测
|
||||
# predicted_data = predictOneByOne(trained_model, total_data, train_data)
|
||||
|
||||
print("predicted_data:", predicted_data)
|
||||
print("predicted_data.shape:", predicted_data.shape)
|
||||
|
||||
plt.figure(1)
|
||||
plt.subplot(2, 1, 1)
|
||||
plt.plot(total_data)
|
||||
# plt.subplot(2, 1, 2)
|
||||
plt.plot(predicted_data)
|
||||
|
||||
# plt.scatter()
|
||||
|
||||
plt.show()
|
||||
|
|
@ -9,13 +9,13 @@
|
|||
|
||||
import tensorflow as tf
|
||||
import numpy as np
|
||||
from model.LSTM.LSTMByDense import LSTMLayer as LSTMLayer
|
||||
import matplotlib.pyplot as plt
|
||||
from keras.callbacks import EarlyStopping
|
||||
|
||||
from model.LossFunction.FTMSE import FTMSE
|
||||
from model.LSTM.DCTAttention_embed_LSTM import AttentionEmbedLSTMLayer as LSTMLayer
|
||||
# from model.LSTM.LSTM import LSTMLayer as LSTMLayer
|
||||
from model.ChannelAttention.DCT_channelAttention import DCTChannelAttention
|
||||
from model.ChannelAttention.Light_channelAttention import LightChannelAttention1 as LightChannelAttention
|
||||
|
||||
import math
|
||||
from sklearn.metrics import mean_absolute_error, mean_squared_error
|
||||
from pylab import *
|
||||
|
|
@ -29,7 +29,7 @@ batch_size = 8
|
|||
EPOCH = 1000
|
||||
unit = 512 # LSTM的维度
|
||||
predict_num = 50 # 预测个数
|
||||
model_name = "FC_FTLSTM"
|
||||
model_name = "dctLSTM"
|
||||
save_name = r"selfMulti_{0}_hidden{1}_unit{2}_feature{3}_predict{4}.h5".format(model_name, hidden_num, unit,
|
||||
feature,
|
||||
predict_num)
|
||||
|
|
@ -100,22 +100,13 @@ def getData(filter_num, dims, if_norm: bool = False):
|
|||
return total_data, train_data, train_label, train_label_single
|
||||
|
||||
|
||||
'''
|
||||
train_data.shape: (total_dims - filter_num - 1, filter_num,dims) :(570,600,30)
|
||||
predict_data.shape: (total_dims - filter_num, filter_num) :(571,600,30)
|
||||
train_label.shape: (total_dims - filter_num - 1, filter_num) :(570,600)
|
||||
'''
|
||||
def remove(train_data, train_label, batch_size):
|
||||
epoch, _, _ = train_data.shape
|
||||
size = int(epoch / batch_size)
|
||||
return train_data[:size * batch_size], train_label[:size * batch_size]
|
||||
|
||||
|
||||
'''
|
||||
train_data.shape: (1230, 10, 10)
|
||||
train_label.shape: (1230, 10)
|
||||
train_label_single.shape: (1230,)
|
||||
'''
|
||||
|
||||
|
||||
def splitValData(data, label, label_single, predict_num=50):
|
||||
sample, hidden, feature = data.shape
|
||||
|
||||
|
|
@ -145,19 +136,16 @@ def predict_model_multi(filter_num, dims):
|
|||
LSTM = LSTMLayer(units=512, return_sequences=True)(input)
|
||||
# LSTM = LightChannelAttention()(LSTM)
|
||||
LSTM = LSTMLayer(units=256, return_sequences=True)(LSTM)
|
||||
LSTM = LightChannelAttention()(LSTM)
|
||||
|
||||
### flatten
|
||||
x = tf.keras.layers.Flatten()(LSTM)
|
||||
x = tf.keras.layers.Dense(128, activation="relu")(x)
|
||||
x = tf.keras.layers.Dense(128, activation="relu")(LSTM)
|
||||
x = tf.keras.layers.Dense(64, activation="relu")(x)
|
||||
x = tf.keras.layers.Dropout(0.2)(x)
|
||||
x = tf.keras.layers.BatchNormalization()(x)
|
||||
x = tf.keras.layers.Dense(32, activation="relu")(x)
|
||||
x = tf.keras.layers.Dropout(0.2)(x)
|
||||
x = tf.keras.layers.BatchNormalization()(x)
|
||||
# x = tf.keras.layers.Dense(16, activation="relu")(x)
|
||||
output = tf.keras.layers.Dense(10, activation="relu", name='output')(x)
|
||||
x = tf.keras.layers.Dense(16, activation="relu")(x)
|
||||
output = tf.keras.layers.Dense(1, activation="relu", name='output')(x)
|
||||
|
||||
model = tf.keras.Model(inputs=input, outputs=output)
|
||||
return model
|
||||
|
|
@ -207,31 +195,31 @@ if __name__ == '__main__':
|
|||
train_label_single,
|
||||
predict_num=predict_num)
|
||||
# # #### TODO 训练
|
||||
# model = predict_model_multi(hidden_num, feature)
|
||||
# checkpoint = tf.keras.callbacks.ModelCheckpoint(
|
||||
# filepath=save_name,
|
||||
# monitor='val_loss',
|
||||
# verbose=2,
|
||||
# save_best_only=True,
|
||||
# mode='min')
|
||||
# lr_scheduler = tf.keras.callbacks.ReduceLROnPlateau(monitor='val_loss', factor=0.2, patience=20, min_lr=0.001)
|
||||
#
|
||||
# model.compile(optimizer=tf.optimizers.SGD(), loss=tf.losses.mse)
|
||||
# # model.compile(optimizer=tf.optimizers.SGD(learning_rate=0.001), loss=FTMSE())
|
||||
# model.summary()
|
||||
# early_stop = EarlyStopping(monitor='val_loss', min_delta=0.0001, patience=100, mode='min', verbose=1)
|
||||
#
|
||||
# history = model.fit(train_data, train_label, epochs=EPOCH,
|
||||
# batch_size=batch_size, validation_data=(val_data, val_label_single), shuffle=True, verbose=2,
|
||||
# callbacks=[checkpoint, lr_scheduler, early_stop])
|
||||
model = predict_model_multi(hidden_num, feature)
|
||||
checkpoint = tf.keras.callbacks.ModelCheckpoint(
|
||||
filepath=save_name,
|
||||
monitor='val_loss',
|
||||
verbose=2,
|
||||
save_best_only=True,
|
||||
mode='min')
|
||||
lr_scheduler = tf.keras.callbacks.ReduceLROnPlateau(monitor='val_loss', factor=0.2, patience=10, min_lr=0.001)
|
||||
|
||||
model.compile(optimizer=tf.optimizers.SGD(), loss=tf.losses.mse)
|
||||
# model.compile(optimizer=tf.optimizers.SGD(learning_rate=0.001), loss=FTMSE())
|
||||
model.summary()
|
||||
early_stop = EarlyStopping(monitor='val_loss', min_delta=0.0001, patience=20, mode='min', verbose=1)
|
||||
|
||||
history = model.fit(train_data, train_label, epochs=EPOCH, validation_data=(val_data, val_label),
|
||||
shuffle=True, verbose=1,
|
||||
callbacks=[checkpoint, lr_scheduler, early_stop])
|
||||
|
||||
#### TODO 测试
|
||||
|
||||
# trained_model = tf.keras.models.load_model(save_name, custom_objects={'LSTMLayer': LSTMLayer, 'FTMSE': FTMSE})
|
||||
|
||||
# todo 解决自定义loss无法导入的问题
|
||||
trained_model = tf.keras.models.load_model(save_name, compile=False, custom_objects={'LSTMLayer': LSTMLayer,'LightChannelAttention1':LightChannelAttention})
|
||||
trained_model.compile(optimizer=tf.optimizers.SGD(), loss=FTMSE())
|
||||
trained_model = tf.keras.models.load_model(save_name, compile=False, custom_objects={'AttentionEmbedLSTMLayer': LSTMLayer})
|
||||
# trained_model.compile(optimizer=tf.optimizers.SGD(), loss=FTMSE())
|
||||
|
||||
# 使用已知的点进行预测
|
||||
predicted_data = predictByEveryData(trained_model, train_data)
|
||||
|
|
|
|||
|
|
@ -9,7 +9,8 @@
|
|||
|
||||
import tensorflow as tf
|
||||
import numpy as np
|
||||
from model.LSTM.LSTM import LSTMLayer as LSTMLayer
|
||||
from model.LSTM.DCTAttention_embed_LSTM import AttentionEmbedLSTMLayer as LSTMLayer
|
||||
# from model.LSTM.LSTM import LSTMLayer as LSTMLayer
|
||||
import matplotlib.pyplot as plt
|
||||
from keras.callbacks import EarlyStopping
|
||||
|
||||
|
|
@ -21,18 +22,30 @@ from pylab import *
|
|||
'''
|
||||
超参数设置:
|
||||
'''
|
||||
hidden_num = 10 # LSTM细胞个数
|
||||
hidden_num = 40 # LSTM细胞个数
|
||||
feature = 10 # 一个点的维度
|
||||
batch_size = 32
|
||||
EPOCH = 1000
|
||||
unit = 512 # LSTM的维度
|
||||
predict_num = 50 # 预测个数
|
||||
model_name = "cnn_LSTM"
|
||||
model_name = "dctLSTM"
|
||||
save_name = r"self_{0}_hidden{1}_unit{2}_feature{3}_predict{4}.h5".format(model_name, hidden_num, unit, feature,
|
||||
predict_num)
|
||||
|
||||
|
||||
def getData(filter_num, dims):
|
||||
def standardization(data):
|
||||
mu = np.mean(data, axis=0)
|
||||
sigma = np.std(data, axis=0)
|
||||
return (data - mu) / sigma
|
||||
|
||||
|
||||
def normalization(data):
|
||||
_range = np.max(data) - np.min(data)
|
||||
return (data - np.min(data)) / _range
|
||||
|
||||
|
||||
# LSTM_cell的数目,维度,是否正则化
|
||||
def getData(filter_num, dims, if_norm: bool = False):
|
||||
# 数据读入
|
||||
HI_merge_data_origin = np.load("../../2012轴承数据集预测挑战/HI_create/HI_merge_data.npy")
|
||||
|
||||
|
|
@ -40,6 +53,10 @@ def getData(filter_num, dims):
|
|||
# 去除掉退化特征不明显前面的点
|
||||
HI_merge_data = HI_merge_data_origin[0:1250, 1]
|
||||
|
||||
# 是否正则化
|
||||
if if_norm:
|
||||
HI_merge_data = normalization(HI_merge_data)
|
||||
|
||||
# plt.plot(HI_merge_data)
|
||||
# plt.show()
|
||||
(total_dims,) = HI_merge_data.shape
|
||||
|
|
@ -125,8 +142,8 @@ def predict_model(filter_num, dims):
|
|||
# LSTM = tf.keras.layers.LSTM(units=256, return_sequences=False)(LSTM)
|
||||
|
||||
#### 自己
|
||||
LSTM = tf.keras.layers.Conv1D(512, kernel_size=8, padding='same')(input)
|
||||
LSTM = LSTMLayer(units=512, return_sequences=True)(LSTM)
|
||||
# LSTM = tf.keras.layers.Conv1D(512, kernel_size=8, padding='same')(input)
|
||||
LSTM = LSTMLayer(units=512, return_sequences=True)(input)
|
||||
LSTM = LSTMLayer(units=256, return_sequences=False)(LSTM)
|
||||
|
||||
x = tf.keras.layers.Dense(128, activation="relu")(LSTM)
|
||||
|
|
@ -194,20 +211,23 @@ if __name__ == '__main__':
|
|||
# verbose=2,
|
||||
# save_best_only=True,
|
||||
# mode='min')
|
||||
# lr_scheduler = tf.keras.callbacks.ReduceLROnPlateau(monitor='val_loss', factor=0.2, patience=20, min_lr=0.001)
|
||||
# lr_scheduler = tf.keras.callbacks.ReduceLROnPlateau(monitor='val_loss', factor=0.2, patience=10, min_lr=0.0001)
|
||||
#
|
||||
# model.compile(optimizer=tf.optimizers.SGD(), loss=tf.losses.mse)
|
||||
# model.summary()
|
||||
# early_stop = EarlyStopping(monitor='val_loss', min_delta=0.0001, patience=100, mode='min', verbose=1)
|
||||
#
|
||||
# history = model.fit(train_data, train_label_single, epochs=EPOCH, validation_data=(val_data, val_label_single), shuffle=True, verbose=1,
|
||||
# model.summary()
|
||||
# early_stop = EarlyStopping(monitor='val_loss', min_delta=0.0001, patience=20, mode='min', verbose=1)
|
||||
#
|
||||
# history = model.fit(train_data, train_label_single, epochs=EPOCH, validation_data=(val_data, val_label_single),
|
||||
# shuffle=True, verbose=1,
|
||||
# callbacks=[checkpoint, lr_scheduler, early_stop])
|
||||
|
||||
#### TODO 测试
|
||||
|
||||
trained_model = tf.keras.models.load_model(save_name, custom_objects={'LSTMLayer': LSTMLayer})
|
||||
trained_model = tf.keras.models.load_model(save_name, custom_objects={'AttentionEmbedLSTMLayer': LSTMLayer})
|
||||
|
||||
# 使用已知的点进行预测
|
||||
print("开始预测")
|
||||
predicted_data = predictByEveryData(trained_model, train_data)
|
||||
# 使用预测的点持续预测
|
||||
# predicted_data = predictOneByOne(trained_model, total_data, train_data)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,18 @@
|
|||
#-*- encoding:utf-8 -*-
|
||||
|
||||
'''
|
||||
@Author : dingjiawen
|
||||
@Date : 2023/11/9 10:26
|
||||
@Usage :
|
||||
@Desc :
|
||||
'''
|
||||
import tensorflow as tf
|
||||
|
||||
# 假设有两个形状为 (3,) 的张量
|
||||
tensor1 = tf.constant([1, 2, 3])
|
||||
tensor2 = tf.constant([4, 5, 6])
|
||||
|
||||
# 在新的轴上堆叠这两个张量
|
||||
stacked_tensor = tf.stack([tensor1, tensor2],axis=-1)
|
||||
|
||||
print(stacked_tensor)
|
||||
|
|
@ -0,0 +1,149 @@
|
|||
# -*- encoding:utf-8 -*-
|
||||
|
||||
'''
|
||||
@Author : dingjiawen
|
||||
@Date : 2023/11/9 16:42
|
||||
@Usage :
|
||||
@Desc :
|
||||
'''
|
||||
|
||||
import tensorflow as tf
|
||||
from model.LossFunction.TransferLoss import TransferLoss
|
||||
|
||||
|
||||
class AdaRNN(tf.keras.Model):
|
||||
def __init__(self, n_input=128, n_hiddens=[64, 64], n_output=6, len_seq=9, trans_loss='mmd'):
|
||||
super(AdaRNN, self).__init__()
|
||||
self.n_input = n_input
|
||||
self.num_layers = len(n_hiddens)
|
||||
self.hiddens = n_hiddens
|
||||
self.n_output = n_output
|
||||
self.trans_loss = trans_loss
|
||||
self.len_seq = len_seq
|
||||
|
||||
self.features = tf.keras.Sequential()
|
||||
for hidden in n_hiddens:
|
||||
rnn = tf.keras.layers.GRU(
|
||||
units=hidden,
|
||||
return_sequences=True
|
||||
)
|
||||
self.features.add(rnn)
|
||||
|
||||
self.fc_out = tf.keras.layers.Dense(n_output, activation=None)
|
||||
|
||||
self.gate = []
|
||||
for _ in range(len(n_hiddens)):
|
||||
gate_weight = tf.keras.layers.Dense(len_seq, activation=None)
|
||||
self.gate.append(gate_weight)
|
||||
self.bn_lst = [tf.keras.layers.BatchNormalization() for _ in range(len(n_hiddens))]
|
||||
self.softmax = tf.keras.layers.Softmax(axis=0)
|
||||
|
||||
# def init_layers(self):
|
||||
# for gate_layer in self.gate:
|
||||
# gate_layer.build((None, self.len_seq * self.hiddens[i] * 2))
|
||||
|
||||
def forward_pre_train(self, x, len_win=0):
|
||||
# 两层GRU之后的结果,每层GRU之后的结果,每层GRU前后权重归一化之后的结果
|
||||
out, out_list_all, out_weight_list = self.gru_features(x)
|
||||
fea = out
|
||||
|
||||
fc_out = self.fc_out(fea[:, -1, :]).squeeze()
|
||||
|
||||
out_list_s, out_list_t = self.get_features(out_list_all)
|
||||
|
||||
loss_transfer = tf.zeros((1,))
|
||||
for i in range(len(out_list_s)):
|
||||
criterion_transder = TransferLoss(
|
||||
loss_type=self.trans_loss)
|
||||
h_start = 0
|
||||
for j in range(h_start, self.len_seq, 1):
|
||||
i_start = max(j - len_win, 0)
|
||||
i_end = j + len_win if j + len_win < self.len_seq else self.len_seq - 1
|
||||
for k in range(i_start, i_end + 1):
|
||||
weight = out_weight_list[i][j]
|
||||
loss_transfer = loss_transfer + weight * criterion_transder(
|
||||
out_list_s[i][:, j, :], out_list_t[i][:, k, :])
|
||||
return fc_out, loss_transfer, out_weight_list
|
||||
|
||||
def call(self, x, len_win=0, training=False):
|
||||
# 两层GRU之后的结果,每层GRU之后的结果,每层GRU前后权重归一化之后的结果
|
||||
out, out_list_all, out_weight_list = self.gru_features(x, training=training)
|
||||
fea = out
|
||||
|
||||
fc_out = self.fc_out(fea[:, -1, :])
|
||||
|
||||
loss_transfer = tf.zeros((1,))
|
||||
for i in range(len(out_list_all)):
|
||||
criterion_transder = TransferLoss(
|
||||
loss_type=self.trans_loss)
|
||||
h_start = 0
|
||||
for j in range(h_start, self.len_seq, 1):
|
||||
i_start = max(j - len_win, 0)
|
||||
i_end = j + len_win if j + len_win < self.len_seq else self.len_seq - 1
|
||||
for k in range(i_start, i_end + 1):
|
||||
weight = out_weight_list[i][j]
|
||||
loss_transfer = loss_transfer + weight * criterion_transder.compute(
|
||||
out_list_all[i][:, j, :], out_list_all[i][:, k, :])
|
||||
return fc_out, loss_transfer, out_weight_list
|
||||
|
||||
def gru_features(self, x, training=False):
|
||||
x_input = x
|
||||
out = None
|
||||
out_lis = []
|
||||
out_weight_list = [] if (
|
||||
self.model_type == 'AdaRNN') else None
|
||||
for i in range(self.num_layers):
|
||||
out = self.features[i](x_input, training=training)
|
||||
x_input = out
|
||||
out_lis.append(out)
|
||||
if self.model_type == 'AdaRNN':
|
||||
out_gate = self.process_gate_weight(x_input, i, training=training)
|
||||
out_weight_list.append(out_gate)
|
||||
return out, out_lis, out_weight_list
|
||||
|
||||
def process_gate_weight(self, out, index, training=False):
|
||||
x_s = out[:, :out.shape[1] // 2] # 可以理解为LSTM的前半段
|
||||
x_t = out[:, out.shape[1] // 2:] # 可以理解为LSTM的后半段
|
||||
x_all = tf.concat((x_s, x_t), 2)
|
||||
x_all = tf.reshape(x_all, (x_all.shape[0], -1))
|
||||
weight = tf.sigmoid(self.bn_lst[index](self.gate[index](x_all)), training=training)
|
||||
weight = tf.reduce_mean(weight, axis=0)
|
||||
res = self.softmax(weight)
|
||||
return res
|
||||
|
||||
def get_features(self, output_list):
|
||||
fea_list_src, fea_list_tar = [], []
|
||||
for fea in output_list:
|
||||
fea_list_src.append(fea[:, :fea.shape[1] // 2])
|
||||
fea_list_tar.append(fea[:, fea.shape[1] // 2:])
|
||||
return fea_list_src, fea_list_tar
|
||||
|
||||
def forward_Boosting(self, x, weight_mat=None):
|
||||
out, out_list_all, _ = self.gru_features(x, training=False)
|
||||
fea = out
|
||||
|
||||
fc_out = self.fc_out(fea[:, -1, :])
|
||||
|
||||
out_list_all = out_list_all
|
||||
out_list_s, out_list_t = self.get_features(out_list_all)
|
||||
loss_transfer = tf.zeros((1,))
|
||||
if weight_mat is None:
|
||||
weight = (1.0 / self.len_seq *
|
||||
tf.ones((self.num_layers, self.len_seq), dtype=tf.float32))
|
||||
else:
|
||||
weight = weight_mat
|
||||
dist_mat = tf.zeros((self.num_layers, self.len_seq), dtype=tf.float32)
|
||||
for i in range(len(out_list_s)):
|
||||
criterion_transder = TransferLoss(
|
||||
loss_type=self.trans_loss)
|
||||
for j in range(self.len_seq):
|
||||
loss_trans = criterion_transder(out_list_s[i][:, j, :], out_list_t[i][:, j, :])
|
||||
loss_transfer = loss_transfer + weight[i, j] * loss_trans
|
||||
dist_mat[i, j] = loss_trans
|
||||
return fc_out, loss_transfer, dist_mat, weight
|
||||
|
||||
def update_weight_Boosting(self, weight_mat, dist_old, dist_new):
|
||||
epsilon = 1e-12
|
||||
dist_old = tf.stop_gradient(dist_old)
|
||||
dist_new = tf.stop_gradient(dist_new)
|
||||
ind = dist_new
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
#-*- encoding:utf-8 -*-
|
||||
|
||||
'''
|
||||
@Author : dingjiawen
|
||||
@Date : 2023/11/9 16:42
|
||||
@Usage :
|
||||
@Desc :
|
||||
'''
|
||||
|
|
@ -16,7 +16,6 @@ import matplotlib.pyplot as plt
|
|||
from tensorflow.keras.layers import Dense, Dropout, ReLU, BatchNormalization
|
||||
from scipy.fftpack import dct
|
||||
|
||||
|
||||
# def dct(x, norm=None):
|
||||
# """
|
||||
# Discrete Cosine Transform, Type II (a.k.a. the DCT)
|
||||
|
|
@ -55,16 +54,15 @@ from scipy.fftpack import dct
|
|||
# return V
|
||||
|
||||
|
||||
|
||||
import tensorflow as tf
|
||||
|
||||
|
||||
'''
|
||||
参考:
|
||||
[1] https://github.com/Zero-coder/FECAM/blob/main/layers/dctnet.py
|
||||
[2] https://arxiv.org/pdf/2212.01209v1.pdf
|
||||
'''
|
||||
|
||||
|
||||
def sdct_tf(signals, frame_length, frame_step, window_fn=tf.signal.hamming_window):
|
||||
"""Compute Short-Time Discrete Cosine Transform of `signals`.
|
||||
|
||||
|
|
@ -128,25 +126,34 @@ def isdct_tf(dcts, *, frame_step, frame_length=None, window_fn=tf.signal.hamming
|
|||
signals = signals / window_signal
|
||||
return signals
|
||||
|
||||
|
||||
class DCTChannelAttention(layers.Layer):
|
||||
|
||||
def build(self, input_shape):
|
||||
_, hidden, channel = input_shape
|
||||
self.l1 = Dense(channel * 2, use_bias=False)
|
||||
self.drop1 = Dropout(0.1)
|
||||
self.relu = ReLU(0.1)
|
||||
self.relu = ReLU()
|
||||
self.l2 = Dense(channel, use_bias=False)
|
||||
self.bn = BatchNormalization()
|
||||
self.bn = BatchNormalization(axis=-1, epsilon=1e-6)
|
||||
|
||||
def call(self, inputs, **kwargs):
|
||||
batch_size, hidden, channel = inputs.shape
|
||||
list = []
|
||||
stack_dct = tf.signal.dct(inputs, norm="ortho",axis=-1)
|
||||
change = tf.transpose(inputs, [0, 2, 1])
|
||||
stack_dct = tf.signal.dct(change, norm="ortho", axis=-1)
|
||||
stack_dct = tf.transpose(stack_dct, [0, 2, 1])
|
||||
|
||||
# for i in range(channel):
|
||||
# freq = tf.signal.dct(inputs[:, i, :], norm="ortho", axis=-1)
|
||||
# freq = tf.signal.dct(inputs[:, :, i], norm="ortho", axis=-1)
|
||||
# # print("freq-shape:",freq.shape)
|
||||
# list.append(freq)
|
||||
# stack_dct = tf.stack(list, dim=1)
|
||||
# freq = tf.expand_dims(freq, axis=2)
|
||||
# if i == 0:
|
||||
# stack_dct = freq
|
||||
# else:
|
||||
# stack_dct = tf.concat([stack_dct, freq], axis=2)
|
||||
# list.append(freq)
|
||||
# stack_dct = tf.stack(list, axis=-1)
|
||||
|
||||
lr_weight = self.bn(stack_dct)
|
||||
lr_weight = self.l1(stack_dct)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,80 @@
|
|||
#-*- encoding:utf-8 -*-
|
||||
|
||||
'''
|
||||
@Author : dingjiawen
|
||||
@Date : 2023/11/8 19:39
|
||||
@Usage :
|
||||
@Desc :
|
||||
'''
|
||||
import tensorflow as tf
|
||||
import numpy as np
|
||||
|
||||
|
||||
# 定义DCT函数
|
||||
def dct(x, norm=None):
|
||||
"""
|
||||
Discrete Cosine Transform, Type II (a.k.a. the DCT)
|
||||
"""
|
||||
x_shape = x.shape
|
||||
N = x_shape[-1]
|
||||
x = tf.reshape(x, [-1, N])
|
||||
|
||||
v = tf.concat([x[:, ::2], tf.reverse(x[:, 1::2], [1])], axis=1)
|
||||
|
||||
Vc = tf.signal.rfft(v, 1)
|
||||
|
||||
k = - tf.range(N, dtype=x.dtype) * np.pi / (2 * N)
|
||||
W_r = tf.cos(k)
|
||||
W_i = tf.sin(k)
|
||||
|
||||
V = Vc[:, :, 0] * W_r - Vc[:, :, 1] * W_i
|
||||
|
||||
if norm == 'ortho':
|
||||
V[:, 0] /= np.sqrt(N) * 2
|
||||
V[:, 1:] /= np.sqrt(N / 2) * 2
|
||||
|
||||
V = 2 * tf.reshape(V, x_shape)
|
||||
|
||||
return V
|
||||
|
||||
|
||||
# 定义tf.keras版本的dct_channel_block
|
||||
class DctChannelBlock(tf.keras.layers.Layer):
|
||||
def __init__(self, channel):
|
||||
super(DctChannelBlock, self).__init__()
|
||||
self.fc = tf.keras.Sequential([
|
||||
tf.keras.layers.Dense(channel * 2, use_bias=False),
|
||||
tf.keras.layers.Dropout(0.1),
|
||||
tf.keras.layers.ReLU(),
|
||||
tf.keras.layers.Dense(channel, use_bias=False),
|
||||
tf.keras.layers.Activation('sigmoid')
|
||||
])
|
||||
self.dct_norm = tf.keras.layers.LayerNormalization(axis=-1, epsilon=1e-6)
|
||||
|
||||
# def get_config(self):
|
||||
# # 自定义层里面的属性
|
||||
# config = (
|
||||
# {
|
||||
# 'units': self.units,
|
||||
# 'return_sequences': self.return_sequences
|
||||
# }
|
||||
# )
|
||||
# base_config = super(DctChannelBlock, self).get_config()
|
||||
# return dict(list(base_config.items()) + list(config.items()))
|
||||
|
||||
def call(self, inputs, **kwargs):
|
||||
x = inputs
|
||||
b, c, l = x.shape
|
||||
dct_list = []
|
||||
for i in range(c):
|
||||
freq = dct(x[:, i, :])
|
||||
dct_list.append(freq)
|
||||
|
||||
stack_dct = tf.stack(dct_list, axis=1)
|
||||
lr_weight = self.dct_norm(stack_dct)
|
||||
lr_weight = self.fc(stack_dct)
|
||||
lr_weight = self.dct_norm(lr_weight)
|
||||
|
||||
return x * lr_weight
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,120 @@
|
|||
# -*- encoding:utf-8 -*-
|
||||
|
||||
'''
|
||||
@Author : dingjiawen
|
||||
@Date : 2023/6/14 13:49
|
||||
@Usage :
|
||||
@Desc : 标准版LSTM
|
||||
'''
|
||||
|
||||
import tensorflow as tf
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
import matplotlib.pyplot as plt
|
||||
from tensorflow.keras.layers import Dense, Conv2D, Conv1D
|
||||
from model.ChannelAttention.DCT_channelAttention import DCTChannelAttention as DctChannelBlock
|
||||
|
||||
from tensorflow.keras import *
|
||||
import tensorflow.keras.layers as layers
|
||||
|
||||
|
||||
class AttentionEmbedLSTMLayer(layers.Layer):
|
||||
# 定义两个权重初始化方法,方便后续调用
|
||||
k_ini = initializers.GlorotUniform()
|
||||
b_ini = initializers.Zeros()
|
||||
|
||||
def __init__(self, units=30, return_sequences: bool = False, **kwargs):
|
||||
super(AttentionEmbedLSTMLayer, self).__init__()
|
||||
self.units = units
|
||||
self.return_sequences = return_sequences
|
||||
|
||||
def get_params(self, num_inputs, num_outputs):
|
||||
def _one(shape, name):
|
||||
# return tf.Variable(tf.random.normal(shape=shape, stddev=0.01, mean=0, dtype=tf.float32))
|
||||
return self.add_weight(shape=shape, name=name, initializer=tf.random_normal_initializer)
|
||||
|
||||
def _three(name1, name2):
|
||||
return (_one(shape=(num_inputs + num_outputs, num_outputs), name=name1),
|
||||
self.add_weight(shape=(num_outputs,), name=name2,
|
||||
initializer=tf.zeros_initializer))
|
||||
|
||||
W_i, b_i = _three("W_i", "b_i") # 输入门参数
|
||||
W_f, b_f = _three("W_f", "b_f") # 遗忘门参数
|
||||
W_o, b_o = _three("W_o", "b_o") # 输出门参数
|
||||
W_c, b_c = _three("W_c", "b_c") # 候选记忆细胞参数
|
||||
|
||||
# 输出层参数
|
||||
return W_i, b_i, W_f, b_f, W_o, b_o, W_c, b_c
|
||||
|
||||
def get_config(self):
|
||||
# 自定义层里面的属性
|
||||
config = (
|
||||
{
|
||||
'units': self.units,
|
||||
'return_sequences': self.return_sequences
|
||||
}
|
||||
)
|
||||
base_config = super(AttentionEmbedLSTMLayer, self).get_config()
|
||||
return dict(list(base_config.items()) + list(config.items()))
|
||||
|
||||
def build(self, input_shape):
|
||||
num_inputs, num_outputs = input_shape[-1], self.units
|
||||
|
||||
self.W_i, self.b_i, self.W_f, self.b_f, self.W_o, self.b_o, self.W_c, self.b_c = self.get_params(
|
||||
num_inputs=num_inputs, num_outputs=num_outputs)
|
||||
self.dctAttention = DctChannelBlock(num_inputs + num_outputs)
|
||||
pass
|
||||
|
||||
def call(self, inputs, **kwargs):
|
||||
epoch, hiddens, dims = inputs.shape
|
||||
# print(filter_num, dims)
|
||||
|
||||
for hidden in range(hiddens):
|
||||
new_input = inputs[:, hidden, :]
|
||||
new_input = tf.expand_dims(new_input, axis=1)
|
||||
|
||||
if hidden != 0:
|
||||
new_input = tf.concat([new_input, ht_1], axis=-1)
|
||||
else:
|
||||
new_input = tf.pad(new_input, [[0, 0], [0, 0], [0, self.units]])
|
||||
|
||||
new_input = self.dctAttention(new_input)
|
||||
|
||||
Wi = tf.matmul(new_input, self.W_i) + self.b_i
|
||||
Wf = tf.matmul(new_input, self.W_f) + self.b_f
|
||||
Wc = tf.matmul(new_input, self.W_c) + self.b_c
|
||||
Wo = tf.matmul(new_input, self.W_o) + self.b_o
|
||||
|
||||
ft = tf.nn.sigmoid(Wf)
|
||||
it = tf.nn.sigmoid(Wi)
|
||||
ct_ = tf.nn.tanh(Wc)
|
||||
ot = tf.nn.sigmoid(Wo)
|
||||
|
||||
if hidden != 0:
|
||||
ct = tf.add(tf.multiply(ft, ct_1), tf.multiply(it, ct_))
|
||||
else:
|
||||
ct = tf.multiply(it, ct_)
|
||||
ht = tf.multiply(tf.nn.tanh(ct), ot)
|
||||
|
||||
if self.return_sequences:
|
||||
if hidden == 0:
|
||||
output = ht
|
||||
else:
|
||||
output = tf.concat([output, ht], axis=1)
|
||||
else:
|
||||
if hidden == hiddens - 1:
|
||||
output = tf.squeeze(ht, axis=1)
|
||||
|
||||
ht_1 = ht
|
||||
ct_1 = ct
|
||||
|
||||
# output = tf.reshape(output, [-1, filter_num, units])
|
||||
|
||||
# print(output.shape)
|
||||
return output
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
pass
|
||||
|
||||
# tf.keras.layers.LSTM(return_sequences=)
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
# -*- encoding:utf-8 -*-
|
||||
|
||||
'''
|
||||
@Author : dingjiawen
|
||||
@Date : 2023/11/9 16:47
|
||||
@Usage :
|
||||
@Desc :
|
||||
'''
|
||||
from model.LossFunction.transfer.mmd import MMDLoss
|
||||
import tensorflow as tf
|
||||
import tensorflow.losses
|
||||
|
||||
|
||||
class TransferLoss(tf.keras.losses.Loss):
|
||||
def __init__(self, loss_type='cosine'):
|
||||
"""
|
||||
Supported loss_type: mmd(mmd_lin), mmd_rbf, coral, cosine, kl, js, mine, adv
|
||||
"""
|
||||
self.loss_type = loss_type
|
||||
|
||||
|
||||
def call(self, X, Y):
|
||||
"""Compute adaptation loss
|
||||
|
||||
Arguments:
|
||||
X {tensor} -- source matrix
|
||||
Y {tensor} -- target matrix
|
||||
|
||||
Returns:
|
||||
[tensor] -- transfer loss
|
||||
"""
|
||||
if self.loss_type == 'mmd_lin' or self.loss_type == 'mmd':
|
||||
mmdloss = MMDLoss(kernel_type='linear')
|
||||
loss = mmdloss(X, Y)
|
||||
elif self.loss_type == 'cosine' or self.loss_type == 'cos':
|
||||
loss = 1 - tf.losses.cosine_similarity(X, Y)
|
||||
elif self.loss_type == 'mmd_rbf':
|
||||
mmdloss = MMDLoss(kernel_type='rbf')
|
||||
loss = mmdloss(X, Y)
|
||||
|
||||
return loss
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
#-*- encoding:utf-8 -*-
|
||||
|
||||
'''
|
||||
@Author : dingjiawen
|
||||
@Date : 2023/11/9 16:54
|
||||
@Usage :
|
||||
@Desc :
|
||||
'''
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
import tensorflow as tf
|
||||
import numpy as np
|
||||
|
||||
|
||||
class MMDLoss(tf.keras.losses.Loss):
|
||||
def __init__(self, kernel_type='linear', kernel_mul=2.0, kernel_num=5):
|
||||
super(MMDLoss, self).__init__()
|
||||
self.kernel_type = kernel_type
|
||||
self.kernel_mul = kernel_mul
|
||||
self.kernel_num = kernel_num
|
||||
|
||||
def get_config(self):
|
||||
# 自定义层里面的属性
|
||||
config = (
|
||||
{
|
||||
'kernel_type': self.kernel_type,
|
||||
'kernel_mul': self.kernel_mul,
|
||||
'kernel_num': self.kernel_num
|
||||
}
|
||||
)
|
||||
base_config = super(MMDLoss, self).get_config()
|
||||
return dict(list(base_config.items()) + list(config.items()))
|
||||
|
||||
def guassian_kernel(self, source, target, kernel_mul=2.0, kernel_num=5, fix_sigma=None):
|
||||
n_samples = int(source.shape[0]) + int(target.shape[0])
|
||||
total = tf.concat([source, target], axis=0)
|
||||
total0 = tf.expand_dims(total, 0)
|
||||
total0 = tf.tile(total0, [total.shape[0], 1, 1])
|
||||
total1 = tf.expand_dims(total, 1)
|
||||
total1 = tf.tile(total1, [1, total.shape[0], 1])
|
||||
L2_distance = tf.reduce_sum((total0 - total1) ** 2, axis=2)
|
||||
|
||||
if fix_sigma:
|
||||
bandwidth = fix_sigma
|
||||
else:
|
||||
bandwidth = tf.reduce_sum(L2_distance) / (n_samples ** 2 - n_samples)
|
||||
bandwidth /= kernel_mul ** (kernel_num // 2)
|
||||
bandwidth_list = [bandwidth * (kernel_mul ** i)
|
||||
for i in range(kernel_num)]
|
||||
kernel_val = [tf.exp(-L2_distance / bandwidth_temp)
|
||||
for bandwidth_temp in bandwidth_list]
|
||||
return sum(kernel_val)
|
||||
|
||||
def linear_mmd(self, X, Y):
|
||||
delta = tf.reduce_mean(X, axis=0) - tf.reduce_mean(Y, axis=0)
|
||||
loss = tf.linalg.matmul(delta, delta, transpose_b=True)
|
||||
return loss
|
||||
|
||||
def call(self, source, target):
|
||||
if self.kernel_type == 'linear':
|
||||
return self.linear_mmd(source, target)
|
||||
elif self.kernel_type == 'rbf':
|
||||
batch_size = int(source.shape[0])
|
||||
kernels = self.guassian_kernel(
|
||||
source, target, kernel_mul=self.kernel_mul, kernel_num=self.kernel_num, fix_sigma=None)
|
||||
with tf.GradientTape(persistent=True) as tape:
|
||||
tape.watch(kernels)
|
||||
XX = tf.reduce_mean(kernels[:batch_size, :batch_size])
|
||||
YY = tf.reduce_mean(kernels[batch_size:, batch_size:])
|
||||
XY = tf.reduce_mean(kernels[:batch_size, batch_size:])
|
||||
YX = tf.reduce_mean(kernels[batch_size:, :batch_size])
|
||||
loss = XX + YY - XY - YX
|
||||
return loss
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
# 示例用法
|
||||
source = np.random.randn(100, 128)
|
||||
target = np.random.randn(100, 128)
|
||||
source_tf = tf.convert_to_tensor(source, dtype=tf.float32)
|
||||
target_tf = tf.convert_to_tensor(target, dtype=tf.float32)
|
||||
|
||||
mmd_loss = MMDLoss(kernel_type='rbf', kernel_mul=2.0, kernel_num=5)
|
||||
loss = mmd_loss(source_tf, target_tf)
|
||||
print("MMD Loss:", loss.numpy())
|
||||
Loading…
Reference in New Issue