模型更新

This commit is contained in:
kevinding1125 2023-06-18 14:13:45 +08:00
parent d97c3e8731
commit 2400af4a1a
63 changed files with 8195 additions and 21 deletions

View File

@ -0,0 +1,41 @@
package com.markilue.leecode.interview.OPPO.T0411;
import java.util.Scanner;
/**
*@BelongsProject: Leecode
*@BelongsPackage: com.markilue.leecode.interview.OPPO.T0411
*@Author: markilue
*@CreateTime: 2023-06-14 10:41
*@Description: TODO
*@Version: 1.0
*/
public class Question1 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String s = sc.next();
solve(s);
}
private static void solve(String s) {
int left = 0;
int right = 0;
int xiaochu = 0;
for (int i = 0; i < s.length(); i++) {
char cur = s.charAt(i);
if (cur == '(') {
left++;
} else if (cur == ')') {
if (left > 0) {
left--;
xiaochu++;
} else {
right++;
}
}
}
System.out.println(s.length() - xiaochu);
}
}

View File

@ -0,0 +1,47 @@
package com.markilue.leecode.interview.OPPO.T0411;
import java.util.Arrays;
import java.util.Scanner;
/**
*@BelongsProject: Leecode
*@BelongsPackage: com.markilue.leecode.interview.OPPO.T0411
*@Author: markilue
*@CreateTime: 2023-06-14 11:02
*@Description: TODO
*@Version: 1.0
*/
public class Question2 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
solve(n);
}
private static void solve(int n) {
if (n % 2 == 0) {
if (n == 2) {
System.out.println(2);
return;
}
System.out.println(cal(n / 2) * 2 * 2 % mod);
} else {
System.out.println(cal(n / 2 + 1) * cal(n / 2) % mod);
}
}
static long[] memo = new long[(int) 1e5];
static long mod = (long) (1e9 + 7);
public static long cal(int n) {
if (memo[n] != 0) {
return memo[n];
} else if (n == 1) {
return 1;
}
memo[n] = n * cal(n - 1) % mod;
return memo[n];
}
}

View File

@ -0,0 +1,44 @@
package com.markilue.leecode.interview.baidu.T0410;
import java.util.Arrays;
import java.util.Scanner;
/**
*@BelongsProject: Leecode
*@BelongsPackage: com.markilue.leecode.interview.baidu.T0410
*@Author: markilue
*@CreateTime: 2023-06-14 11:32
*@Description: TODO
*@Version: 1.0
*/
public class Question1 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int k = sc.nextInt();
int[] nums = new int[n];
for (int i = 0; i < n; i++) {
nums[i] = sc.nextInt();
}
solve(nums, k);
}
//猜测:前k-1个单独分最小的前k-1个数;后面全在一起
private static void solve(int[] nums, int k) {
Arrays.sort(nums);
double result = 0;
//前k-1个单独是一个
for (int i = 0; i < k - 1; i++) {
result += nums[i];
}
//后面全在一起
double temp = 0;
for (int i = k - 1; i < nums.length; i++) {
temp += nums[i];
}
double avg = temp / (nums.length - k + 1);
System.out.println((result+avg));
}
}

View File

@ -39,7 +39,7 @@ public class Question3 {
{-2, -3, 4}, {-2, -3, 4},
}; };
// calculateMaxRectangleSum(2, 3, income); // calculateMaxRectangleSum(2, 3, income);
calculate(2, 3, income); calculate1(2, 3, income);
} }
private static void calculateMaxRectangleSum(int m, int n, int[][] matrix) { private static void calculateMaxRectangleSum(int m, int n, int[][] matrix) {
@ -106,4 +106,39 @@ public class Question3 {
} }
//二刷尝试:由于需要计算那一块的面积但是不知道那一块的具体大小所以考虑使用前缀和进行计算
private static void calculate1(int m, int n, int[][] matrix) {
int[][] prefix = new int[m + 1][n + 1];
//构造前缀和数组
for (int i = 1; i < m + 1; i++) {
for (int j = 1; j < n + 1; j++) {
prefix[i][j] = prefix[i - 1][j] + prefix[i][j - 1] - prefix[i - 1][j - 1] + matrix[i - 1][j - 1];
}
}
//挨个遍历寻找面积最大值
int result = Integer.MIN_VALUE;
int edge = 0;
for (int i = 1; i < m + 1; i++) {
for (int j = 1; j < n + 1; j++) {//左上角
for (int k = i; k < m + 1; k++) {
for (int l = j; l < n + 1; l++) {//右下角
int cur = prefix[k][l] - prefix[i - 1][l] - prefix[k][j - 1] + prefix[i - 1][j - 1];
if (cur > result) {
result = cur;
edge = (k - i + 1) * (l - j + 1);
}
}
}
}
}
System.out.println(edge + " " + result);
}
} }

View File

@ -0,0 +1,146 @@
import tensorflow as tf
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
# 数据导入
data = np.load("../data/HI_DATA/HI_data.npy")
print(data.shape) # (2803, 2560)
(samples, dims) = data.shape
# # 24个指标建立
fs = 25.6 * 1000
T1 = np.mean(data, axis=1)
print(T1.shape)
#
T2 = np.sqrt(np.var(data, axis=1))
T3 = np.mean(np.sqrt(np.abs(data)), axis=1) ** 2
T4 = np.sqrt(np.mean(data ** 2, axis=1))
T5 = np.max(np.abs(data), axis=1)
T6 = np.mean((data - np.broadcast_to(np.expand_dims(T1, axis=1), (samples, dims))) ** 3, axis=1) / (T4 ** 3)
T7 = np.mean((data - np.broadcast_to(np.expand_dims(T1, axis=1), (samples, dims))) ** 4, axis=1) / (T4 ** 4)
T8 = T5 / T4
T9 = T5 / T3
T10 = T4 / np.mean(np.abs(data), axis=1)
T11 = T5 / np.mean(np.abs(data), axis=1)
# 频域
sk = np.abs(np.fft.rfft(data, axis=1) * 2 / dims)
sk = sk[:, 0:-1] # (2803,1280)
(samples, k) = sk.shape # (2803,1280)
print("data:", data)
print("sk:", sk)
fk = np.empty(shape=[samples, k])
for sample in range(samples):
for i in range(k):
fk[sample][i] = (fs / dims) * (i + 1)
# print(fk)
# print(fk.shape)
# plt.plot(sk[1,:])
# plt.xlim((0,k))
# plt.ylim((0,1.5))
# plt.show()
# print(sk.shape)
F1 = np.mean(sk, axis=1)
F2 = np.var(sk, axis=1) * k / (k - 1)
F3 = np.mean((sk - np.broadcast_to(np.expand_dims(F1, axis=1), (samples, k))) ** 3, axis=1) / (np.sqrt(F2) ** 3)
F4 = np.mean((sk - np.broadcast_to(np.expand_dims(F1, axis=1), (samples, k))) ** 4, axis=1) / (F2 ** 2)
F5 = np.sum(np.multiply(fk, sk), axis=1) / np.sum(sk, axis=1)
F6 = np.sqrt(np.mean(np.multiply((fk - np.broadcast_to(np.expand_dims(F5, axis=1), (samples, k))) ** 2, sk), axis=1))
F7 = np.sqrt(np.sum(np.multiply(fk ** 2, sk), axis=1) / np.sum(sk, axis=1))
F8 = np.sqrt(np.sum(np.multiply(fk ** 4, sk), axis=1) / np.sum(fk ** 2 * sk, axis=1))
F9 = np.sum(np.multiply(fk ** 2, sk), axis=1) / np.sqrt(np.sum(sk, axis=1) * np.sum(np.multiply(fk ** 4, sk), axis=1))
F10 = F6 / F5
F11 = np.mean(np.multiply((fk - np.broadcast_to(np.expand_dims(F5, axis=1), (samples, k))) ** 3, sk), axis=1) / (
F6 ** 3)
F12 = np.mean(np.multiply((fk - np.broadcast_to(np.expand_dims(F5, axis=1), (samples, k))) ** 4, sk), axis=1) / (
F6 ** 4)
F13 = np.mean(np.sqrt(np.abs(fk - np.broadcast_to(np.expand_dims(F5, axis=1), (samples, k)))) * sk, axis=1) / np.sqrt(
F6)
# 归一化处理
# T1 = (T1 - np.min(T1)) / (np.max(T1) - np.min(T1))
# T2 = (T2 - np.min(T2)) / (np.max(T2) - np.min(T2))
# T3 = (T3 - np.min(T3)) / (np.max(T3) - np.min(T3))
# T4 = (T4 - np.min(T4)) / (np.max(T4) - np.min(T4))
# T5 = (T5 - np.min(T5)) / (np.max(T5) - np.min(T5))
# T6 = (T6 - np.min(T6)) / (np.max(T6) - np.min(T6))
# T7 = (T7 - np.min(T7)) / (np.max(T7) - np.min(T7))
# T8 = (T8 - np.min(T8)) / (np.max(T8) - np.min(T8))
# T9 = (T9 - np.min(T9)) / (np.max(T9) - np.min(T9))
# T10 = (T10 - np.min(T10)) / (np.max(T10) - np.min(T10))
# T11 = (T11 - np.min(T11)) / (np.max(T11) - np.min(T11))
# F1 = (F1 - np.min(F1)) / (np.max(F1) - np.min(F1))
# F2 = (F2 - np.min(F2)) / (np.max(F2) - np.min(F2))
# F3 = (F3 - np.min(F3)) / (np.max(F3) - np.min(F3))
# F4 = (F4 - np.min(F4)) / (np.max(F4) - np.min(F4))
# F5 = (F5 - np.min(F5)) / (np.max(F5) - np.min(F5))
# F6 = (F6 - np.min(F6)) / (np.max(F6) - np.min(F6))
# F7 = (F7 - np.min(F7)) / (np.max(F7) - np.min(F7))
# F8 = (F8 - np.min(F8)) / (np.max(F8) - np.min(F8))
# F9 = (F9 - np.min(F9)) / (np.max(F9) - np.min(F9))
# F10 = (F10 - np.min(F10)) / (np.max(F10) - np.min(F10))
# F11 = (F11 - np.min(F11)) / (np.max(F11) - np.min(F11))
# F12 = (F12 - np.min(F12)) / (np.max(F12) - np.min(F12))
# F13 = (F13 - np.min(F13)) / (np.max(F13) - np.min(F13))
print(F5)
plt.plot(F5)
plt.show()
#
# if __name__ == '__main__':
#
# T1 = np.expand_dims(T1, axis=1)
# T2 = np.expand_dims(T2, axis=1)
# T3 = np.expand_dims(T3, axis=1)
# T4 = np.expand_dims(T4, axis=1)
# T5 = np.expand_dims(T5, axis=1)
# T6 = np.expand_dims(T6, axis=1)
# T7 = np.expand_dims(T7, axis=1)
# T8 = np.expand_dims(T8, axis=1)
# T9 = np.expand_dims(T9, axis=1)
# T10 = np.expand_dims(T10, axis=1)
# T11 = np.expand_dims(T11, axis=1)
# F1 = np.expand_dims(F1, axis=1)
# F2 = np.expand_dims(F2, axis=1)
# F3 = np.expand_dims(F3, axis=1)
# F4 = np.expand_dims(F4, axis=1)
# F5 = np.expand_dims(F5, axis=1)
# F6 = np.expand_dims(F6, axis=1)
# F7 = np.expand_dims(F7, axis=1)
# F8 = np.expand_dims(F8, axis=1)
# F9 = np.expand_dims(F9, axis=1)
# F10 = np.expand_dims(F10, axis=1)
# F11 = np.expand_dims(F11, axis=1)
# F12 = np.expand_dims(F12, axis=1)
# F13 = np.expand_dims(F13, axis=1)
# feature_data=tf.concat([T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,F1,F2,F3,F4,F5,F6,F7,F8,F9,F10,F11,F12,F13],axis=1)
# np.save('feature_data.npy',feature_data)
# print(feature_data.shape)
# print(HI_data.shape)
# np.save("../data/HI_DATA/HIed_data.npy",HI_data)

View File

@ -0,0 +1,62 @@
import tensorflow as tf
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
# 数据读取
# train_data = np.load("Select_data.npy")
# print(train_data.shape)
feature_data = np.load("../data/HI_DATA/feature_data.npy")
print(feature_data.shape) # (2803,24)
indexs=[1,2,3,11,20,23]
z = 0
for index in indexs:
if z == 0:
Selected_data = feature_data[:, index]
else:
Selected_data = np.vstack([Selected_data, feature_data[:, index]])
z += 1
Selected_data = np.transpose(Selected_data, [1, 0]) # (2803,9)
train_data=Selected_data[1500:-1,:]
print(train_data.shape)
# 建立模型
class model():
def __init__(self, input_shape=9):
self.input = input
pass
def getModel(self, model_Type='ae'):
if model_Type == 'ae':
model = self.AE_model()
return model
else:
raise ValueError("模型尚未实现")
def AE_model(self, input_shape=6):
input = tf.keras.Input(shape=input_shape)
d1 = tf.keras.layers.Dense(4)(input)
# d2 = tf.keras.layers.Dense(2, activation='relu')(d1)
d3 = tf.keras.layers.Dense(2, name='mid', activation='relu')(d1)
# d4 = tf.keras.layers.Dense(2, activation='relu')(d3)
d5 = tf.keras.layers.Dense(4)(d3)
d6 = tf.keras.layers.Dense(input_shape)(d5)
model = tf.keras.Model(inputs=input, outputs=d6)
return model
# HI指标训练和合成
if __name__ == '__main__':
model = model(input_shape=6).getModel(model_Type='ae')
model.compile(optimizer=tf.optimizers.Adam(0.001), loss=tf.losses.mse, metrics=['acc'])
model.summary()
history = model.fit(train_data, train_data, epochs=300, batch_size=100)
HI_merge_data = tf.keras.models.Model(inputs=model.input, outputs=model.get_layer('mid').output).predict(train_data)
print(HI_merge_data)
acc = np.array(history.history.get('acc'))
# if acc[299] > 0.9:
np.save("HI_merge_data.npy", HI_merge_data)
model.save("AE_model.h5")

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

View File

@ -0,0 +1,98 @@
import tensorflow as tf
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
# 数据导入
feature_data = np.load("../data/HI_DATA/feature_data.npy")
print(feature_data.shape) # (2803,24)
feature_data = np.transpose(feature_data, [1, 0])
print(feature_data.shape) # (24,2803)
# data.shape:(24,2803)
class HI_select():
def __init__(self, data):
self.data = data
def getScore(self):
score = (self.getTred() + self.getMon() + self.getScale()) / 2
print(score.shape)
return score
def getTred(self):
h = self.data
(features, dims) = h.shape
h_mean = np.mean(h, axis=1)
tk = np.broadcast_to(np.expand_dims(np.arange(dims), axis=0), (features, dims)) # (24,2803)
tk_mean = np.mean(tk, axis=1)
tred = np.abs(np.sum(np.multiply((h - np.broadcast_to(np.expand_dims(h_mean, axis=1), (features, dims))),
(tk - np.broadcast_to(np.expand_dims(tk_mean, axis=1), (features, dims)))),
axis=1)) / np.sqrt(
np.sum((h - np.broadcast_to(np.expand_dims(h_mean, axis=1), (features, dims))) ** 2, axis=1) * np.sum(
(tk - np.broadcast_to(np.expand_dims(tk_mean, axis=1), (features, dims))) ** 2, axis=1))
# print(tred)
tred = np.expand_dims(tred, axis=1)
# print("tred.shape:", tred.shape)
return tred
# 单调性
def getMon(self):
h = self.data
(features, dims) = h.shape
mon = np.empty(shape=[24, 1])
for feature in range(features):
positive = 0
negative = 0
for dim in range(dims):
if dim + 1 >= dims:
break
if h[feature][dim + 1] - h[feature][dim] > 0:
positive += 1
if h[feature][dim + 1] - h[feature][dim] < 0:
negative += 1
# print("positive:",positive)
# print("negetive:",negative)
mon[feature] = np.abs((positive - negative) / (dims - 1))
# print(mon[feature])
# print(mon)
# print("mon.shape",mon.shape)
return mon
# 尺度相似性
def getScale(self):
scale = np.zeros(shape=[24, 1])
return scale
if __name__ == '__main__':
scores = HI_select(feature_data).getScore()
(feature, score) = scores.shape
scores = np.ravel(scores)
print(scores.shape)
# 归一化处理
# scores = (scores - np.min(scores)) / (np.max(scores) - np.min(scores))
# score图
plt.bar(range(feature),scores,color=['r','g','b','c','m','y'])
plt.show()
# 获取前9个最大值的索引
# print(scores)
# indexs = np.argpartition(scores, -12)[-12:] # [ 1 23 16 9 19 20 2 22 18] 自选【1,2,3,11,20,23】 备选【9,16,18】
# print(indexs)
# # 选出所需的data
# Selected_data = []
# feature_data = np.transpose(feature_data, [1, 0]) # (2803,24)
# z = 0
# for index in indexs:
# if z == 0:
# Selected_data = feature_data[:, index]
# else:
# Selected_data = np.vstack([Selected_data, feature_data[:, index]])
# z += 1
# Selected_data=np.transpose(Selected_data,[1,0]) #(2803,9)
# # np.save("Select_data.npy",Selected_data)
# print(Selected_data.shape)

View File

@ -0,0 +1,13 @@
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
#数据导入
HI_merge_data=np.load("HI_merge_data.npy")
HI_merge_data=HI_merge_data[0:1250,1]
print(HI_merge_data.shape)
print(HI_merge_data)
plt.plot(HI_merge_data)
plt.show()

View File

@ -0,0 +1,175 @@
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
from model.LSTM.before.LSTM_realize_self import LSTM_realize
# 数据读入
# HI_merge_data = np.load("../HI_create/HI_merge_data.npy")
# # 去除掉退化特征不明显前面的点
# HI_merge_data = HI_merge_data[0:1250, 1]
# print(HI_merge_data)
# print(HI_merge_data.shape)
# plt.plot(HI_merge_data)
# plt.show()
# (dims,)=HI_merge_data.shape
# # 将其分成重叠采样状态-滑动窗口函数
# #train_data =np.lib.stride_stricks.sliding_window_view(HI_merge_data, 3)
# # train_data =np.lib.stride_stricks.as_strided(HI_merge_data,(1240,10),(10,))
#
# train_data=np.empty(shape=[49,1200])
# train_label=np.empty(shape=[1,1200])
# predict_data=np.empty(shape=[50,1200])
# z=0
# for dim in range(dims):
#
# if dim+1200>=dims:
# break
# predict_data[dim]=HI_merge_data[dim:dim+1200]
#
# if dim+1200==dims-1:
# train_label=HI_merge_data[dim:dim+1200]
# else:
# train_data[dim] = HI_merge_data[dim:dim + 1200]
#
# print(train_data.shape)
# print(train_data)
# print(train_label.shape)
# print(train_label)
#
# print(predict_data.shape)
# print(predict_data)
# #
# np.save("../data/trian_data/train_data.npy", train_data)
# np.save("../data/trian_data/train_label.npy", train_label)
# np.save("../data/trian_data/predict_data.npy",predict_data)
# train_label=
# 处理好的trian_data的读取
train_data = np.load("../data/trian_data/train_data.npy") # (49,1200)
train_label = np.load("../data/trian_data/train_label.npy") # (1200,)
predict_data = np.load("../data/trian_data/predict_data.npy") # (50,1200)
# train_label = np.expand_dims(train_label, axis=0)
# # 数据处理 - 分成一个epoch训练240次
filter_num = 600
dims = 49
batch_size = 1
train_data = np.reshape(train_data, [dims, filter_num, -1]) # (49,5,240)
train_data = np.transpose(train_data, [2, 0, 1]) # (240,49,5)
predict_data = np.reshape(predict_data, [dims + 1, filter_num, -1]) # (50,5,240)
predict_data = np.transpose(predict_data, [2, 0, 1]) # (240,50,5)
train_label = np.reshape(train_label, [filter_num, -1]) # (5,240)
train_label = np.transpose(train_label, [1, 0]) # (240,5)
#
# train_label=np.ravel(train_label)
print(train_data.shape)
print(train_label.shape)
print(predict_data.shape)
# LSTM_realize(input=train_data, filters=1200).getLayer(layer='LSTM')
def predict_model():
input = tf.keras.Input(shape=[dims, filter_num])
input = tf.cast(input, tf.float32)
print(input.shape)
# LSTM=tf.keras.layers.LSTM(filter_num)(input)
LSTM = LSTM_realize(input=input, filters=filter_num, batch_size=batch_size).getLayer(layer='SA_convLSTM',
query=train_label)
d1 = tf.keras.layers.Dense(1000, activation='relu')(LSTM)
# drop = tf.keras.layers.Dropout(0.2)(LSTM)
# bn = tf.keras.layers.BatchNormalization()(Lstm)
output = tf.keras.layers.Dense(filter_num, name='output')(d1)
model = tf.keras.Model(inputs=input, outputs=output)
return model
#
if __name__ == '__main__':
model = predict_model()
model.compile(optimizer=tf.optimizers.Adam(0.01), loss=tf.losses.mse, metrics=['acc'])
model.summary()
history = model.fit(train_data, train_label, validation_data=(train_data, train_label), epochs=200,
batch_size=batch_size)
# model.save("LSTM_model.h5")
# model = tf.keras.models.load_model("LSTM_model.h5")
#
# fig3 = plt.figure()
# ax3 = fig3.add_subplot()
# plt.plot(history.epoch, history.history.get('acc'), label='acc')
# plt.plot(history.epoch, history.history.get('val_acc'), label='val_acc')
# plt.show()
#
# fig4 = plt.figure()
# ax4 = fig3.add_subplot()
# plt.plot(history.epoch, history.history.get('loss'), label='loss')
# plt.plot(history.epoch, history.history.get('val_loss'), label='val_loss')
# plt.show()
# predict_data.shape=(240,50,5)
# 连续预测五十个点并画出来
predict_num = 50
each_predict_data = predict_data[:, 1:, :] # (240,49,5)
all_data = predict_data # (240,50,5)
for each_predict in range(predict_num):
trained_data = tf.keras.models.Model(inputs=model.input, outputs=model.get_layer('output').output).predict(
each_predict_data, batch_size=batch_size) # (240,5)
trained_data = tf.expand_dims(trained_data, axis=1)
each_predict_data = tf.concat([each_predict_data[:, 1:, :], trained_data], axis=1)
all_data = tf.concat([all_data, trained_data], axis=1)
# 获取到的所有data进行画图
print(all_data.shape) # (240,100,5)
epoch, dims, filter_num = all_data.shape
all_data = tf.transpose(all_data, [1, 2, 0])
all_data = tf.reshape(all_data, shape=[dims, filter_num * epoch]) # (100,240*5)
flatten_all_data = np.empty(shape=[dims + filter_num * epoch, ])
(all_dims,) = flatten_all_data.shape
# 将所有数据展平为一维进行画图
for each in range(dims):
if each == 0:
flatten_all_data[:filter_num * epoch] = all_data[each, :]
else:
flatten_all_data[filter_num * epoch + each] = all_data[each, -1]
print(flatten_all_data.shape) # (1300,)
plt.plot(flatten_all_data)
(all_dims,) = flatten_all_data.shape
all_x = np.arange(all_dims)
print(all_x.shape)
# 获取到的所有data进行画图
print(predict_data.shape) # (240,100,5)
epoch, dims, filter_num = predict_data.shape
predict_data = tf.transpose(predict_data, [1, 2, 0])
all_data = tf.reshape(predict_data, shape=[dims, filter_num * epoch]) # (100,240*5)
before_data = np.empty(shape=[dims + filter_num * epoch, ])
# 将所有数据展平为一维进行画图
for each in range(dims):
if each == 0:
before_data[:filter_num * epoch] = all_data[each, :]
else:
before_data[filter_num * epoch + each] = all_data[each, -1]
print(before_data.shape) # (1300,)
print(before_data)
(before_dims,) = before_data.shape
plt.plot(before_data)
plt.show()
before_x = np.arange(before_dims)
all_x = np.arange(all_dims)
plt.plot(before_x, before_data)
plt.scatter(before_dims, before_data)
plt.scatter(all_x, flatten_all_data)
plt.show()

View File

@ -0,0 +1,215 @@
import tensorflow as tf
import numpy as np
from model.LSTM.before.LSTM_realize_self3 import LSTM_realize
from keras.callbacks import EarlyStopping
'''说明将输入LSTM的维度理解为多少维度个点LSTM的一个cell所做的事就是根据这dim个点得出dim+1个点的信息'''
# 超参数设置
filter_num = 30 # 时间部
dims = 50 # 表示一个点的维度
batch_size = 10
EPOCH = 2
model_name = 'SA_ConvLSTM'
predict_num = 50
save_name = "../model/{0}_FilterNum{1}_Dims{2}_BatchSize{3}_Epoch{4}.h5".format(model_name, filter_num, dims,
batch_size, EPOCH)
predict_name = "../data/predict_data/{0}_FilterNum{1}_Dims{2}_BatchSize{3}_Epoch{4}_predict{5}.npy".format(model_name,
filter_num,
dims,
batch_size,
EPOCH,
predict_num)
# 数据读入
HI_merge_data = np.load("../HI_create/HI_merge_data.npy")
# plt.plot(HI_merge_data[0:1250, 1])
# 去除掉退化特征不明显前面的点
HI_merge_data = HI_merge_data[0:1201, 1]
print(HI_merge_data)
print(HI_merge_data.shape)
# plt.plot(HI_merge_data)
# plt.show()
(total_dims,) = HI_merge_data.shape
# # 将其分成重叠采样状态-滑动窗口函数
# # train_data =np.lib.stride_stricks.sliding_window_view(HI_merge_data, 3)
# # train_data =np.lib.stride_stricks.as_strided(HI_merge_data,(1240,10),(10,))
#
train_data = np.empty(shape=[total_dims - filter_num - 1, filter_num])
predict_data = np.empty(shape=[total_dims - filter_num, filter_num])
z = 0
# 重叠采样获取时间部和训练次数
for dim in range(total_dims):
if dim + filter_num >= total_dims:
break
predict_data[dim] = HI_merge_data[dim:dim + filter_num]
if dim + filter_num < total_dims - 1:
train_data[dim] = HI_merge_data[dim:dim + filter_num]
a, _ = train_data.shape
train_label = predict_data[dims + 1:, :]
b, _ = predict_data.shape
# 再重叠采样获取一个点的维度
'''train_data.shape:(sample,filter_num)'''
resample_train_data = train_data[:a - dims, :]
resample_train_data = np.expand_dims(resample_train_data, axis=0)
resample_predict_data = predict_data[:b - dims, :]
resample_predict_data = np.expand_dims(resample_predict_data, axis=0)
for dim in range(dims - 1):
resample_train_data2 = train_data[(dim + 1):(a - dims + dim + 1), :]
resample_train_data2 = np.expand_dims(resample_train_data2, axis=0)
resample_train_data = tf.concat([resample_train_data, resample_train_data2], axis=0)
resample_predict_data2 = predict_data[(dim + 1):(b - dims + dim + 1), :]
resample_predict_data2 = np.expand_dims(resample_predict_data2, axis=0)
resample_predict_data = tf.concat([resample_predict_data, resample_predict_data2], axis=0)
resample_train_data = np.transpose(resample_train_data, [1, 2, 0])
train_data = resample_train_data
resample_predict_data = np.transpose(resample_predict_data, [1, 2, 0])
predict_data = resample_predict_data
print(train_data.shape) # (649,600)
print(train_data)
print(predict_data.shape) # (650,600)
print(predict_data)
print(train_label.shape) # (649,600)
print(train_label)
# # # #
# # np.save("../data/trian_data/train_data.npy", train_data)
# # np.save("../data/trian_data/train_label.npy", train_label)
# # np.save("../data/trian_data/predict_data.npy",predict_data)
# # np.save("../data/trian_data/total_data.npy",HI_merge_data)
# # # train_label=
#
#
# 处理好的train_data的读取
'''
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]
# # 数据处理 - 分成一个epoch训练240次
train_data, train_label = remove(train_data, train_label, batch_size) # 去除直至能整除
# train_data = np.expand_dims(train_data, axis=-1) # (649,600,1)
# predict_data = np.expand_dims(predict_data, axis=-1) # (650,600,1)
train_label = train_label
query_label = np.expand_dims(train_label, axis=-1) # (649,600,1)
total_data = HI_merge_data
train_data = tf.cast(train_data, dtype=tf.float32)
predict_data = tf.cast(predict_data, dtype=tf.float32)
train_label = tf.cast(train_label, dtype=tf.float32)
# query_label = tf.cast(query_label, dtype=tf.float32)
# todo 解决模型保存时,query无法序列化的问题
query_label = np.array(query_label,dtype=np.float32)
print("predict_data.shape:", predict_data.shape) # (649,600,1)
print("train_data.shape:", train_data.shape) # (649,600,1)
print("train_label.shape:", train_label.shape) # (650,600,1)
print("query_label.shape:", query_label.shape)
def predict_model():
input = tf.keras.Input(shape=[filter_num, dims])
input = tf.cast(input, tf.float32)
LSTM_object = LSTM_realize(units=50, batch_size=batch_size, if_SA=True, if_Conv=True,query=query_label)
# LSTM_object = LSTM_realize(units=50, batch_size=batch_size, if_SA=False, if_Conv=False)
LSTM = LSTM_object(inputs=input, layer='SA_ConvLSTM')
# LSTM = LSTM_object(inputs=input, layer='LSTM')
drop = tf.keras.layers.Dropout(0.2)(LSTM)
bn = tf.keras.layers.BatchNormalization()(drop)
d1 = tf.keras.layers.Dense(32)(bn)
drop = tf.keras.layers.Dropout(0.2)(d1)
output = tf.keras.layers.Dense(1, name='output')(drop)
model = tf.keras.Model(inputs=input, outputs=output)
return model
#
if __name__ == '__main__':
model = predict_model()
model.compile(optimizer=tf.optimizers.Adam(0.01), loss=tf.losses.mse)
model.summary()
early_stop = EarlyStopping(monitor='loss', min_delta=0.001, patience=8, mode='min', verbose=1)
history = model.fit(train_data, train_label, epochs=EPOCH,
batch_size=batch_size, verbose=1)
model.save(save_name)
# LSTM_object = LSTM_realize(units=50, batch_size=batch_size, if_SA=True, if_Conv=True)
newModel = tf.keras.models.load_model(save_name, custom_objects={'LSTM_realize': LSTM_realize})
# '''
# train_data.shape:(570,600,30)
# predict_data.shape:(571,600,30)
# train_label.shape:(570,600)
# query_label.shape:(570,600,1)
# '''
# # 连续预测五十个点并画出来
# predict_num = 50
# (samples, filter_num, dims) = predict_data.shape
# each_predict_data = predict_data[samples - batch_size:, :, :] # (5,filter_num,30)
# all_data = total_data # (1201,)
# for each_predict in range(predict_num):
# trained_data = tf.keras.models.Model(inputs=model.input, outputs=model.get_layer('output').output).predict(
# each_predict_data, batch_size=batch_size) # (batch_size,filer_num,1)
#
# all_data = tf.concat([all_data, tf.expand_dims(trained_data[-1, -1, -1], axis=-1)], axis=0)
# trained_data = tf.concat([each_predict_data[-1, :, 1:], trained_data[-1, :, :]], axis=-1)
# # trained_data=tf.reshape(trained_data,[batch_size,filter_num,1])
# # trained_data = tf.expand_dims(trained_data, axis=0)
#
# each_predict_data = tf.concat([each_predict_data[1:, :, :], tf.expand_dims(trained_data, axis=0)], axis=0)
#
# # 获取到的所有data进行画图
#
# print(all_data.shape) # (700,600,1)
# (all_dims,) = all_data.shape
# all_x = np.arange(all_dims)
# print(all_x.shape)
# np.save(predict_name,all_data)
#
# before_data = total_data
# (before_dims,) = before_data.shape
# before_x = np.arange(before_dims)
# all_x = np.arange(all_dims)
#
# fig5 = plt.figure()
# ax5 = fig5.add_subplot()
# plt.plot(all_data)
# plt.plot(before_data)
# plt.show()
#
# print("before_data.shape:", before_data.shape)
# print("flatten_all_data.shape:", all_data.shape)
# print("before_x.shape:", before_x.shape)
# print("all_x.shape:", all_x.shape)
#
# fig6 = plt.figure()
# ax6 = fig6.add_subplot()
# plt.plot(before_x, before_data)
# plt.scatter(before_x, before_data)
# plt.scatter(all_x, all_data)
# plt.show()
#
#
# fig4 = plt.figure()
# ax4 = fig4.add_subplot()
# plt.plot(history.epoch, history.history.get('loss'), label='loss')
# # plt.plot(history.epoch, history.history.get('val_loss'), label='val_loss')
# plt.show()

View File

