模型更新
This commit is contained in:
parent
d97c3e8731
commit
2400af4a1a
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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];
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
|
@ -39,7 +39,7 @@ public class Question3 {
|
|||
{-2, -3, 4},
|
||||
};
|
||||
// calculateMaxRectangleSum(2, 3, income);
|
||||
calculate(2, 3, income);
|
||||
calculate1(2, 3, income);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
@ -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.
Binary file not shown.
|
After Width: | Height: | Size: 7.8 KiB |
|
|
@ -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)
|
||||
Binary file not shown.
|
|
@ -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()
|
||||
|
||||
|
||||
|
|
@ -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()
|
||||
|
|
@ -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()
|
||||
|
|
@ -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()
|
||||
|
|
@ -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()
|
||||
|
|
@ -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()
|
||||
|
|
@ -9,6 +9,7 @@
|
|||
import numpy as np
|
||||
import tensorflow as tf
|
||||
|
||||
|
||||
'''
|
||||
freq_value: 可以是时域通过np.fft.fft转换而来
|
||||
'''
|
||||
|
|
|
|||
|
|
@ -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, )
|
||||
|
||||
|
||||
|
|
@ -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)
|
||||
|
|
@ -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()
|
||||
|
|
@ -32,11 +32,11 @@ amp = np.abs(np.fft.fft(array) / len(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(angle1)
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
@ -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()
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
# _*_ coding: UTF-8 _*_
|
||||
|
||||
|
||||
'''
|
||||
@Author : dingjiawen
|
||||
@Date : 2022/7/12 17:48
|
||||
@Usage :
|
||||
@Desc :
|
||||
'''
|
||||
|
|
@ -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
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
# _*_ coding: UTF-8 _*_
|
||||
|
||||
|
||||
'''
|
||||
@Author : dingjiawen
|
||||
@Date : 2022/7/14 17:36
|
||||
@Usage :
|
||||
@Desc :
|
||||
'''
|
||||
|
|
@ -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
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
# _*_ coding: UTF-8 _*_
|
||||
|
||||
|
||||
'''
|
||||
@Author : dingjiawen
|
||||
@Date : 2022/7/12 16:59
|
||||
@Usage :
|
||||
@Desc :
|
||||
'''
|
||||
|
|
@ -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
|
||||
|
|
@ -0,0 +1,445 @@
|
|||
# _*_ coding: UTF-8 _*_
|
||||
|
||||
|
||||
'''
|
||||
@Author : dingjiawen
|
||||
@Date : 2022/7/14 9:40
|
||||
@Usage : 联合监测模型
|
||||
@Desc : 将预测值放入分类器,已测试,准确率可以到99.7% ,dense层300后直接接output,cross_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
|
||||
|
|
@ -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
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
# _*_ coding: UTF-8 _*_
|
||||
|
||||
|
||||
'''
|
||||
@Author : dingjiawen
|
||||
@Date : 2022/7/14 9:40
|
||||
@Usage :
|
||||
@Desc :
|
||||
'''
|
||||
|
|
@ -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
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# coding: utf-8
|
||||
|
||||
'''
|
||||
@Author : dingjiawen
|
||||
@Date : 2022/10/11 20:30
|
||||
@Usage :
|
||||
@Desc :
|
||||
'''
|
||||
|
|
@ -2,7 +2,14 @@
|
|||
# 线性循环单元(Linear Recurrent Unit)
|
||||
# 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):
|
||||
|
|
@ -26,7 +33,7 @@ class LRU(Layer):
|
|||
self.unroll = unroll
|
||||
self.kernel_initializer = initializers.get(kernel_initializer)
|
||||
|
||||
@integerize_shape
|
||||
|
||||
def build(self, input_shape):
|
||||
super(LRU, self).build(input_shape)
|
||||
hidden_size = input_shape[-1]
|
||||
|
|
@ -57,7 +64,7 @@ class LRU(Layer):
|
|||
name='params_log', shape=(3, self.units), initializer=initializer
|
||||
)
|
||||
|
||||
@recompute_grad
|
||||
|
||||
def call(self, inputs, mask=None):
|
||||
u = self.i_dense(inputs)
|
||||
params = K.exp(self.params_log)
|
||||
|
|
@ -70,7 +77,7 @@ class LRU(Layer):
|
|||
else:
|
||||
L_in = K.shape(u)[1]
|
||||
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.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 = 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)
|
||||
|
||||
def get_config(self):
|
||||
|
|
|
|||
|
|
@ -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=)
|
||||
|
|
@ -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=)
|
||||
|
|
@ -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()
|
||||
|
|
@ -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()
|
||||
|
|
@ -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()
|
||||
|
|
@ -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()
|
||||
|
|
@ -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()
|
||||
|
|
@ -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()
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
#-*- encoding:utf-8 -*-
|
||||
|
||||
'''
|
||||
@Author : dingjiawen
|
||||
@Date : 2023/6/14 13:49
|
||||
@Usage :
|
||||
@Desc :
|
||||
'''
|
||||
|
|
@ -11,25 +11,26 @@ import tensorflow as tf
|
|||
import tensorflow.keras.backend as K
|
||||
|
||||
|
||||
|
||||
class FTMSE(tf.keras.losses.Loss):
|
||||
def call(self, y_true, y_pred):
|
||||
y_true = tf.cast(y_true, tf.float64)
|
||||
y_pred = tf.cast(y_pred, tf.float64)
|
||||
y_true = tf.cast(y_true, tf.float32)
|
||||
y_pred = tf.cast(y_pred, tf.float32)
|
||||
|
||||
# 需要转为复数形式
|
||||
yt_fft = tf.signal.fft(tf.cast(y_true,tf.complex64))
|
||||
yp_fft = tf.signal.fft(tf.cast(y_pred,tf.complex64))
|
||||
yt_fft = tf.signal.fft(tf.cast(y_true, 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))
|
||||
|
||||
freq_loss = tf.reduce_mean(tf.abs(yt_fft - yp_fft))
|
||||
|
||||
ftLoss = time_loss+freq_loss
|
||||
ftLoss = time_loss + amp_loss + angle_loss
|
||||
return ftLoss
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
@ -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
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# coding: utf-8
|
||||
|
||||
'''
|
||||
@Author : dingjiawen
|
||||
@Date : 2022/7/18 21:33
|
||||
@Usage :
|
||||
@Desc :
|
||||
'''
|
||||
|
|
@ -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))
|
||||
|
|
@ -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))
|
||||
|
|
@ -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)
|
||||
|
|
@ -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
|
||||
|
|
@ -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>]
|
||||
Loading…
Reference in New Issue