在极大的学习率倍率下可以一定程度上复现论文的效果

This commit is contained in:
MuJ 2024-01-10 00:15:33 +08:00
parent 1aa5d08034
commit b4431d20ab
1 changed files with 85 additions and 80 deletions

155
main.py
View File

@ -1,16 +1,16 @@
from tqdm import tqdm
from sklearn.preprocessing import MinMaxScaler
from keras.layers import Dropout
from keras.callbacks import TensorBoard, LearningRateScheduler
from keras import regularizers
import matplotlib.pyplot as plt
import tensorflow as tf
import pandas as pd
import numpy as np
import os
import warnings
warnings.filterwarnings('ignore')
import tensorflow as tf
tf.compat.v1.logging.set_verbosity(tf.compat.v1.logging.ERROR)
import matplotlib.pyplot as plt
from keras import regularizers
from keras.callbacks import TensorBoard, LearningRateScheduler
from keras.layers import Dropout
from sklearn.preprocessing import MinMaxScaler
from tqdm import tqdm
def data_read(data_address):
@ -29,64 +29,72 @@ def data_read(data_address):
# 转换为时间序列数据格式
time_steps = 34
X_series, Y_series = [], []
for i in range(0, len(X) - time_steps):
i = 0
while i < len(X):
X_series.append(X[i:(i + time_steps)])
Y_series.append(Y[i + time_steps - 1])
i += time_steps
return np.array(X_series), np.array(Y_series)
# 编写绘图函数,画出训练集电压数据
def plant_for_voltage(x_train_new, x_train_orginal, gamma, learning_rate, y_train, different_location):
# 绘制X_train的图形
for i in different_location:
if i % 100 == 0:
plt.figure()
time_Step = list(range(0, 34))
plt.plot(time_Step,
x_train_new[i])
# 添加标题和标签
plt.title(f'gamma:{gamma},learning_rate:{learning_rate},Y:{y_train[i]}')
plt.xlabel('time_step')
plt.ylabel('voltage')
try:
os.makedirs(f'Liu/picture/gamma{gamma} learningrate{learning_rate}')
except FileExistsError:
pass
plt.savefig(f'Liu/picture/gamma{gamma} learningrate{learning_rate}/X_train_new_{i}.png')
plt.close()
plt.clf()
# 画出原始图像
plt.figure()
time_Step = list(range(0, 34))
plt.plot(time_Step,
x_train_orginal[i])
# 添加标题和标签
plt.title(f'gamma:{gamma},learning_rate:{learning_rate},Y:{y_train[i]}')
plt.xlabel('time_step')
plt.ylabel('voltage')
try:
os.makedirs(f'Liu/picture/gamma{gamma} learningrate{learning_rate}')
except FileExistsError:
pass
plt.savefig(f'Liu/picture/gamma{gamma} learningrate{learning_rate}/X_train_{i}.png')
plt.close()
plt.clf()
# 绘制X_train的图形
for i in different_location:
if i % 100 == 0:
plt.figure()
time_Step = list(range(0, 34))
plt.plot(time_Step,
x_train_new[i])
# 添加标题和标签
plt.title(
f'gamma:{gamma},learning_rate:{learning_rate},Y:{y_train[i]}')
plt.xlabel('time_step')
plt.ylabel('voltage')
try:
os.makedirs(
f'Liu/picture/gamma{gamma} learningrate{learning_rate}')
except FileExistsError:
pass
plt.savefig(
f'Liu/picture/gamma{gamma} learningrate{learning_rate}/X_train_new_{i}.png')
plt.close()
plt.clf()
# 画出原始图像
plt.figure()
time_Step = list(range(0, 34))
plt.plot(time_Step,
x_train_orginal[i])
# 添加标题和标签
plt.title(
f'gamma:{gamma},learning_rate:{learning_rate},Y:{y_train[i]}')
plt.xlabel('time_step')
plt.ylabel('voltage')
try:
os.makedirs(
f'Liu/picture/gamma{gamma} learningrate{learning_rate}')
except FileExistsError:
pass
plt.savefig(
f'Liu/picture/gamma{gamma} learningrate{learning_rate}/X_train_{i}.png')
plt.close()
plt.clf()
def if_diff(a, b):
# 比较两个数组相同位置上的元素是否相等
diff = np.where(a != b)
# 比较两个数组相同位置上的元素是否相等
diff = np.where(a != b)
list_diff = []
list_diff = []
# 打印不同元素的索引及其对应的元素
for i in range(len(diff[0])):
idx = (diff[0][i], diff[1][i])
list_diff.append(idx[0])
return list_diff
# 打印不同元素的索引及其对应的元素
for i in range(len(diff[0])):
idx = (diff[0][i], diff[1][i])
list_diff.append(idx[0])
return list_diff
X_train, Y_train = data_read(
'Liu\data\VOLTAGE-QUALITY-CLASSIFICATION-MODEL--main\Voltage Quality.csv')
@ -122,7 +130,7 @@ model = tf.keras.models.Sequential([
tf.keras.layers.SimpleRNN(100),
Dropout(0.2),
tf.keras.layers.Dense(n_classes, activation='relu',
) # kernel_regularizer=regularizers.l2(0.3)
) # kernel_regularizer=regularizers.l2(0.3)
])
# 编译模型
@ -132,30 +140,39 @@ model.compile(
metrics=['accuracy'])
# 定义学习率指数递减的函数
def lr_schedule(epoch):
initial_learning_rate = 0.01
decay_rate = 0.1
decay_steps = 250
new_learning_rate = initial_learning_rate * decay_rate ** (epoch / decay_steps)
new_learning_rate = initial_learning_rate * \
decay_rate ** (epoch / decay_steps)
return new_learning_rate
# 定义学习率调度器
lr_scheduler = LearningRateScheduler(lr_schedule)
# Save initial weights
initial_weights = model.get_weights()
# TensorBoard 回调
log_dir = "logs/fit"
tensorboard_callback = TensorBoard(log_dir=log_dir, histogram_freq=1)
# 训练模型,添加 TensorBoard 回调
model.fit(X_train, Y_train, epochs=500,
batch_size=32, callbacks=[tensorboard_callback, lr_scheduler])
# 评估模型
loss, accuracy = model.evaluate(X_test, Y_test)
print("Test original accuracy:", accuracy)
# 制作扰动数据
# 转换X_train和Y_train为TensorFlow张量
X_train_tensor = tf.convert_to_tensor(X_train, dtype=tf.float64)
Y_train_tensor = tf.convert_to_tensor(Y_train, dtype=tf.int32)
# 转换X_test和Y_test为TensorFlow张量
X_train_tensor = tf.convert_to_tensor(X_test, dtype=tf.float64)
Y_train_tensor = tf.convert_to_tensor(Y_test, dtype=tf.int32)
# 使用tf.GradientTape来计算梯度
with tf.GradientTape() as tape:
@ -176,7 +193,7 @@ accuracy_per_gamma = {}
flattened_gradients = tf.reshape(gradients, [-1])
# 选择最大的γ * |X|个梯度
for gamma in tqdm([0.6, 0.7, 0.8, 0.9, 0.99]):
for gamma in [0.05, 0.1, 0.2, 0.4]:
num_gradients_to_select = int(
gamma * tf.size(flattened_gradients, out_type=tf.dtypes.float32))
top_gradients_indices = tf.argsort(flattened_gradients, direction='DESCENDING')[
@ -200,34 +217,24 @@ for gamma in tqdm([0.6, 0.7, 0.8, 0.9, 0.99]):
# 创建准确率列表
accuracy_list = []
for learning_rate in tqdm([0.1, 0.2, 0.3, 0.4, 0.5]):
for learning_rate in [0.1, 0.2, 0.3, 0.4, 0.5]:
# 应用学习率到梯度
scaled_gradients = (learning_rate * 100) * updated_gradients
scaled_gradients = (learning_rate * 17000) * updated_gradients
# 使用缩放后的梯度更新X_train_tensor
X_train_updated = tf.add(X_train_tensor, scaled_gradients)
X_train_updated = X_train_updated.numpy()
list_diff = if_diff(X_train, X_train_updated)
# 显示扰动数据和原始数据的可视化图像
# plant_for_voltage(X_train_updated, X_train, gamma, learning_rate, Y_train, list_diff)
# Reset model weights to initial weights
model.set_weights(initial_weights)
# 训练模型,添加 TensorBoard 回调
history = model.fit(X_train_updated, Y_train, epochs=500,
batch_size=32, callbacks=[tensorboard_callback, lr_scheduler], verbose=0)
# 评估模型
loss, accuracy = model.evaluate(X_test, Y_test)
loss, accuracy = model.evaluate(X_train_updated, Y_test)
print(f"Accuracy gamma: {gamma},learning:{learning_rate}", accuracy)
# 记录准确率
accuracy_list.append(accuracy)
# 记录该gamma下的准确率
accuracy_per_gamma[gamma] = accuracy_list
@ -254,5 +261,3 @@ plt.legend()
# 显示图像
plt.show()
# tensorboard --logdir logs/fit