@ -0,0 +1,204 @@
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
from model.LSTM.before.LSTM_realize_self2 import LSTM_realize
'''说明把所有点都当做维度为1输入进LSTM'''
# 超参数的设置
filter_num = 100 # 时间部
dims = 1 # 表示一个点的维度
batch_size = 7
EPOCH = 200
model_name = 'SA_ConvLSTM'
save_name = "{0}_FilterNum{1}_Dims{2}_BatchSize{3}_Epoch{4}.h5".format(model_name, filter_num, dims, batch_size, EPOCH)
# 数据读入
HI_merge_data = np.load("../HI_create/HI_merge_data.npy")
# 去除掉退化特征不明显前面的点
HI_merge_data = HI_merge_data[0:1250, 1]
print(HI_merge_data)
print(HI_merge_data.shape)
# plt.plot(HI_merge_data)
# plt.show()
(total_dims,) = HI_merge_data.shape
# 将其分成重叠采样状态-滑动窗口函数
# train_data =np.lib.stride_stricks.sliding_window_view(HI_merge_data, 3)
# train_data =np.lib.stride_stricks.as_strided(HI_merge_data,(1240,10),(10,))
train_data = np.empty(shape=[total_dims - filter_num - 1, filter_num])
predict_data = np.empty(shape=[total_dims - filter_num, filter_num])
z = 0
for dim in range(total_dims):
if dim + filter_num >= total_dims:
break
predict_data[dim] = HI_merge_data[dim:dim + filter_num]
if dim + filter_num < total_dims - 1:
train_data[dim] = HI_merge_data[dim:dim + filter_num]
train_label = predict_data[1:, :]
print(train_data.shape) # (649,600)
print(train_data)
print(predict_data.shape) # (650,600)
print(predict_data)
print(train_label.shape) # (649,600)
print(train_label)
# #
# np.save("../data/trian_data/train_data.npy", train_data)
# np.save("../data/trian_data/train_label.npy", train_label)
# np.save("../data/trian_data/predict_data.npy",predict_data)
# train_label=
# 让LSTM看50个信息(NONE,50,1) 每一个信息就是一个点这个点只有一个维度如果想使用多个维度可以考虑前面使用CNN增加其channel的数量
# 处理好的train_data的读取
'''
train_data.shape: (total_dims - filter_num - 1, filter_num) :(649,600)
predict_data.shape: (total_dims - filter_num, filter_num) :(650,600)
train_label.shape: (total_dims - filter_num - 1, filter_num) :(649,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]
# # 数据处理 - 分成一个epoch训练240次
train_data, train_label = remove(train_data, train_label, batch_size) # 去除直至能整除
train_data = np.expand_dims(train_data, axis=-1) # (649,600,1)
predict_data = np.expand_dims(predict_data, axis=-1) # (650,600,1)
train_label = train_label
query_label = np.expand_dims(train_label, axis=-1) # (649,600,1)
total_data = HI_merge_data
train_data = tf.cast(train_data, dtype=tf.float32)
predict_data = tf.cast(predict_data, dtype=tf.float32)
train_label = tf.cast(train_label, dtype=tf.float32)
query_label = tf.cast(query_label, dtype=tf.float32)
print(train_data.shape) # (649,600,1)
print(train_label.shape) # (650,600,1)
print(query_label.shape)
print(predict_data.shape) # (649,600,1)
def predict_model():
input = tf.keras.Input(shape=[filter_num, dims])
input = tf.cast(input, tf.float32)
LSTM = LSTM_realize(input=input, units=256, batch_size=batch_size, if_SA=True).getLayer(layer='SA_ConvLSTM',
query=query_label)
drop = tf.keras.layers.Dropout(0.2)(LSTM)
bn = tf.keras.layers.BatchNormalization()(drop)
d1 = tf.keras.layers.Dense(32)(bn)
drop = tf.keras.layers.Dropout(0.2)(d1)
output = tf.keras.layers.Dense(dims, name='output')(drop)
model = tf.keras.Model(inputs=input, outputs=output)
return model
#
if __name__ == '__main__':
# model = predict_model()
# model.compile(optimizer=tf.optimizers.Adam(0.01), loss=tf.losses.mse)
# model.summary()
# early_stop = EarlyStopping(monitor='loss', min_delta=0.001, patience=8, mode='min', verbose=1)
# history = model.fit(train_data, train_label, epochs=EPOCH,
# batch_size=batch_size)
# model.save(save_name)
model = tf.keras.models.load_model(save_name)
# fig3 = plt.figure()
# ax3 = fig3.add_subplot()
# plt.plot(history.epoch, history.history.get('acc'), label='acc')
# plt.plot(history.epoch, history.history.get('val_acc'), label='val_acc')
# plt.show()
#
# fig4 = plt.figure()
# ax4 = fig3.add_subplot()
# plt.plot(history.epoch, history.history.get('loss'), label='loss')
# plt.plot(history.epoch, history.history.get('val_loss'), label='val_loss')
# plt.show()
'''
train_data.shape:(649,600,1)
predict_data.shape:(650,600,1)
train_label.shape:(649,600,1)
'''
# 连续预测五十个点并画出来
predict_num = 50
(samples, filter_num, dims) = predict_data.shape
each_predict_data = predict_data[samples - batch_size:, :, :] # (6,filter_num,1)
all_data = predict_data # (samples,filter_num,1)
for each_predict in range(predict_num):
trained_data = tf.keras.models.Model(inputs=model.input, outputs=model.get_layer('output').output).predict(
each_predict_data, batch_size=batch_size) # (batch_size,filer_num,1)
# trained_data=tf.reshape(trained_data,[batch_size,filter_num,1])
# trained_data = tf.expand_dims(trained_data, axis=0)
each_predict_data = tf.concat([each_predict_data[1:, :, :], tf.expand_dims(trained_data[-1, :, :], axis=0)],
axis=0)
all_data = tf.concat([all_data, tf.expand_dims(trained_data[-1, :, :], axis=0)], axis=0)
# 获取到的所有data进行画图
print(all_data.shape) # (700,600,1)
samples, filter_num, dims = all_data.shape
# all_data = tf.transpose(all_data, [1, 2, 0])
all_data = tf.reshape(all_data, shape=[samples, filter_num * dims]) # (100,240*5)
flatten_all_data = np.zeros(shape=[samples + filter_num * dims, ])
(all_dims,) = flatten_all_data.shape
# 将所有数据展平为一维进行画图
for each in range(samples):
if each == 0:
flatten_all_data[:filter_num * dims] = all_data[each, :]
else:
flatten_all_data[filter_num * dims + each] = all_data[each, -1]
print(flatten_all_data.shape) # (1300,)
(all_dims,) = flatten_all_data.shape
all_x = np.arange(all_dims)
print(all_x.shape)
#
# # 获取到的所有data进行画图
# print(predict_data.shape) # (240,100,5)
# epoch, dims, filter_num = predict_data.shape
# predict_data = tf.transpose(predict_data, [1, 2, 0])
# all_data = tf.reshape(predict_data, shape=[dims, filter_num * epoch]) # (100,240*5)
# before_data = np.empty(shape=[dims + filter_num * epoch, ])
# # 将所有数据展平为一维进行画图
# for each in range(dims):
# if each == 0:
# before_data[:filter_num * epoch] = all_data[each, :]
# else:
# before_data[filter_num * epoch + each] = all_data[each, -1]
#
# print(before_data.shape) # (1300,)
# print(before_data)
# (before_dims,) = before_data.shape
#
before_data = total_data
(before_dims,) = before_data.shape
before_x = np.arange(before_dims)
all_x = np.arange(all_dims)
plt.plot(flatten_all_data)
plt.plot(before_data)
plt.show()
print("before_data.shape:",before_data.shape)
print("flatten_all_data.shape:",flatten_all_data.shape)
print("before_x.shape:",before_x.shape)
print("all_x.shape:",all_x.shape)
plt.plot(before_x, before_data)
plt.scatter(before_x, before_data)
plt.scatter(all_x, flatten_all_data)
plt.show()

View File

@ -0,0 +1,481 @@
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
from model.LSTM.before.LSTM_realize_self4 import LSTM_realize, PredictModel
import os
import shutil
# TODO 使用函数式编程的方式书写model.fit对应于self4
'''说明将输入LSTM的维度理解为多少维度个点LSTM的一个cell所做的事就是根据这dim个点得出dim+1个点的信息'''
# 超参数设置
filter_num = 500 # 时间部
dims = 50 # 表示一个点的维度
unit = 20
batch_size = 10
EPOCH = 100
model_name = 'SA_ConvLSTM'
predict_num = 50
save_name = "../model/weight/{0}_unit{1}_FilterNum{2}_Dims{3}_Epoch{4}_weight/weight".format(model_name, unit,
filter_num, dims,
EPOCH)
save_loss_name = "../model/loss/{0}_unit{1}_FilterNum{2}_Dims{3}_Epoch{4}_loss.npy".format(model_name, unit, filter_num,
dims,
EPOCH)
# save_name = "../model/weight/{0}_FilterNum{1}_Dims{2}_BatchSize{3}_Epoch{4}_weight".format(model_name,
# filter_num, dims,
# batch_size, EPOCH)
# save_loss_name = "../model/loss/{0}_FilterNum{1}_Dims{2}_BatchSize{3}_Epoch{4}_loss.npy".format(model_name, unit,
# filter_num,
# dims,
# batch_size, EPOCH)
predict_name = "../data/predict_data/{0}_FilterNum{1}_Dims{2}_BatchSize{3}_Epoch{4}_predict{5}.npy".format(model_name,
filter_num,
dims,
batch_size,
EPOCH,
predict_num)
# 数据读入
HI_merge_data_origin = np.load("../HI_create/HI_merge_data.npy")
# plt.plot(HI_merge_data[0:1250, 1])
# 去除掉退化特征不明显前面的点
HI_merge_data = HI_merge_data_origin[0:1201, 1]
print(HI_merge_data)
print(HI_merge_data.shape)
# plt.plot(HI_merge_data)
# plt.show()
(total_dims,) = HI_merge_data.shape
# # 将其分成重叠采样状态-滑动窗口函数
# # train_data =np.lib.stride_stricks.sliding_window_view(HI_merge_data, 3)
# # train_data =np.lib.stride_stricks.as_strided(HI_merge_data,(1240,10),(10,))
#
train_data = np.empty(shape=[total_dims - filter_num - 1, filter_num])
predict_data = np.empty(shape=[total_dims - filter_num, filter_num])
z = 0
# 重叠采样获取时间部和训练次数
for dim in range(total_dims):
if dim + filter_num >= total_dims:
break
predict_data[dim] = HI_merge_data[dim:dim + filter_num]
if dim + filter_num < total_dims - 1:
train_data[dim] = HI_merge_data[dim:dim + filter_num]
a, _ = train_data.shape
train_label = predict_data[dims + 1:, :]
b, _ = predict_data.shape
# 再重叠采样获取一个点的维度
'''train_data.shape:(sample,filter_num)'''
resample_train_data = train_data[:a - dims, :]
resample_train_data = np.expand_dims(resample_train_data, axis=0)
resample_predict_data = predict_data[:b - dims, :]
resample_predict_data = np.expand_dims(resample_predict_data, axis=0)
for dim in range(dims - 1):
resample_train_data2 = train_data[(dim + 1):(a - dims + dim + 1), :]
resample_train_data2 = np.expand_dims(resample_train_data2, axis=0)
resample_train_data = tf.concat([resample_train_data, resample_train_data2], axis=0)
resample_predict_data2 = predict_data[(dim + 1):(b - dims + dim + 1), :]
resample_predict_data2 = np.expand_dims(resample_predict_data2, axis=0)
resample_predict_data = tf.concat([resample_predict_data, resample_predict_data2], axis=0)
resample_train_data = np.transpose(resample_train_data, [1, 2, 0])
train_data = resample_train_data
resample_predict_data = np.transpose(resample_predict_data, [1, 2, 0])
predict_data = resample_predict_data
print(train_data.shape) # (649,600)
print(train_data)
print(predict_data.shape) # (650,600)
print(predict_data)
print(train_label.shape) # (649,600)
print(train_label)
# # # #
# # np.save("../data/trian_data/train_data.npy", train_data)
# # np.save("../data/trian_data/train_label.npy", train_label)
# # np.save("../data/trian_data/predict_data.npy",predict_data)
# # np.save("../data/trian_data/total_data.npy",HI_merge_data)
# # # train_label=
#
#
# 处理好的train_data的读取
'''
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]
# # 数据处理 - 分成一个epoch训练240次
train_data, train_label = remove(train_data, train_label, batch_size) # 去除直至能整除
# train_data = np.expand_dims(train_data, axis=-1) # (649,600,1)
# predict_data = np.expand_dims(predict_data, axis=-1) # (650,600,1)
train_label = train_label
query_label = np.expand_dims(train_label, axis=-1) # (649,600,1)
total_data = HI_merge_data
train_data = tf.cast(train_data, dtype=tf.float32)
predict_data = tf.cast(predict_data, dtype=tf.float32)
train_label = tf.cast(train_label, dtype=tf.float32)
# query_label = tf.cast(query_label, dtype=tf.float32)
# todo 解决模型保存时,query无法序列化的问题
query_label = np.array(query_label, dtype=np.float32)
print("predict_data.shape:", predict_data.shape) # (21, 1200, 30)
print("train_data.shape:", train_data.shape) # (20, 1200, 30)
print("train_label.shape:", train_label.shape) # (20, 1200)
print("query_label.shape:", query_label.shape) # (20, 1200, 1)
def predict_model():
input = tf.keras.Input(shape=[filter_num, dims])
input = tf.cast(input, tf.float32)
LSTM_object = LSTM_realize(units=50, batch_size=batch_size, if_SA=True, if_Conv=True, query=query_label)
# LSTM_object = LSTM_realize(units=50, batch_size=batch_size, if_SA=False, if_Conv=False)
LSTM = LSTM_object(inputs=input, layer='SA_ConvLSTM')
# LSTM = LSTM_object(inputs=input, layer='LSTM')
drop = tf.keras.layers.Dropout(0.2)(LSTM)
bn = tf.keras.layers.BatchNormalization()(drop)
d1 = tf.keras.layers.Dense(32)(bn)
drop = tf.keras.layers.Dropout(0.2)(d1)
output = tf.keras.layers.Dense(1, name='output')(drop)
model = tf.keras.Model(inputs=input, outputs=output)
return model
# 仅使用预测出来的最新的一个点预测以后
def predictOneByOne(predict_data, predict_num=30):
(samples, filter_num, dims) = predict_data.shape # predict_data.shape: (21, 1200, 30)
each_predict_data = predict_data[samples - batch_size:, :, :] # (5,filter_num,30)
all_data = total_data # (1201,)
for each_predict in range(predict_num):
trained_data = newModel.predict(each_predict_data, batch_size=batch_size) # (batch_size,filer_num,1)
all_data = tf.concat([all_data, tf.expand_dims(trained_data[-1, -1, -1], axis=-1)], axis=0)
temp1 = tf.concat([each_predict_data[-1, -1, 1:], tf.expand_dims(trained_data[-1, -1, -1], axis=-1)], axis=0)
temp2 = tf.concat([each_predict_data[-1, 1:, :], tf.expand_dims(temp1, axis=0)], axis=0)
each_predict_data = tf.concat([each_predict_data[1:, :, :], tf.expand_dims(temp2, axis=0)], axis=0)
return all_data
# 使用最后预测出来的一整行与之前的拼接
def predictContinued(predict_data, predict_num=30):
# predict_num = 30
(samples, filter_num, dims) = predict_data.shape # predict_data.shape: (21, 1200, 30)
each_predict_data = predict_data[samples - batch_size:, :, :] # (5,filter_num,30)
all_data = total_data # (1201,)
for each_predict in range(predict_num):
trained_data = newModel.predict(
each_predict_data, batch_size=batch_size) # (batch_size,filer_num,1)
all_data = tf.concat([all_data, tf.expand_dims(trained_data[-1, -1, -1], axis=-1)], axis=0)
trained_data = tf.concat([each_predict_data[-1, :, 1:], trained_data[-1, :, :]], axis=-1)
# trained_data=tf.reshape(trained_data,[batch_size,filter_num,1])
# trained_data = tf.expand_dims(trained_data, axis=0)
each_predict_data = tf.concat([each_predict_data[1:, :, :], tf.expand_dims(trained_data, axis=0)], axis=0)
return all_data
# 使用最后预测出来的一整行与之前的拼接,预测函数使用自己的call函数实现,否则传统的两个方法的query就是一直使用的以前的,而且z一直是0
def selfPredictContinued(predict_data, query_label, predict_num=30):
# predict_num = 30
(samples, filter_num, dims) = predict_data.shape # predict_data.shape: (21, 1200, 30)
(samples1, filter_num1, dims1) = query_label.shape
# 只留下最后一个batch
each_predict_data = predict_data[samples - batch_size:, :, :] # (10,1200,30)
each_query_data = query_label[samples1 - batch_size:, :, :] # (10, 1200, 1)
# 当想要的下一个点的数据没有的时候,使用最后一个点当做下一个点的query
temp1 = each_query_data[-1, 1:, :]
temp2 = each_query_data[-1, -1, -1]
temp22 = tf.expand_dims(tf.expand_dims(temp2, axis=-1), axis=-1)
each_query_data = tf.concat([each_query_data[1:, :, :], tf.expand_dims(tf.concat([temp1, temp22], axis=0), axis=0)],
axis=0)
print(each_query_data.shape) # (10,1200,1)
# 尝试一次预测
each_query_data = each_query_data[-1, :, :]
each_predict_data = each_predict_data[-1, :, :]
each_predict_data = tf.expand_dims(each_predict_data, axis=0)
each_query_data = tf.expand_dims(each_query_data, axis=0)
all_data = total_data # (1201,)
i = 1 # 用于看第几次预测了
for each_predict in range(predict_num):
trained_data = newModel.call(each_predict_data, query=each_query_data, batch_size=1) # (batch_size,filer_num,1)
print("", i, "次预测已完成")
all_data = tf.concat([all_data, tf.expand_dims(trained_data[-1, -1, -1], axis=-1)], axis=0)
one_data = tf.concat([each_predict_data[-1, :, 1:], trained_data[-1, :, :]], axis=-1)
# 这里的1-1是为了去掉上一次重复的那个
temp1 = each_query_data[-1, 1:-1, :]
temp2 = tf.expand_dims(tf.expand_dims(trained_data[-1, -1, -1], axis=-1), axis=-1)
# 拼接两次上面的值,其中最后一次为与上一次类似的预测点
temp3 = tf.concat([tf.concat([temp1, temp2], axis=0), temp2], axis=0)
each_query_data = tf.concat(
[each_query_data[1:, :, :], tf.expand_dims(temp3, axis=0)], axis=0)
each_predict_data = tf.concat([each_predict_data[1:, :, :], tf.expand_dims(one_data, axis=0)], axis=0)
i += 1
return all_data
# 使用最后预测出来的最后一个与之前的拼接,预测函数使用自己的call函数实现,否则传统的两个方法的query就是一直使用的以前的,而且z一直是0
def selfPredictOneByOne(predict_data, query_label, predict_num=30):
# predict_num = 30
(samples, filter_num, dims) = predict_data.shape # predict_data.shape: (21, 1200, 30)
(samples1, filter_num1, dims1) = query_label.shape
# 只留下最后一个batch
each_predict_data = predict_data[samples - batch_size:, :, :] # (10,1200,30)
each_query_data = query_label[samples1 - batch_size:, :, :] # (10, 1200, 1)
# 当想要的下一个点的数据没有的时候,使用最后一个点当做下一个点的query
temp1 = each_query_data[-1, 1:, :]
temp2 = each_query_data[-1, -1, -1]
temp22 = tf.expand_dims(tf.expand_dims(temp2, axis=-1), axis=-1)
each_query_data = tf.concat([each_query_data[1:, :, :], tf.expand_dims(tf.concat([temp1, temp22], axis=0), axis=0)],
axis=0)
print(each_query_data.shape) # (10,1200,1)
# 尝试一次预测
each_query_data = each_query_data[-1, :, :]
each_predict_data = each_predict_data[-1, :, :]
each_predict_data = tf.expand_dims(each_predict_data, axis=0)
each_query_data = tf.expand_dims(each_query_data, axis=0)
all_data = total_data # (1201,)
i = 1 # 用于看第几次预测了
for each_predict in range(predict_num):
trained_data = newModel.call(each_predict_data, query=each_query_data, batch_size=1) # (batch_size,filer_num,1)
print("", i, "次预测已完成")
all_data = tf.concat([all_data, tf.expand_dims(trained_data[-1, -1, -1], axis=-1)], axis=0)
_temp1 = tf.concat([each_predict_data[-1, -1, 1:], tf.expand_dims(trained_data[-1, -1, -1], axis=-1)], axis=0)
_temp2 = tf.concat([each_predict_data[-1, 1:, :], tf.expand_dims(_temp1, axis=0)], axis=0)
# one_data = tf.concat([each_predict_data[-1, :, 1:], temp1], axis=-1)
# 这里的1-1是为了去掉上一次重复的那个
temp1 = each_query_data[-1, 1:-1, :]
temp2 = tf.expand_dims(tf.expand_dims(trained_data[-1, -1, -1], axis=-1), axis=-1)
# 拼接两次上面的值,其中最后一次为与上一次类似的预测点
temp3 = tf.concat([tf.concat([temp1, temp2], axis=0), temp2], axis=0)
each_query_data = tf.concat(
[each_query_data[1:, :, :], tf.expand_dims(temp3, axis=0)], axis=0)
each_predict_data = tf.concat([each_predict_data[1:, :, :], tf.expand_dims(_temp2, axis=0)], axis=0)
i += 1
return all_data
def folderGenerate(folder_name):
if not os.path.exists(folder_name):
os.mkdir(folder_name)
# 递归删除文件夹
def folderDelete(folder_name):
if os.path.exists(folder_name):
shutil.rmtree(folder_name)
# 判断这次是否进行模型保存,history_loss存储历史上的loss
def SaveBestModel(history_loss, loss_value):
weight_folder = save_name[:-7]
# 如果history_loss为空,那么直接保存
if len(history_loss) == 0:
folderGenerate(weight_folder)
model.save_weights(save_name)
return
# 先判断要不要存模型,如果上一次的比这一次的loss要大,就保存这一次的
if np.min(history_loss) > loss_value:
# 删除上一次的保存这一次的
folderDelete(weight_folder)
folderGenerate(weight_folder)
model.save_weights(save_name)
return
pass
def IsStopTraining(history_loss, patience=5):
if len(history_loss) <= patience:
return False
for i in range(1, patience):
if history_loss[-(patience + 1)] > history_loss[-i]:
return False
print(patience, "次loss未下降,训练停止")
return True
def shuffle(data, label):
label = tf.expand_dims(label, axis=-1)
total = tf.concat([data, label], axis=-1)
total = tf.random.shuffle(total)
data = total[:, :, :-1]
label = total[:, :, -1]
query = tf.expand_dims(label, axis=-1)
return data, label, query
def splitValData(data, label, val_radio=0.2):
size, filter_num, dims = data.shape
val_data = data[:int(size * val_radio), :, :]
train_data = data[int(size * val_radio):, :, :]
val_label = label[:int(size * val_radio), :]
train_label = label[int(size * val_radio):, :]
val_query = tf.expand_dims(val_label, axis=-1)
train_query = tf.expand_dims(train_label, axis=-1)
return (train_data, train_label, train_query), (val_data, val_label, val_query)
def Is_Reduce_learning_rate(history_loss, patience=3):
if len(history_loss) <= patience:
return False
for i in range(patience):
if history_loss[-(patience + 1)] > history_loss[-i]:
return False
print(patience,"次loss未下降,降低学习率")
return True
#
if __name__ == '__main__':
# model = predict_model()
# # opt = tf.optimizers.Adam(1e-3)
model = PredictModel(filter_num=filter_num, dims=dims, batch_size=batch_size, query_label=query_label)
#
# # # # TODO 需要运行编译一次,才能打印model.summary()
# model.call(inputs=train_data[0:batch_size], label=train_label[0:batch_size])
# model.build(input_shape=(batch_size, filter_num, dims))
# model.summary()
#
history_loss = []
history_val_loss = []
learning_rate = 1e-3
for epoch in range(EPOCH):
train_data, train_label, query_label = shuffle(train_data, train_label)
if epoch == 0:
(train_data, train_label, query_label), (val_data, val_label, val_query) = splitValData(data=train_data,
label=train_label,
val_radio=0.2)
print()
print("EPOCH:", epoch, "/", EPOCH, ":")
# 用于让train知道这是这个epoch中的第几次训练
z = 0
# 用于batch_size次再训练
k = 1
for data_1, label_1 in zip(train_data, train_label):
size, _, _ = train_data.shape
data_1 = tf.expand_dims(data_1, axis=0)
label_1 = tf.expand_dims(label_1, axis=0)
if batch_size != 1:
if k % batch_size == 1:
data = data_1
label = label_1
else:
data = tf.concat([data, data_1], axis=0)
label = tf.concat([label, label_1], axis=0)
else:
data = data_1
label = label_1
if k % batch_size == 0:
label = tf.expand_dims(label, axis=-1)
loss_value = model.train(input_tensor=data, label=label, query=query_label, learning_rate=learning_rate,
z=z)
print(z * batch_size, "/", size, ":===============>", "loss:", loss_value.numpy())
k = 0
z = z + 1
k = k + 1
val_loss = model.get_val_loss(val_data=val_data, val_label=val_label, val_query=val_query, batch_size=1)
SaveBestModel(history_loss=history_val_loss, loss_value=val_loss.numpy())
history_val_loss.append(val_loss)
history_loss.append(loss_value.numpy())
print('Training loss is :', loss_value.numpy())
print('Validating loss is :', val_loss.numpy())
if IsStopTraining(history_loss=history_val_loss, patience=7):
break
if Is_Reduce_learning_rate(history_loss=history_val_loss, patience=3):
learning_rate = 1e-4
# loss_folder = save_loss_name[:-4]
# folderGenerate(loss_folder)
# np.save(save_loss_name, history_loss)
model.save_weights(save_name)
newModel = PredictModel(filter_num=filter_num, dims=dims, batch_size=batch_size, query_label=query_label)
# newModel.load_weights(save_name)
# # history_loss=np.load(save_loss_name)
# # print(history_loss)
#
#
# # # '''
# # # train_data.shape:(570,600,30)
# # # predict_data.shape:(571,600,30)
# # # train_label.shape:(570,600)
# # # query_label.shape:(570,600,1)
# # # '''
# # 连续预测五十个点并画出来
predict_num = 50
# all_data = predictContinued(predict_data=predict_data, predict_num=predict_num)
# all_data = predictOneByOne(predict_data=predict_data, predict_num=predict_num)
# all_data = selfPredictContinued(predict_data=predict_data, query_label=query_label, predict_num=predict_num)
all_data = selfPredictOneByOne(predict_data=predict_data, query_label=query_label, predict_num=predict_num)
# 获取到的所有data进行画图
print(all_data.shape) # (700,600,1)
(all_dims,) = all_data.shape
all_x = np.arange(all_dims)
print(all_x.shape)
# np.save(predict_name, all_data)
before_data = total_data
(before_dims,) = before_data.shape
before_x = np.arange(before_dims)
all_x = np.arange(all_dims)
fig5 = plt.figure()
ax5 = fig5.add_subplot(2, 1, 1)
ax5.plot(all_data)
ax5.plot(before_data)
ax51 = fig5.add_subplot(2, 1, 2)
ax51.plot(HI_merge_data_origin[0:all_dims, 1])
plt.show()
print("before_data.shape:", before_data.shape)
print("flatten_all_data.shape:", all_data.shape)
print("before_x.shape:", before_x.shape)
print("all_x.shape:", all_x.shape)
fig6 = plt.figure()
ax6 = fig6.add_subplot()
plt.plot(before_x, before_data)
plt.scatter(before_x, before_data)
plt.scatter(all_x, all_data)
plt.show()
# fig4 = plt.figure()
# ax4 = fig4.add_subplot()
# plt.plot(history.epoch, history.history.get('loss'), label='loss')
# # plt.plot(history.epoch, history.history.get('val_loss'), label='val_loss')
# plt.show()

View File

@ -0,0 +1,592 @@
import tensorflow as tf
import numpy as np
from model.LSTM.before.LSTM_realize_self5 import LSTM_realize, PredictModel
from keras.callbacks import EarlyStopping
import os
import shutil
from model.LossFunction.FTMSE import FTMSE
# TODO 使用函数式编程的方式书写model.fit对应于self5,LSTM参数共享测试
'''说明将输入LSTM的维度理解为多少维度个点LSTM的一个cell所做的事就是根据这dim个点得出dim+1个点的信息'''
# save_name = "../model/weight/{0}_FilterNum{1}_Dims{2}_BatchSize{3}_Epoch{4}_weight".format(model_name,
# filter_num, dims,
# batch_size, EPOCH)
# save_loss_name = "../model/loss/{0}_FilterNum{1}_Dims{2}_BatchSize{3}_Epoch{4}_loss.npy".format(model_name, unit,
# filter_num,
# dims,
# batch_size, EPOCH)
def getData(filter_num, dims, batch_size):
# 数据读入
HI_merge_data_origin = np.load("../HI_create/HI_merge_data.npy")
# plt.plot(HI_merge_data[0:1250, 1])
# 去除掉退化特征不明显前面的点
HI_merge_data = HI_merge_data_origin[0:1201, 1]
print(HI_merge_data)
print(HI_merge_data.shape)
# plt.plot(HI_merge_data)
# plt.show()
(total_dims,) = HI_merge_data.shape
# # 将其分成重叠采样状态-滑动窗口函数
# # train_data =np.lib.stride_stricks.sliding_window_view(HI_merge_data, 3)
# # train_data =np.lib.stride_stricks.as_strided(HI_merge_data,(1240,10),(10,))
#
train_data = np.empty(shape=[total_dims - filter_num - 1, filter_num])
predict_data = np.empty(shape=[total_dims - filter_num, filter_num])
z = 0
# 重叠采样获取时间部和训练次数
for dim in range(total_dims):
if dim + filter_num >= total_dims:
break
predict_data[dim] = HI_merge_data[dim:dim + filter_num]
if dim + filter_num < total_dims - 1:
train_data[dim] = HI_merge_data[dim:dim + filter_num]
a, _ = train_data.shape
train_label = predict_data[dims + 1:, :]
b, _ = predict_data.shape
# 再重叠采样获取一个点的维度
'''train_data.shape:(sample,filter_num)'''
resample_train_data = train_data[:a - dims, :]
resample_train_data = np.expand_dims(resample_train_data, axis=0)
resample_predict_data = predict_data[:b - dims, :]
resample_predict_data = np.expand_dims(resample_predict_data, axis=0)
for dim in range(dims - 1):
resample_train_data2 = train_data[(dim + 1):(a - dims + dim + 1), :]
resample_train_data2 = np.expand_dims(resample_train_data2, axis=0)
resample_train_data = tf.concat([resample_train_data, resample_train_data2], axis=0)
resample_predict_data2 = predict_data[(dim + 1):(b - dims + dim + 1), :]
resample_predict_data2 = np.expand_dims(resample_predict_data2, axis=0)
resample_predict_data = tf.concat([resample_predict_data, resample_predict_data2], axis=0)
resample_train_data = np.transpose(resample_train_data, [1, 2, 0])
train_data = resample_train_data
resample_predict_data = np.transpose(resample_predict_data, [1, 2, 0])
predict_data = resample_predict_data
print(train_data.shape) # (649,600)
print(train_data)
print(predict_data.shape) # (650,600)
print(predict_data)
print(train_label.shape) # (649,600)
print(train_label)
# # 数据处理 - 分成一个epoch训练240次
# train_data, train_label = remove(train_data, train_label, batch_size) # 去除直至能整除
# train_data = np.expand_dims(train_data, axis=-1) # (649,600,1)
# predict_data = np.expand_dims(predict_data, axis=-1) # (650,600,1)
train_label = train_label
query_label = np.expand_dims(train_label, axis=-1) # (649,600,1)
total_data = HI_merge_data
train_data = tf.cast(train_data, dtype=tf.float32)
predict_data = tf.cast(predict_data, dtype=tf.float32)
train_label = tf.cast(tf.expand_dims(train_label, axis=-1), dtype=tf.float32)
# query_label = tf.cast(query_label, dtype=tf.float32)
# todo 解决模型保存时,query无法序列化的问题
query_label = np.array(query_label, dtype=np.float32)
print("predict_data.shape:", predict_data.shape) # (21, 1200, 30)
print("train_data.shape:", train_data.shape) # (20, 1200, 30)
print("train_label.shape:", train_label.shape) # (20, 1200)
print("query_label.shape:", query_label.shape) # (20, 1200, 1)
return predict_data, train_data, train_label, query_label, total_data, HI_merge_data_origin
# # # #
# # np.save("../data/trian_data/train_data.npy", train_data)
# # np.save("../data/trian_data/train_label.npy", train_label)
# # np.save("../data/trian_data/predict_data.npy",predict_data)
# # np.save("../data/trian_data/total_data.npy",HI_merge_data)
# # # train_label=
#
#
# 处理好的train_data的读取
'''
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]
# 仅使用预测出来的最新的一个点预测以后没有batch_size
def predictOneByOneWithBatch1(newModel, predict_data, predict_num=30):
(samples, filter_num, dims) = predict_data.shape # predict_data.shape: (21, 1200, 30)
each_predict_data = predict_data[-1, :, :] # (5,filter_num,30)
each_predict_data = tf.expand_dims(each_predict_data, axis=0)
all_data = total_data # (1201,)
i = 1 # 用于看第几次预测
for each_predict in range(predict_num):
trained_data = newModel.predict(each_predict_data) # (batch_size,filer_num,1)
all_data = tf.concat([all_data, tf.expand_dims(trained_data[-1, -1, -1], axis=-1)], axis=0)
temp1 = tf.concat([each_predict_data[-1, -1, 1:], tf.expand_dims(trained_data[-1, -1, -1], axis=-1)], axis=0)
temp2 = tf.concat([each_predict_data[-1, 1:, :], tf.expand_dims(temp1, axis=0)], axis=0)
each_predict_data = tf.concat([each_predict_data[1:, :, :], tf.expand_dims(temp2, axis=0)], axis=0)
print("", i, "次预测已经完成")
i += 1
return all_data
# 仅使用预测出来的最新的一个点预测以后
def predictOneByOne(newModel, predict_data, predict_num=30):
(samples, filter_num, dims) = predict_data.shape # predict_data.shape: (21, 1200, 30)
each_predict_data = predict_data[samples - batch_size:, :, :] # (5,filter_num,30)
all_data = total_data # (1201,)
for each_predict in range(predict_num):
trained_data = newModel.predict(each_predict_data, batch_size=batch_size) # (batch_size,filer_num,1)
all_data = tf.concat([all_data, tf.expand_dims(trained_data[-1, -1, -1], axis=-1)], axis=0)
temp1 = tf.concat([each_predict_data[-1, -1, 1:], tf.expand_dims(trained_data[-1, -1, -1], axis=-1)], axis=0)
temp2 = tf.concat([each_predict_data[-1, 1:, :], tf.expand_dims(temp1, axis=0)], axis=0)
each_predict_data = tf.concat([each_predict_data[1:, :, :], tf.expand_dims(temp2, axis=0)], axis=0)
return all_data
# 使用最后预测出来的一整行与之前的拼接
def predictContinued(newModel, predict_data, predict_num=30):
# predict_num = 30
(samples, filter_num, dims) = predict_data.shape # predict_data.shape: (21, 1200, 30)
each_predict_data = predict_data[samples - batch_size:, :, :] # (5,filter_num,30)
all_data = total_data # (1201,)
for each_predict in range(predict_num):
trained_data = newModel.predict(
each_predict_data, batch_size=batch_size) # (batch_size,filer_num,1)
all_data = tf.concat([all_data, tf.expand_dims(trained_data[-1, -1, -1], axis=-1)], axis=0)
trained_data = tf.concat([each_predict_data[-1, :, 1:], trained_data[-1, :, :]], axis=-1)
# trained_data=tf.reshape(trained_data,[batch_size,filter_num,1])
# trained_data = tf.expand_dims(trained_data, axis=0)
each_predict_data = tf.concat([each_predict_data[1:, :, :], tf.expand_dims(trained_data, axis=0)], axis=0)
return all_data
# 使用最后预测出来的一整行与之前的拼接,预测函数使用自己的call函数实现,否则传统的两个方法的query就是一直使用的以前的,而且z一直是0
def selfPredictContinued(newModel, predict_data, query_label, predict_num=30):
# predict_num = 30
(samples, filter_num, dims) = predict_data.shape # predict_data.shape: (21, 1200, 30)
(samples1, filter_num1, dims1) = query_label.shape
# 只留下最后一个batch
each_predict_data = predict_data[samples - batch_size:, :, :] # (10,1200,30)
each_query_data = query_label[samples1 - batch_size:, :, :] # (10, 1200, 1)
# 当想要的下一个点的数据没有的时候,使用最后一个点当做下一个点的query
temp1 = each_query_data[-1, 1:, :]
temp2 = each_query_data[-1, -1, -1]
temp22 = tf.expand_dims(tf.expand_dims(temp2, axis=-1), axis=-1)
each_query_data = tf.concat([each_query_data[1:, :, :], tf.expand_dims(tf.concat([temp1, temp22], axis=0), axis=0)],
axis=0)
print(each_query_data.shape) # (10,1200,1)
# 尝试一次预测
each_query_data = each_query_data[-1, :, :]
each_predict_data = each_predict_data[-1, :, :]
each_predict_data = tf.expand_dims(each_predict_data, axis=0)
each_query_data = tf.expand_dims(each_query_data, axis=0)
all_data = total_data # (1201,)
i = 1 # 用于看第几次预测了
for each_predict in range(predict_num):
trained_data = newModel.call(each_predict_data, query=each_query_data, batch_size=1) # (batch_size,filer_num,1)
print("", i, "次预测已完成")
all_data = tf.concat([all_data, tf.expand_dims(trained_data[-1, -1, -1], axis=-1)], axis=0)
one_data = tf.concat([each_predict_data[-1, :, 1:], trained_data[-1, :, :]], axis=-1)
# 这里的1-1是为了去掉上一次重复的那个
temp1 = each_query_data[-1, 1:-1, :]
temp2 = tf.expand_dims(tf.expand_dims(trained_data[-1, -1, -1], axis=-1), axis=-1)
# 拼接两次上面的值,其中最后一次为与上一次类似的预测点
temp3 = tf.concat([tf.concat([temp1, temp2], axis=0), temp2], axis=0)
each_query_data = tf.concat(
[each_query_data[1:, :, :], tf.expand_dims(temp3, axis=0)], axis=0)
each_predict_data = tf.concat([each_predict_data[1:, :, :], tf.expand_dims(one_data, axis=0)], axis=0)
i += 1
return all_data
# 使用最后预测出来的最后一个与之前的拼接,预测函数使用自己的call函数实现,否则传统的两个方法的query就是一直使用的以前的,而且z一直是0
def selfPredictOneByOne(newModel, predict_data, query_label, predict_num=30):
# predict_num = 30
(samples, filter_num, dims) = predict_data.shape # predict_data.shape: (21, 1200, 30)
(samples1, filter_num1, dims1) = query_label.shape
# 只留下最后一个batch
each_predict_data = predict_data[samples - batch_size:, :, :] # (10,1200,30)
each_query_data = query_label[samples1 - batch_size:, :, :] # (10, 1200, 1)
# 当想要的下一个点的数据没有的时候,使用最后一个点当做下一个点的query
temp1 = each_query_data[-1, 1:, :]
temp2 = each_query_data[-1, -1, -1]
temp22 = tf.expand_dims(tf.expand_dims(temp2, axis=-1), axis=-1)
each_query_data = tf.concat([each_query_data[1:, :, :], tf.expand_dims(tf.concat([temp1, temp22], axis=0), axis=0)],
axis=0)
print(each_query_data.shape) # (10,1200,1)
# 尝试一次预测
each_query_data = each_query_data[-1, :, :]
each_predict_data = each_predict_data[-1, :, :]
each_predict_data = tf.expand_dims(each_predict_data, axis=0)
each_query_data = tf.expand_dims(each_query_data, axis=0)
all_data = total_data # (1201,)
i = 1 # 用于看第几次预测了
for each_predict in range(predict_num):
trained_data = newModel.call(each_predict_data, query=each_query_data, batch_size=1) # (batch_size,filer_num,1)
print("", i, "次预测已完成")
all_data = tf.concat([all_data, tf.expand_dims(trained_data[-1, -1, -1], axis=-1)], axis=0)
_temp1 = tf.concat([each_predict_data[-1, -1, 1:], tf.expand_dims(trained_data[-1, -1, -1], axis=-1)], axis=0)
_temp2 = tf.concat([each_predict_data[-1, 1:, :], tf.expand_dims(_temp1, axis=0)], axis=0)
# one_data = tf.concat([each_predict_data[-1, :, 1:], temp1], axis=-1)
# 这里的1-1是为了去掉上一次重复的那个
temp1 = each_query_data[-1, 1:-1, :]
temp2 = tf.expand_dims(tf.expand_dims(trained_data[-1, -1, -1], axis=-1), axis=-1)
# 拼接两次上面的值,其中最后一次为与上一次类似的预测点
temp3 = tf.concat([tf.concat([temp1, temp2], axis=0), temp2], axis=0)
each_query_data = tf.concat(
[each_query_data[1:, :, :], tf.expand_dims(temp3, axis=0)], axis=0)
each_predict_data = tf.concat([each_predict_data[1:, :, :], tf.expand_dims(_temp2, axis=0)], axis=0)
i += 1
return all_data
def folderGenerate(folder_name):
if not os.path.exists(folder_name):
os.mkdir(folder_name)
# 递归删除文件夹
def folderDelete(folder_name):
if os.path.exists(folder_name):
shutil.rmtree(folder_name)
# 判断这次是否进行模型保存,history_loss存储历史上的loss
def SaveBestModel(model, history_loss, loss_value):
weight_folder = save_name[:-7]
# 如果history_loss为空,那么直接保存
if len(history_loss) == 0:
folderGenerate(weight_folder)
model.save_weights(save_name)
return
# 先判断要不要存模型,如果上一次的比这一次的loss要大,就保存这一次的
if np.min(history_loss) > loss_value:
# 删除上一次的保存这一次的
folderDelete(weight_folder)
folderGenerate(weight_folder)
model.save_weights(save_name)
print("保存这次模型")
return
pass
def IsStopTraining(history_loss, patience=5):
if len(history_loss) <= patience:
return False
for i in range(1, patience):
if history_loss[-(patience + 1)] > history_loss[-i]:
return False
print(patience, "次loss未下降,训练停止")
return True
def shuffle(data, label):
label = tf.expand_dims(label, axis=-1)
total = tf.concat([data, label], axis=-1)
total = tf.random.shuffle(total)
data = total[:, :, :-1]
label = total[:, :, -1]
query = tf.expand_dims(label, axis=-1)
return data, label, query
def splitValData(data, label, val_radio=0.2):
size, filter_num, dims = data.shape
val_data = data[:int(size * val_radio), :, :]
train_data = data[int(size * val_radio):, :, :]
val_label = label[:int(size * val_radio), :]
train_label = label[int(size * val_radio):, :]
val_query = tf.expand_dims(val_label, axis=-1)
train_query = tf.expand_dims(train_label, axis=-1)
return (train_data, train_label, train_query), (val_data, val_label, val_query)
def Is_Reduce_learning_rate(history_loss, patience=3):
if len(history_loss) <= patience:
return False
for i in range(patience):
if history_loss[-(patience + 1)] > history_loss[-i]:
return False
print(patience, "次loss未下降,降低学习率")
return True
def predict_model():
input = tf.keras.Input(shape=[filter_num, dims])
input = tf.cast(input, tf.float32)
LSTM = LSTM_realize(units=10, batch_size=batch_size, if_SA=False, if_Conv=True, if_mutiHead=False,
num_heads=2)(inputs=input, layer='ConvLSTM')
# LSTM = LSTM_object(inputs=input, layer='SA_ConvLSTM1')
# LSTM = tf.keras.layers.LSTM(units=20,return_sequences=True)(input)
# LSTM = tf.keras.layers.LSTM(units=10,return_sequences=True)(input)
bn = tf.keras.layers.BatchNormalization()(LSTM)
drop = tf.keras.layers.Dropout(0.2)(bn)
# # LSTM_object = LSTM_realize(units=256, batch_size=batch_size, if_SA=False, if_Conv=False, if_mutiHead=False,
# # num_heads=2)
# # LSTM = LSTM_object(inputs=drop, layer='LSTM')
# LSTM=tf.keras.layers.LSTM(units=256,return_sequences=True)(drop)
# bn = tf.keras.layers.BatchNormalization()(LSTM)
# drop = tf.keras.layers.Dropout(0.2)(bn)
#
#
# # LSTM_object = LSTM_realize(units=128, batch_size=batch_size, if_SA=False, if_Conv=False, if_mutiHead=False,
# # num_heads=2)
# # LSTM = LSTM_object(inputs=drop, layer='LSTM')
# LSTM = tf.keras.layers.LSTM(units=128, return_sequences=True)(drop)
# bn = tf.keras.layers.BatchNormalization()(LSTM)
# drop = tf.keras.layers.Dropout(0.2)(bn)
# # LSTM = LSTM_object(inputs=input, layer='LSTM')
# d1 = tf.keras.layers.Dense(64)(drop)
# bn = tf.keras.layers.BatchNormalization()(d1)
# drop = tf.keras.layers.Dropout(0.2)(bn)
#
# d1 = tf.keras.layers.Dense(32)(drop)
# bn = tf.keras.layers.BatchNormalization()(d1)
# drop = tf.keras.layers.Dropout(0.2)(bn)
#
d1 = tf.keras.layers.Dense(5)(drop)
bn = tf.keras.layers.BatchNormalization()(d1)
# drop = tf.keras.layers.Dropout(0.2)(bn)
output = tf.keras.layers.Dense(1, name='output')(bn)
model = tf.keras.Model(inputs=input, outputs=output)
return model
def self_train():
model = PredictModel(batch_size=batch_size)
# # # # TODO 需要运行编译一次,才能打印model.summary()
# model.build(input_shape=(batch_size, filter_num, dims))
# model.summary()
history_loss = []
history_val_loss = []
learning_rate = 1e-3
for epoch in range(EPOCH):
train_data, train_label, query_label = shuffle(train_data, train_label)
if epoch == 0:
(train_data, train_label, query_label), (val_data, val_label, val_query) = splitValData(data=train_data,
label=train_label,
val_radio=0.2)
print()
print("EPOCH:", epoch, "/", EPOCH, ":")
# 用于让train知道这是这个epoch中的第几次训练
z = 0
# 用于batch_size次再训练
k = 1
for data_1, label_1 in zip(train_data, train_label):
size, _, _ = train_data.shape
data_1 = tf.expand_dims(data_1, axis=0)
label_1 = tf.expand_dims(label_1, axis=0)
if batch_size != 1:
if k % batch_size == 1:
data = data_1
label = label_1
else:
data = tf.concat([data, data_1], axis=0)
label = tf.concat([label, label_1], axis=0)
else:
data = data_1
label = label_1
if k % batch_size == 0:
label = tf.expand_dims(label, axis=-1)
loss_value = model.train(input_tensor=data, label=label, query=query_label, learning_rate=learning_rate,
z=z)
print(z * batch_size, "/", size, ":===============>", "loss:", loss_value.numpy())
k = 0
z = z + 1
k = k + 1
val_loss = model.get_val_loss(val_data=val_data, val_label=val_label, val_query=val_query, batch_size=1)
SaveBestModel(model=model, history_loss=history_val_loss, loss_value=val_loss.numpy())
history_val_loss.append(val_loss)
history_loss.append(loss_value.numpy())
print('Training loss is :', loss_value.numpy())
print('Validating loss is :', val_loss.numpy())
if IsStopTraining(history_loss=history_val_loss, patience=7):
break
if Is_Reduce_learning_rate(history_loss=history_val_loss, patience=3):
learning_rate = 1e-4
def lr_schedule(epoch):
# Learning Rate Schedule
lr = 1e-3
total_epochs = EPOCH
check_1 = int(total_epochs * 0.9)
check_2 = int(total_epochs * 0.8)
check_3 = int(total_epochs * 0.6)
check_4 = int(total_epochs * 0.4)
if epoch > check_1:
lr *= 1e-4
elif epoch > check_2:
lr *= 1e-3
elif epoch > check_3:
lr *= 1e-2
elif epoch > check_4:
lr *= 1e-1
return lr
def split_data(train_data, train_label):
return train_data[:1150, :, :], train_label[:1150, :], train_data[-70:, :, :], train_label[-70:, :]
#
if __name__ == '__main__':
# 超参数设置
filter_num = 50 # 时间部
dims = 10 # 表示一个点的维度
unit = 20
batch_size = 32
EPOCH = 1000
model_name = 'self_LSTM'
predict_num = 50
# save_name = "../model/weight/{0}_unit{1}_FilterNum{2}_Dims{3}_Epoch{4}_weight/weight".format(model_name, unit,
# filter_num, dims,
# EPOCH)
save_name = "../model/{0}_unit{1}_FilterNum{2}_Dims{3}_Epoch{4}.h5".format(model_name, unit,
filter_num, dims,
EPOCH)
save_loss_name = "../model/loss/{0}_unit{1}_FilterNum{2}_Dims{3}_Epoch{4}_loss.npy".format(model_name, unit,
filter_num,
dims,
EPOCH)
predict_name = "../data/predict_data/{0}_FilterNum{1}_Dims{2}_BatchSize{3}_Epoch{4}_predict{5}.npy".format(
model_name,
filter_num,
dims,
batch_size,
EPOCH,
predict_num)
predict_data, train_data, train_label, query_label, total_data, HI_merge_data_origin = getData(
filter_num=filter_num, dims=dims, batch_size=batch_size)
model = predict_model()
checkpoint = tf.keras.callbacks.ModelCheckpoint(
filepath=save_name,
monitor='val_loss',
verbose=1,
save_best_only=True,
mode='min',
period=1)
lr_scheduler = tf.keras.callbacks.ReduceLROnPlateau(monitor='val_loss', factor=0.2, patience=5, min_lr=0.001)
model.compile(optimizer=tf.optimizers.Adam(0.01), loss=FTMSE())
model.summary()
early_stop = EarlyStopping(monitor='val_loss', min_delta=0.0001, patience=200, mode='min', verbose=1)
train_data, train_label, val_data, val_label = split_data(train_data=train_data, train_label=train_label)
history = model.fit(train_data, train_label, epochs=EPOCH,
batch_size=batch_size, validation_data=(val_data, val_label), shuffle=False, verbose=1,
callbacks=[checkpoint, lr_scheduler, early_stop])
# # # # model.save(save_name)
# newModel = tf.keras.models.load_model(save_name, custom_objects={'LSTM_realize': LSTM_realize})
# fig4 = plt.figure()
# ax4 = fig4.add_subplot()
# plt.plot(history.epoch, history.history.get('loss'), label='loss')
# plt.plot(history.epoch, history.history.get('val_loss'), label='val_loss')
# plt.show()
# loss_folder = save_loss_name[:-4]
# folderGenerate(loss_folder)
# np.save(save_loss_name, history_loss)
# newModel = PredictModel(filter_num=filter_num, dims=dims, batch_size=batch_size, query_label=query_label)
# newModel.load_weights(save_name)
# # history_loss=np.load(save_loss_name)
# # print(history_loss)
#
#
# # # '''
# # # train_data.shape:(570,600,30)
# # # predict_data.shape:(571,600,30)
# # # train_label.shape:(570,600)
# # # query_label.shape:(570,600,1) # # # '''
# # 连续预测五十个点并画出来
# predict_num = 50
# all_data = predictOneByOneWithBatch1(newModel=newModel, predict_data=predict_data, predict_num=predict_num)
#
# # all_data = predictContinued(predict_data=predict_data, predict_num=predict_num)
# # all_data = predictOneByOne(predict_data=predict_data, predict_num=predict_num)
# # all_data = selfPredictContinued(predict_data=predict_data, query_label=query_label, predict_num=predict_num)
# # all_data = selfPredictOneByOne(predict_data=predict_data, query_label=query_label, predict_num=predict_num)
#
# # 获取到的所有data进行画图
# print(all_data.shape) # (700,600,1)
# (all_dims,) = all_data.shape
# all_x = np.arange(all_dims)
# print(all_x.shape)
# # np.save(predict_name, all_data)
#
# before_data = total_data
# (before_dims,) = before_data.shape
# before_x = np.arange(before_dims)
# all_x = np.arange(all_dims)
#
# fig5 = plt.figure()
# ax5 = fig5.add_subplot(2, 1, 1)
# ax5.plot(all_data)
# ax5.plot(before_data)
# ax51 = fig5.add_subplot(2, 1, 2)
# ax51.plot(HI_merge_data_origin[0:all_dims, 1])
# plt.show()
#
# print("before_data.shape:", before_data.shape)
# print("flatten_all_data.shape:", all_data.shape)
# print("before_x.shape:", before_x.shape)
# print("all_x.shape:", all_x.shape)
#
# fig6 = plt.figure()
# ax6 = fig6.add_subplot()
# plt.plot(before_x, before_data)
# plt.scatter(before_x, before_data)
# plt.scatter(all_x, all_data)
# plt.show()
# fig4 = plt.figure()
# ax4 = fig4.add_subplot()
# plt.plot(history.epoch, history.history.get('loss'), label='loss')
# # plt.plot(history.epoch, history.history.get('val_loss'), label='val_loss')
# plt.show()

View File

@ -9,6 +9,7 @@
import numpy as np import numpy as np
import tensorflow as tf import tensorflow as tf
''' '''
freq_value: 可以是时域通过np.fft.fft转换而来 freq_value: 可以是时域通过np.fft.fft转换而来
''' '''

View File

@ -0,0 +1,116 @@
# -*- encoding:utf-8 -*-
'''
@Author : dingjiawen
@Date : 2023/6/14 15:28
@Usage :
@Desc : 一些画图方法
'''
from sklearn.metrics import mean_absolute_error, mean_squared_error
from pylab import *
# 图像上显示中文
mpl.rcParams['font.sans-serif'] = ['SimHei']
# 调整使图像支持负号
mpl.rcParams["axes.unicode_minus"] = False
font1 = {
'family': 'Times New Roman',
'weight': 'normal',
'size': 12,
}
font2 = {
'family': 'Times New Roman',
'weight': 'normal',
'size': 15,
}
def calScore(y_test, pred):
# TODO 打印误差
test_mse = round(mean_squared_error(y_test, pred), 4)
test_rmse = round(math.sqrt(mean_squared_error(y_test, pred)), 4)
# mape 暂时这样
test_mape = round(mean_absolute_error(pred, y_test) * 100, 4)
test_mae = round(mean_absolute_error(pred, y_test), 4)
# TODO 计算得分
result = list(np.squeeze(pred, 1))
exceed = list(filter(lambda res: res >= y_test[-1], result))
print("len(exceed)", len(exceed))
if len(exceed) > 0:
exceed_index = result.index(exceed[0])
print("len(result)", len(result))
# Eri = round((((2750 - (len(result) - exceed_index)) - 2750) / 2750), 4)
Eri = round((exceed_index / len(result)), 4)
print("RUL", 100 - (len(result) - exceed_index))
print("Eri", Eri)
if Eri <= 0:
score = round(math.exp(-math.log(0.5, e) * (Eri / 5)), 4)
else:
score = round(math.exp(math.log(0.5, e) * (Eri / 20)), 4)
print("score1", score)
score = exceed_index / len(result)
else:
Eri = nan
score = nan
print('MSE_testScore: %.4f MSE' % test_mse)
print('RMSE_testScore: %.4f RMSE' % test_rmse)
print('MAE_testScore: %.4f MAE' % test_mae)
print('MAPE_testScore: %.4f MAPE' % test_mape)
print("score: %.4f score" % score)
pass
# 画图
def getPlot(data, feature, time_step, x_train, x_test, pred, truePred, train_pred,
saveName="../store/test"):
train_pred = np.squeeze(train_pred, 1)
print("train_pred", train_pred)
# TODO 实际值
# 设置xtick和ytick的方向in、out、inout
plt.rcParams['xtick.direction'] = 'in'
plt.rcParams['ytick.direction'] = 'in'
plt.plot(list(range(data.shape[0])), data)
# 画出 y=1 这条水平线
plt.axhline(data[-1], c='green')
plt.grid()
plt.ylim(0, 1)
plt.xlim(-50, 1300)
# TODO 真实预测散点图
# TODO 图2
plt.figure(2)
point_len = x_train.shape[0] + feature + time_step - 1
# plt.figure(2, figsize=(12, 4))
# 设置xtick和ytick的方向in、out、inout
plt.rcParams['xtick.direction'] = 'in'
plt.rcParams['ytick.direction'] = 'in'
print("pred", pred[:, -1])
print("truePred", truePred[:, -1])
figname2 = saveName + "single.png"
plt.scatter(list(range(data.shape[0])), data, c='blue', s=12, label='Actual value')
# # TODO 这里要改成Training value 10(重叠丢失) + 9(转置) +1141(训练数据已知) + 9(转置) = 1169 + 81 (预测数据) =1250
# # 训练数据传入模型预测一次即为训练数据
plt.plot(list(range(time_step + feature - 1, point_len)), train_pred, linewidth=2, color='red',
label='Training value')
plt.scatter(list(range(point_len, point_len + x_test.shape[0])), pred, c='black', s=15,
label='Predictive value')
# 画出 y=1 这条水平线
plt.axhline(data[-1], linewidth=2, c='green', label='Failure threshold')
plt.ylim(-0.2, 0.95)
plt.xlim(-50, 1300)
plt.xlabel("Serial number of the fusion feature point", font=font2)
plt.ylabel("Virtual health indicator", font=font2)
plt.legend(loc='upper left', prop=font1)
plt.savefig(figname2, )

View File

@ -0,0 +1,138 @@
#-*- encoding:utf-8 -*-
'''
@Author : dingjiawen
@Date : 2023/6/18 11:10
@Usage :
@Desc :
'''
from distutils.command.config import config
import torch.nn as nn
import math
import numpy as np
import torch
try:
from torch import irfft
from torch import rfft
except ImportError:
def rfft(x, d):
t = torch.fft.fft(x, dim=(-d))
r = torch.stack((t.real, t.imag), -1)
return r
def irfft(x, d):
t = torch.fft.ifft(torch.complex(x[:, :, 0], x[:, :, 1]), dim=(-d))
return t.real
def dct(x, norm=None):
"""
Discrete Cosine Transform, Type II (a.k.a. the DCT)
For the meaning of the parameter `norm`, see:
https://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.fftpack.dct.html
:param x: the input signal
:param norm: the normalization, None or 'ortho'
:return: the DCT-II of the signal over the last dimension
"""
x_shape = x.shape
N = x_shape[-1]
x = x.contiguous().view(-1, N)
v = torch.cat([x[:, ::2], x[:, 1::2].flip([1])], dim=1)
# Vc = torch.fft.rfft(v, 1, onesided=False)
Vc = rfft(v, 1)
k = - torch.arange(N, dtype=x.dtype, device=x.device)[None, :] * np.pi / (2 * N)
W_r = torch.cos(k)
W_i = torch.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 * V.view(*x_shape)
return V
# class senet_block(nn.Module):
# def __init__(self, channel=512, ratio=1):
# super(dct_channel_block, self).__init__()
# self.avg_pool = nn.AdaptiveAvgPool1d(1) #innovation
# self.fc = nn.Sequential(
# nn.Linear(channel, channel // 4, bias=False),
# nn.ReLU(inplace=True),
# nn.Linear(channel //4, channel, bias=False),
# nn.Sigmoid()
# )
# def forward(self, x):
# # b, c, l = x.size() # (B,C,L)
# # y = self.avg_pool(x) # (B,C,L) -> (B,C,1)
# # print("y",y.shape)
# x = x.permute(0,2,1)
# b, c, l = x.size()
# y = self.avg_pool(x).view(b, c) # (B,C,L) ->(B,C,1)
# # print("y",y.shape)
# # y = self.fc(y).view(b, c, 96)
# y = self.fc(y).view(b,c,1)
# # print("y",y.shape)
# # return x * y
# return (x*y).permute(0,2,1)
class dct_channel_block(nn.Module):
def __init__(self, channel):
super(dct_channel_block, self).__init__()
# self.avg_pool = nn.AdaptiveAvgPool1d(1) #innovation
self.fc = nn.Sequential(
nn.Linear(channel, channel * 2, bias=False),
nn.Dropout(p=0.1),
nn.ReLU(inplace=True),
nn.Linear(channel * 2, channel, bias=False),
nn.Sigmoid()
)
# self.dct_norm = nn.LayerNorm([512], eps=1e-6)
self.dct_norm = nn.LayerNorm([96], eps=1e-6) # for lstm on length-wise
# self.dct_norm = nn.LayerNorm([36], eps=1e-6)#for lstm on length-wise on ill with input =36
def forward(self, x):
b, c, l = x.size() # (B,C,L) (32,96,512)
# y = self.avg_pool(x) # (B,C,L) -> (B,C,1)
# y = self.avg_pool(x).view(b, c) # (B,C,L) -> (B,C,1)
# print("y",y.shape
# y = self.fc(y).view(b, c, 96)
list = []
for i in range(c):
freq = dct(x[:, i, :])
# print("freq-shape:",freq.shape)
list.append(freq)
stack_dct = torch.stack(list, dim=1)
stack_dct = torch.tensor(stack_dct)
'''
for traffic mission:f_weight = self.dct_norm(f_weight.permute(0,2,1))#matters for traffic datasets
'''
lr_weight = self.dct_norm(stack_dct)
lr_weight = self.fc(stack_dct)
lr_weight = self.dct_norm(lr_weight)
# print("lr_weight",lr_weight.shape)
return x * lr_weight # result
if __name__ == '__main__':
tensor = torch.rand(8, 7, 96)
dct_model = dct_channel_block()
result = dct_model.forward(tensor)
print("result.shape:", result.shape)

View File

@ -0,0 +1,52 @@
#-*- encoding:utf-8 -*-
'''
@Author : dingjiawen
@Date : 2023/6/18 11:03
@Usage :
@Desc : 离散余弦变换DCT测试
'''
'''
参考:
[1] https://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.fftpack.dct.html
'''
import numpy as np
import cv2
from scipy.fftpack import dct,idct
import matplotlib.pyplot as plt
array = np.array([-0.029078494757,
-0.33095228672,
-0.12124221772,
0.553512275219,
-0.158036053181,
0.268739402294,
-0.638222515583,
0.233140587807,
-0.173265621066,
0.467218101025,
-0.372010827065,
-0.136630430818,
0.343256533146,
0.008932195604])
dct_array = dct(array,norm='ortho')
dct_array_t = idct(dct_array,norm='ortho')
amp = np.abs(np.fft.fft(array) / len(array))
print(amp)
print(dct_array)
plt.subplot(4, 1, 1)
plt.plot(array)
plt.subplot(4, 1, 2)
plt.plot(dct_array)
plt.subplot(4, 1, 3)
plt.plot(dct_array_t)
plt.subplot(4, 1, 4)
plt.plot(amp)
plt.show()

View File

@ -32,11 +32,11 @@ amp = np.abs(np.fft.fft(array) / len(array))
# 相角 # 相角
angle = np.angle(np.fft.fft(array)) angle = np.angle(np.fft.fft(array))
# 时部 # 时部
real = np.real(np.fft.rfft(array) * 2 / len(array)) real = np.real(np.fft.fft(array) * 2 / len(array))
# 虚部 # 虚部
imag = np.imag(np.fft.rfft(array) * 2 / len(array)) imag = np.imag(np.fft.fft(array) * 2 / len(array))
# #
angle1 = np.arctan(imag / real) angle1 = np.arctan2(imag, real)
print(angle) print(angle)
print(angle1) print(angle1)

View File

@ -0,0 +1,268 @@
# -*- 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.LSTMByDense 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 = "LSTM"
save_name = r"selfMulti_norm_{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_multi(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 = LSTMLayer(units=512, return_sequences=True)(input)
LSTM = LSTMLayer(units=256, return_sequences=True)(LSTM)
###flatten
x = tf.keras.layers.Flatten()(LSTM)
x = tf.keras.layers.Dense(128, activation="relu")(x)
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)
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 predictContinueByOne(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)
for each_predict in range(predict_num):
# predicted_data.shape : (1,10) 取最后一条
predicted_data = newModel.predict(each_predict_data) # (batch_size,filer_num,1)
predicted_data = np.expand_dims(predicted_data[:, -1], axis=-1)
predicted_list[each_predict] = predicted_data
# (1,1) => (10,1)l
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):
# shape:(1180,10) 取每一次的最后一个点就是从头到尾预测的
predicted_data = trained_model.predict(predict_data)
predicted_data = np.expand_dims(predicted_data[:, -1], axis=-1)
predicted_data = np.concatenate([np.expand_dims(total_data[:hidden_num + feature, ], axis=1), predicted_data],
axis=0)
data = predictContinueByOne(trained_model, predict_data, predict_num=predict_num)
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, if_norm=False)
# 根据预测的点数划分训练集和测试集(验证集)
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_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.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])
#### TODO 测试
trained_model = tf.keras.models.load_model(save_name, custom_objects={'LSTMLayer': LSTMLayer})
# 使用已知的点进行预测
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()

View File

@ -0,0 +1,223 @@
# -*- 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.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 = "LSTM"
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 = 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=20, 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=100, mode='min', verbose=1)
history = model.fit(train_data, train_label_single, epochs=EPOCH,
batch_size=batch_size, validation_data=(val_data, val_label_single), shuffle=True, verbose=2,
callbacks=[checkpoint, lr_scheduler, early_stop])
#### TODO 测试
trained_model = tf.keras.models.load_model(save_name, custom_objects={'LSTMLayer': LSTMLayer})
# 使用已知的点进行预测
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()

View File

@ -0,0 +1,74 @@
# -*- encoding:utf-8 -*-
'''
@Author : dingjiawen
@Date : 2023/6/18 14:08
@Usage :
@Desc : DCT的通道注意力模块
'''
import tensorflow as tf
import tensorflow.keras
from tensorflow.keras import *
import tensorflow.keras.layers as layers
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from model.DepthwiseCon1D.DepthwiseConv1D import DepthwiseConv1D
class DCTChannelAttention(layers.Layer):
def __init__(self):
# 调用父类__init__()方法
super(DCTChannelAttention, self).__init__()
self.DWC = DepthwiseConv1D(kernel_size=1, padding='SAME')
def build(self, input_shape):
if len(input_shape) != 3:
raise ValueError('Inputs to `DynamicChannelAttention` should have rank 3. '
'Received input shape:', str(input_shape))
# print(input_shape)
# GAP
self.GAP = tf.keras.layers.GlobalAvgPool1D()
self.c1 = tf.keras.layers.Conv1D(filters=input_shape[2], kernel_size=1, padding='SAME')
# s1 = tf.nn.sigmoid(c1)
# GMP
self.GMP = tf.keras.layers.GlobalMaxPool1D()
self.c2 = tf.keras.layers.Conv1D(filters=input_shape[2], kernel_size=1, padding='SAME')
# s2 = tf.nn.sigmoid(c2)
# weight
self.weight_kernel = self.add_weight(
shape=(1, input_shape[2]),
initializer='glorot_uniform',
name='weight_kernel')
def call(self, inputs, **kwargs):
batch_size, length, channel = inputs.shape
# print(batch_size,length,channel)
DWC1 = self.DWC(inputs)
# GAP
GAP = self.GAP(DWC1)
GAP = tf.expand_dims(GAP, axis=1)
c1 = self.c1(GAP)
c1 = tf.keras.layers.BatchNormalization()(c1)
s1 = tf.nn.sigmoid(c1)
# GMP
GMP = self.GMP(DWC1)
GMP = tf.expand_dims(GMP, axis=1)
c2 = self.c2(GMP)
c2 = tf.keras.layers.BatchNormalization()(c2)
s2 = tf.nn.sigmoid(c2)
# print(self.weight_kernel)
weight_kernel = tf.broadcast_to(self.weight_kernel, shape=[length, channel])
weight_kernel = tf.broadcast_to(weight_kernel, shape=[batch_size, length, channel])
s1 = tf.broadcast_to(s1, shape=[batch_size, length, channel])
s2 = tf.broadcast_to(s2, shape=[batch_size, length, channel])
output = tf.add(weight_kernel * s1 * inputs, (tf.ones_like(weight_kernel) - weight_kernel) * s2 * inputs)
return output

View File

@ -0,0 +1,129 @@
# _*_ coding: UTF-8 _*_
'''
@Author : dingjiawen
@Date : 2022/7/12 17:48
@Usage :
@Desc :
'''
import tensorflow as tf
import tensorflow.keras
from tensorflow.keras import *
import tensorflow.keras.layers as layers
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from model.DepthwiseCon1D.DepthwiseConv1D import DepthwiseConv1D
import keras.backend as K
class Between_0_1(tf.keras.constraints.Constraint):
def __call__(self, w):
# 调用父类__init__()方法
super(Between_0_1, self).__init__()
return K.clip(w, 0, 1)
class DynamicChannelAttention(layers.Layer):
def __init__(self):
# 调用父类__init__()方法
super(DynamicChannelAttention, self).__init__()
self.DWC = DepthwiseConv1D(kernel_size=1, padding='SAME')
# self.DWC = DepthwiseConv1D(kernel_size=1, padding='causal',dilation_rate=4,data_format='channels_last')
def build(self, input_shape):
if len(input_shape) != 3:
raise ValueError('Inputs to `DynamicChannelAttention` should have rank 3. '
'Received input shape:', str(input_shape))
# print(input_shape)
# GAP
self.GAP = tf.keras.layers.GlobalAvgPool1D()
self.c1 = tf.keras.layers.Conv1D(filters=input_shape[2], kernel_size=1, padding='SAME')
# s1 = tf.nn.sigmoid(c1)
# GMP
self.GMP = tf.keras.layers.GlobalMaxPool1D()
self.c2 = tf.keras.layers.Conv1D(filters=input_shape[2], kernel_size=1, padding='SAME')
# s2 = tf.nn.sigmoid(c2)
# weight
self.weight_kernel = self.add_weight(
shape=(1, input_shape[2]),
initializer='glorot_uniform',
name='weight_kernel',
constraint=Between_0_1())
def call(self, inputs, **kwargs):
batch_size, length, channel = inputs.shape
# print(batch_size,length,channel)
DWC1 = self.DWC(inputs)
# GAP
GAP = self.GAP(DWC1)
GAP = tf.expand_dims(GAP, axis=1)
c1 = self.c1(GAP)
c1 = tf.keras.layers.BatchNormalization()(c1)
s1 = tf.nn.sigmoid(c1)
# GMP
GMP = self.GMP(DWC1)
GMP = tf.expand_dims(GMP, axis=1)
c2 = self.c2(GMP)
c2 = tf.keras.layers.BatchNormalization()(c2)
s2 = tf.nn.sigmoid(c2)
# print(self.weight_kernel)
weight_kernel = tf.broadcast_to(self.weight_kernel, shape=[length, channel])
weight_kernel = tf.broadcast_to(weight_kernel, shape=[batch_size, length, channel])
s1 = tf.broadcast_to(s1, shape=[batch_size, length, channel])
s2 = tf.broadcast_to(s2, shape=[batch_size, length, channel])
output = tf.add(weight_kernel * s1 * inputs, (tf.ones_like(weight_kernel) - weight_kernel) * s2 * inputs)
return output
class DynamicPooling(layers.Layer):
def __init__(self, pool_size=2):
# 调用父类__init__()方法
super(DynamicPooling, self).__init__()
self.pool_size = pool_size
pass
def build(self, input_shape):
if len(input_shape) != 3:
raise ValueError('Inputs to `DynamicChannelAttention` should have rank 3. '
'Received input shape:', str(input_shape))
# GAP
self.AP = tf.keras.layers.AveragePooling1D(pool_size=self.pool_size)
# GMP
self.MP = tf.keras.layers.MaxPool1D(pool_size=self.pool_size)
# weight
self.weight_kernel = self.add_weight(
shape=(int(input_shape[1] / self.pool_size), input_shape[2]),
initializer='glorot_uniform',
name='weight_kernel',
constraint=Between_0_1())
def call(self, inputs, **kwargs):
batch_size, length, channel = inputs.shape
# GAP
GAP = self.AP(inputs)
# GMP
GMP = self.MP(inputs)
weight_kernel = tf.broadcast_to(self.weight_kernel, shape=GMP.shape)
output = tf.add(weight_kernel * GAP, (tf.ones_like(weight_kernel) - weight_kernel) * GMP)
return output

View File

@ -0,0 +1,9 @@
# _*_ coding: UTF-8 _*_
'''
@Author : dingjiawen
@Date : 2022/7/12 17:48
@Usage :
@Desc :
'''

View File

@ -0,0 +1,163 @@
# -*- coding: utf-8 -*-
# coding: utf-8
'''
@Author : dingjiawen
@Date : 2022/7/14 17:36
@Usage :
@Desc :
'''
import os
import shutil
import tensorflow as tf
import tensorflow.keras as keras
import numpy as np
import pandas as pd
def folderGenerate(folder_name):
if not os.path.exists(folder_name):
os.makedirs(folder_name)
# os.mkdir(folder_name)
# 递归删除文件夹
def folderDelete(folder_name):
if os.path.exists(folder_name):
shutil.rmtree(folder_name)
# 判断这次是否进行模型保存,history_loss存储历史上的loss
def SaveBestModel(model, save_name, history_loss, loss_value, pattern: str = "min",epoch=0,is_all=False):
weight_folder = save_name[:-7]
if is_all:
weight_folder=weight_folder+'_epoch'+str(epoch)+"_"+str(loss_value)
save_name=weight_folder+save_name[-7:]
# 如果history_loss为空,那么直接保存
if len(history_loss) == 0:
folderGenerate(weight_folder)
model.save_weights(save_name)
return
if pattern == "min":
# 先判断要不要存模型,如果上一次的比这一次的loss要大,就保存这一次的
if np.min(history_loss) > loss_value:
# 删除上一次的保存这一次的
folderDelete(weight_folder)
folderGenerate(weight_folder)
model.save_weights(save_name)
print("保存这次模型")
return
elif pattern == "max":
# 先判断要不要存模型,如果上一次的比这一次的loss要大,就保存这一次的
if np.max(history_loss) < loss_value:
# 删除上一次的保存这一次的
folderDelete(weight_folder)
folderGenerate(weight_folder)
model.save_weights(save_name)
print("保存这次模型")
return
else:
raise ValueError("算法尚未实现")
pass
# 判断这次是否进行模型保存,history_loss存储历史上的loss
def SaveBestModelByAccuracy(model, save_name, history_accuracy, accuracy_value):
weight_folder = save_name[:-7]
# 如果history_loss为空,那么直接保存
if len(history_accuracy) == 0:
folderGenerate(weight_folder)
model.save_weights(save_name)
return
# 先判断要不要存模型,如果上一次的比这一次的loss要大,就保存这一次的
if np.max(history_accuracy) < accuracy_value:
# 删除上一次的保存这一次的
folderDelete(weight_folder)
folderGenerate(weight_folder)
model.save_weights(save_name)
print("保存这次模型")
return
pass
# 判断这次是否进行模型保存,history_loss存储历史上的loss
def SaveBestH5Model(model: tf.keras.Model, save_name, history_loss, loss_value):
dirpath = os.path.dirname(save_name)
folderGenerate(dirpath)
# 如果history_loss为空,那么直接保存
if len(history_loss) == 0:
model.save(save_name)
return
# 先判断要不要存模型,如果上一次的比这一次的loss要大,就保存这一次的
if np.min(history_loss) > loss_value:
# 删除上一次的保存这一次的
model.save(save_name, overwrite=True)
print("保存这次模型")
return
pass
def IsStopTraining(history_loss, patience=5, pattern: str = "min"):
if len(history_loss) <= patience:
return False
if pattern == "min":
for i in range(1, patience):
if history_loss[-(patience + 1)] > history_loss[-i]:
return False
elif pattern == "max":
for i in range(1, patience):
if history_loss[-(patience + 1)] > history_loss[-i]:
return False
else:
raise ValueError("算法尚未实现")
print(patience, "次loss未下降,训练停止")
return True
def shuffle(data, label):
label = tf.expand_dims(label, axis=-1)
total = tf.concat([data, label], axis=-1)
total = tf.random.shuffle(total)
data = total[:, :, :-1]
label = total[:, :, -1]
return data, label
def splitValData(data, label, val_radio=0.2):
size, filter_num, dims = data.shape
val_data = data[:int(size * val_radio), :, :]
train_data = data[int(size * val_radio):, :, :]
val_label = label[:int(size * val_radio), :]
train_label = label[int(size * val_radio):, :]
val_query = tf.expand_dims(val_label, axis=-1)
train_query = tf.expand_dims(train_label, axis=-1)
return (train_data, train_label, train_query), (val_data, val_label, val_query)
def Is_Reduce_learning_rate(history_loss, patience=3, pattern: str = "min"):
if len(history_loss) <= patience:
return False
if pattern == "min":
for i in range(patience):
if history_loss[-(patience + 1)] > history_loss[-i]:
return False
elif pattern == "max":
for i in range(patience):
if history_loss[-(patience + 1)] < history_loss[-i]:
return False
else:
raise ValueError("算法尚未实现")
print(patience, "次loss未下降,降低学习率")
return True

View File

@ -0,0 +1,9 @@
# _*_ coding: UTF-8 _*_
'''
@Author : dingjiawen
@Date : 2022/7/14 17:36
@Usage :
@Desc :
'''

View File

@ -0,0 +1,247 @@
# _*_ coding: UTF-8 _*_
'''
@Author : dingjiawen
@Date : 2022/7/12 16:59
@Usage :
@Desc :
'''
import tensorflow as tf
from tensorflow.python.framework import tensor_shape
from tensorflow.python.keras import models, layers, initializers, regularizers, constraints
from tensorflow.python.keras.layers import Conv1D
from tensorflow.python.keras.engine.input_spec import InputSpec
from tensorflow.python.keras.utils import conv_utils
from tensorflow.python.keras.utils import tf_utils
from tensorflow.python.keras import backend
from tensorflow.python.ops import array_ops
from tensorflow.python.ops import nn
from tensorflow.python.ops import nn_ops
from tensorflow.python.util.tf_export import keras_export
"""
Depthwise separable 1D convolution.
Depthwise Separable convolutions consists in performing
just the first step in a depthwise spatial convolution
(which acts on each input channel separately).
The `depth_multiplier` argument controls how many
output channels are generated per input channel in the depthwise step.
Arguments:
kernel_size: An integer, specifying the
length of the 1D convolution window.
strides: An integer specifying the strides of the convolution.
padding: one of `'valid'` or `'same'` (case-insensitive).
common_kernel: if set to True, same kernel is applied to each channel,
if False, separate kernel is applied to each channel (default case)
depth_multiplier: The number of depthwise convolution output channels
for each input channel.
The total number of depthwise convolution output
channels will be equal to `filters_in * depth_multiplier`.
data_format: A string,
one of `channels_last` (default) or `channels_first`.
The ordering of the dimensions in the inputs.
`channels_last` corresponds to inputs with shape
`(batch_size, length, channels)` while `channels_first`
corresponds to inputs with shape
`(batch_size, channels, length)`.
It defaults to the `image_data_format` value found in your
Keras config file at `~/.keras/keras.json`.
If you never set it, then it will be 'channels_last'.
activation: Activation function to use.
If you don't specify anything, no activation is applied (
see `keras.activations`).
use_bias: Boolean, whether the layer uses a bias vector.
depthwise_initializer: Initializer for the depthwise kernel matrix (
see `keras.initializers`).
bias_initializer: Initializer for the bias vector (
see `keras.initializers`).
depthwise_regularizer: Regularizer function applied to
the depthwise kernel matrix (see `keras.regularizers`).
bias_regularizer: Regularizer function applied to the bias vector (
see `keras.regularizers`).
activity_regularizer: Regularizer function applied to
the output of the layer (its 'activation') (
see `keras.regularizers`).
depthwise_constraint: Constraint function applied to
the depthwise kernel matrix (
see `keras.constraints`).
bias_constraint: Constraint function applied to the bias vector (
see `keras.constraints`).
Input shape:
3D tensor with shape:
`[batch_size, channels, length]` if data_format='channels_first'
or 3D tensor with shape:
`[batch_size, length, channels]` if data_format='channels_last'.
Output shape:
3D tensor with shape:
`[batch_size, filters, new_length]` if data_format='channels_first'
or 3D tensor with shape:
`[batch_size, new_length, filters]` if data_format='channels_last'.
`length` value might have changed due to padding.
Returns:
A tensor of rank 3 representing
`activation(depthwiseconv1d(inputs, kernel) + bias)`.
"""
class DepthwiseConv1D(Conv1D):
def __init__(self,
kernel_size,
strides=1,
padding='valid',
common_kernel=False,
depth_multiplier=1,
data_format=None,
activation=None,
use_bias=True,
depthwise_initializer='glorot_uniform',
bias_initializer='zeros',
depthwise_regularizer=None,
bias_regularizer=None,
activity_regularizer=None,
depthwise_constraint=None,
bias_constraint=None,
dilation_rate=1,
**kwargs):
super(DepthwiseConv1D, self).__init__(
filters=None,
kernel_size=kernel_size,
strides=strides,
padding=padding,
data_format=data_format,
activation=activation,
use_bias=use_bias,
bias_regularizer=bias_regularizer,
activity_regularizer=activity_regularizer,
bias_constraint=bias_constraint,
**kwargs)
self.common_kernel = common_kernel
self.depth_multiplier = depth_multiplier
self.depthwise_initializer = initializers.get(depthwise_initializer)
self.depthwise_regularizer = regularizers.get(depthwise_regularizer)
self.depthwise_constraint = constraints.get(depthwise_constraint)
self.bias_initializer = initializers.get(bias_initializer)
self.dilation_rate = (dilation_rate,dilation_rate)
# For compatibility with some older versions of Keras
def _get_channel_axis(self):
if self.data_format == 'channels_first':
return 1
else:
return -1
def build(self, input_shape):
if len(input_shape) != 3:
raise ValueError('Inputs to `DepthwiseConv1D` should have rank 3. '
'Received input shape:', str(input_shape))
input_shape = tensor_shape.TensorShape(input_shape)
channel_axis = self._get_channel_axis()
if input_shape.dims[channel_axis].value is None:
raise ValueError('The channel dimension of the inputs to '
'`DepthwiseConv1D` should be defined. Found `None`.')
input_dim = int(input_shape[channel_axis])
kernel_dim = 1 if self.common_kernel == True else input_dim
depthwise_kernel_shape = (self.kernel_size[0], kernel_dim, self.depth_multiplier)
self.channels = input_dim
self.depthwise_kernel = self.add_weight(
shape=depthwise_kernel_shape,
initializer=self.depthwise_initializer,
name='depthwise_kernel',
regularizer=self.depthwise_regularizer,
constraint=self.depthwise_constraint)
if self.use_bias:
self.bias = self.add_weight(shape=(kernel_dim * self.depth_multiplier,),
initializer=self.bias_initializer,
name='bias',
regularizer=self.bias_regularizer,
constraint=self.bias_constraint)
else:
self.bias = None
self.input_spec = InputSpec(ndim=3, axes={channel_axis: input_dim})
self.built = True
def call(self, inputs):
if self.padding == 'causal':
inputs = array_ops.pad(inputs, self._compute_causal_padding())
if self.data_format == 'channels_last':
strides = (1,) + self.strides * 2 + (1,)
spatial_start_dim = 1
else:
strides = (1, 1) + self.strides * 2
spatial_start_dim = 2
# Explicitly broadcast inputs and kernels to 4D.
inputs = array_ops.expand_dims(inputs, spatial_start_dim)
if self.common_kernel == True:
# Need to replicate kernel {channels} times over axis 1
dw_kernel = tf.tile(self.depthwise_kernel, (1, self.channels, 1))
bias_kernel = tf.tile(self.bias, (self.channels,))
else:
dw_kernel = self.depthwise_kernel
bias_kernel = self.bias
dw_kernel = array_ops.expand_dims(dw_kernel, 0)
if self.padding == 'causal':
op_padding = 'valid'
else:
op_padding = self.padding
outputs = nn.depthwise_conv2d(
inputs,
dw_kernel,
strides=strides,
padding=op_padding.upper(),
data_format=conv_utils.convert_data_format(self.data_format, ndim=4))
# outputs = backend.depthwise_conv2d(
# inputs,
# dw_kernel,
# strides=strides,
# padding=op_padding.upper(),
# dilation_rate=self.dilation_rate,
# data_format='channels_last')
outputs = array_ops.squeeze(outputs, [spatial_start_dim])
if self.use_bias:
outputs = backend.bias_add(outputs, bias_kernel, data_format=self.data_format)
if self.activation is not None:
return self.activation(outputs)
return outputs
@tf_utils.shape_type_conversion
def compute_output_shape(self, input_shape):
if self.data_format == 'channels_first':
length = input_shape[2]
out_filters = input_shape[1] * self.depth_multiplier
elif self.data_format == 'channels_last':
length = input_shape[1]
out_filters = input_shape[2] * self.depth_multiplier
length_new = conv_utils.conv_output_length(length, self.kernel_size,
self.padding,
self.strides)
if self.data_format == 'channels_first':
return (input_shape[0], out_filters, length_new)
elif self.data_format == 'channels_last':
return (input_shape[0], length_new, out_filters)
def get_config(self):
config = super(DepthwiseConv1D, self).get_config()
config.pop('filters')
config.pop('kernel_initializer')
config.pop('kernel_regularizer')
config.pop('kernel_constraint')
config['depth_multiplier'] = self.depth_multiplier
config['depthwise_initializer'] = initializers.serialize(self.depthwise_initializer)
config['depthwise_regularizer'] = regularizers.serialize(self.depthwise_regularizer)
config['depthwise_constraint'] = constraints.serialize(self.depthwise_constraint)
return config

View File

@ -0,0 +1,9 @@
# _*_ coding: UTF-8 _*_
'''
@Author : dingjiawen
@Date : 2022/7/12 16:59
@Usage :
@Desc :
'''

View File

@ -0,0 +1,402 @@
# _*_ coding: UTF-8 _*_
'''
@Author : dingjiawen
@Date : 2022/7/14 9:40
@Usage : 联合监测模型
@Desc : 将CNN特征提取结果放入分类器
'''
import tensorflow as tf
import tensorflow.keras as keras
from tensorflow.keras import *
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from model.DepthwiseCon1D.DepthwiseConv1D import DepthwiseConv1D
from model.Dynamic_channelAttention.Dynamic_channelAttention import DynamicChannelAttention, DynamicPooling
from condition_monitoring.data_deal import loadData
from model.LossFunction.smooth_L1_Loss import SmoothL1Loss
class Joint_Monitoring(keras.Model):
def __init__(self, conv_filter=20):
# 调用父类__init__()方法
super(Joint_Monitoring, self).__init__()
# step one
self.RepDCBlock1 = RevConvBlock(num=3, kernel_size=5)
self.conv1 = tf.keras.layers.Conv1D(filters=conv_filter, kernel_size=1, strides=2, padding='SAME')
self.upsample1 = tf.keras.layers.UpSampling1D(size=2)
self.DACU2 = DynamicChannelAttention()
self.RepDCBlock2 = RevConvBlock(num=3, kernel_size=3)
self.conv2 = tf.keras.layers.Conv1D(filters=2 * conv_filter, kernel_size=1, strides=2, padding='SAME')
self.upsample2 = tf.keras.layers.UpSampling1D(size=2)
self.DACU3 = DynamicChannelAttention()
self.RepDCBlock3 = RevConvBlock(num=3, kernel_size=3)
self.p1 = DynamicPooling(pool_size=2)
self.conv3 = tf.keras.layers.Conv1D(filters=2 * conv_filter, kernel_size=3, strides=2, padding='SAME')
self.DACU4 = DynamicChannelAttention()
self.RepDCBlock4 = RevConvBlock(num=3, kernel_size=3)
self.p2 = DynamicPooling(pool_size=4)
self.conv4 = tf.keras.layers.Conv1D(filters=conv_filter, kernel_size=3, strides=2, padding='SAME')
self.RepDCBlock5 = RevConvBlock(num=3, kernel_size=3)
self.p3 = DynamicPooling(pool_size=2)
# step two
# 重现原数据
self.GRU1 = tf.keras.layers.GRU(128, return_sequences=False)
self.d1 = tf.keras.layers.Dense(300, activation=tf.nn.leaky_relu)
self.output1 = tf.keras.layers.Dense(10, activation=tf.nn.leaky_relu)
self.GRU2 = tf.keras.layers.GRU(128, return_sequences=False)
self.d2 = tf.keras.layers.Dense(300, activation=tf.nn.leaky_relu)
self.output2 = tf.keras.layers.Dense(10, activation=tf.nn.leaky_relu)
self.GRU3 = tf.keras.layers.GRU(128, return_sequences=False)
self.d3 = tf.keras.layers.Dense(300, activation=tf.nn.leaky_relu)
self.output3 = tf.keras.layers.Dense(10, activation=tf.nn.leaky_relu)
# step three
# 分类器
self.d4 = tf.keras.layers.Dense(1024, activation=tf.nn.leaky_relu)
self.d5 = tf.keras.layers.Dense(512, activation=tf.nn.leaky_relu)
# tf.nn.softmax
self.output4 = tf.keras.layers.Dense(1, activation=tf.nn.sigmoid)
# loss
self.train_loss = []
def call(self, inputs, training=None, mask=None, is_first_time: bool = True):
# step one
RepDCBlock1 = self.RepDCBlock1(inputs)
RepDCBlock1 = tf.keras.layers.BatchNormalization()(RepDCBlock1)
conv1 = self.conv1(RepDCBlock1)
conv1 = tf.nn.leaky_relu(conv1)
conv1 = tf.keras.layers.BatchNormalization()(conv1)
upsample1 = self.upsample1(conv1)
DACU2 = self.DACU2(upsample1)
DACU2 = tf.keras.layers.BatchNormalization()(DACU2)
RepDCBlock2 = self.RepDCBlock2(DACU2)
RepDCBlock2 = tf.keras.layers.BatchNormalization()(RepDCBlock2)
conv2 = self.conv2(RepDCBlock2)
conv2 = tf.nn.leaky_relu(conv2)
conv2 = tf.keras.layers.BatchNormalization()(conv2)
upsample2 = self.upsample2(conv2)
DACU3 = self.DACU3(upsample2)
DACU3 = tf.keras.layers.BatchNormalization()(DACU3)
RepDCBlock3 = self.RepDCBlock3(DACU3)
RepDCBlock3 = tf.keras.layers.BatchNormalization()(RepDCBlock3)
conv3 = self.conv3(RepDCBlock3)
conv3 = tf.nn.leaky_relu(conv3)
conv3 = tf.keras.layers.BatchNormalization()(conv3)
concat1 = tf.concat([conv2, conv3], axis=1)
DACU4 = self.DACU4(concat1)
DACU4 = tf.keras.layers.BatchNormalization()(DACU4)
RepDCBlock4 = self.RepDCBlock4(DACU4)
RepDCBlock4 = tf.keras.layers.BatchNormalization()(RepDCBlock4)
conv4 = self.conv4(RepDCBlock4)
conv4 = tf.nn.leaky_relu(conv4)
conv4 = tf.keras.layers.BatchNormalization()(conv4)
concat2 = tf.concat([conv1, conv4], axis=1)
RepDCBlock5 = self.RepDCBlock5(concat2)
RepDCBlock5 = tf.keras.layers.BatchNormalization()(RepDCBlock5)
output1 = []
output2 = []
output3 = []
output4 = []
if is_first_time:
# step two
# 重现原数据
# 接block3
GRU1 = self.GRU1(RepDCBlock3)
GRU1 = tf.keras.layers.BatchNormalization()(GRU1)
d1 = self.d1(GRU1)
# tf.nn.softmax
output1 = self.output1(d1)
# 接block4
GRU2 = self.GRU2(RepDCBlock4)
GRU2 = tf.keras.layers.BatchNormalization()(GRU2)
d2 = self.d2(GRU2)
# tf.nn.softmax
output2 = self.output2(d2)
# 接block5
GRU3 = self.GRU3(RepDCBlock5)
GRU3 = tf.keras.layers.BatchNormalization()(GRU3)
d3 = self.d3(GRU3)
# tf.nn.softmax
output3 = self.output3(d3)
else:
# 多尺度动态池化
# 多尺度动态池化
p1 = self.p1(RepDCBlock3)
B, _, _ = p1.shape
f1 = tf.reshape(p1, shape=[B, -1])
p2 = self.p2(RepDCBlock4)
f2 = tf.reshape(p2, shape=[B, -1])
p3 = self.p3(RepDCBlock5)
f3 = tf.reshape(p3, shape=[B, -1])
# step three
# 分类器
concat3 = tf.concat([f1, f2, f3], axis=0)
d4 = self.d4(concat3)
d4 = tf.keras.layers.BatchNormalization()(d4)
output4 = self.output4(d4)
return RepDCBlock3, RepDCBlock4, RepDCBlock5, output4
def get_loss(self, inputs_tensor, label1=None, label2=None, is_first_time: bool = True, pred_3=None, pred_4=None,
pred_5=None):
# step one
RepDCBlock1 = self.RepDCBlock1(inputs_tensor)
RepDCBlock1 = tf.keras.layers.BatchNormalization()(RepDCBlock1)
conv1 = self.conv1(RepDCBlock1)
conv1 = tf.nn.leaky_relu(conv1)
conv1 = tf.keras.layers.BatchNormalization()(conv1)
upsample1 = self.upsample1(conv1)
DACU2 = self.DACU2(upsample1)
DACU2 = tf.keras.layers.BatchNormalization()(DACU2)
RepDCBlock2 = self.RepDCBlock2(DACU2)
RepDCBlock2 = tf.keras.layers.BatchNormalization()(RepDCBlock2)
conv2 = self.conv2(RepDCBlock2)
conv2 = tf.nn.leaky_relu(conv2)
conv2 = tf.keras.layers.BatchNormalization()(conv2)
upsample2 = self.upsample2(conv2)
DACU3 = self.DACU3(upsample2)
DACU3 = tf.keras.layers.BatchNormalization()(DACU3)
RepDCBlock3 = self.RepDCBlock3(DACU3)
RepDCBlock3 = tf.keras.layers.BatchNormalization()(RepDCBlock3)
conv3 = self.conv3(RepDCBlock3)
conv3 = tf.nn.leaky_relu(conv3)
conv3 = tf.keras.layers.BatchNormalization()(conv3)
concat1 = tf.concat([conv2, conv3], axis=1)
DACU4 = self.DACU4(concat1)
DACU4 = tf.keras.layers.BatchNormalization()(DACU4)
RepDCBlock4 = self.RepDCBlock4(DACU4)
RepDCBlock4 = tf.keras.layers.BatchNormalization()(RepDCBlock4)
conv4 = self.conv4(RepDCBlock4)
conv4 = tf.nn.leaky_relu(conv4)
conv4 = tf.keras.layers.BatchNormalization()(conv4)
concat2 = tf.concat([conv1, conv4], axis=1)
RepDCBlock5 = self.RepDCBlock5(concat2)
RepDCBlock5 = tf.keras.layers.BatchNormalization()(RepDCBlock5)
if is_first_time:
# step two
# 重现原数据
# 接block3
GRU1 = self.GRU1(RepDCBlock3)
GRU1 = tf.keras.layers.BatchNormalization()(GRU1)
d1 = self.d1(GRU1)
# tf.nn.softmax
output1 = self.output1(d1)
# 接block4
GRU2 = self.GRU2(RepDCBlock4)
GRU2 = tf.keras.layers.BatchNormalization()(GRU2)
d2 = self.d2(GRU2)
# tf.nn.softmax
output2 = self.output2(d2)
# 接block5
GRU3 = self.GRU3(RepDCBlock5)
GRU3 = tf.keras.layers.BatchNormalization()(GRU3)
d3 = self.d3(GRU3)
# tf.nn.softmax
output3 = self.output3(d3)
# reduce_mean降维计算均值
MSE_loss1 = tf.reduce_mean(tf.keras.losses.mse(y_true=label1, y_pred=output1))
MSE_loss2 = tf.reduce_mean(tf.keras.losses.mse(y_true=label1, y_pred=output2))
MSE_loss3 = tf.reduce_mean(tf.keras.losses.mse(y_true=label1, y_pred=output3))
print("MSE_loss1:", MSE_loss1.numpy())
print("MSE_loss2:", MSE_loss2.numpy())
print("MSE_loss3:", MSE_loss3.numpy())
loss = MSE_loss1 + MSE_loss2 + MSE_loss3
else:
# 多尺度动态池化
p1 = self.p1(RepDCBlock3)
B, _, _ = p1.shape
f1 = tf.reshape(p1, shape=[B, -1])
p2 = self.p2(RepDCBlock4)
f2 = tf.reshape(p2, shape=[B, -1])
p3 = self.p3(RepDCBlock5)
f3 = tf.reshape(p3, shape=[B, -1])
# step three
# 分类器
concat3 = tf.concat([f1, f2, f3], axis=1)
# dropout = tf.keras.layers.Dropout(0.25)(concat3)
d4 = self.d4(concat3)
d5 = self.d5(d4)
# d4 = tf.keras.layers.BatchNormalization()(d4)
output4 = self.output4(d5)
# reduce_mean降维计算均值
MSE_loss = SmoothL1Loss()(y_true=pred_3, y_pred=RepDCBlock3)
MSE_loss += SmoothL1Loss()(y_true=pred_4, y_pred=RepDCBlock4)
MSE_loss += SmoothL1Loss()(y_true=pred_5, y_pred=RepDCBlock5)
Cross_Entropy_loss = tf.reduce_mean(
tf.losses.binary_crossentropy(y_true=label2, y_pred=output4, from_logits=True))
print("MSE_loss:", MSE_loss.numpy())
print("Cross_Entropy_loss:", Cross_Entropy_loss.numpy())
Accuracy_num = self.get_Accuracy(label=label2, output=output4)
loss = MSE_loss + 100 * Cross_Entropy_loss
return loss, Accuracy_num
def get_Accuracy(self, output, label):
predict_label = tf.round(output)
label = tf.cast(label, dtype=tf.float32)
t = np.array(label - predict_label)
b = t[t[:] == 0]
return b.__len__()
def get_grad(self, input_tensor, label1=None, label2=None, is_first_time: bool = True, pred_3=None, pred_4=None,
pred_5=None):
with tf.GradientTape() as tape:
# todo 原本tape只会监控由tf.Variable创建的trainable=True属性
# tape.watch(self.variables)
L, Accuracy_num = self.get_loss(input_tensor, label1=label1, label2=label2, is_first_time=is_first_time,
pred_3=pred_3,
pred_4=pred_4, pred_5=pred_5)
# 保存一下loss用于输出
self.train_loss = L
g = tape.gradient(L, self.variables)
return g, Accuracy_num
def train(self, input_tensor, label1=None, label2=None, learning_rate=1e-3, is_first_time: bool = True, pred_3=None,
pred_4=None, pred_5=None):
g, Accuracy_num = self.get_grad(input_tensor, label1=label1, label2=label2, is_first_time=is_first_time,
pred_3=pred_3,
pred_4=pred_4, pred_5=pred_5)
optimizers.Adam(learning_rate).apply_gradients(zip(g, self.variables))
return self.train_loss, Accuracy_num
# 暂时只支持batch_size等于1,不然要传z比较麻烦
def get_val_loss(self, val_data, val_label1, val_label2, batch_size=16, is_first_time: bool = True,
step_one_model=None):
val_loss = []
accuracy_num = 0
size, length, dims = val_data.shape
if batch_size == None:
batch_size = self.batch_size
for epoch in range(0, size - batch_size, batch_size):
each_val_data = val_data[epoch:epoch + batch_size, :, :]
each_val_label1 = val_label1[epoch:epoch + batch_size, :]
each_val_label2 = val_label2[epoch:epoch + batch_size, ]
# each_val_data = tf.expand_dims(each_val_data, axis=0)
# each_val_query = tf.expand_dims(each_val_query, axis=0)
# each_val_label = tf.expand_dims(each_val_label, axis=0)
if not is_first_time:
output1, output2, output3, _ = step_one_model.call(inputs=each_val_data, is_first_time=True)
each_loss, each_accuracy_num = self.get_loss(each_val_data, each_val_label1, each_val_label2,
is_first_time=is_first_time,
pred_3=output1, pred_4=output2, pred_5=output3)
accuracy_num += each_accuracy_num
val_loss.append(each_loss)
val_accuracy = accuracy_num / (epoch - 1) * batch_size
val_total_loss = tf.reduce_mean(val_loss)
return val_total_loss, val_accuracy
class RevConv(keras.layers.Layer):
def __init__(self, kernel_size=3):
# 调用父类__init__()方法
super(RevConv, self).__init__()
self.kernel_size = kernel_size
def get_config(self):
# 自定义层里面的属性
config = (
{
'kernel_size': self.kernel_size
}
)
base_config = super(RevConv, self).get_config()
return dict(list(base_config.items()) + list(config.items()))
def build(self, input_shape):
# print(input_shape)
_, _, output_dim = input_shape[0], input_shape[1], input_shape[2]
self.conv1 = tf.keras.layers.Conv1D(filters=output_dim, kernel_size=self.kernel_size, strides=1,
padding='causal',
dilation_rate=4)
self.conv2 = tf.keras.layers.Conv1D(filters=output_dim, kernel_size=1, strides=1, padding='causal',
dilation_rate=4)
# self.b2 = tf.keras.layers.BatchNormalization()
# self.b3 = tf.keras.layers.BatchNormalization()
# out = tf.keras.layers.Add()([b1, b2, b3])
# out = tf.nn.relu(out)
def call(self, inputs, **kwargs):
conv1 = self.conv1(inputs)
b1 = tf.keras.layers.BatchNormalization()(conv1)
b1 = tf.nn.leaky_relu(b1)
# b1 = self.b1
conv2 = self.conv2(inputs)
b2 = tf.keras.layers.BatchNormalization()(conv2)
b2 = tf.nn.leaky_relu(b2)
b3 = tf.keras.layers.BatchNormalization()(inputs)
out = tf.keras.layers.Add()([b1, b2, b3])
out = tf.nn.relu(out)
return out
class RevConvBlock(keras.layers.Layer):
def __init__(self, num: int = 3, kernel_size=3):
# 调用父类__init__()方法
super(RevConvBlock, self).__init__()
self.num = num
self.kernel_size = kernel_size
self.L = []
for i in range(num):
RepVGG = RevConv(kernel_size=kernel_size)
self.L.append(RepVGG)
def get_config(self):
# 自定义层里面的属性
config = (
{
'kernel_size': self.kernel_size,
'num': self.num
}
)
base_config = super(RevConvBlock, self).get_config()
return dict(list(base_config.items()) + list(config.items()))
def call(self, inputs, **kwargs):
for i in range(self.num):
inputs = self.L[i](inputs)
return inputs

View File

@ -0,0 +1,445 @@
# _*_ coding: UTF-8 _*_
'''
@Author : dingjiawen
@Date : 2022/7/14 9:40
@Usage : 联合监测模型
@Desc : 将预测值放入分类器已测试准确率可以到99.7% ,dense层300后直接接outputcross_entropy Loss还放大了一百倍
'''
import tensorflow as tf
import tensorflow.keras as keras
from tensorflow.keras import *
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from model.DepthwiseCon1D.DepthwiseConv1D import DepthwiseConv1D
from model.Dynamic_channelAttention.Dynamic_channelAttention import DynamicChannelAttention, DynamicPooling
from condition_monitoring.data_deal import loadData
from model.LossFunction.smooth_L1_Loss import SmoothL1Loss
class Joint_Monitoring(keras.Model):
def __init__(self, conv_filter=20):
# 调用父类__init__()方法
super(Joint_Monitoring, self).__init__()
# step one
self.RepDCBlock1 = RevConvBlock(num=3, kernel_size=5)
self.conv1 = tf.keras.layers.Conv1D(filters=conv_filter, kernel_size=1, strides=2, padding='SAME')
self.upsample1 = tf.keras.layers.UpSampling1D(size=2)
self.DACU2 = DynamicChannelAttention()
self.RepDCBlock2 = RevConvBlock(num=3, kernel_size=3)
self.conv2 = tf.keras.layers.Conv1D(filters=2 * conv_filter, kernel_size=1, strides=2, padding='SAME')
self.upsample2 = tf.keras.layers.UpSampling1D(size=2)
self.DACU3 = DynamicChannelAttention()
self.RepDCBlock3 = RevConvBlock(num=3, kernel_size=3)
self.p1 = DynamicPooling(pool_size=2)
self.conv3 = tf.keras.layers.Conv1D(filters=2 * conv_filter, kernel_size=3, strides=2, padding='SAME')
self.DACU4 = DynamicChannelAttention()
self.RepDCBlock4 = RevConvBlock(num=3, kernel_size=3)
self.p2 = DynamicPooling(pool_size=4)
self.conv4 = tf.keras.layers.Conv1D(filters=conv_filter, kernel_size=3, strides=2, padding='SAME')
self.RepDCBlock5 = RevConvBlock(num=3, kernel_size=3)
self.p3 = DynamicPooling(pool_size=2)
# step two
# 重现原数据
self.GRU1 = tf.keras.layers.GRU(128, return_sequences=False)
self.d1 = tf.keras.layers.Dense(300, activation=tf.nn.leaky_relu)
self.output1 = tf.keras.layers.Dense(10, activation=tf.nn.leaky_relu)
self.GRU2 = tf.keras.layers.GRU(128, return_sequences=False)
self.d2 = tf.keras.layers.Dense(300, activation=tf.nn.leaky_relu)
self.output2 = tf.keras.layers.Dense(10, activation=tf.nn.leaky_relu)
self.GRU3 = tf.keras.layers.GRU(128, return_sequences=False)
self.d3 = tf.keras.layers.Dense(300, activation=tf.nn.leaky_relu)
self.output3 = tf.keras.layers.Dense(10, activation=tf.nn.leaky_relu)
# step three
# 分类器
self.d4 = tf.keras.layers.Dense(300, activation=tf.nn.leaky_relu)
self.d5 = tf.keras.layers.Dense(10, activation=tf.nn.leaky_relu)
# tf.nn.softmax
self.output4 = tf.keras.layers.Dense(1, activation=tf.nn.sigmoid)
# loss
self.train_loss = []
def call(self, inputs, training=None, mask=None, is_first_time: bool = True):
# step one
RepDCBlock1 = self.RepDCBlock1(inputs)
RepDCBlock1 = tf.keras.layers.BatchNormalization()(RepDCBlock1)
conv1 = self.conv1(RepDCBlock1)
conv1 = tf.nn.leaky_relu(conv1)
conv1 = tf.keras.layers.BatchNormalization()(conv1)
upsample1 = self.upsample1(conv1)
DACU2 = self.DACU2(upsample1)
DACU2 = tf.keras.layers.BatchNormalization()(DACU2)
RepDCBlock2 = self.RepDCBlock2(DACU2)
RepDCBlock2 = tf.keras.layers.BatchNormalization()(RepDCBlock2)
conv2 = self.conv2(RepDCBlock2)
conv2 = tf.nn.leaky_relu(conv2)
conv2 = tf.keras.layers.BatchNormalization()(conv2)
upsample2 = self.upsample2(conv2)
DACU3 = self.DACU3(upsample2)
DACU3 = tf.keras.layers.BatchNormalization()(DACU3)
RepDCBlock3 = self.RepDCBlock3(DACU3)
RepDCBlock3 = tf.keras.layers.BatchNormalization()(RepDCBlock3)
conv3 = self.conv3(RepDCBlock3)
conv3 = tf.nn.leaky_relu(conv3)
conv3 = tf.keras.layers.BatchNormalization()(conv3)
concat1 = tf.concat([conv2, conv3], axis=1)
DACU4 = self.DACU4(concat1)
DACU4 = tf.keras.layers.BatchNormalization()(DACU4)
RepDCBlock4 = self.RepDCBlock4(DACU4)
RepDCBlock4 = tf.keras.layers.BatchNormalization()(RepDCBlock4)
conv4 = self.conv4(RepDCBlock4)
conv4 = tf.nn.leaky_relu(conv4)
conv4 = tf.keras.layers.BatchNormalization()(conv4)
concat2 = tf.concat([conv1, conv4], axis=1)
RepDCBlock5 = self.RepDCBlock5(concat2)
RepDCBlock5 = tf.keras.layers.BatchNormalization()(RepDCBlock5)
output1 = []
output2 = []
output3 = []
output4 = []
if is_first_time:
# step two
# 重现原数据
# 接block3
GRU1 = self.GRU1(RepDCBlock3)
GRU1 = tf.keras.layers.BatchNormalization()(GRU1)
d1 = self.d1(GRU1)
# tf.nn.softmax
output1 = self.output1(d1)
# 接block4
GRU2 = self.GRU2(RepDCBlock4)
GRU2 = tf.keras.layers.BatchNormalization()(GRU2)
d2 = self.d2(GRU2)
# tf.nn.softmax
output2 = self.output2(d2)
# 接block5
GRU3 = self.GRU3(RepDCBlock5)
GRU3 = tf.keras.layers.BatchNormalization()(GRU3)
d3 = self.d3(GRU3)
# tf.nn.softmax
output3 = self.output3(d3)
else:
GRU1 = self.GRU1(RepDCBlock3)
GRU1 = tf.keras.layers.BatchNormalization()(GRU1)
d1 = self.d1(GRU1)
# tf.nn.softmax
output1 = self.output1(d1)
# 接block4
GRU2 = self.GRU2(RepDCBlock4)
GRU2 = tf.keras.layers.BatchNormalization()(GRU2)
d2 = self.d2(GRU2)
# tf.nn.softmax
output2 = self.output2(d2)
# 接block5
GRU3 = self.GRU3(RepDCBlock5)
GRU3 = tf.keras.layers.BatchNormalization()(GRU3)
d3 = self.d3(GRU3)
# tf.nn.softmax
output3 = self.output3(d3)
# 多尺度动态池化
# p1 = self.p1(output1)
# B, _, _ = p1.shape
# f1 = tf.reshape(p1, shape=[B, -1])
# p2 = self.p2(output2)
# f2 = tf.reshape(p2, shape=[B, -1])
# p3 = self.p3(output3)
# f3 = tf.reshape(p3, shape=[B, -1])
# step three
# 分类器
concat3 = tf.concat([output1, output2, output3], axis=1)
# dropout = tf.keras.layers.Dropout(0.25)(concat3)
d4 = self.d4(concat3)
# d5 = self.d5(d4)
# d4 = tf.keras.layers.BatchNormalization()(d4)
output4 = self.output4(d4)
return output1, output2, output3, output4
def get_loss(self, inputs_tensor, label1=None, label2=None, is_first_time: bool = True, pred_3=None, pred_4=None,
pred_5=None):
# step one
RepDCBlock1 = self.RepDCBlock1(inputs_tensor)
RepDCBlock1 = tf.keras.layers.BatchNormalization()(RepDCBlock1)
conv1 = self.conv1(RepDCBlock1)
conv1 = tf.nn.leaky_relu(conv1)
conv1 = tf.keras.layers.BatchNormalization()(conv1)
upsample1 = self.upsample1(conv1)
DACU2 = self.DACU2(upsample1)
DACU2 = tf.keras.layers.BatchNormalization()(DACU2)
RepDCBlock2 = self.RepDCBlock2(DACU2)
RepDCBlock2 = tf.keras.layers.BatchNormalization()(RepDCBlock2)
conv2 = self.conv2(RepDCBlock2)
conv2 = tf.nn.leaky_relu(conv2)
conv2 = tf.keras.layers.BatchNormalization()(conv2)
upsample2 = self.upsample2(conv2)
DACU3 = self.DACU3(upsample2)
DACU3 = tf.keras.layers.BatchNormalization()(DACU3)
RepDCBlock3 = self.RepDCBlock3(DACU3)
RepDCBlock3 = tf.keras.layers.BatchNormalization()(RepDCBlock3)
conv3 = self.conv3(RepDCBlock3)
conv3 = tf.nn.leaky_relu(conv3)
conv3 = tf.keras.layers.BatchNormalization()(conv3)
concat1 = tf.concat([conv2, conv3], axis=1)
DACU4 = self.DACU4(concat1)
DACU4 = tf.keras.layers.BatchNormalization()(DACU4)
RepDCBlock4 = self.RepDCBlock4(DACU4)
RepDCBlock4 = tf.keras.layers.BatchNormalization()(RepDCBlock4)
conv4 = self.conv4(RepDCBlock4)
conv4 = tf.nn.leaky_relu(conv4)
conv4 = tf.keras.layers.BatchNormalization()(conv4)
concat2 = tf.concat([conv1, conv4], axis=1)
RepDCBlock5 = self.RepDCBlock5(concat2)
RepDCBlock5 = tf.keras.layers.BatchNormalization()(RepDCBlock5)
if is_first_time:
# step two
# 重现原数据
# 接block3
GRU1 = self.GRU1(RepDCBlock3)
GRU1 = tf.keras.layers.BatchNormalization()(GRU1)
d1 = self.d1(GRU1)
# tf.nn.softmax
output1 = self.output1(d1)
# 接block4
GRU2 = self.GRU2(RepDCBlock4)
GRU2 = tf.keras.layers.BatchNormalization()(GRU2)
d2 = self.d2(GRU2)
# tf.nn.softmax
output2 = self.output2(d2)
# 接block5
GRU3 = self.GRU3(RepDCBlock5)
GRU3 = tf.keras.layers.BatchNormalization()(GRU3)
d3 = self.d3(GRU3)
# tf.nn.softmax
output3 = self.output3(d3)
# reduce_mean降维计算均值
MSE_loss1 = tf.reduce_mean(tf.keras.losses.mse(y_true=label1, y_pred=output1))
MSE_loss2 = tf.reduce_mean(tf.keras.losses.mse(y_true=label1, y_pred=output2))
MSE_loss3 = tf.reduce_mean(tf.keras.losses.mse(y_true=label1, y_pred=output3))
print("MSE_loss1:", MSE_loss1.numpy())
print("MSE_loss2:", MSE_loss2.numpy())
print("MSE_loss3:", MSE_loss3.numpy())
loss = MSE_loss1 + MSE_loss2 + MSE_loss3
Accuracy_num=0
else:
# step two
# 重现原数据
# 接block3
GRU1 = self.GRU1(RepDCBlock3)
GRU1 = tf.keras.layers.BatchNormalization()(GRU1)
d1 = self.d1(GRU1)
# tf.nn.softmax
output1 = self.output1(d1)
# 接block4
GRU2 = self.GRU2(RepDCBlock4)
GRU2 = tf.keras.layers.BatchNormalization()(GRU2)
d2 = self.d2(GRU2)
# tf.nn.softmax
output2 = self.output2(d2)
# 接block5
GRU3 = self.GRU3(RepDCBlock5)
GRU3 = tf.keras.layers.BatchNormalization()(GRU3)
d3 = self.d3(GRU3)
# tf.nn.softmax
output3 = self.output3(d3)
# 多尺度动态池化
# p1 = self.p1(output1)
# B, _, _ = p1.shape
# f1 = tf.reshape(p1, shape=[B, -1])
# p2 = self.p2(output2)
# f2 = tf.reshape(p2, shape=[B, -1])
# p3 = self.p3(output3)
# f3 = tf.reshape(p3, shape=[B, -1])
# step three
# 分类器
concat3 = tf.concat([output1, output2, output3], axis=1)
# dropout = tf.keras.layers.Dropout(0.25)(concat3)
d4 = self.d4(concat3)
# d5=self.d5(d4)
# d4 = tf.keras.layers.BatchNormalization()(d4)
output4 = self.output4(d4)
# reduce_mean降维计算均值
MSE_loss = SmoothL1Loss()(y_true=pred_3, y_pred=output1)
MSE_loss += SmoothL1Loss()(y_true=pred_4, y_pred=output2)
MSE_loss += SmoothL1Loss()(y_true=pred_5, y_pred=output3)
Cross_Entropy_loss = tf.reduce_mean(
tf.losses.binary_crossentropy(y_true=label2, y_pred=output4, from_logits=True))
print("MSE_loss:", MSE_loss.numpy())
print("Cross_Entropy_loss:", Cross_Entropy_loss.numpy())
Accuracy_num = self.get_Accuracy(label=label2, output=output4)
loss = MSE_loss + Cross_Entropy_loss
return loss, Accuracy_num
def get_Accuracy(self, output, label):
predict_label = tf.round(output)
label = tf.cast(label, dtype=tf.float32)
t = np.array(label - predict_label)
b = t[t[:] == 0]
return b.__len__()
def get_grad(self, input_tensor, label1=None, label2=None, is_first_time: bool = True, pred_3=None, pred_4=None,
pred_5=None):
with tf.GradientTape() as tape:
# todo 原本tape只会监控由tf.Variable创建的trainable=True属性
# tape.watch(self.variables)
L, Accuracy_num = self.get_loss(input_tensor, label1=label1, label2=label2, is_first_time=is_first_time,
pred_3=pred_3,
pred_4=pred_4, pred_5=pred_5)
# 保存一下loss用于输出
self.train_loss = L
g = tape.gradient(L, self.variables)
return g, Accuracy_num
def train(self, input_tensor, label1=None, label2=None, learning_rate=1e-3, is_first_time: bool = True, pred_3=None,
pred_4=None, pred_5=None):
g, Accuracy_num = self.get_grad(input_tensor, label1=label1, label2=label2, is_first_time=is_first_time,
pred_3=pred_3,
pred_4=pred_4, pred_5=pred_5)
optimizers.Adam(learning_rate).apply_gradients(zip(g, self.variables))
return self.train_loss, Accuracy_num
# 暂时只支持batch_size等于1,不然要传z比较麻烦
def get_val_loss(self, val_data, val_label1, val_label2, batch_size=16, is_first_time: bool = True,
step_one_model=None):
val_loss = []
accuracy_num = 0
size, length, dims = val_data.shape
if batch_size == None:
batch_size = self.batch_size
for epoch in range(0, size - batch_size, batch_size):
each_val_data = val_data[epoch:epoch + batch_size, :, :]
each_val_label1 = val_label1[epoch:epoch + batch_size, :]
each_val_label2 = val_label2[epoch:epoch + batch_size, ]
# each_val_data = tf.expand_dims(each_val_data, axis=0)
# each_val_query = tf.expand_dims(each_val_query, axis=0)
# each_val_label = tf.expand_dims(each_val_label, axis=0)
if not is_first_time:
output1, output2, output3, _ = step_one_model.call(inputs=each_val_data, is_first_time=True)
each_loss, each_accuracy_num = self.get_loss(each_val_data, each_val_label1, each_val_label2,
is_first_time=is_first_time,
pred_3=output1, pred_4=output2, pred_5=output3)
accuracy_num += each_accuracy_num
val_loss.append(each_loss)
# print(accuracy_num)
val_accuracy = accuracy_num / (epoch+1) * batch_size
val_total_loss = tf.reduce_mean(val_loss)
return val_total_loss, val_accuracy
class RevConv(keras.layers.Layer):
def __init__(self, kernel_size=3):
# 调用父类__init__()方法
super(RevConv, self).__init__()
self.kernel_size = kernel_size
def get_config(self):
# 自定义层里面的属性
config = (
{
'kernel_size': self.kernel_size
}
)
base_config = super(RevConv, self).get_config()
return dict(list(base_config.items()) + list(config.items()))
def build(self, input_shape):
# print(input_shape)
_, _, output_dim = input_shape[0], input_shape[1], input_shape[2]
self.conv1 = tf.keras.layers.Conv1D(filters=output_dim, kernel_size=self.kernel_size, strides=1,
padding='causal',
dilation_rate=4)
self.conv2 = tf.keras.layers.Conv1D(filters=output_dim, kernel_size=1, strides=1, padding='causal',
dilation_rate=4)
# self.b2 = tf.keras.layers.BatchNormalization()
# self.b3 = tf.keras.layers.BatchNormalization()
# out = tf.keras.layers.Add()([b1, b2, b3])
# out = tf.nn.relu(out)
def call(self, inputs, **kwargs):
conv1 = self.conv1(inputs)
b1 = tf.keras.layers.BatchNormalization()(conv1)
b1 = tf.nn.leaky_relu(b1)
# b1 = self.b1
conv2 = self.conv2(inputs)
b2 = tf.keras.layers.BatchNormalization()(conv2)
b2 = tf.nn.leaky_relu(b2)
b3 = tf.keras.layers.BatchNormalization()(inputs)
out = tf.keras.layers.Add()([b1, b2, b3])
out = tf.nn.relu(out)
return out
class RevConvBlock(keras.layers.Layer):
def __init__(self, num: int = 3, kernel_size=3):
# 调用父类__init__()方法
super(RevConvBlock, self).__init__()
self.num = num
self.kernel_size = kernel_size
self.L = []
for i in range(num):
RepVGG = RevConv(kernel_size=kernel_size)
self.L.append(RepVGG)
def get_config(self):
# 自定义层里面的属性
config = (
{
'kernel_size': self.kernel_size,
'num': self.num
}
)
base_config = super(RevConvBlock, self).get_config()
return dict(list(base_config.items()) + list(config.items()))
def call(self, inputs, **kwargs):
for i in range(self.num):
inputs = self.L[i](inputs)
return inputs

View File

@ -0,0 +1,453 @@
# _*_ coding: UTF-8 _*_
'''
@Author : dingjiawen
@Date : 2022/7/14 9:40
@Usage : 联合监测模型
@Desc : 将预测值放入分类器,分类器放两层逐渐递减的dense层
'''
import tensorflow as tf
import tensorflow.keras as keras
from tensorflow.keras import *
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from model.DepthwiseCon1D.DepthwiseConv1D import DepthwiseConv1D
from model.Dynamic_channelAttention.Dynamic_channelAttention import DynamicChannelAttention, DynamicPooling
from condition_monitoring.data_deal import loadData
from model.LossFunction.smooth_L1_Loss import SmoothL1Loss
import math
class Joint_Monitoring(keras.Model):
def __init__(self, conv_filter=20):
# 调用父类__init__()方法
super(Joint_Monitoring, self).__init__()
# step one
self.RepDCBlock1 = RevConvBlock(num=3, kernel_size=5)
self.conv1 = tf.keras.layers.Conv1D(filters=conv_filter, kernel_size=1, strides=2, padding='SAME')
self.upsample1 = tf.keras.layers.UpSampling1D(size=2)
self.DACU2 = DynamicChannelAttention()
self.RepDCBlock2 = RevConvBlock(num=3, kernel_size=3)
self.conv2 = tf.keras.layers.Conv1D(filters=2 * conv_filter, kernel_size=1, strides=2, padding='SAME')
self.upsample2 = tf.keras.layers.UpSampling1D(size=2)
self.DACU3 = DynamicChannelAttention()
self.RepDCBlock3 = RevConvBlock(num=3, kernel_size=3)
self.p1 = DynamicPooling(pool_size=2)
self.conv3 = tf.keras.layers.Conv1D(filters=2 * conv_filter, kernel_size=3, strides=2, padding='SAME')
self.DACU4 = DynamicChannelAttention()
self.RepDCBlock4 = RevConvBlock(num=3, kernel_size=3)
self.p2 = DynamicPooling(pool_size=4)
self.conv4 = tf.keras.layers.Conv1D(filters=conv_filter, kernel_size=3, strides=2, padding='SAME')
self.RepDCBlock5 = RevConvBlock(num=3, kernel_size=3)
self.p3 = DynamicPooling(pool_size=2)
# step two
# 重现原数据
self.GRU1 = tf.keras.layers.GRU(128, return_sequences=False)
self.d1 = tf.keras.layers.Dense(300, activation=tf.nn.leaky_relu)
self.output1 = tf.keras.layers.Dense(10, activation=tf.nn.leaky_relu)
self.GRU2 = tf.keras.layers.GRU(128, return_sequences=False)
self.d2 = tf.keras.layers.Dense(300, activation=tf.nn.leaky_relu)
self.output2 = tf.keras.layers.Dense(10, activation=tf.nn.leaky_relu)
self.GRU3 = tf.keras.layers.GRU(128, return_sequences=False)
self.d3 = tf.keras.layers.Dense(300, activation=tf.nn.leaky_relu)
self.output3 = tf.keras.layers.Dense(10, activation=tf.nn.leaky_relu)
# step three
# 分类器
self.d4 = tf.keras.layers.Dense(300, activation=tf.nn.leaky_relu)
self.d5 = tf.keras.layers.Dense(10, activation=tf.nn.leaky_relu)
# tf.nn.softmax
self.output4 = tf.keras.layers.Dense(1, activation=tf.nn.sigmoid)
# loss
self.train_loss = []
def call(self, inputs, training=None, mask=None, is_first_time: bool = True):
# step one
RepDCBlock1 = self.RepDCBlock1(inputs)
RepDCBlock1 = tf.keras.layers.BatchNormalization()(RepDCBlock1)
conv1 = self.conv1(RepDCBlock1)
conv1 = tf.nn.leaky_relu(conv1)
conv1 = tf.keras.layers.BatchNormalization()(conv1)
upsample1 = self.upsample1(conv1)
DACU2 = self.DACU2(upsample1)
DACU2 = tf.keras.layers.BatchNormalization()(DACU2)
RepDCBlock2 = self.RepDCBlock2(DACU2)
RepDCBlock2 = tf.keras.layers.BatchNormalization()(RepDCBlock2)
conv2 = self.conv2(RepDCBlock2)
conv2 = tf.nn.leaky_relu(conv2)
conv2 = tf.keras.layers.BatchNormalization()(conv2)
upsample2 = self.upsample2(conv2)
DACU3 = self.DACU3(upsample2)
DACU3 = tf.keras.layers.BatchNormalization()(DACU3)
RepDCBlock3 = self.RepDCBlock3(DACU3)
RepDCBlock3 = tf.keras.layers.BatchNormalization()(RepDCBlock3)
conv3 = self.conv3(RepDCBlock3)
conv3 = tf.nn.leaky_relu(conv3)
conv3 = tf.keras.layers.BatchNormalization()(conv3)
concat1 = tf.concat([conv2, conv3], axis=1)
DACU4 = self.DACU4(concat1)
DACU4 = tf.keras.layers.BatchNormalization()(DACU4)
RepDCBlock4 = self.RepDCBlock4(DACU4)
RepDCBlock4 = tf.keras.layers.BatchNormalization()(RepDCBlock4)
conv4 = self.conv4(RepDCBlock4)
conv4 = tf.nn.leaky_relu(conv4)
conv4 = tf.keras.layers.BatchNormalization()(conv4)
concat2 = tf.concat([conv1, conv4], axis=1)
RepDCBlock5 = self.RepDCBlock5(concat2)
RepDCBlock5 = tf.keras.layers.BatchNormalization()(RepDCBlock5)
output1 = []
output2 = []
output3 = []
output4 = []
if is_first_time:
# step two
# 重现原数据
# 接block3
GRU1 = self.GRU1(RepDCBlock3)
GRU1 = tf.keras.layers.BatchNormalization()(GRU1)
d1 = self.d1(GRU1)
# tf.nn.softmax
output1 = self.output1(d1)
# 接block4
GRU2 = self.GRU2(RepDCBlock4)
GRU2 = tf.keras.layers.BatchNormalization()(GRU2)
d2 = self.d2(GRU2)
# tf.nn.softmax
output2 = self.output2(d2)
# 接block5
GRU3 = self.GRU3(RepDCBlock5)
GRU3 = tf.keras.layers.BatchNormalization()(GRU3)
d3 = self.d3(GRU3)
# tf.nn.softmax
output3 = self.output3(d3)
else:
GRU1 = self.GRU1(RepDCBlock3)
GRU1 = tf.keras.layers.BatchNormalization()(GRU1)
d1 = self.d1(GRU1)
# tf.nn.softmax
output1 = self.output1(d1)
# 接block4
GRU2 = self.GRU2(RepDCBlock4)
GRU2 = tf.keras.layers.BatchNormalization()(GRU2)
d2 = self.d2(GRU2)
# tf.nn.softmax
output2 = self.output2(d2)
# 接block5
GRU3 = self.GRU3(RepDCBlock5)
GRU3 = tf.keras.layers.BatchNormalization()(GRU3)
d3 = self.d3(GRU3)
# tf.nn.softmax
output3 = self.output3(d3)
# 多尺度动态池化
# p1 = self.p1(output1)
# B, _, _ = p1.shape
# f1 = tf.reshape(p1, shape=[B, -1])
# p2 = self.p2(output2)
# f2 = tf.reshape(p2, shape=[B, -1])
# p3 = self.p3(output3)
# f3 = tf.reshape(p3, shape=[B, -1])
# step three
# 分类器
concat3 = tf.concat([output1, output2, output3], axis=1)
# dropout = tf.keras.layers.Dropout(0.25)(concat3)
d4 = self.d4(concat3)
d5 = self.d5(d4)
# d4 = tf.keras.layers.BatchNormalization()(d4)
output4 = self.output4(d5)
return output1, output2, output3, output4
def get_loss(self, inputs_tensor, label1=None, label2=None, is_first_time: bool = True, pred_3=None, pred_4=None,
pred_5=None):
# step one
RepDCBlock1 = self.RepDCBlock1(inputs_tensor)
RepDCBlock1 = tf.keras.layers.BatchNormalization()(RepDCBlock1)
conv1 = self.conv1(RepDCBlock1)
conv1 = tf.nn.leaky_relu(conv1)
conv1 = tf.keras.layers.BatchNormalization()(conv1)
upsample1 = self.upsample1(conv1)
DACU2 = self.DACU2(upsample1)
DACU2 = tf.keras.layers.BatchNormalization()(DACU2)
RepDCBlock2 = self.RepDCBlock2(DACU2)
RepDCBlock2 = tf.keras.layers.BatchNormalization()(RepDCBlock2)
conv2 = self.conv2(RepDCBlock2)
conv2 = tf.nn.leaky_relu(conv2)
conv2 = tf.keras.layers.BatchNormalization()(conv2)
upsample2 = self.upsample2(conv2)
DACU3 = self.DACU3(upsample2)
DACU3 = tf.keras.layers.BatchNormalization()(DACU3)
RepDCBlock3 = self.RepDCBlock3(DACU3)
RepDCBlock3 = tf.keras.layers.BatchNormalization()(RepDCBlock3)
conv3 = self.conv3(RepDCBlock3)
conv3 = tf.nn.leaky_relu(conv3)
conv3 = tf.keras.layers.BatchNormalization()(conv3)
concat1 = tf.concat([conv2, conv3], axis=1)
DACU4 = self.DACU4(concat1)
DACU4 = tf.keras.layers.BatchNormalization()(DACU4)
RepDCBlock4 = self.RepDCBlock4(DACU4)
RepDCBlock4 = tf.keras.layers.BatchNormalization()(RepDCBlock4)
conv4 = self.conv4(RepDCBlock4)
conv4 = tf.nn.leaky_relu(conv4)
conv4 = tf.keras.layers.BatchNormalization()(conv4)
concat2 = tf.concat([conv1, conv4], axis=1)
RepDCBlock5 = self.RepDCBlock5(concat2)
RepDCBlock5 = tf.keras.layers.BatchNormalization()(RepDCBlock5)
if is_first_time:
# step two
# 重现原数据
# 接block3
GRU1 = self.GRU1(RepDCBlock3)
GRU1 = tf.keras.layers.BatchNormalization()(GRU1)
d1 = self.d1(GRU1)
# tf.nn.softmax
output1 = self.output1(d1)
# 接block4
GRU2 = self.GRU2(RepDCBlock4)
GRU2 = tf.keras.layers.BatchNormalization()(GRU2)
d2 = self.d2(GRU2)
# tf.nn.softmax
output2 = self.output2(d2)
# 接block5
GRU3 = self.GRU3(RepDCBlock5)
GRU3 = tf.keras.layers.BatchNormalization()(GRU3)
d3 = self.d3(GRU3)
# tf.nn.softmax
output3 = self.output3(d3)
# reduce_mean降维计算均值
MSE_loss1 = tf.reduce_mean(tf.keras.losses.mse(y_true=label1, y_pred=output1))
MSE_loss2 = tf.reduce_mean(tf.keras.losses.mse(y_true=label1, y_pred=output2))
MSE_loss3 = tf.reduce_mean(tf.keras.losses.mse(y_true=label1, y_pred=output3))
# print("MSE_loss1:", MSE_loss1.numpy())
# print("MSE_loss2:", MSE_loss2.numpy())
# print("MSE_loss3:", MSE_loss3.numpy())
loss = MSE_loss1 + MSE_loss2 + MSE_loss3
Accuracy_num = 0
else:
# step two
# 重现原数据
# 接block3
GRU1 = self.GRU1(RepDCBlock3)
GRU1 = tf.keras.layers.BatchNormalization()(GRU1)
d1 = self.d1(GRU1)
# tf.nn.softmax
output1 = self.output1(d1)
# 接block4
GRU2 = self.GRU2(RepDCBlock4)
GRU2 = tf.keras.layers.BatchNormalization()(GRU2)
d2 = self.d2(GRU2)
# tf.nn.softmax
output2 = self.output2(d2)
# 接block5
GRU3 = self.GRU3(RepDCBlock5)
GRU3 = tf.keras.layers.BatchNormalization()(GRU3)
d3 = self.d3(GRU3)
# tf.nn.softmax
output3 = self.output3(d3)
# 多尺度动态池化
# p1 = self.p1(output1)
# B, _, _ = p1.shape
# f1 = tf.reshape(p1, shape=[B, -1])
# p2 = self.p2(output2)
# f2 = tf.reshape(p2, shape=[B, -1])
# p3 = self.p3(output3)
# f3 = tf.reshape(p3, shape=[B, -1])
# step three
# 分类器
concat3 = tf.concat([output1, output2, output3], axis=1)
# dropout = tf.keras.layers.Dropout(0.25)(concat3)
d4 = self.d4(concat3)
d5 = self.d5(d4)
# d4 = tf.keras.layers.BatchNormalization()(d4)
output4 = self.output4(d5)
# reduce_mean降维计算均值
a = 50
beta = 0.5 * math.cos(min(self.epoch * 2 / self.epochs, 1) * math.pi) + 0.5
MSE_loss = SmoothL1Loss()(y_true=pred_3, y_pred=output1)
MSE_loss += SmoothL1Loss()(y_true=pred_4, y_pred=output2)
MSE_loss += SmoothL1Loss()(y_true=pred_5, y_pred=output3)
Cross_Entropy_loss = tf.reduce_mean(
tf.losses.binary_crossentropy(y_true=label2, y_pred=output4, from_logits=True))
print("MSE_loss:", MSE_loss.numpy())
print("Cross_Entropy_loss:", Cross_Entropy_loss.numpy())
Accuracy_num = self.get_Accuracy(label=label2, output=output4)
loss = beta * MSE_loss + a * Cross_Entropy_loss
return loss, Accuracy_num
def get_Accuracy(self, output, label):
predict_label = tf.round(output)
label = tf.cast(label, dtype=tf.float32)
t = np.array(label - predict_label)
b = t[t[:] == 0]
return b.__len__()
def get_grad(self, input_tensor, label1=None, label2=None, is_first_time: bool = True, pred_3=None, pred_4=None,
pred_5=None):
with tf.GradientTape() as tape:
# todo 原本tape只会监控由tf.Variable创建的trainable=True属性
# tape.watch(self.variables)
L, Accuracy_num = self.get_loss(input_tensor, label1=label1, label2=label2, is_first_time=is_first_time,
pred_3=pred_3,
pred_4=pred_4, pred_5=pred_5)
# 保存一下loss用于输出
self.train_loss = L
g = tape.gradient(L, self.variables)
return g, Accuracy_num
def train(self, input_tensor, label1=None, label2=None, learning_rate=1e-3, is_first_time: bool = True, pred_3=None,
pred_4=None, pred_5=None):
g, Accuracy_num = self.get_grad(input_tensor, label1=label1, label2=label2, is_first_time=is_first_time,
pred_3=pred_3,
pred_4=pred_4, pred_5=pred_5)
optimizers.Adam(learning_rate).apply_gradients(zip(g, self.variables))
return self.train_loss, Accuracy_num
# 暂时只支持batch_size等于1,不然要传z比较麻烦
def get_val_loss(self, val_data, val_label1, val_label2, batch_size=16, is_first_time: bool = True,
step_one_model=None):
val_loss = []
accuracy_num = 0
output1 = 0
output2 = 0
output3 = 0
z = 1
size, length, dims = val_data.shape
if batch_size == None:
batch_size = self.batch_size
for epoch in range(0, size - batch_size, batch_size):
each_val_data = val_data[epoch:epoch + batch_size, :, :]
each_val_label1 = val_label1[epoch:epoch + batch_size, :]
each_val_label2 = val_label2[epoch:epoch + batch_size, ]
# each_val_data = tf.expand_dims(each_val_data, axis=0)
# each_val_query = tf.expand_dims(each_val_query, axis=0)
# each_val_label = tf.expand_dims(each_val_label, axis=0)
if not is_first_time:
output1, output2, output3, _ = step_one_model.call(inputs=each_val_data, is_first_time=True)
each_loss, each_accuracy_num = self.get_loss(each_val_data, each_val_label1, each_val_label2,
is_first_time=is_first_time,
pred_3=output1, pred_4=output2, pred_5=output3)
accuracy_num += each_accuracy_num
val_loss.append(each_loss)
z += 1
val_accuracy = accuracy_num / ((z - 1) * batch_size)
val_total_loss = tf.reduce_mean(val_loss)
return val_total_loss, val_accuracy
class RevConv(keras.layers.Layer):
def __init__(self, kernel_size=3):
# 调用父类__init__()方法
super(RevConv, self).__init__()
self.kernel_size = kernel_size
def get_config(self):
# 自定义层里面的属性
config = (
{
'kernel_size': self.kernel_size
}
)
base_config = super(RevConv, self).get_config()
return dict(list(base_config.items()) + list(config.items()))
def build(self, input_shape):
# print(input_shape)
_, _, output_dim = input_shape[0], input_shape[1], input_shape[2]
self.conv1 = tf.keras.layers.Conv1D(filters=output_dim, kernel_size=self.kernel_size, strides=1,
padding='causal',
dilation_rate=4)
self.conv2 = tf.keras.layers.Conv1D(filters=output_dim, kernel_size=1, strides=1, padding='causal',
dilation_rate=4)
# self.b2 = tf.keras.layers.BatchNormalization()
# self.b3 = tf.keras.layers.BatchNormalization()
# out = tf.keras.layers.Add()([b1, b2, b3])
# out = tf.nn.relu(out)
def call(self, inputs, **kwargs):
conv1 = self.conv1(inputs)
b1 = tf.keras.layers.BatchNormalization()(conv1)
b1 = tf.nn.leaky_relu(b1)
# b1 = self.b1
conv2 = self.conv2(inputs)
b2 = tf.keras.layers.BatchNormalization()(conv2)
b2 = tf.nn.leaky_relu(b2)
b3 = tf.keras.layers.BatchNormalization()(inputs)
out = tf.keras.layers.Add()([b1, b2, b3])
out = tf.nn.relu(out)
return out
class RevConvBlock(keras.layers.Layer):
def __init__(self, num: int = 3, kernel_size=3):
# 调用父类__init__()方法
super(RevConvBlock, self).__init__()
self.num = num
self.kernel_size = kernel_size
self.L = []
for i in range(num):
RepVGG = RevConv(kernel_size=kernel_size)
self.L.append(RepVGG)
def get_config(self):
# 自定义层里面的属性
config = (
{
'kernel_size': self.kernel_size,
'num': self.num
}
)
base_config = super(RevConvBlock, self).get_config()
return dict(list(base_config.items()) + list(config.items()))
def call(self, inputs, **kwargs):
for i in range(self.num):
inputs = self.L[i](inputs)
return inputs

View File

@ -0,0 +1,9 @@
# _*_ coding: UTF-8 _*_
'''
@Author : dingjiawen
@Date : 2022/7/14 9:40
@Usage :
@Desc :
'''

View File

@ -0,0 +1,447 @@
# _*_ coding: UTF-8 _*_
'''
@Author : dingjiawen
@Date : 2022/7/14 9:40
@Usage : 联合监测模型
@Desc : RNet:去除掉DCAU
'''
import tensorflow as tf
import tensorflow.keras as keras
from tensorflow.keras import *
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from model.DepthwiseCon1D.DepthwiseConv1D import DepthwiseConv1D
from model.Dynamic_channelAttention.Dynamic_channelAttention import DynamicChannelAttention, DynamicPooling
from condition_monitoring.data_deal import loadData
from model.LossFunction.smooth_L1_Loss import SmoothL1Loss
class Joint_Monitoring(keras.Model):
def __init__(self, conv_filter=20):
# 调用父类__init__()方法
super(Joint_Monitoring, self).__init__()
# step one
self.RepDCBlock1 = RevConvBlock(num=3, kernel_size=5)
self.conv1 = tf.keras.layers.Conv1D(filters=conv_filter, kernel_size=1, strides=2, padding='SAME')
self.upsample1 = tf.keras.layers.UpSampling1D(size=2)
# self.DACU2 = DynamicChannelAttention()
self.RepDCBlock2 = RevConvBlock(num=3, kernel_size=3)
self.conv2 = tf.keras.layers.Conv1D(filters=2 * conv_filter, kernel_size=1, strides=2, padding='SAME')
self.upsample2 = tf.keras.layers.UpSampling1D(size=2)
# self.DACU3 = DynamicChannelAttention()
self.RepDCBlock3 = RevConvBlock(num=3, kernel_size=3)
self.p1 = DynamicPooling(pool_size=2)
self.conv3 = tf.keras.layers.Conv1D(filters=2 * conv_filter, kernel_size=3, strides=2, padding='SAME')
# self.DACU4 = DynamicChannelAttention()
self.RepDCBlock4 = RevConvBlock(num=3, kernel_size=3)
self.p2 = DynamicPooling(pool_size=4)
self.conv4 = tf.keras.layers.Conv1D(filters=conv_filter, kernel_size=3, strides=2, padding='SAME')
self.RepDCBlock5 = RevConvBlock(num=3, kernel_size=3)
self.p3 = DynamicPooling(pool_size=2)
# step two
# 重现原数据
self.GRU1 = tf.keras.layers.GRU(128, return_sequences=False)
self.d1 = tf.keras.layers.Dense(300, activation=tf.nn.leaky_relu)
self.output1 = tf.keras.layers.Dense(10, activation=tf.nn.leaky_relu)
self.GRU2 = tf.keras.layers.GRU(128, return_sequences=False)
self.d2 = tf.keras.layers.Dense(300, activation=tf.nn.leaky_relu)
self.output2 = tf.keras.layers.Dense(10, activation=tf.nn.leaky_relu)
self.GRU3 = tf.keras.layers.GRU(128, return_sequences=False)
self.d3 = tf.keras.layers.Dense(300, activation=tf.nn.leaky_relu)
self.output3 = tf.keras.layers.Dense(10, activation=tf.nn.leaky_relu)
# loss
self.train_loss = []
def call(self, inputs, training=None, mask=None, is_first_time: bool = True):
# step one
RepDCBlock1 = self.RepDCBlock1(inputs)
RepDCBlock1 = tf.keras.layers.BatchNormalization()(RepDCBlock1)
conv1 = self.conv1(RepDCBlock1)
conv1 = tf.nn.leaky_relu(conv1)
conv1 = tf.keras.layers.BatchNormalization()(conv1)
upsample1 = self.upsample1(conv1)
# DACU2 = self.DACU2(upsample1)
DACU2 = tf.keras.layers.BatchNormalization()(upsample1)
RepDCBlock2 = self.RepDCBlock2(DACU2)
RepDCBlock2 = tf.keras.layers.BatchNormalization()(RepDCBlock2)
conv2 = self.conv2(RepDCBlock2)
conv2 = tf.nn.leaky_relu(conv2)
conv2 = tf.keras.layers.BatchNormalization()(conv2)
upsample2 = self.upsample2(conv2)
# DACU3 = self.DACU3(upsample2)
DACU3 = tf.keras.layers.BatchNormalization()(upsample2)
RepDCBlock3 = self.RepDCBlock3(DACU3)
RepDCBlock3 = tf.keras.layers.BatchNormalization()(RepDCBlock3)
conv3 = self.conv3(RepDCBlock3)
conv3 = tf.nn.leaky_relu(conv3)
conv3 = tf.keras.layers.BatchNormalization()(conv3)
concat1 = tf.concat([conv2, conv3], axis=1)
# DACU4 = self.DACU4(concat1)
DACU4 = tf.keras.layers.BatchNormalization()(concat1)
RepDCBlock4 = self.RepDCBlock4(DACU4)
RepDCBlock4 = tf.keras.layers.BatchNormalization()(RepDCBlock4)
conv4 = self.conv4(RepDCBlock4)
conv4 = tf.nn.leaky_relu(conv4)
conv4 = tf.keras.layers.BatchNormalization()(conv4)
concat2 = tf.concat([conv1, conv4], axis=1)
RepDCBlock5 = self.RepDCBlock5(concat2)
RepDCBlock5 = tf.keras.layers.BatchNormalization()(RepDCBlock5)
output1 = []
output2 = []
output3 = []
output4 = []
if is_first_time:
# step two
# 重现原数据
# 接block3
GRU1 = self.GRU1(RepDCBlock3)
GRU1 = tf.keras.layers.BatchNormalization()(GRU1)
d1 = self.d1(GRU1)
# tf.nn.softmax
output1 = self.output1(d1)
# 接block4
GRU2 = self.GRU2(RepDCBlock4)
GRU2 = tf.keras.layers.BatchNormalization()(GRU2)
d2 = self.d2(GRU2)
# tf.nn.softmax
output2 = self.output2(d2)
# 接block5
GRU3 = self.GRU3(RepDCBlock5)
GRU3 = tf.keras.layers.BatchNormalization()(GRU3)
d3 = self.d3(GRU3)
# tf.nn.softmax
output3 = self.output3(d3)
else:
GRU1 = self.GRU1(RepDCBlock3)
GRU1 = tf.keras.layers.BatchNormalization()(GRU1)
d1 = self.d1(GRU1)
# tf.nn.softmax
output1 = self.output1(d1)
# 接block4
GRU2 = self.GRU2(RepDCBlock4)
GRU2 = tf.keras.layers.BatchNormalization()(GRU2)
d2 = self.d2(GRU2)
# tf.nn.softmax
output2 = self.output2(d2)
# 接block5
GRU3 = self.GRU3(RepDCBlock5)
GRU3 = tf.keras.layers.BatchNormalization()(GRU3)
d3 = self.d3(GRU3)
# tf.nn.softmax
output3 = self.output3(d3)
# 多尺度动态池化
# p1 = self.p1(output1)
# B, _, _ = p1.shape
# f1 = tf.reshape(p1, shape=[B, -1])
# p2 = self.p2(output2)
# f2 = tf.reshape(p2, shape=[B, -1])
# p3 = self.p3(output3)
# f3 = tf.reshape(p3, shape=[B, -1])
# step three
# 分类器
concat3 = tf.concat([output1, output2, output3], axis=1)
# dropout = tf.keras.layers.Dropout(0.25)(concat3)
d4 = self.d4(concat3)
d5 = self.d5(d4)
# d4 = tf.keras.layers.BatchNormalization()(d4)
output4 = self.output4(d5)
return output1, output2, output3, output4
def get_loss(self, inputs_tensor, label1=None, label2=None, is_first_time: bool = True, pred_3=None, pred_4=None,
pred_5=None):
# step one
RepDCBlock1 = self.RepDCBlock1(inputs_tensor)
RepDCBlock1 = tf.keras.layers.BatchNormalization()(RepDCBlock1)
conv1 = self.conv1(RepDCBlock1)
conv1 = tf.nn.leaky_relu(conv1)
conv1 = tf.keras.layers.BatchNormalization()(conv1)
upsample1 = self.upsample1(conv1)
# DACU2 = self.DACU2(upsample1)
DACU2 = tf.keras.layers.BatchNormalization()(upsample1)
RepDCBlock2 = self.RepDCBlock2(DACU2)
RepDCBlock2 = tf.keras.layers.BatchNormalization()(RepDCBlock2)
conv2 = self.conv2(RepDCBlock2)
conv2 = tf.nn.leaky_relu(conv2)
conv2 = tf.keras.layers.BatchNormalization()(conv2)
upsample2 = self.upsample2(conv2)
# DACU3 = self.DACU3(upsample2)
DACU3 = tf.keras.layers.BatchNormalization()(upsample2)
RepDCBlock3 = self.RepDCBlock3(DACU3)
RepDCBlock3 = tf.keras.layers.BatchNormalization()(RepDCBlock3)
conv3 = self.conv3(RepDCBlock3)
conv3 = tf.nn.leaky_relu(conv3)
conv3 = tf.keras.layers.BatchNormalization()(conv3)
concat1 = tf.concat([conv2, conv3], axis=1)
# DACU4 = self.DACU4(concat1)
DACU4 = tf.keras.layers.BatchNormalization()(concat1)
RepDCBlock4 = self.RepDCBlock4(DACU4)
RepDCBlock4 = tf.keras.layers.BatchNormalization()(RepDCBlock4)
conv4 = self.conv4(RepDCBlock4)
conv4 = tf.nn.leaky_relu(conv4)
conv4 = tf.keras.layers.BatchNormalization()(conv4)
concat2 = tf.concat([conv1, conv4], axis=1)
RepDCBlock5 = self.RepDCBlock5(concat2)
RepDCBlock5 = tf.keras.layers.BatchNormalization()(RepDCBlock5)
if is_first_time:
# step two
# 重现原数据
# 接block3
GRU1 = self.GRU1(RepDCBlock3)
GRU1 = tf.keras.layers.BatchNormalization()(GRU1)
d1 = self.d1(GRU1)
# tf.nn.softmax
output1 = self.output1(d1)
# 接block4
GRU2 = self.GRU2(RepDCBlock4)
GRU2 = tf.keras.layers.BatchNormalization()(GRU2)
d2 = self.d2(GRU2)
# tf.nn.softmax
output2 = self.output2(d2)
# 接block5
GRU3 = self.GRU3(RepDCBlock5)
GRU3 = tf.keras.layers.BatchNormalization()(GRU3)
d3 = self.d3(GRU3)
# tf.nn.softmax
output3 = self.output3(d3)
# reduce_mean降维计算均值
MSE_loss1 = SmoothL1Loss()(y_true=label1, y_pred=output1)
MSE_loss2 = SmoothL1Loss()(y_true=label1, y_pred=output2)
MSE_loss3 = SmoothL1Loss()(y_true=label1, y_pred=output3)
# MSE_loss1 = tf.reduce_mean(tf.keras.losses.mse(y_true=label1, y_pred=output1))
# MSE_loss2 = tf.reduce_mean(tf.keras.losses.mse(y_true=label1, y_pred=output2))
# MSE_loss3 = tf.reduce_mean(tf.keras.losses.mse(y_true=label1, y_pred=output3))
print("MSE_loss1:", MSE_loss1.numpy())
print("MSE_loss2:", MSE_loss2.numpy())
print("MSE_loss3:", MSE_loss3.numpy())
loss = MSE_loss1 + MSE_loss2 + MSE_loss3
Accuracy_num = 0
else:
# step two
# 重现原数据
# 接block3
GRU1 = self.GRU1(RepDCBlock3)
GRU1 = tf.keras.layers.BatchNormalization()(GRU1)
d1 = self.d1(GRU1)
# tf.nn.softmax
output1 = self.output1(d1)
# 接block4
GRU2 = self.GRU2(RepDCBlock4)
GRU2 = tf.keras.layers.BatchNormalization()(GRU2)
d2 = self.d2(GRU2)
# tf.nn.softmax
output2 = self.output2(d2)
# 接block5
GRU3 = self.GRU3(RepDCBlock5)
GRU3 = tf.keras.layers.BatchNormalization()(GRU3)
d3 = self.d3(GRU3)
# tf.nn.softmax
output3 = self.output3(d3)
# 多尺度动态池化
# p1 = self.p1(output1)
# B, _, _ = p1.shape
# f1 = tf.reshape(p1, shape=[B, -1])
# p2 = self.p2(output2)
# f2 = tf.reshape(p2, shape=[B, -1])
# p3 = self.p3(output3)
# f3 = tf.reshape(p3, shape=[B, -1])
# step three
# 分类器
concat3 = tf.concat([output1, output2, output3], axis=1)
# dropout = tf.keras.layers.Dropout(0.25)(concat3)
d4 = self.d4(concat3)
d5 = self.d5(d4)
# d4 = tf.keras.layers.BatchNormalization()(d4)
output4 = self.output4(d5)
# reduce_mean降维计算均值
MSE_loss = SmoothL1Loss()(y_true=pred_3, y_pred=output1)
MSE_loss += SmoothL1Loss()(y_true=pred_4, y_pred=output2)
MSE_loss += SmoothL1Loss()(y_true=pred_5, y_pred=output3)
Cross_Entropy_loss = tf.reduce_mean(
tf.losses.binary_crossentropy(y_true=label2, y_pred=output4, from_logits=True))
print("MSE_loss:", MSE_loss.numpy())
print("Cross_Entropy_loss:", Cross_Entropy_loss.numpy())
Accuracy_num = self.get_Accuracy(label=label2, output=output4)
loss = MSE_loss + Cross_Entropy_loss
return loss, Accuracy_num
def get_Accuracy(self, output, label):
predict_label = tf.round(output)
label = tf.cast(label, dtype=tf.float32)
t = np.array(label - predict_label)
b = t[t[:] == 0]
return b.__len__()
def get_grad(self, input_tensor, label1=None, label2=None, is_first_time: bool = True, pred_3=None, pred_4=None,
pred_5=None):
with tf.GradientTape() as tape:
# todo 原本tape只会监控由tf.Variable创建的trainable=True属性
# tape.watch(self.variables)
L, Accuracy_num = self.get_loss(input_tensor, label1=label1, label2=label2, is_first_time=is_first_time,
pred_3=pred_3,
pred_4=pred_4, pred_5=pred_5)
# 保存一下loss用于输出
self.train_loss = L
g = tape.gradient(L, self.variables)
return g, Accuracy_num
def train(self, input_tensor, label1=None, label2=None, learning_rate=1e-3, is_first_time: bool = True, pred_3=None,
pred_4=None, pred_5=None):
g, Accuracy_num = self.get_grad(input_tensor, label1=label1, label2=label2, is_first_time=is_first_time,
pred_3=pred_3,
pred_4=pred_4, pred_5=pred_5)
optimizers.Adam(learning_rate).apply_gradients(zip(g, self.variables))
return self.train_loss, Accuracy_num
# 暂时只支持batch_size等于1,不然要传z比较麻烦
def get_val_loss(self, val_data, val_label1, val_label2, batch_size=16, is_first_time: bool = True,
step_one_model=None):
val_loss = []
accuracy_num = 0
output1 = 0
output2 = 0
output3 = 0
z = 1
size, length, dims = val_data.shape
if batch_size == None:
batch_size = self.batch_size
for epoch in range(0, size - batch_size, batch_size):
each_val_data = val_data[epoch:epoch + batch_size, :, :]
each_val_label1 = val_label1[epoch:epoch + batch_size, :]
each_val_label2 = val_label2[epoch:epoch + batch_size, ]
# each_val_data = tf.expand_dims(each_val_data, axis=0)
# each_val_query = tf.expand_dims(each_val_query, axis=0)
# each_val_label = tf.expand_dims(each_val_label, axis=0)
if not is_first_time:
output1, output2, output3, _ = step_one_model.call(inputs=each_val_data, is_first_time=True)
each_loss, each_accuracy_num = self.get_loss(each_val_data, each_val_label1, each_val_label2,
is_first_time=is_first_time,
pred_3=output1, pred_4=output2, pred_5=output3)
accuracy_num += each_accuracy_num
val_loss.append(each_loss)
z += 1
val_accuracy = accuracy_num / ((z-1) * batch_size)
val_total_loss = tf.reduce_mean(val_loss)
return val_total_loss, val_accuracy
class RevConv(keras.layers.Layer):
def __init__(self, kernel_size=3):
# 调用父类__init__()方法
super(RevConv, self).__init__()
self.kernel_size = kernel_size
def get_config(self):
# 自定义层里面的属性
config = (
{
'kernel_size': self.kernel_size
}
)
base_config = super(RevConv, self).get_config()
return dict(list(base_config.items()) + list(config.items()))
def build(self, input_shape):
# print(input_shape)
_, _, output_dim = input_shape[0], input_shape[1], input_shape[2]
self.conv1 = tf.keras.layers.Conv1D(filters=output_dim, kernel_size=self.kernel_size, strides=1,
padding='causal',
dilation_rate=4)
self.conv2 = tf.keras.layers.Conv1D(filters=output_dim, kernel_size=1, strides=1, padding='causal',
dilation_rate=4)
# self.b2 = tf.keras.layers.BatchNormalization()
# self.b3 = tf.keras.layers.BatchNormalization()
# out = tf.keras.layers.Add()([b1, b2, b3])
# out = tf.nn.relu(out)
def call(self, inputs, **kwargs):
conv1 = self.conv1(inputs)
b1 = tf.keras.layers.BatchNormalization()(conv1)
b1 = tf.nn.leaky_relu(b1)
# b1 = self.b1
conv2 = self.conv2(inputs)
b2 = tf.keras.layers.BatchNormalization()(conv2)
b2 = tf.nn.leaky_relu(b2)
b3 = tf.keras.layers.BatchNormalization()(inputs)
out = tf.keras.layers.Add()([b1, b2, b3])
out = tf.nn.relu(out)
return out
class RevConvBlock(keras.layers.Layer):
def __init__(self, num: int = 3, kernel_size=3):
# 调用父类__init__()方法
super(RevConvBlock, self).__init__()
self.num = num
self.kernel_size = kernel_size
self.L = []
for i in range(num):
RepVGG = RevConv(kernel_size=kernel_size)
self.L.append(RepVGG)
def get_config(self):
# 自定义层里面的属性
config = (
{
'kernel_size': self.kernel_size,
'num': self.num
}
)
base_config = super(RevConvBlock, self).get_config()
return dict(list(base_config.items()) + list(config.items()))
def call(self, inputs, **kwargs):
for i in range(self.num):
inputs = self.L[i](inputs)
return inputs

View File

@ -0,0 +1,10 @@
# -*- coding: utf-8 -*-
# coding: utf-8
'''
@Author : dingjiawen
@Date : 2022/10/11 20:30
@Usage :
@Desc :
'''

View File

@ -2,7 +2,14 @@
# 线性循环单元Linear Recurrent Unit # 线性循环单元Linear Recurrent Unit
# tensorflow 1.15 + bert4keras 0.11.4 测试通过 # tensorflow 1.15 + bert4keras 0.11.4 测试通过
from bert4keras.layers import * # from bert4keras.layers import *
import numpy as np
import tensorflow.keras.backend as K
import tensorflow as tf
import tensorflow.keras.layers as layers
import tensorflow.keras.activations as activations
import tensorflow.keras.initializers as initializers
from tensorflow.keras.layers import Dense,Layer
class LRU(Layer): class LRU(Layer):
@ -26,7 +33,7 @@ class LRU(Layer):
self.unroll = unroll self.unroll = unroll
self.kernel_initializer = initializers.get(kernel_initializer) self.kernel_initializer = initializers.get(kernel_initializer)
@integerize_shape
def build(self, input_shape): def build(self, input_shape):
super(LRU, self).build(input_shape) super(LRU, self).build(input_shape)
hidden_size = input_shape[-1] hidden_size = input_shape[-1]
@ -57,7 +64,7 @@ class LRU(Layer):
name='params_log', shape=(3, self.units), initializer=initializer name='params_log', shape=(3, self.units), initializer=initializer
) )
@recompute_grad
def call(self, inputs, mask=None): def call(self, inputs, mask=None):
u = self.i_dense(inputs) u = self.i_dense(inputs)
params = K.exp(self.params_log) params = K.exp(self.params_log)
@ -70,7 +77,7 @@ class LRU(Layer):
else: else:
L_in = K.shape(u)[1] L_in = K.shape(u)[1]
log2_L = K.log(K.cast(L_in, K.floatx())) / K.log(2.) log2_L = K.log(K.cast(L_in, K.floatx())) / K.log(2.)
log2_L = K.cast(tf.ceil(log2_L), 'int32') log2_L = K.cast(tf.math.ceil(log2_L), 'int32')
u = tf.complex(u[..., ::2], u[..., 1::2]) u = tf.complex(u[..., ::2], u[..., 1::2])
u = tf.pad(u, [[0, 0], [0, 2**log2_L - K.shape(u)[1]], [0, 0]]) u = tf.pad(u, [[0, 0], [0, 2**log2_L - K.shape(u)[1]], [0, 0]])
@ -101,7 +108,7 @@ class LRU(Layer):
_, x = tf.while_loop(lambda i, x: i <= log2_L, lru, [1, u]) _, x = tf.while_loop(lambda i, x: i <= log2_L, lru, [1, u])
x = x[:, :L_in] * tf.complex(gamma, 0.) x = x[:, :L_in] * tf.complex(gamma, 0.)
x = K.concatenate([tf.real(x), tf.imag(x)], axis=-1) x = K.concatenate([tf.math.real(x), tf.math.imag(x)], axis=-1)
return self.o_dense(x) return self.o_dense(x)
def get_config(self): def get_config(self):

View File

@ -0,0 +1,116 @@
# -*- 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 tensorflow.keras import *
import tensorflow.keras.layers as layers
class LSTMLayer(layers.Layer):
# 定义两个权重初始化方法,方便后续调用
k_ini = initializers.GlorotUniform()
b_ini = initializers.Zeros()
def __init__(self, units=30, return_sequences: bool = False, **kwargs):
super(LSTMLayer, 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(LSTMLayer, 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)
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]])
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=)

View File

@ -0,0 +1,110 @@
# -*- 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 tensorflow.keras import *
import tensorflow.keras.layers as layers
class LSTMLayer(layers.Layer):
# 定义两个权重初始化方法,方便后续调用
k_ini = initializers.GlorotUniform()
b_ini = initializers.Zeros()
def __init__(self, units=30, return_sequences: bool = False, **kwargs):
super(LSTMLayer, self).__init__()
self.units = units
self.return_sequences = return_sequences
def get_params(self, num_outputs):
def _three():
return Dense(num_outputs)
W_i = _three() # 输入门参数
W_f = _three() # 遗忘门参数
W_o = _three() # 输出门参数
W_c = _three() # 候选记忆细胞参数
# 输出层参数
return W_i, W_f, W_o, W_c
def get_config(self):
# 自定义层里面的属性
config = (
{
'units': self.units,
'return_sequences': self.return_sequences
}
)
base_config = super(LSTMLayer, 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.W_f, self.W_o, self.W_c = self.get_params(num_outputs=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]])
Wi = self.W_i(new_input)
Wf = self.W_f(new_input)
Wc = self.W_c(new_input)
Wo = self.W_o(new_input)
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=)

View File

@ -0,0 +1,300 @@
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
class LSTM_realize():
def __init__(self, input=np.empty(shape=[100, 1]), filters=100, batch_size=10, if_SA=False):
self.input = input
self.filters = filters
self.batch_size = batch_size
self.if_SA = if_SA
def getLayer(self, layer='LSTM', query=None):
if layer == 'LSTM':
layer = self.LSTM_layer()
return layer
elif layer == 'ConvLSTM':
layer = self.convLSTM()
return layer
elif layer == 'SA_LSTM':
layer = self.SA_LSTM(query)
return layer
elif layer == 'SA_ConvLSTM':
self.if_SA = True
layer = self.SA_ConvLSTM(query)
return layer
else:
raise ValueError("算法尚未实现")
def LSTM_layer(self):
input = self.input
batch_size = self.batch_size
epoch, seq, filter_num = input.shape
print(seq, filter_num)
ct_1 = tf.zeros(shape=[1, 1])
ht_1 = tf.zeros(shape=[1, 1])
for i in range(batch_size):
output = []
for batch in range(filter_num):
new_input = input[0, :, batch]
new_input = tf.expand_dims(new_input, axis=0)
if batch != 0:
new_input = tf.concat([new_input, ht_1], axis=-1)
Wi = Dense(1)(new_input)
Wf = Dense(1)(new_input)
Wc = Dense(1)(new_input)
Wo = Dense(1)(new_input)
ft = tf.nn.sigmoid(Wf)
it = tf.nn.sigmoid(Wi)
ct_ = tf.nn.tanh(Wc)
ot = tf.nn.sigmoid(Wo)
ct = tf.add(tf.multiply(ft, ct_1), tf.multiply(it, ct_))
ht = tf.multiply(tf.nn.tanh(ct), ot)
if batch == 0:
output = ht
else:
output = tf.concat([output, ht], axis=1)
ht_1 = ht
ct_1 = ct
if i == 0:
sum = output
else:
sum = tf.concat([sum, output], axis=0)
output = tf.reshape(sum, [batch_size, filter_num])
# output=tf.expand_dims(output,axis=0)
print(output.shape)
return output
def ConvLSTM(self):
input = self.input
batch_size = self.batch_size
epoch, seq, filter_num = input.shape
print(seq, filter_num)
ct_1 = tf.zeros(shape=[1, 1])
ht_1 = tf.zeros(shape=[1, 1])
for i in range(batch_size):
output = []
for batch in range(filter_num):
new_input = input[0, :, batch]
new_input = tf.expand_dims(new_input, axis=0)
new_input = tf.transpose(new_input, [1, 0])
new_input = tf.expand_dims(new_input, axis=0)
if batch != 0:
new_input = tf.concat([new_input, ht_1], axis=-1)
Wi = Conv1D(1, kernel_size=3, padding='SAME')(new_input)
Wf = Conv1D(1, kernel_size=3, padding='SAME')(new_input)
Wc = Conv1D(1, kernel_size=3, padding='SAME')(new_input)
Wo = Conv1D(1, kernel_size=3, padding='SAME')(new_input)
ft = tf.nn.sigmoid(Wf)
it = tf.nn.sigmoid(Wi)
ct_ = tf.nn.tanh(Wc)
ot = tf.nn.sigmoid(Wo)
ct = tf.add(tf.multiply(ft, ct_1), tf.multiply(it, ct_))
ht = tf.multiply(tf.nn.tanh(ct), ot)
if batch == 0:
output = ht
else:
output = tf.concat([output, ht], axis=-1)
ht_1 = ht
ct_1 = ct
if i == 0:
sum = output
else:
sum = tf.concat([sum, output], axis=0)
output = tf.reshape(sum, [batch_size, filter_num])
# output=tf.expand_dims(output,axis=0)
print(output.shape)
return output
def SA_LSTM(self, query):
self.query = query
input = self.input
batch_size = self.batch_size
epoch, seq, filter_num = input.shape
print(seq, filter_num)
ct_1 = tf.zeros(shape=[1, 1])
ht_1 = tf.zeros(shape=[1, 1])
for i in range(batch_size):
output = []
for batch in range(filter_num):
new_input = input[0, :, batch]
new_input = tf.expand_dims(new_input, axis=0)
# new_input = tf.transpose(new_input, [1, 0])
# new_input = tf.expand_dims(new_input, axis=0)
if batch != 0:
new_input = tf.concat([new_input, ht_1], axis=-1)
# new_input.shape=(1,50)
# self_attention模块
temp = tf.expand_dims(query[i][batch], axis=0)
query_cell=tf.expand_dims(temp,axis=1)
new_input1 = tf.concat([new_input, query_cell], axis=1)
(_, new_input_dims) = new_input1.shape
temp1 = Dense(new_input_dims)(new_input1)
temp1=temp1[:,:-1]
temp2 = tf.nn.tanh(temp1)
Si = Dense(new_input_dims-1)(temp2)
ai = tf.nn.softmax(Si)
ones=tf.ones(shape=ai.shape)
new_input = tf.multiply((ai + ones), new_input)
Wi = Dense(1)(new_input)
Wf = Dense(1)(new_input)
Wc = Dense(1)(new_input)
Wo = Dense(1)(new_input)
# Wi = Conv1D(1, kernel_size=3, padding='SAME')(new_input)
# Wf = Conv1D(1, kernel_size=3, padding='SAME')(new_input)
# Wc = Conv1D(1, kernel_size=3, padding='SAME')(new_input)
# Wo = Conv1D(1, kernel_size=3, padding='SAME')(new_input)
ft = tf.nn.sigmoid(Wf)
it = tf.nn.sigmoid(Wi)
ct_ = tf.nn.tanh(Wc)
ot = tf.nn.sigmoid(Wo)
ct = tf.add(tf.multiply(ft, ct_1), tf.multiply(it, ct_))
ht = tf.multiply(tf.nn.tanh(ct), ot)
if batch == 0:
output = ht
else:
output = tf.concat([output, ht], axis=-1)
ht_1 = ht
ct_1 = ct
if i == 0:
sum = output
else:
sum = tf.concat([sum, output], axis=0)
output = tf.reshape(sum, [batch_size, filter_num])
# output=tf.expand_dims(output,axis=0)
print(output.shape)
return output
def SA_ConvLSTM(self, query):
self.query = query
input = self.input
batch_size = self.batch_size
epoch, seq, filter_num = input.shape
print(seq, filter_num)
ct_1 = tf.zeros(shape=[1, 1])
ht_1 = tf.zeros(shape=[1, 1])
for i in range(batch_size):
output = []
for batch in range(filter_num):
new_input = input[0, :, batch]
new_input = tf.expand_dims(new_input, axis=0)
# new_input = tf.transpose(new_input, [1, 0])
# new_input = tf.expand_dims(new_input, axis=0)
if batch != 0:
new_input = tf.concat([new_input, ht_1], axis=-1)
# new_input.shape=(1,50)
# self_attention模块
temp = tf.expand_dims(query[i][batch], axis=0)
query_cell=tf.expand_dims(temp,axis=1)
new_input1 = tf.concat([new_input, query_cell], axis=1)
(_, new_input_dims) = new_input1.shape
temp1 = Dense(new_input_dims)(new_input1)
temp1=temp1[:,:-1]
temp2 = tf.nn.tanh(temp1)
Si = Dense(new_input_dims-1)(temp2)
ai = tf.nn.softmax(Si)
ones=tf.ones(shape=ai.shape)
new_input = tf.multiply((ai + ones), new_input)
Wi = Conv1D(1, kernel_size=3, padding='SAME')(new_input)
Wf = Conv1D(1, kernel_size=3, padding='SAME')(new_input)
Wc = Conv1D(1, kernel_size=3, padding='SAME')(new_input)
Wo = Conv1D(1, kernel_size=3, padding='SAME')(new_input)
ft = tf.nn.sigmoid(Wf)
it = tf.nn.sigmoid(Wi)
ct_ = tf.nn.tanh(Wc)
ot = tf.nn.sigmoid(Wo)
ct = tf.add(tf.multiply(ft, ct_1), tf.multiply(it, ct_))
ht = tf.multiply(tf.nn.tanh(ct), ot)
if batch == 0:
output = ht
else:
output = tf.concat([output, ht], axis=-1)
ht_1 = ht
ct_1 = ct
if i == 0:
sum = output
else:
sum = tf.concat([sum, output], axis=0)
output = tf.reshape(sum, [batch_size, filter_num])
# output=tf.expand_dims(output,axis=0)
print(output.shape)
return output
# if __name__ == '__main__':
# input=tf.random.truncated_normal(shape=[5,10])
# LSTM(input=input).getlayer()

View File

@ -0,0 +1,179 @@
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
class LSTM_realize():
def __init__(self, input=np.empty(shape=[100, 1]), units=30, batch_size=10, if_SA=False):
self.input = input
self.units = units
self.batch_size = batch_size
self.if_SA = if_SA
def getLayer(self, layer='LSTM', query=None):
if layer == 'LSTM':
layer = self.LSTM_layer()
return layer
elif layer == 'ConvLSTM':
layer = self.convLSTM()
return layer
elif layer == 'SA_LSTM':
layer = self.SA_LSTM(query)
return layer
elif layer == 'SA_ConvLSTM':
self.if_SA = True
layer = self.SA_ConvLSTM(query)
return layer
else:
raise ValueError("算法尚未实现")
def LSTM_layer(self):
input = self.input
batch_size = self.batch_size
units = self.units
epoch, filter_num, dims = input.shape
print(filter_num, dims)
ct_1 = tf.zeros(shape=[1, units])
ht_1 = tf.zeros(shape=[1, units])
for i in range(batch_size):
output = []
for batch in range(filter_num):
new_input = input[0, batch, :]
new_input = tf.expand_dims(new_input, axis=0)
if batch != 0:
new_input = tf.concat([new_input, ht_1], axis=-1)
Wi = Dense(units)(new_input)
Wf = Dense(units)(new_input)
Wc = Dense(units)(new_input)
Wo = Dense(units)(new_input)
ft = tf.nn.sigmoid(Wf)
it = tf.nn.sigmoid(Wi)
ct_ = tf.nn.tanh(Wc)
ot = tf.nn.sigmoid(Wo)
ct = tf.add(tf.multiply(ft, ct_1), tf.multiply(it, ct_))
ht = tf.multiply(tf.nn.tanh(ct), ot)
if batch == 0:
output = ht
else:
output = tf.concat([output, ht], axis=-1)
ht_1 = ht
ct_1 = ct
if i == 0:
sum = output
# sum = tf.expand_dims(sum,axis=0)
else:
# output = tf.expand_dims(output, axis=0)
sum = tf.concat([sum, output], axis=0)
#
output = tf.reshape(sum, [batch_size, filter_num])
# output=tf.expand_dims(output,axis=0)
print(output.shape)
return output
def convLSTM(self):
return None
def SA_ConvLSTM(self, query):
self.query = query
input = self.input
batch_size = self.batch_size
units = self.units
epoch, filter_num, dims = input.shape
print(filter_num, dims)
ct_1 = tf.zeros(shape=[1, units])
ht_1 = tf.zeros(shape=[1, units])
for i in range(batch_size):
output = []
for batch in range(filter_num):
new_input = input[0, batch, :]
new_input = tf.expand_dims(new_input, axis=0)
if batch != 0:
new_input = tf.concat([new_input, ht_1], axis=-1)
# new_input.shape=(1,50)
# self_attention模块
temp = tf.expand_dims(query[i][batch], axis=0)
query_cell = tf.expand_dims(temp, axis=1)
new_input1 = tf.concat([new_input, query_cell], axis=1)
(_, new_input_dims) = new_input1.shape
temp1 = Dense(new_input_dims)(new_input1)
temp1 = temp1[:, :-1]
temp2 = tf.nn.tanh(temp1)
Si = Dense(new_input_dims - 1)(temp2)
ai = tf.nn.softmax(Si)
ones = tf.ones(shape=ai.shape)
new_input = tf.multiply((ai + ones), new_input)
new_input = tf.expand_dims(new_input, axis=1)
Wi = Conv1D(units, kernel_size=3, padding='SAME')(new_input)
Wf = Conv1D(units, kernel_size=3, padding='SAME')(new_input)
Wc = Conv1D(units, kernel_size=3, padding='SAME')(new_input)
Wo = Conv1D(units, kernel_size=3, padding='SAME')(new_input)
Wi = tf.keras.layers.Flatten()(Wi)
Wf = tf.keras.layers.Flatten()(Wf)
Wc = tf.keras.layers.Flatten()(Wc)
Wo = tf.keras.layers.Flatten()(Wo)
ft = tf.nn.sigmoid(Wf)
it = tf.nn.sigmoid(Wi)
ct_ = tf.nn.tanh(Wc)
ot = tf.nn.sigmoid(Wo)
ct = tf.add(tf.multiply(ft, ct_1), tf.multiply(it, ct_))
ht = tf.multiply(tf.nn.tanh(ct), ot)
if batch == 0:
output = ht
else:
output = tf.concat([output, ht], axis=-1)
ht_1 = ht
ct_1 = ct
if i == 0:
sum = output
else:
sum = tf.concat([sum, output], axis=0)
output = tf.reshape(sum, [batch_size, filter_num])
# output=tf.expand_dims(output,axis=0)
print(output.shape)
return output
# if __name__ == '__main__':
# input=tf.random.truncated_normal(shape=[5,10])
# LSTM(input=input).getlayer()

View File

@ -0,0 +1,162 @@
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
tf.keras.backend.clear_session()
import tensorflow.keras as keras
import tensorflow.keras.layers as layers
'''
支持各种dim维度的数据进去但是SA模块的查询暂时有问题
需要知道batch是第几次
'''
class LSTM_realize(layers.Layer):
def __init__(self, input, units=30, batch_size=10, if_SA=False):
super(LSTM_realize, self).__init__()
self.input = input
self.units = units
self.batch_size = batch_size
self.if_SA = if_SA
def getLayer(self, layer='LSTM', query=None):
if layer == 'LSTM':
layer = self.LSTM_layer()
return layer
elif layer == 'ConvLSTM':
layer = self.convLSTM()
return layer
elif layer == 'SA_LSTM':
layer = self.SA_LSTM(query)
return layer
elif layer == 'SA_ConvLSTM':
self.if_SA = True
layer = self.SA_ConvLSTM(query)
return layer
else:
raise ValueError("算法尚未实现")
def LSTM_layer(self):
input = self.input
batch_size = self.batch_size
units = self.units
epoch, filter_num, dims = input.shape
print(filter_num, dims)
ct_1 = tf.zeros(shape=[batch_size, 1, units])
ht_1 = tf.zeros(shape=[batch_size, 1, units])
for batch in range(filter_num):
new_input = input[:, batch, :]
new_input = tf.expand_dims(new_input, axis=1)
if batch != 0:
new_input = tf.concat([new_input, ht_1], axis=-1)
Wi = Dense(units)(new_input)
Wf = Dense(units)(new_input)
Wc = Dense(units)(new_input)
Wo = Dense(units)(new_input)
ft = tf.nn.sigmoid(Wf)
it = tf.nn.sigmoid(Wi)
ct_ = tf.nn.tanh(Wc)
ot = tf.nn.sigmoid(Wo)
ct = tf.add(tf.multiply(ft, ct_1), tf.multiply(it, ct_))
ht = tf.multiply(tf.nn.tanh(ct), ot)
if batch == 0:
output = ht
else:
output = tf.concat([output, ht], axis=1)
ht_1 = ht
ct_1 = ct
output = tf.reshape(output, [batch_size, filter_num, units])
print(output.shape)
return output
def convLSTM(self):
return None
def SA_ConvLSTM(self, query):
self.query = query
print(query.shape)
input = self.input
batch_size = self.batch_size
units = self.units
epoch, filter_num, dims = input.shape
print(filter_num, dims)
ct_1 = tf.zeros(shape=[batch_size, 1, units])
ht_1 = tf.zeros(shape=[batch_size, 1, units])
for batch in range(filter_num):
new_input = input[:, batch, :]
new_input = tf.expand_dims(new_input, axis=1)
if batch != 0:
new_input = tf.concat([new_input, ht_1], axis=-1)
# new_input.shape=(1,50,1)
# self_attention模块
# query_cell = query[batch * batch_size:(batch + 1) * batch_size, batch, :]
query_cell = tf.expand_dims(query[batch * batch_size:(batch + 1) * batch_size, batch, :], axis=-1)
# query_cell = tf.expand_dims(temp, axis=1)
new_input1 = tf.concat([new_input, query_cell], axis=-1)
(_, _, new_input_dims) = new_input1.shape
temp1 = Dense(new_input_dims)(new_input1)
temp1 = temp1[:, :, :-1]
temp2 = tf.nn.tanh(temp1)
Si = Dense(new_input_dims - 1)(temp2)
ai = tf.nn.softmax(Si)
ones = tf.ones(shape=ai.shape)
new_input = tf.multiply((ai + ones), new_input)
Wi = Conv1D(units, kernel_size=3, padding='SAME')(new_input)
Wf = Conv1D(units, kernel_size=3, padding='SAME')(new_input)
Wc = Conv1D(units, kernel_size=3, padding='SAME')(new_input)
Wo = Conv1D(units, kernel_size=3, padding='SAME')(new_input)
ft = tf.nn.sigmoid(Wf)
it = tf.nn.sigmoid(Wi)
ct_ = tf.nn.tanh(Wc)
ot = tf.nn.sigmoid(Wo)
ct = tf.add(tf.multiply(ft, ct_1), tf.multiply(it, ct_))
ht = tf.multiply(tf.nn.tanh(ct), ot)
if batch == 0:
output = ht
else:
output = tf.concat([output, ht], axis=1)
ht_1 = ht
ct_1 = ct
# output = tf.reshape(sum, [batch_size , filter_num, units])
# output=tf.expand_dims(output,axis=0)
print(output.shape)
return output
# if __name__ == '__main__':
# input=tf.random.truncated_normal(shape=[5,10])
# LSTM(input=input).getlayer()

View File

@ -0,0 +1,235 @@
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
tf.keras.backend.clear_session()
import tensorflow.keras as keras
import tensorflow.keras.layers as layers
'''
增加了build和call方法初始化参数z做到可以知道当前的batch
也可以去查询SA模块
init中带参数的层必须重写get_config
存在问题:首先是模型保存问题,添加self.z知道当前的训练次数以后这个参数似乎无法保存,保存之后无法提取的问题
第二点是 由于在训练的时候使用的model.fit,训练过程封装的太好了,以至于这个类似乎只在初始化和训练第一次时加载一次,self.z不会随着训练次数的增加而增加
TODO 第一个问题已经解决
'''
class LSTM_realize(layers.Layer):
def __init__(self, units=30, batch_size=10, if_SA=False, if_Conv=False,query=None, **kwargs):
super(LSTM_realize, self).__init__()
self.units = units
self.batch_size = batch_size
self.if_SA = if_SA
self.if_Conv = if_Conv
self.query=query
def get_config(self):
# 自定义层里面的属性
config = (
{
'units': self.units,
'batch_size': self.batch_size,
'if_SA': self.if_SA,
'if_Conv': self.if_Conv,
'query': self.query
}
)
base_config = super(LSTM_realize, self).get_config()
return dict(list(base_config.items()) + list(config.items()))
def build(self, input_shape):
# 初始化可训练参数
self.Wi = []
self.Wf = []
self.Wc = []
self.Wo = []
self.Si = []
self.temp1 = []
for i in range(input_shape[1]):
if not self.if_Conv:
Wi = Dense(self.units)
Wf = Dense(self.units)
Wc = Dense(self.units)
Wo = Dense(self.units)
else:
Wi = Conv1D(self.units, kernel_size=3, padding='SAME')
Wf = Conv1D(self.units, kernel_size=3, padding='SAME')
Wc = Conv1D(self.units, kernel_size=3, padding='SAME')
Wo = Conv1D(self.units, kernel_size=3, padding='SAME')
if self.if_SA:
if i == 0:
Si = Dense(input_shape[-1])
temp1 = Dense(input_shape[-1] + 1)
else:
Si = Dense(self.units + input_shape[-1])
temp1 = Dense(self.units + input_shape[-1] + 1)
self.Si.append(Si)
self.temp1.append(temp1)
self.Wi.append(Wi)
self.Wf.append(Wf)
self.Wc.append(Wc)
self.Wo.append(Wo)
self.z = 0
def call(self, inputs, layer='LSTM', **kwargs):
self.inputs = inputs
return self.getLayer(layer=layer, query=self.query)
def getLayer(self, layer='LSTM', query=None):
if layer == 'LSTM':
self.if_SA = False
self.if_Conv = False
layer = self.LSTM_layer()
return layer
elif layer == 'ConvLSTM':
self.if_SA = False
self.if_Conv = True
layer = self.convLSTM()
return layer
elif layer == 'SA_LSTM':
self.if_SA = True
self.if_Conv = False
layer = self.SA_LSTM(query)
return layer
elif layer == 'SA_ConvLSTM':
self.if_SA = True
self.if_Conv = True
layer = self.SA_ConvLSTM(query)
return layer
else:
raise ValueError("算法尚未实现")
def LSTM_layer(self):
input = self.inputs
batch_size = self.batch_size
units = self.units
epoch, filter_num, dims = input.shape
print(filter_num, dims)
for batch in range(filter_num):
new_input = input[:, batch, :]
new_input = tf.expand_dims(new_input, axis=1)
if batch != 0:
new_input = tf.concat([new_input, ht_1], axis=-1)
Wi = self.Wi[batch](new_input)
Wf = self.Wf[batch](new_input)
Wc = self.Wc[batch](new_input)
Wo = self.Wo[batch](new_input)
ft = tf.nn.sigmoid(Wf)
it = tf.nn.sigmoid(Wi)
ct_ = tf.nn.tanh(Wc)
ot = tf.nn.sigmoid(Wo)
if batch != 0:
ct = tf.add(tf.multiply(ft, ct_1), tf.multiply(it, ct_))
else:
ct = tf.add(ft, tf.multiply(it, ct_))
ht = tf.multiply(tf.nn.tanh(ct), ot)
if batch == 0:
output = ht
else:
output = tf.concat([output, ht], axis=1)
ht_1 = ht
ct_1 = ct
# output = tf.reshape(output, [-1, filter_num, units])
print(output.shape)
return output
def convLSTM(self):
return None
def SA_ConvLSTM(self, query):
# TODO 解决模型保存时,该数组会被序列化,然后返序列化以后不再是np或者是tf的问题
query = tf.cast(query, dtype=tf.float32)
# print(query.shape)
input = self.inputs
batch_size = self.batch_size
units = self.units
epoch, filter_num, dims = input.shape
# print(filter_num, dims)
for batch in range(filter_num):
new_input = input[:, batch, :]
new_input = tf.expand_dims(new_input, axis=1)
if batch != 0:
new_input = tf.concat([new_input, ht_1], axis=-1)
# new_input.shape=(1,50,1)
# self_attention模块
# query_cell = query[batch * batch_size:(batch + 1) * batch_size, batch, :]
query_cell = tf.expand_dims(query[self.z * batch_size:(self.z + 1) * batch_size, batch, :], axis=-1)
# query_cell = tf.expand_dims(temp, axis=1)
new_input1 = tf.concat([new_input, query_cell], axis=-1)
(_, _, new_input_dims) = new_input1.shape
temp1 = self.temp1[batch](new_input1)
temp1 = temp1[:, :, :-1]
temp2 = tf.nn.tanh(temp1)
Si = self.Si[batch](temp2)
ai = tf.nn.softmax(Si)
ones = tf.ones(shape=ai.shape)
new_input = tf.multiply((ai + ones), new_input)
Wi = self.Wi[batch](new_input)
Wf = self.Wf[batch](new_input)
Wc = self.Wc[batch](new_input)
Wo = self.Wo[batch](new_input)
ft = tf.nn.sigmoid(Wf)
it = tf.nn.sigmoid(Wi)
ct_ = tf.nn.tanh(Wc)
ot = tf.nn.sigmoid(Wo)
if batch != 0:
ct = tf.add(tf.multiply(ft, ct_1), tf.multiply(it, ct_))
else:
ct = tf.add(ft, tf.multiply(it, ct_))
ht = tf.multiply(tf.nn.tanh(ct), ot)
if batch == 0:
output = ht
else:
output = tf.concat([output, ht], axis=1)
ht_1 = ht
ct_1 = ct
# output = tf.reshape(sum, [batch_size , filter_num, units])
# output=tf.expand_dims(output,axis=0)
# print(output.shape)
print("z=", self.z)
self.z += 1
return output
# if __name__ == '__main__':
# input=tf.random.truncated_normal(shape=[5,10])
# LSTM(input=input).getlayer()

View File

@ -0,0 +1,393 @@
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
# tf.keras.backend.clear_session()
from tensorflow.keras import *
import tensorflow.keras.layers as layers
#TODO 权重非共享式LSTM
'''
利用函数式编程的方式解决self3存在的无法知道训练了多少次的问题
'''
class PredictModel(Model):
def __init__(self, filter_num, dims, batch_size, query_label):
# 调用父类__init__()方法
super(PredictModel, self).__init__()
self.filter_num = filter_num
self.dims = dims
self.batch_size = batch_size
self.query = query_label
self.train_loss = None
self.val_loss = []
# self.LSTM_object = LSTM_realize(units=50, batch_size=batch_size, if_SA=False, if_Conv=False)
self.input_model_shape = tf.keras.Input(shape=[self.filter_num, self.dims])
self.LSTM_object = LSTM_realize(units=20, batch_size=self.batch_size, if_SA=True, if_Conv=True,
query=self.query)
# self.drop1 = tf.keras.layers.Dropout(0.2)
self.bn = tf.keras.layers.BatchNormalization()
self.d1 = tf.keras.layers.Dense(10)
self.drop2 = tf.keras.layers.Dropout(0.2)
self.d2 = tf.keras.layers.Dense(1, name='output')
# def build(self, input_shape):
# pass
# 将动态图转换为静态图
# 在静态图模型中,输入数据的数据维度不对、数据类型不对、数据名称不对都会报错
# @tf.function(input_signature=[tf.TensorSpec([None, 30,50], tf.float32, name='digits')])
# @tf.function
def call(self, inputs, training=None, mask=None, z=0, label=None, query=None, batch_size=None):
if query == None:
query = self.query
if batch_size == None:
batch_size = self.batch_size
input = tf.cast(inputs, tf.float32)
LSTM = self.LSTM_object(inputs=input, layer='SA_ConvLSTM', z=z, query=query, batch_size=batch_size)
# LSTM = self.LSTM_object(inputs=input, layer='LSTM')
# drop1 = self.drop1(LSTM)
# bn = self.bn(drop1)
bn = self.bn(LSTM)
d1 = self.d1(bn)
drop2 = self.drop2(d1)
output = self.d2(drop2)
# model = tf.keras.Model(inputs=input, outputs=output)
# return model
return output
def get_loss(self, inputs_tensor, label, query=None, batch_size=None, z=0):
if query == None:
query = self.query
if batch_size == None:
batch_size = self.batch_size
# inputs = self.input_model_shape(inputs_tensor)
input = tf.cast(inputs_tensor, tf.float32)
LSTM = self.LSTM_object(inputs=input, layer='SA_ConvLSTM', z=z, query=query, batch_size=batch_size)
# LSTM = self.LSTM_object(inputs=input, layer='LSTM')
# drop1 = self.drop1(LSTM)
# bn = self.bn(drop1)
bn = self.bn(LSTM)
d1 = self.d1(bn)
drop2 = self.drop2(d1)
output = self.d2(drop2)
# reduce_mean降维计算均值
loss = tf.reduce_mean(tf.keras.losses.mse(y_true=label, y_pred=output))
return loss
def get_selfLoss(self, inputs_tensor, label, query=None, batch_size=None, z=0):
if query == None:
query = self.query
if batch_size == None:
batch_size = self.batch_size
# inputs = self.input_model_shape(inputs_tensor)
input = tf.cast(inputs_tensor, tf.float32)
LSTM = self.LSTM_object(inputs=input, layer='SA_ConvLSTM', z=z, query=query, batch_size=batch_size)
batch, filer_num, dims = LSTM.shape
aloss = 0
bloss = 0
for i in range(filer_num - 1):
aloss += tf.abs(LSTM[:, i + 1, :] - LSTM[:, i, :])
for i in range(filer_num-3):
bloss += tf.abs(LSTM[:, i + 3, :] - LSTM[:, i+2, :]-(LSTM[:, i + 1, :] - LSTM[:, i, :]))
# LSTM = self.LSTM_object(inputs=input, layer='LSTM')
# drop1 = self.drop1(LSTM)
# bn = self.bn(drop1)
aloss = tf.reduce_mean(aloss)
bloss = tf.reduce_mean(bloss)
desired_aloss = 0.05
desired_bloss = 0.1
# aloss的权重惩罚项
aalpha = 0.1
abeita = 0.01
# bloss的权重惩罚项
bbeita = 0.01
bn = self.bn(LSTM)
d1 = self.d1(bn)
drop2 = self.drop2(d1)
output = self.d2(drop2)
# reduce_mean降维计算均值
loss = tf.reduce_mean(tf.keras.losses.mse(y_true=label, y_pred=output))
# total_loss = loss+abeita*(desired_aloss*tf.math.log(desired_aloss/aloss)+(1-desired_aloss)*tf.math.log((1-desired_aloss)/(1-aloss)))+bbeita*(desired_bloss*tf.math.log(desired_bloss/bloss)+(1-desired_bloss)*tf.math.log((1-desired_bloss)/(1-bloss)))
total_loss = loss +abeita*aloss+bbeita*bloss
return total_loss
def get_grad(self, input_tensor, label, query=None, z=0):
with tf.GradientTape() as tape:
# todo 原本tape只会监控由tf.Variable创建的trainable=True属性
tape.watch(self.variables)
L = self.get_selfLoss(input_tensor, label=label, query=query, z=z)
# 保存一下loss用于输出
self.train_loss = L
g = tape.gradient(L, self.variables)
return g
def train(self, input_tensor, label, query=None, learning_rate=1e-3, z=0):
g = self.get_grad(input_tensor, label=label, query=query, z=z)
optimizers.Adam(learning_rate).apply_gradients(zip(g, self.variables))
return self.train_loss
# 暂时只支持batch_size等于1,不然要传z比较麻烦
def get_val_loss(self, val_data, val_label, val_query, batch_size=1, z=0):
self.val_loss = []
size, filernums, dims = val_data.shape
if batch_size == None:
batch_size = self.batch_size
for epoch in range(size):
each_val_data = val_data[epoch, :, :]
each_val_query = val_query[epoch, :, :]
each_val_label = val_label[epoch, :]
each_val_data = tf.expand_dims(each_val_data, axis=0)
each_val_query = tf.expand_dims(each_val_query, axis=0)
each_val_label = tf.expand_dims(each_val_label, axis=0)
input = tf.cast(each_val_data, tf.float32)
LSTM = self.LSTM_object(inputs=input, layer='SA_ConvLSTM', z=z, query=each_val_query, batch_size=batch_size)
# LSTM = self.LSTM_object(inputs=input, layer='LSTM')
# drop1 = self.drop1(LSTM)
# bn = self.bn(drop1)
bn = self.bn(LSTM)
d1 = self.d1(bn)
drop2 = self.drop2(d1)
output = self.d2(drop2)
# reduce_mean降维计算均值
each_loss = tf.reduce_mean(tf.keras.losses.mse(y_true=each_val_label, y_pred=output))
self.val_loss.append(each_loss)
val_total_loss = tf.reduce_mean(self.val_loss)
return val_total_loss
class LSTM_realize(layers.Layer):
def __init__(self, units=30, batch_size=10, if_SA=False, if_Conv=False, query=None, **kwargs):
super(LSTM_realize, self).__init__()
self.units = units
self.batch_size = batch_size
self.if_SA = if_SA
self.if_Conv = if_Conv
self.query = query
def get_config(self):
# 自定义层里面的属性
config = (
{
'units': self.units,
'batch_size': self.batch_size,
'if_SA': self.if_SA,
'if_Conv': self.if_Conv,
'query': self.query
}
)
base_config = super(LSTM_realize, self).get_config()
return dict(list(base_config.items()) + list(config.items()))
def build(self, input_shape):
# 初始化可训练参数
self.Wi = []
self.Wf = []
self.Wc = []
self.Wo = []
self.Si = []
self.temp1 = []
for i in range(input_shape[1]):
if not self.if_Conv:
Wi = Dense(self.units)
Wf = Dense(self.units)
Wc = Dense(self.units)
Wo = Dense(self.units)
else:
Wi = Conv1D(self.units, kernel_size=3, padding='SAME')
Wf = Conv1D(self.units, kernel_size=3, padding='SAME')
Wc = Conv1D(self.units, kernel_size=3, padding='SAME')
Wo = Conv1D(self.units, kernel_size=3, padding='SAME')
if self.if_SA:
if i == 0:
Si = Dense(input_shape[-1])
temp1 = Dense(input_shape[-1] + 1)
else:
Si = Dense(self.units + input_shape[-1])
temp1 = Dense(self.units + input_shape[-1] + 1)
self.Si.append(Si)
self.temp1.append(temp1)
self.Wi.append(Wi)
self.Wf.append(Wf)
self.Wc.append(Wc)
self.Wo.append(Wo)
# self.z = 0
def call(self, inputs, layer='LSTM', z=0, query=None, batch_size=None, **kwargs):
self.inputs = inputs
# 这里在之前判断过,就不需要判断了
# if query == None:
# query = self.query
# if batch_size == None:
# batch_size = self.batch_size
return self.getLayer(layer=layer, query=query, z=z, batch_size=batch_size)
def getLayer(self, layer='LSTM', query=None, z=0, batch_size=None):
if layer == 'LSTM':
self.if_SA = False
self.if_Conv = False
layer = self.LSTM_layer()
return layer
elif layer == 'ConvLSTM':
self.if_SA = False
self.if_Conv = True
layer = self.convLSTM()
return layer
elif layer == 'SA_LSTM':
self.if_SA = True
self.if_Conv = False
layer = self.SA_LSTM(query, z=z)
return layer
elif layer == 'SA_ConvLSTM':
self.if_SA = True
self.if_Conv = True
layer = self.SA_ConvLSTM(query, z=z, batch_size=batch_size)
return layer
elif layer == 'SA_ConvLSTM1':
self.if_SA = True
self.if_Conv = True
layer = self.SA_ConvLSTM1()
return layer
else:
raise ValueError("算法尚未实现")
def LSTM_layer(self):
input = self.inputs
batch_size = self.batch_size
units = self.units
epoch, filter_num, dims = input.shape
print(filter_num, dims)
for batch in range(filter_num):
new_input = input[:, batch, :]
new_input = tf.expand_dims(new_input, axis=1)
if batch != 0:
new_input = tf.concat([new_input, ht_1], axis=-1)
Wi = self.Wi[batch](new_input)
Wf = self.Wf[batch](new_input)
Wc = self.Wc[batch](new_input)
Wo = self.Wo[batch](new_input)
ft = tf.nn.sigmoid(Wf)
it = tf.nn.sigmoid(Wi)
ct_ = tf.nn.tanh(Wc)
ot = tf.nn.sigmoid(Wo)
if batch != 0:
ct = tf.add(tf.multiply(ft, ct_1), tf.multiply(it, ct_))
else:
ct = tf.add(ft, tf.multiply(it, ct_))
ht = tf.multiply(tf.nn.tanh(ct), ot)
if batch == 0:
output = ht
else:
output = tf.concat([output, ht], axis=1)
ht_1 = ht
ct_1 = ct
# output = tf.reshape(output, [-1, filter_num, units])
print(output.shape)
return output
def convLSTM(self):
return None
# self_attention with true_query
def SA_ConvLSTM(self, query, z=0, batch_size=None):
# TODO 解决模型保存时,该数组会被序列化,然后返序列化以后不再是np或者是tf的问题
query = tf.cast(query, dtype=tf.float32)
# print(query.shape)
if batch_size == None:
batch_size = self.batch_size
input = self.inputs
# batch_size = self.batch_size
units = self.units
epoch, filter_num, dims = input.shape
# print(filter_num, dims)
for batch in range(filter_num):
new_input = input[:, batch, :]
new_input = tf.expand_dims(new_input, axis=1)
if batch != 0:
new_input = tf.concat([new_input, ht_1], axis=-1)
# new_input.shape=(1,50,1)
# self_attention模块
# query_cell = query[batch * batch_size:(batch + 1) * batch_size, batch, :]
query_cell = tf.expand_dims(query[z * batch_size:(z + 1) * batch_size, batch, :], axis=-1)
# query_cell = tf.expand_dims(temp, axis=1)
new_input1 = tf.concat([new_input, query_cell], axis=-1)
(_, _, new_input_dims) = new_input1.shape
temp1 = self.temp1[batch](new_input1)
temp1 = temp1[:, :, :-1]
temp2 = tf.nn.tanh(temp1)
Si = self.Si[batch](temp2)
ai = tf.nn.softmax(Si)
ones = tf.ones(shape=ai.shape)
new_input = tf.multiply((ai + ones), new_input)
Wi = self.Wi[batch](new_input)
Wf = self.Wf[batch](new_input)
Wc = self.Wc[batch](new_input)
Wo = self.Wo[batch](new_input)
ft = tf.nn.sigmoid(Wf)
it = tf.nn.sigmoid(Wi)
ct_ = tf.nn.tanh(Wc)
ot = tf.nn.sigmoid(Wo)
if batch != 0:
ct = tf.add(tf.multiply(ft, ct_1), tf.multiply(it, ct_))
else:
ct = tf.add(ft, tf.multiply(it, ct_))
ht = tf.multiply(tf.nn.tanh(ct), ot)
if batch == 0:
output = ht
else:
output = tf.concat([output, ht], axis=1)
ht_1 = ht
ct_1 = ct
# output = tf.reshape(sum, [batch_size , filter_num, units])
# output=tf.expand_dims(output,axis=0)
# print(output.shape)
# print("z=", z)
return output
# self_attention with kqv
def SA_ConvLSTM1(self):
pass
# if __name__ == '__main__':
# input=tf.random.truncated_normal(shape=[5,10])
# LSTM(input=input).getlayer()

View File

@ -0,0 +1,740 @@
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
# tf.keras.backend.clear_session()
from tensorflow.keras import *
import tensorflow.keras.layers as layers
# TODO 权重非共享式LSTM
'''
尝试LSTM权重共享策略所谓权重共享策略是指
cell 的权重是共享的这是什么意思呢这是指这张图片上有三个绿色的大框代表三个 cell 对吧
但是实际上它只是代表了一个 cell 在不同时序时候的状态所有的数据只会通过一个 cell然后不断更新它的权重
尝试每一个cell权重共享的lstm
同时增加了Mutihead_self_attention模块放在了PredictModel_MutiHead(Model)
'''
class PredictModel(Model):
def __init__(self, batch_size, query_label=None):
# 调用父类__init__()方法
super(PredictModel, self).__init__()
self.batch_size = batch_size
self.query = query_label
self.train_loss = None
self.val_loss = []
# self.LSTM_object = LSTM_realize(units=50, batch_size=batch_size, if_SA=False, if_Conv=False)
# self.input_model_shape = tf.keras.Input(shape=[self.filter_num, self.dims])
self.LSTM_object1 = LSTM_realize(units=128, batch_size=self.batch_size, if_SA=True, if_Conv=True,
query=self.query)
self.LSTM_object2 = LSTM_realize(units=256, batch_size=self.batch_size, if_SA=True, if_Conv=True,
query=self.query)
self.LSTM_object3 = LSTM_realize(units=512, batch_size=self.batch_size, if_SA=True, if_Conv=True,
query=self.query)
# self.drop1 = tf.keras.layers.Dropout(0.2)
self.bn1 = tf.keras.layers.BatchNormalization()
self.bn2 = tf.keras.layers.BatchNormalization()
self.bn3 = tf.keras.layers.BatchNormalization()
self.d1 = tf.keras.layers.Dense(10)
self.drop2 = tf.keras.layers.Dropout(0.2)
self.d2 = tf.keras.layers.Dense(1, name='output')
# def build(self, input_shape):
# pass
# 将动态图转换为静态图
# 在静态图模型中,输入数据的数据维度不对、数据类型不对、数据名称不对都会报错
# @tf.function(input_signature=[tf.TensorSpec([None, 30,50], tf.float32, name='digits')])
# @tf.function
def call(self, inputs, training=None, mask=None, z=0, label=None, query=None, batch_size=None):
if query == None:
query = self.query
if batch_size == None:
batch_size = self.batch_size
input = tf.cast(inputs, tf.float32)
LSTM = self.LSTM_object(inputs=input, layer='SA_ConvLSTM', z=z, query=query, batch_size=batch_size)
bn = self.bn1(LSTM)
LSTM = self.LSTM_object(inputs=bn, layer='SA_ConvLSTM', z=z, query=query, batch_size=batch_size)
bn = self.bn2(LSTM)
LSTM = self.LSTM_object(inputs=bn, layer='SA_ConvLSTM', z=z, query=query, batch_size=batch_size)
bn = self.bn3(LSTM)
# LSTM = self.LSTM_object(inputs=input, layer='LSTM')
# drop1 = self.drop1(LSTM)
# bn = self.bn(drop1)
d1 = self.d1(bn)
# drop2 = self.drop2(d1)
output = self.d2(d1)
# model = tf.keras.Model(inputs=input, outputs=output)
# return model
return output
def get_loss(self, inputs_tensor, label, query=None, batch_size=None, z=0):
if query == None:
query = self.query
if batch_size == None:
batch_size = self.batch_size
# inputs = self.input_model_shape(inputs_tensor)
input = tf.cast(inputs_tensor, tf.float32)
LSTM = self.LSTM_object(inputs=input, layer='SA_ConvLSTM', z=z, query=query, batch_size=batch_size)
bn = self.bn1(LSTM)
LSTM = self.LSTM_object(inputs=bn, layer='SA_ConvLSTM', z=z, query=query, batch_size=batch_size)
bn = self.bn2(LSTM)
LSTM = self.LSTM_object(inputs=bn, layer='SA_ConvLSTM', z=z, query=query, batch_size=batch_size)
bn = self.bn3(LSTM)
d1 = self.d1(bn)
# drop2 = self.drop2(d1)
output = self.d2(d1)
# reduce_mean降维计算均值
loss = tf.reduce_mean(tf.keras.losses.mse(y_true=label, y_pred=output))
return loss
def get_selfLoss(self, inputs_tensor, label, query=None, batch_size=None, z=0):
if query == None:
query = self.query
if batch_size == None:
batch_size = self.batch_size
# inputs = self.input_model_shape(inputs_tensor)
input = tf.cast(inputs_tensor, tf.float32)
LSTM = self.LSTM_object(inputs=input, layer='SA_ConvLSTM', z=z, query=query, batch_size=batch_size)
batch, filer_num, dims = LSTM.shape
aloss = 0
bloss = 0
for i in range(filer_num - 1):
aloss += tf.abs(LSTM[:, i + 1, :] - LSTM[:, i, :])
for i in range(filer_num - 3):
bloss += tf.abs(LSTM[:, i + 3, :] - LSTM[:, i + 2, :] - (LSTM[:, i + 1, :] - LSTM[:, i, :]))
# LSTM = self.LSTM_object(inputs=input, layer='LSTM')
# drop1 = self.drop1(LSTM)
# bn = self.bn(drop1)
aloss = tf.reduce_mean(aloss)
bloss = tf.reduce_mean(bloss)
desired_aloss = 0.05
desired_bloss = 0.1
# aloss的权重惩罚项
aalpha = 0.1
abeita = 0.01
# bloss的权重惩罚项
bbeita = 0.01
bn = self.bn(LSTM)
d1 = self.d1(bn)
drop2 = self.drop2(d1)
output = self.d2(drop2)
# reduce_mean降维计算均值
loss = tf.reduce_mean(tf.keras.losses.mse(y_true=label, y_pred=output))
# total_loss = loss+abeita*(desired_aloss*tf.math.log(desired_aloss/aloss)+(1-desired_aloss)*tf.math.log((1-desired_aloss)/(1-aloss)))+bbeita*(desired_bloss*tf.math.log(desired_bloss/bloss)+(1-desired_bloss)*tf.math.log((1-desired_bloss)/(1-bloss)))
total_loss = loss + abeita * aloss + bbeita * bloss
return total_loss
def get_grad(self, input_tensor, label, query=None, z=0):
with tf.GradientTape() as tape:
# todo 原本tape只会监控由tf.Variable创建的trainable=True属性
tape.watch(self.variables)
L = self.get_loss(input_tensor, label=label, query=query, z=z)
# 保存一下loss用于输出
self.train_loss = L
g = tape.gradient(L, self.variables)
return g
def train(self, input_tensor, label, query=None, learning_rate=1e-3, z=0):
g = self.get_grad(input_tensor, label=label, query=query, z=z)
optimizers.Adam(learning_rate).apply_gradients(zip(g, self.variables))
return self.train_loss
# 暂时只支持batch_size等于1,不然要传z比较麻烦
def get_val_loss(self, val_data, val_label, val_query, batch_size=1, z=0):
self.val_loss = []
size, filernums, dims = val_data.shape
if batch_size == None:
batch_size = self.batch_size
for epoch in range(size):
each_val_data = val_data[epoch, :, :]
each_val_query = val_query[epoch, :, :]
each_val_label = val_label[epoch, :]
each_val_data = tf.expand_dims(each_val_data, axis=0)
each_val_query = tf.expand_dims(each_val_query, axis=0)
each_val_label = tf.expand_dims(each_val_label, axis=0)
input = tf.cast(each_val_data, tf.float32)
LSTM = self.LSTM_object(inputs=input, layer='SA_ConvLSTM', z=z, query=each_val_query, batch_size=batch_size)
# LSTM = self.LSTM_object(inputs=input, layer='LSTM')
# drop1 = self.drop1(LSTM)
# bn = self.bn(drop1)
bn = self.bn(LSTM)
d1 = self.d1(bn)
drop2 = self.drop2(d1)
output = self.d2(drop2)
# reduce_mean降维计算均值
each_loss = tf.reduce_mean(tf.keras.losses.mse(y_true=each_val_label, y_pred=output))
self.val_loss.append(each_loss)
val_total_loss = tf.reduce_mean(self.val_loss)
return val_total_loss
class PredictModel_MutiHead(Model):
def __init__(self, batch_size, query_label):
# 调用父类__init__()方法
super(PredictModel, self).__init__()
self.batch_size = batch_size
self.query = query_label
self.train_loss = None
self.val_loss = []
# self.LSTM_object = LSTM_realize(units=50, batch_size=batch_size, if_SA=False, if_Conv=False)
# self.input_model_shape = tf.keras.Input(shape=[self.filter_num, self.dims])
self.LSTM_object1 = LSTM_realize(units=128, batch_size=self.batch_size, if_SA=True, if_Conv=True,
query=self.query)
self.LSTM_object2 = LSTM_realize(units=256, batch_size=self.batch_size, if_SA=True, if_Conv=True,
query=self.query)
self.LSTM_object3 = LSTM_realize(units=512, batch_size=self.batch_size, if_SA=True, if_Conv=True,
query=self.query)
# self.drop1 = tf.keras.layers.Dropout(0.2)
self.bn1 = tf.keras.layers.BatchNormalization()
self.bn2 = tf.keras.layers.BatchNormalization()
self.bn3 = tf.keras.layers.BatchNormalization()
self.d1 = tf.keras.layers.Dense(10)
self.drop2 = tf.keras.layers.Dropout(0.2)
self.d2 = tf.keras.layers.Dense(1, name='output')
# def build(self, input_shape):
# pass
# 将动态图转换为静态图
# 在静态图模型中,输入数据的数据维度不对、数据类型不对、数据名称不对都会报错
# @tf.function(input_signature=[tf.TensorSpec([None, 30,50], tf.float32, name='digits')])
# @tf.function
def call(self, inputs, training=None, mask=None, z=0, label=None, query=None, batch_size=None):
if query == None:
query = self.query
if batch_size == None:
batch_size = self.batch_size
input = tf.cast(inputs, tf.float32)
LSTM = self.LSTM_object(inputs=input, layer='SA_ConvLSTM', z=z, query=query, batch_size=batch_size)
bn = self.bn1(LSTM)
LSTM = self.LSTM_object(inputs=bn, layer='SA_ConvLSTM', z=z, query=query, batch_size=batch_size)
bn = self.bn2(LSTM)
LSTM = self.LSTM_object(inputs=bn, layer='SA_ConvLSTM', z=z, query=query, batch_size=batch_size)
bn = self.bn3(LSTM)
# LSTM = self.LSTM_object(inputs=input, layer='LSTM')
# drop1 = self.drop1(LSTM)
# bn = self.bn(drop1)
d1 = self.d1(bn)
# drop2 = self.drop2(d1)
output = self.d2(d1)
# model = tf.keras.Model(inputs=input, outputs=output)
# return model
return output
def get_loss(self, inputs_tensor, label, query=None, batch_size=None, z=0):
if query == None:
query = self.query
if batch_size == None:
batch_size = self.batch_size
# inputs = self.input_model_shape(inputs_tensor)
input = tf.cast(inputs_tensor, tf.float32)
LSTM = self.LSTM_object(inputs=input, layer='SA_ConvLSTM', z=z, query=query, batch_size=batch_size)
bn = self.bn1(LSTM)
LSTM = self.LSTM_object(inputs=bn, layer='SA_ConvLSTM', z=z, query=query, batch_size=batch_size)
bn = self.bn2(LSTM)
LSTM = self.LSTM_object(inputs=bn, layer='SA_ConvLSTM', z=z, query=query, batch_size=batch_size)
bn = self.bn3(LSTM)
d1 = self.d1(bn)
# drop2 = self.drop2(d1)
output = self.d2(d1)
# reduce_mean降维计算均值
loss = tf.reduce_mean(tf.keras.losses.mse(y_true=label, y_pred=output))
return loss
def get_selfLoss(self, inputs_tensor, label, query=None, batch_size=None, z=0):
if query == None:
query = self.query
if batch_size == None:
batch_size = self.batch_size
# inputs = self.input_model_shape(inputs_tensor)
input = tf.cast(inputs_tensor, tf.float32)
LSTM = self.LSTM_object(inputs=input, layer='SA_ConvLSTM', z=z, query=query, batch_size=batch_size)
batch, filer_num, dims = LSTM.shape
aloss = 0
bloss = 0
for i in range(filer_num - 1):
aloss += tf.abs(LSTM[:, i + 1, :] - LSTM[:, i, :])
for i in range(filer_num - 3):
bloss += tf.abs(LSTM[:, i + 3, :] - LSTM[:, i + 2, :] - (LSTM[:, i + 1, :] - LSTM[:, i, :]))
# LSTM = self.LSTM_object(inputs=input, layer='LSTM')
# drop1 = self.drop1(LSTM)
# bn = self.bn(drop1)
aloss = tf.reduce_mean(aloss)
bloss = tf.reduce_mean(bloss)
desired_aloss = 0.05
desired_bloss = 0.1
# aloss的权重惩罚项
aalpha = 0.1
abeita = 0.01
# bloss的权重惩罚项
bbeita = 0.01
bn = self.bn(LSTM)
d1 = self.d1(bn)
drop2 = self.drop2(d1)
output = self.d2(drop2)
# reduce_mean降维计算均值
loss = tf.reduce_mean(tf.keras.losses.mse(y_true=label, y_pred=output))
# total_loss = loss+abeita*(desired_aloss*tf.math.log(desired_aloss/aloss)+(1-desired_aloss)*tf.math.log((1-desired_aloss)/(1-aloss)))+bbeita*(desired_bloss*tf.math.log(desired_bloss/bloss)+(1-desired_bloss)*tf.math.log((1-desired_bloss)/(1-bloss)))
total_loss = loss + abeita * aloss + bbeita * bloss
return total_loss
def get_grad(self, input_tensor, label, query=None, z=0):
with tf.GradientTape() as tape:
# todo 原本tape只会监控由tf.Variable创建的trainable=True属性
tape.watch(self.variables)
L = self.get_loss(input_tensor, label=label, query=query, z=z)
# 保存一下loss用于输出
self.train_loss = L
g = tape.gradient(L, self.variables)
return g
def train(self, input_tensor, label, query=None, learning_rate=1e-3, z=0):
g = self.get_grad(input_tensor, label=label, query=query, z=z)
optimizers.Adam(learning_rate).apply_gradients(zip(g, self.variables))
return self.train_loss
# 暂时只支持batch_size等于1,不然要传z比较麻烦
def get_val_loss(self, val_data, val_label, val_query, batch_size=1, z=0):
self.val_loss = []
size, filernums, dims = val_data.shape
if batch_size == None:
batch_size = self.batch_size
for epoch in range(size):
each_val_data = val_data[epoch, :, :]
each_val_query = val_query[epoch, :, :]
each_val_label = val_label[epoch, :]
each_val_data = tf.expand_dims(each_val_data, axis=0)
each_val_query = tf.expand_dims(each_val_query, axis=0)
each_val_label = tf.expand_dims(each_val_label, axis=0)
input = tf.cast(each_val_data, tf.float32)
LSTM = self.LSTM_object(inputs=input, layer='SA_ConvLSTM', z=z, query=each_val_query, batch_size=batch_size)
# LSTM = self.LSTM_object(inputs=input, layer='LSTM')
# drop1 = self.drop1(LSTM)
# bn = self.bn(drop1)
bn = self.bn(LSTM)
d1 = self.d1(bn)
drop2 = self.drop2(d1)
output = self.d2(drop2)
# reduce_mean降维计算均值
each_loss = tf.reduce_mean(tf.keras.losses.mse(y_true=each_val_label, y_pred=output))
self.val_loss.append(each_loss)
val_total_loss = tf.reduce_mean(self.val_loss)
return val_total_loss
class LSTM_realize(layers.Layer):
# 定义两个权重初始化方法,方便后续调用
k_ini = initializers.GlorotUniform()
b_ini = initializers.Zeros()
def __init__(self, units=30, batch_size=10, if_SA=False, if_Conv=False, if_mutiHead=False, num_heads=8,
qkv_bias=False,
qk_scale=None,
attn_drop_ratio=0.,
proj_drop_ratio=0., query=None, **kwargs):
super(LSTM_realize, self).__init__()
self.units = units
self.batch_size = batch_size
self.if_SA = if_SA
self.if_Conv = if_Conv
self.query = query
self.if_mutiHead = if_mutiHead
self.num_heads = num_heads
self.qkv_bias = qkv_bias
self.qkv_scale = qk_scale
self.attn_drop_ratio = attn_drop_ratio
self.proj_drop_ratio = proj_drop_ratio
def get_config(self):
# 自定义层里面的属性
config = (
{
'units': self.units,
'batch_size': self.batch_size,
'if_SA': self.if_SA,
'if_Conv': self.if_Conv,
'proj_drop_ratio': self.proj_drop_ratio,
'attn_drop_ratio': self.attn_drop_ratio,
'qkv_bias': self.qkv_bias,
'if_mutiHead': self.if_mutiHead,
'num_heads': self.num_heads,
'qkv_scale': self.qkv_scale,
'query': self.query
}
)
base_config = super(LSTM_realize, self).get_config()
return dict(list(base_config.items()) + list(config.items()))
def build(self, input_shape):
# 初始化可训练参数
self.Wi = []
self.Wf = []
self.Wc = []
self.Wo = []
self.Si = []
self.temp1 = []
if not self.if_Conv:
Wi = Dense(self.units, kernel_initializer=self.k_ini)
Wf = Dense(self.units, kernel_initializer=self.k_ini)
Wc = Dense(self.units, kernel_initializer=self.k_ini)
Wo = Dense(self.units, kernel_initializer=self.k_ini)
else:
Wi = Conv1D(self.units, kernel_size=3, padding='SAME', kernel_initializer=self.k_ini)
Wf = Conv1D(self.units, kernel_size=3, padding='SAME', kernel_initializer=self.k_ini)
Wc = Conv1D(self.units, kernel_size=3, padding='SAME', kernel_initializer=self.k_ini)
Wo = Conv1D(self.units, kernel_size=3, padding='SAME', kernel_initializer=self.k_ini)
if self.if_SA:
# Si = Dense(input_shape[-1])
# temp1 = Dense(input_shape[-1] + 1)
Si = Dense(self.units + input_shape[-1], use_bias=False)
temp1 = Dense(self.units + input_shape[-1] + 1, use_bias=False)
self.Si.append(Si)
self.temp1.append(temp1)
if self.if_mutiHead:
head_dim = input_shape[-1] // self.num_heads
# 如果传入了qk_scale就用传入的如果没传入就用sqrt(head_dim)
self.scale = self.qkv_scale or head_dim ** -0.5
self.qkv = Dense(3 * (self.units + input_shape[-1]), use_bias=self.qkv_bias, name="qkv",
kernel_initializer=self.k_ini, bias_initializer=self.b_ini)
self.attn_drop = layers.Dropout(self.attn_drop_ratio)
# 这里的全连接层是生成Wo矩阵将得到的b进一步拼接
# 由于这里multi-head self-attention模块的输入输出维度是一样的所以这里的节点个数是dim
self.proj = layers.Dense(input_shape[-1] + self.units, name="out",
kernel_initializer=self.k_ini, bias_initializer=self.b_ini)
self.proj_drop = layers.Dropout(self.proj_drop_ratio)
self.reshape1 = tf.keras.layers.Reshape(
target_shape=(1, 3, self.num_heads, (input_shape[-1] + self.units) // self.num_heads))
self.reshape2 = tf.keras.layers.Reshape(
target_shape=(1, (input_shape[-1] + self.units)))
self.Wi.append(Wi)
self.Wf.append(Wf)
self.Wc.append(Wc)
self.Wo.append(Wo)
def call(self, inputs, layer='LSTM', z=0, query=None, batch_size=None, **kwargs):
self.inputs = inputs
# 这里在之前判断过,就不需要判断了
# if query == None:
# query = self.query
# if batch_size == None:
# batch_size = self.batch_size
return self.getLayer(layer=layer, query=query, z=z, batch_size=batch_size)
def getLayer(self, layer='LSTM', query=None, z=0, batch_size=None):
if layer == 'LSTM':
self.if_SA = False
self.if_Conv = False
layer = self.LSTM_layer()
return layer
elif layer == 'ConvLSTM':
self.if_SA = False
self.if_Conv = True
layer = self.convLSTM()
return layer
elif layer == 'SA_LSTM':
self.if_SA = True
self.if_Conv = False
layer = self.SA_LSTM(query, z=z)
return layer
elif layer == 'SA_ConvLSTM':
self.if_SA = True
self.if_Conv = True
layer = self.SA_ConvLSTM(query, z=z, batch_size=batch_size)
return layer
elif layer == 'SA_ConvLSTM1':
self.if_mutiHead = True
layer = self.SA_ConvLSTM1()
return layer
else:
raise ValueError("算法尚未实现")
def LSTM_layer(self):
input = self.inputs
batch_size = self.batch_size
units = self.units
epoch, filter_num, dims = input.shape
# print(filter_num, dims)
for batch in range(filter_num):
new_input = input[:, batch, :]
new_input = tf.expand_dims(new_input, axis=1)
if batch != 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]])
Wi = self.Wi[0](new_input)
Wf = self.Wf[0](new_input)
Wc = self.Wc[0](new_input)
Wo = self.Wo[0](new_input)
ft = tf.nn.sigmoid(Wf)
it = tf.nn.sigmoid(Wi)
ct_ = tf.nn.tanh(Wc)
ot = tf.nn.sigmoid(Wo)
if batch != 0:
ct = tf.add(tf.multiply(ft, ct_1), tf.multiply(it, ct_))
else:
ct = tf.add(ft, tf.multiply(it, ct_))
ht = tf.multiply(tf.nn.tanh(ct), ot)
if batch == 0:
output = ht
else:
output = tf.concat([output, ht], axis=1)
ht_1 = ht
ct_1 = ct
# output = tf.reshape(output, [-1, filter_num, units])
# print(output.shape)
return output
def convLSTM(self):
input = self.inputs
batch_size = self.batch_size
units = self.units
epoch, filter_num, dims = input.shape
# print(filter_num, dims)
for batch in range(filter_num):
new_input = input[:, batch, :]
new_input = tf.expand_dims(new_input, axis=1)
if batch != 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]])
Wi = self.Wi[0](new_input)
Wf = self.Wf[0](new_input)
Wc = self.Wc[0](new_input)
Wo = self.Wo[0](new_input)
ft = tf.nn.sigmoid(Wf)
it = tf.nn.sigmoid(Wi)
ct_ = tf.nn.tanh(Wc)
ot = tf.nn.sigmoid(Wo)
if batch != 0:
ct = tf.add(tf.multiply(ft, ct_1), tf.multiply(it, ct_))
else:
ct = tf.add(ft, tf.multiply(it, ct_))
ht = tf.multiply(tf.nn.tanh(ct), ot)
if batch == 0:
output = ht
else:
output = tf.concat([output, ht], axis=1)
ht_1 = ht
ct_1 = ct
# output = tf.reshape(output, [-1, filter_num, units])
# print(output.shape)
return output
def SA_LSTM(self):
output = self.SA_ConvLSTM1()
return output
# self_attention with true_query
def SA_ConvLSTM(self, query, z=0, batch_size=None):
# TODO 解决模型保存时,该数组会被序列化,然后返序列化以后不再是np或者是tf的问题
query = tf.cast(query, dtype=tf.float32)
# print(query.shape)
if batch_size == None:
batch_size = self.batch_size
input = self.inputs
# batch_size = self.batch_size
units = self.units
epoch, filter_num, dims = input.shape
# print(filter_num, dims)
for batch in range(filter_num):
new_input = input[:, batch, :]
new_input = tf.expand_dims(new_input, axis=1)
if batch != 0:
new_input = tf.concat([new_input, ht_1], axis=-1)
# new_input.shape=(1,50,1)
# self_attention模块
# query_cell = query[batch * batch_size:(batch + 1) * batch_size, batch, :]
query_cell = tf.expand_dims(query[z * batch_size:(z + 1) * batch_size, batch, :], axis=-1)
# query_cell = tf.expand_dims(temp, axis=1)
new_input1 = tf.concat([new_input, query_cell], axis=-1)
(_, _, new_input_dims) = new_input1.shape
temp1 = self.temp1[0](new_input1)
temp1 = temp1[:, :, :-1]
temp2 = tf.nn.tanh(temp1)
Si = self.Si[0](temp2)
ai = tf.nn.softmax(Si)
ones = tf.ones(shape=ai.shape)
new_input = tf.multiply((ai + ones), new_input)
Wi = self.Wi[0](new_input)
Wf = self.Wf[0](new_input)
Wc = self.Wc[0](new_input)
Wo = self.Wo[0](new_input)
ft = tf.nn.sigmoid(Wf)
it = tf.nn.sigmoid(Wi)
ct_ = tf.nn.tanh(Wc)
ot = tf.nn.sigmoid(Wo)
if batch != 0:
ct = tf.add(tf.multiply(ft, ct_1), tf.multiply(it, ct_))
else:
ct = tf.add(ft, tf.multiply(it, ct_))
ht = tf.multiply(tf.nn.tanh(ct), ot)
if batch == 0:
output = ht
else:
output = tf.concat([output, ht], axis=1)
ht_1 = ht
ct_1 = ct
# output = tf.reshape(sum, [batch_size , filter_num, units])
# output=tf.expand_dims(output,axis=0)
# print(output.shape)
# print("z=", z)
return output
# self_attention with kqv
def SA_ConvLSTM1(self):
input = self.inputs
epoch, filter_num, dims = input.shape
# print(filter_num, dims)
for batch in range(filter_num):
new_input = input[:, batch, :]
new_input = tf.expand_dims(new_input, axis=1)
if batch == 0:
new_input = tf.pad(new_input,[[0,0],[0,0],[0,self.units]])
if batch != 0:
new_input = tf.concat([new_input, ht_1], axis=-1)
# self_attention模块
new_input = self.muti_head_attention(new_input, z=batch)
Wi = self.Wi[0](new_input)
Wf = self.Wf[0](new_input)
Wc = self.Wc[0](new_input)
Wo = self.Wo[0](new_input)
ft = tf.nn.sigmoid(Wf)
it = tf.nn.sigmoid(Wi)
ct_ = tf.nn.tanh(Wc)
ot = tf.nn.sigmoid(Wo)
if batch != 0:
ct = tf.add(tf.multiply(ft, ct_1), tf.multiply(it, ct_))
else:
ct = tf.add(ft, tf.multiply(it, ct_))
ht = tf.multiply(tf.nn.tanh(ct), ot)
if batch == 0:
output = ht
else:
output = tf.concat([output, ht], axis=1)
ht_1 = ht
ct_1 = ct
return output
def muti_head_attention(self, inputs, z=0, training=None):
batch, filter_num, dims = inputs.shape
qkv = self.qkv(inputs)
qkv = self.reshape1(qkv)
# qkv(): -> [batch_size, num_patches + 1, 3 * total_embed_dim]
# 分成三份分别对应qkv,C // self.num_heads得到每一个head的维度
# reshape: -> [batch_size, num_patches + 1, 3, num_heads, embed_dim_per_head]
# 用transpose方法来调整一下维度的顺序[2, 0, 3, 1, 4]表示调换之后的顺序
# transpose: -> [3, batch_size, num_heads, num_patches + 1, embed_dim_per_head]
qkv = tf.transpose(qkv, [2, 0, 3, 1, 4])
# [batch_size, num_heads, num_patches + 1, embed_dim_per_head]
q, k, v = qkv[0], qkv[1], qkv[2]
# transpose: -> [batch_size, num_heads, embed_dim_per_head, num_patches + 1]
# 这里的矩阵相乘实际上指的是矩阵的最后两个维度相乘而b的转置(transpose_b)
# 实际上是[batch_size, num_heads, embed_dim_per_head, num_patches + 1]
# multiply -> [batch_size, num_heads, num_patches + 1, num_patches + 1]
attn = tf.matmul(a=q, b=k, transpose_b=True) * self.scale
attn = tf.nn.softmax(attn, axis=-1)
attn = self.attn_drop(attn, training=training)
# 与v相乘得到b
# multiply -> [batch_size, num_heads, num_patches + 1, embed_dim_per_head]
x = tf.matmul(attn, v)
# 再用transpose调换一下顺序
# transpose: -> [batch_size, num_patches + 1, num_heads, embed_dim_per_head]
x = tf.transpose(x, [0, 2, 1, 3])
# reshape: -> [batch_size, num_patches + 1, total_embed_dim]
x = self.reshape2(x)
x = self.proj(x)
# 与Wo相乘进一步融合得到输出
x = self.proj_drop(x, training=training)
return x
# if __name__ == '__main__':
# input=tf.random.truncated_normal(shape=[5,10])
# LSTM(input=input).getlayer()

View File

@ -0,0 +1,8 @@
#-*- encoding:utf-8 -*-
'''
@Author : dingjiawen
@Date : 2023/6/14 13:49
@Usage :
@Desc :
'''

View File

@ -11,25 +11,26 @@ import tensorflow as tf
import tensorflow.keras.backend as K import tensorflow.keras.backend as K
class FTMSE(tf.keras.losses.Loss): class FTMSE(tf.keras.losses.Loss):
def call(self, y_true, y_pred): def call(self, y_true, y_pred):
y_true = tf.cast(y_true, tf.float64) y_true = tf.cast(y_true, tf.float32)
y_pred = tf.cast(y_pred, tf.float64) y_pred = tf.cast(y_pred, tf.float32)
# 需要转为复数形式 # 需要转为复数形式
yt_fft = tf.signal.fft(tf.cast(y_true, tf.complex64)) yt_fft = tf.signal.fft(tf.cast(y_true, tf.complex64))
yp_fft = tf.signal.fft(tf.cast(y_pred, tf.complex64)) yp_fft = tf.signal.fft(tf.cast(y_pred, tf.complex64))
epoch, length, _ = yp_fft.shape
# 幅值 # 幅值
amp = tf.abs(yt_fft / len(yt_fft)) yt_amp = tf.abs(yt_fft / length)
yp_amp = tf.abs(yp_fft / length)
# 相角 # 相角
angle = tf.angle(freq_value) yt_angle = tf.math.angle(yt_fft)
yp_angle = tf.math.angle(yp_fft)
time_loss = tf.keras.losses.mean_squared_error(y_true, y_pred)
amp_loss = tf.keras.losses.mean_squared_error(yt_amp, yp_amp)
angle_loss = tf.keras.losses.mean_squared_error(yt_angle, yp_angle)
time_loss = tf.reduce_mean(tf.abs(y_true - y_pred)) ftLoss = time_loss + amp_loss + angle_loss
freq_loss = tf.reduce_mean(tf.abs(yt_fft - yp_fft))
ftLoss = time_loss+freq_loss
return ftLoss return ftLoss

View File

@ -0,0 +1,72 @@
# -*- coding: utf-8 -*-
# coding: utf-8
'''
@Author : dingjiawen
@Date : 2022/7/19 10:16
@Usage :
@Desc :
'''
import numpy as np
def Giou_np(bbox_p, bbox_g):
"""
:param bbox_p: predict of bbox(N,4)(x1,y1,x2,y2)
:param bbox_g: groundtruth of bbox(N,4)(x1,y1,x2,y2)
:return:
"""
# for details should go to https://arxiv.org/pdf/1902.09630.pdf
# ensure predict's bbox form
x1p = np.minimum(bbox_p[:, 0], bbox_p[:, 2]).reshape(-1,1)
x2p = np.maximum(bbox_p[:, 0], bbox_p[:, 2]).reshape(-1,1)
y1p = np.minimum(bbox_p[:, 1], bbox_p[:, 3]).reshape(-1,1)
y2p = np.maximum(bbox_p[:, 1], bbox_p[:, 3]).reshape(-1,1)
bbox_p = np.concatenate([x1p, y1p, x2p, y2p], axis=1)
# calc area of Bg
area_p = (bbox_p[:, 2] - bbox_p[:, 0]) * (bbox_p[:, 3] - bbox_p[:, 1])
# calc area of Bp
area_g = (bbox_g[:, 2] - bbox_g[:, 0]) * (bbox_g[:, 3] - bbox_g[:, 1])
# cal intersection
x1I = np.maximum(bbox_p[:, 0], bbox_g[:, 0])
y1I = np.maximum(bbox_p[:, 1], bbox_g[:, 1])
x2I = np.minimum(bbox_p[:, 2], bbox_g[:, 2])
y2I = np.minimum(bbox_p[:, 3], bbox_g[:, 3])
I = np.maximum((y2I - y1I), 0) * np.maximum((x2I - x1I), 0)
# find enclosing box
x1C = np.minimum(bbox_p[:, 0], bbox_g[:, 0])
y1C = np.minimum(bbox_p[:, 1], bbox_g[:, 1])
x2C = np.maximum(bbox_p[:, 2], bbox_g[:, 2])
y2C = np.maximum(bbox_p[:, 3], bbox_g[:, 3])
# calc area of Bc
area_c = (x2C - x1C) * (y2C - y1C)
U = area_p + area_g - I
iou = 1.0 * I / U
# Giou
giou = iou - (area_c - U) / area_c
# loss_iou = 1 - iou loss_giou = 1 - giou
loss_iou = 1.0 - iou
loss_giou = 1.0 - giou
return giou, loss_iou, loss_giou
# def giou_tf
if __name__ == '__main__':
p = np.array([[21,45,103,172],
[34,283,155,406],
[202,174,271,255]])
g = np.array([[59,106,154,230],
[71,272,191,419],
[257,244,329,351]])
Giou_np(p, g)

View File

@ -0,0 +1,47 @@
# -*- coding: utf-8 -*-
# coding: utf-8
'''
@Author : dingjiawen
@Date : 2022/7/18 21:33
@Usage : IoU loss Function
@Desc :
'''
import tensorflow.keras.backend as K
# 实际上就是计算边框没有重合的部分占重合部分的比重
def iou_loss(y_true, y_pred):
# iou loss for bounding box prediction
# input must be as [x1, y1, x2, y2]
# AOG = Area of Groundtruth box
AoG = K.abs(K.transpose(y_true)[2] - K.transpose(y_true)[0] + 1) * K.abs(
K.transpose(y_true)[3] - K.transpose(y_true)[1] + 1)
# AOP = Area of Predicted box
AoP = K.abs(K.transpose(y_pred)[2] - K.transpose(y_pred)[0] + 1) * K.abs(
K.transpose(y_pred)[3] - K.transpose(y_pred)[1] + 1)
# overlaps are the co-ordinates of intersection box
overlap_0 = K.maximum(K.transpose(y_true)[0], K.transpose(y_pred)[0])
overlap_1 = K.maximum(K.transpose(y_true)[1], K.transpose(y_pred)[1])
overlap_2 = K.minimum(K.transpose(y_true)[2], K.transpose(y_pred)[2])
overlap_3 = K.minimum(K.transpose(y_true)[3], K.transpose(y_pred)[3])
# intersection area
intersection = (overlap_2 - overlap_0 + 1) * (overlap_3 - overlap_1 + 1)
# area of union of both boxes
union = AoG + AoP - intersection
# iou calculation
iou = intersection / union
# bounding values of iou to (0,1)
iou = K.clip(iou, 0.0 + K.epsilon(), 1.0 - K.epsilon())
# loss for the iou value
iou_loss = -K.log(iou)
return iou_loss

View File

@ -0,0 +1,10 @@
# -*- coding: utf-8 -*-
# coding: utf-8
'''
@Author : dingjiawen
@Date : 2022/7/18 21:33
@Usage :
@Desc :
'''

View File

@ -0,0 +1,24 @@
# -*- coding: utf-8 -*-
# coding: utf-8
'''
@Author : dingjiawen
@Date : 2022/7/20 14:13
@Usage :
@Desc :
'''
import tensorflow as tf
import tensorflow.keras.backend as K
class SmoothL1Loss(tf.keras.losses.Loss):
def call(self, y_true, y_pred):
y_true = tf.cast(y_true, tf.float32)
y_pred = tf.cast(y_pred, tf.float32)
dif = tf.reduce_mean(tf.abs(y_true - y_pred))
if dif < 1:
return tf.reduce_mean(0.5 * tf.square(y_pred - y_true))
else:
return dif - 0.5
# return tf.reduce_mean(tf.square(y_pred - y_true))

View File

@ -0,0 +1,159 @@
import tensorflow as tf
import numpy as np
import pandas as pd
from tensorflow.keras import *
import tensorflow.keras.backend as kb
import sys
import matplotlib.pyplot as plt
# 输入输出为16 × 1的列表
# inputList为输入列表
def SAEFC(inputList):
inputList = np.array(inputList)
# 输入特征个数
inputFeatureNum = len(inputList[0])
# 隐藏层参数个数输入特征3倍
hiddenNum = 3 * inputFeatureNum
# 稀疏度(密度)
density = 0.1
lossList = []
saeModel = SAEModel(inputList.shape[-1], hiddenNum)
for i in range(1000):
loss = saeModel.network_learn(tf.constant(inputList))
lossList.append(loss)
print(loss)
# 绘制损失值图像
x = np.arange(len(lossList)) + 1
plt.plot(x, lossList)
plt.show()
return saeModel
# 自定义隐藏层
class SAELayer(layers.Layer):
def __init__(self, num_outputs):
super(SAELayer, self).__init__()
# 该层最后一个节点其值固定为1,
# 前期可以按照同样的手段让该节点和其他节点一样进行计算,
# 最后在传递给下一层前将其设置为1即可即其值固定为1
self.num_outputs = num_outputs
def build(self, input_shape):
self.kernel = self.add_variable("kernel",
shape=[int(input_shape[-1]),
self.num_outputs - 1])
self.bias = self.add_variable("bias",
shape=[self.num_outputs - 1])
def call(self, input):
output = tf.matmul(input, self.kernel) + self.bias
# sigmoid函数
output = tf.nn.sigmoid(output)
bias_list = tf.ones([input.shape[0], 1])
output = tf.concat([output, bias_list], 1)
self.result = output
return output
# 自定义模型
class SAEModel(Model):
# 可以传入一些超参数,用以动态构建模型
# __init_——()方法在创建模型对象时被调用
# input_shape: 输入层和输出层的节点个数输入层实际要比这多1因为有个bias
# hidden_shape: 隐藏层节点个数隐藏层节点的最后一个节点值固定为1也是bias
# 使用方法直接传入实际的input_shape即可在call中也直接传入原始Input_tensor即可
# 一切关于数据适配模型的处理都在模型中实现
def __init__(self, input_shape, hidden_shape=None):
# print("init")
# 隐藏层节点个数默认为输入层的3倍
if hidden_shape == None:
hidden_shape = 3 * input_shape
# 调用父类__init__()方法
super(SAEModel, self).__init__()
self.train_loss = None
self.layer_2 = SAELayer(hidden_shape)
self.layer_3 = layers.Dense(input_shape, activation=tf.nn.sigmoid)
def call(self, input_tensor, training=False):
# 将input_tensor最后加一列1
bias_list = tf.ones([len(input_tensor), 1])
input_tensor = tf.concat([input_tensor, bias_list], 1)
# 输入数据
# x = self.layer_1(input_tensor)
hidden = self.layer_2(input_tensor)
output = self.layer_3(hidden)
return output
def get_loss(self, input_tensor):
# print("get_loss")
bias_list = tf.ones([len(input_tensor), 1])
new_input = tf.concat([input_tensor, bias_list], 1)
hidden = self.layer_2(new_input)
output = self.layer_3(hidden)
# 计算loss
# 计算MSE
mse = (1 / 2) * tf.reduce_sum(kb.square(input_tensor - output))
# 计算权重乘法项
alpha = 0.1
W1 = self.layer_2.kernel
W2 = self.layer_3.kernel
weightPunish = (alpha / 2) * (tf.reduce_sum(kb.square(W1)) + tf.reduce_sum(kb.square(W2)))
# 计算KL散度
# 惩罚因子
beita = 0.1
# 每一层的期望密度
desired_density = 0.1
layer2_output = self.layer_2.result
# 实际密度是所有输入数据的密度的平均值
actual_density = tf.reduce_mean(tf.math.count_nonzero(layer2_output, axis=1) / layer2_output.shape[1])
actual_density = tf.cast(actual_density, tf.float32)
if actual_density == tf.constant(1.0, dtype=tf.float32):
actual_density = tf.constant(0.999)
actual_density = actual_density.numpy()
KL = desired_density * np.log(desired_density / actual_density)
KL += (1 - desired_density) * np.log((1 - desired_density) / (1 - actual_density))
KL *= beita
ans = tf.constant(mse + weightPunish + KL)
return ans
def get_grad(self, input_tensor):
with tf.GradientTape() as tape:
# todo 原本tape只会监控由tf.Variable创建的trainable=True属性
tape.watch(self.variables)
L = self.get_loss(input_tensor)
# 保存一下loss用于输出
self.train_loss = L
g = tape.gradient(L, self.variables)
return g
def network_learn(self, input_tensor):
g = self.get_grad(input_tensor)
optimizers.Adam().apply_gradients(zip(g, self.variables))
return self.train_loss
# 如果模型训练好了,需要获得隐藏层的输出,直接获取麻烦,则直接运行一遍
def getReprestation(self, input_tensor):
bias_list = tf.ones([len(input_tensor), 1])
new_input = tf.concat([input_tensor, bias_list], 1)
hidden = self.layer_2(new_input)
return hidden
if __name__ == '__main__':
saeModel = SAEModel(inputList.shape[-1], hiddenNum)
for i in range(1000):
saeModel.network_learn(tf.constant(inputList))

View File

@ -0,0 +1,143 @@
import os
import tensorflow as tf
from tensorflow import keras
from PIL import Image
from matplotlib import pyplot as plt
from tensorflow.keras import Sequential, layers
import numpy as np
tf.random.set_seed(2322)
np.random.seed(23422)
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
assert tf.__version__.startswith('2.')
# 把num张图片保存到一张
def save_images(img, name,num):
new_im = Image.new('L', (28*num, 28*num))
index = 0
for i in range(0, 28*num, 28):
for j in range(0, 28*num, 28):
im = img[index]
im = Image.fromarray(im, mode='L')
new_im.paste(im, (i, j))
index += 1
new_im.save(name)
# 定义超参数
batchsz = 256
lr = 1e-4
# 数据集加载,自编码器不需要标签因为是无监督学习
(x_train, _), (x_test, _) = keras.datasets.fashion_mnist.load_data()
x_train, x_test = x_train.astype(np.float32) / 255., x_test.astype(np.float32) / 255.
train_db = tf.data.Dataset.from_tensor_slices(x_train)
train_db = train_db.shuffle(batchsz * 5).batch(batchsz)
test_db = tf.data.Dataset.from_tensor_slices(x_test)
test_db = test_db.batch(batchsz)
# 搭建模型
z_dim = 10
class VAE(keras.Model):
def __init__(self,z_dim,units=256):
super(VAE, self).__init__()
self.z_dim = z_dim
self.units = units
# 编码网络
self.vae_encoder = layers.Dense(self.units)
# 均值网络
self.vae_mean = layers.Dense(self.z_dim) # get mean prediction
# 方差网络(均值和方差是一一对应的,所以维度相同)
self.vae_variance = layers.Dense(self.z_dim) # get variance prediction
# 解码网络
self.vae_decoder = layers.Dense(self.units)
# 输出网络
self.vae_out = layers.Dense(784)
# encoder传播的过程
def encoder(self, x):
h = tf.nn.relu(self.vae_encoder(x))
#计算均值
mu = self.vae_mean(h)
#计算方差
log_var = self.vae_variance(h)
return mu, log_var
# decoder传播的过程
def decoder(self, z):
out = tf.nn.relu(self.vae_decoder(z))
out = self.vae_out(out)
return out
def reparameterize(self, mu, log_var):
eps = tf.random.normal(log_var.shape)
std = tf.exp(log_var) # 去掉log, 得到方差;
std = std**0.5 # 开根号,得到标准差;
z = mu + std * eps
return z
def call(self, inputs):
mu, log_var = self.encoder(inputs)
# reparameterizaion trick最核心的部分
z = self.reparameterize(mu, log_var)
# decoder 进行还原
x_hat = self.decoder(z)
# Variational auto-encoder除了前向传播不同之外还有一个额外的约束
# 这个约束使得你的mu, var更接近正太分布所以我们把mu, log_var返回
return x_hat, mu, log_var
model = VAE(z_dim,units=128)
model.build(input_shape=(128, 784))
optimizer = keras.optimizers.Adam(lr=lr)
epochs = 30
for epoch in range(epochs):
for step, x in enumerate(train_db):
x = tf.reshape(x, [-1, 784])
with tf.GradientTape() as tape:
# shape
x_hat, mu, log_var = model(x)
# 把每个像素点当成一个二分类的问题;
rec_loss = tf.losses.binary_crossentropy(x, x_hat, from_logits=True)
rec_loss = tf.reduce_mean(rec_loss)
# compute kl divergence (mu, var) ~ N(0, 1): 我们得到的均值方差和正太分布的;
# 链接参考: https://stats.stackexchange.com/questions/7440/kl-divergence-between-two-univariate-gaussians
kl_div = -0.5 * (log_var + 1 -mu**2 - tf.exp(log_var))
kl_div = tf.reduce_mean(kl_div) / batchsz
loss = rec_loss + 1. * kl_div
grads = tape.gradient(loss, model.trainable_variables)
optimizer.apply_gradients(zip(grads, model.trainable_variables))
if step % 100 ==0:
print('\repoch: %3d, step:%4d, kl_div: %5f, rec_loss:%9f' %(epoch, step, float(kl_div), float(rec_loss)),end="")
num_pic = 9
# evaluation 1: 从正太分布直接sample
z = tf.random.normal((batchsz, z_dim)) # 从正太分布中sample这个尺寸的
logits = model.decoder(z) # 通过这个得到decoder
x_hat = tf.sigmoid(logits)
x_hat = tf.reshape(x_hat, [-1, 28, 28]).numpy() * 255.
logits = x_hat.astype(np.uint8) # 标准的图片格式;
save_images(logits, 'd:\\vae_images\\sampled_epoch%d.png' %epoch,num_pic) # 直接sample出的正太分布
# evaluation 2: 正常的传播过程;
x = next(iter(test_db))
x = tf.reshape(x, [-1, 784])
x_hat_logits, _, _ = model(x) # 前向传播返回的还有mu, log_var
x_hat = tf.sigmoid(x_hat_logits)
x_hat = tf.reshape(x_hat, [-1, 28, 28]).numpy() * 255.
x_hat = x_hat.astype(np.uint8) # 标准的图片格式;
# print(x_hat.shape)
save_images(x_hat, 'd:\\vae_images\\rec_epoch%d.png' %epoch,num_pic)

View File

@ -0,0 +1,66 @@
from matplotlib import pyplot as plt
import numpy as np
from scipy.signal import hilbert
class VMD:
def __init__(self, K, alpha, tau, tol=1e-7, maxIters=200, eps=1e-9):
"""
:param K: 模态数
:param alpha: 每个模态初始中心约束强度
:param tau: 对偶项的梯度下降学习率
:param tol: 终止阈值
:param maxIters: 最大迭代次数
:param eps: eps
"""
self.K = K
self.alpha = alpha
self.tau = tau
self.tol = tol
self.maxIters = maxIters
self.eps = eps
def __call__(self, f):
T = f.shape[0]
t = np.linspace(1, T, T) / T
omega = t - 1. / T
# 转换为解析信号
f = hilbert(f)
f_hat = np.fft.fft(f)
u_hat = np.zeros((self.K, T), dtype=np.complex)
omega_K = np.zeros((self.K,))
lambda_hat = np.zeros((T,), dtype=np.complex)
# 用以判断
u_hat_pre = np.zeros((self.K, T), dtype=np.complex)
u_D = self.tol + self.eps
# 迭代
n = 0
while n < self.maxIters and u_D > self.tol:
for k in range(self.K):
# u_hat
sum_u_hat = np.sum(u_hat, axis=0) - u_hat[k, :]
res = f_hat - sum_u_hat
u_hat[k, :] = (res + lambda_hat / 2) / (1 + self.alpha * (omega - omega_K[k]) ** 2)
# omega
u_hat_k_2 = np.abs(u_hat[k, :]) ** 2
omega_K[k] = np.sum(omega * u_hat_k_2) / np.sum(u_hat_k_2)
# lambda_hat
sum_u_hat = np.sum(u_hat, axis=0)
res = f_hat - sum_u_hat
lambda_hat -= self.tau * res
n += 1
u_D = np.sum(np.abs(u_hat - u_hat_pre) ** 2)
u_hat_pre[::] = u_hat[::]
# 重构,反傅立叶之后取实部
u = np.real(np.fft.ifft(u_hat, axis=-1))
omega_K = omega_K * T
idx = np.argsort(omega_K)
omega_K = omega_K[idx]
u = u[idx, :]
return u, omega_K

View File

@ -0,0 +1,45 @@
from matplotlib import pyplot as plt
import numpy as np
from scipy.signal import hilbert
from model.VMD.VMD_realize import VMD
T = 1000
fs = 1. / T
t = np.linspace(0, 1, 1000, endpoint=True)
f_1 = 10
f_2 = 50
f_3 = 100
mode_1 = (2 * t) ** 2
mode_2 = np.sin(2 * np.pi * f_1 * t)
mode_3 = np.sin(2 * np.pi * f_2 * t)
mode_4 = np.sin(2 * np.pi * f_3 * t)
f = mode_1 + mode_2 + mode_3 + mode_4 + 0.5 * np.random.randn(1000)
plt.figure(figsize=(6, 3), dpi=150)
plt.plot(f, linewidth=1)
K = 4
alpha = 2000
tau = 1e-6
vmd = VMD(K, alpha, tau)
u, omega_K = vmd(f)
omega_K
# array([0.85049797, 10.08516203, 50.0835613, 100.13259275]))
plt.figure(figsize=(5, 7), dpi=200)
plt.subplot(4, 1, 1)
plt.plot(mode_1, linewidth=0.5, linestyle='--')
plt.plot(u[0, :], linewidth=0.2, c='r')
plt.subplot(4, 1, 2)
plt.plot(mode_2, linewidth=0.5, linestyle='--')
plt.plot(u[1, :], linewidth=0.2, c='r')
plt.subplot(4, 1, 3)
plt.plot(mode_3, linewidth=0.5, linestyle='--')
plt.plot(u[2, :], linewidth=0.2, c='r')
plt.subplot(4, 1, 4)
plt.plot(mode_4, linewidth=0.5, linestyle='--')
plt.plot(u[3, :], linewidth=0.2, c='r')
plt.show()
# [<matplotlib.lines.Line2D at 0x7fac532f4dd8>]