2.2 計算適應度

2.3 位置更新

根據alpha、beta和delta狼的位置來更新其余灰狼的位置,更新公式如下:

2.3.1?距離向量計算

2.3.2?計算新的位置向量

2.3.3 更新灰狼位置

1.2?流程圖

兩圖分別為灰狼優化算法流程圖、灰狼的等級制度(從上到下的優勢遞減),灰狼優化算法通過模擬灰狼獵食過程中領袖狼和群體狼的行為,利用領袖狼的位置引導其他灰狼逐步逼近獵物(全局最優解),從而實現全局優化,其核心在于通過位置更新公式,不斷逼近最優解

2. 灰狼算法優缺點

優點:與其他優化算法相比,灰狼算法的優化過程更快,因為它們先得出答案,再把不同答案進行比較并相應地進行排序,以此輸出最佳解決方案缺點:灰狼優化算法屬于啟發式優化算法,產生的最優解僅接近于原始最優解,并不是問題真正的最優解

3. 灰狼算法實現

3.1?灰狼算法在簡單函數上求最值

import numpy as np
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = 'SimHei'
plt.rcParams['axes.unicode_minus'] = False

# 定義優化問題的目標函數
def objective_function(x):
return np.sum(x ** 2 + x)

# 初始化灰狼優化算法的參數
dim = 2 # 解的維度
num_wolves = 300 # 種群大小
max_iter = 100 # 最大迭代次數

# 初始化灰狼種群的位置
wolves = np.random.uniform(-10, 10, (num_wolves, dim))

# 初始化 alpha、beta、delta 狼的位置
alpha_pos = np.zeros(dim)
beta_pos = np.zeros(dim)
delta_pos = np.zeros(dim)
alpha_score = float("inf")
beta_score = float("inf")
delta_score = float("inf")

# 開始迭代
a = 2 # 控制參數,逐漸減小
convergence_curve = []

for t in range(max_iter):
for i in range(num_wolves):
fitness = objective_function(wolves[i])

if fitness < alpha_score:
alpha_score = fitness
alpha_pos = wolves[i].copy()
elif fitness < beta_score:
beta_score = fitness
beta_pos = wolves[i].copy()
elif fitness < delta_score:
delta_score = fitness
delta_pos = wolves[i].copy()

a = 2 - t * (2 / max_iter) # 線性減少 a

for i in range(num_wolves):
for j in range(dim):
r1, r2 = np.random.rand(), np.random.rand()
A1 = 2 * a * r1 - a
C1 = 2 * r2
D_alpha = abs(C1 * alpha_pos[j] - wolves[i][j])
X1 = alpha_pos[j] - A1 * D_alpha

r1, r2 = np.random.rand(), np.random.rand()
A2 = 2 * a * r1 - a
C2 = 2 * r2
D_beta = abs(C2 * beta_pos[j] - wolves[i][j])
X2 = beta_pos[j] - A2 * D_beta

r1, r2 = np.random.rand(), np.random.rand()
A3 = 2 * a * r1 - a
C3 = 2 * r2
D_delta = abs(C3 * delta_pos[j] - wolves[i][j])
X3 = delta_pos[j] - A3 * D_delta

wolves[i][j] = (X1 + X2 + X3) / 3

convergence_curve.append(alpha_score)

print(f"最優解: {alpha_pos}")
print(f"最優值: {alpha_score}")

# 繪制收斂曲線
plt.figure(figsize=(15,5))
plt.plot(convergence_curve)
plt.title("收斂曲線")
plt.xlabel("迭代次數")
plt.ylabel("適應度值")
plt.show()

# 可視化灰狼種群位置
if dim == 2:
plt.figure(figsize=(15,5))
plt.scatter(wolves[:, 0], wolves[:, 1], c='blue', label='Wolves')
plt.scatter(alpha_pos[0], alpha_pos[1], c='red', label='Alpha', marker='x')
plt.scatter(beta_pos[0], beta_pos[1], c='green', label='Beta', marker='x')
plt.scatter(delta_pos[0], delta_pos[1], c='purple', label='Delta', marker='x')
plt.title("灰狼種群位置")
plt.legend()
plt.show()

3.2?灰狼算法在標準測試函數Rastrigin上求最值

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

plt.rcParams['font.sans-serif'] = 'SimHei'
plt.rcParams['axes.unicode_minus'] = False

# 定義優化問題的目標函數(Rastrigin函數)
def objective_function(x):
return 10 * len(x) + np.sum(x ** 2 - 10 * np.cos(2 * np.pi * x))

# 初始化灰狼優化算法的參數
dim = 2 # 解的維度
num_wolves = 300 # 種群大小
max_iter = 100 # 最大迭代次數

# 初始化灰狼種群的位置
wolves = np.random.uniform(-5.12, 5.12, (num_wolves, dim))

# 初始化 alpha、beta、delta 狼的位置
alpha_pos = np.zeros(dim)
beta_pos = np.zeros(dim)
delta_pos = np.zeros(dim)
alpha_score = float("inf")
beta_score = float("inf")
delta_score = float("inf")

# 開始迭代
a = 2 # 控制參數,逐漸減小
convergence_curve = []

for t in range(max_iter):
for i in range(num_wolves):
fitness = objective_function(wolves[i])

if fitness < alpha_score:
alpha_score = fitness
alpha_pos = wolves[i].copy()
elif fitness < beta_score:
beta_score = fitness
beta_pos = wolves[i].copy()
elif fitness < delta_score:
delta_score = fitness
delta_pos = wolves[i].copy()

a = 2 - t * (2 / max_iter) # 線性減少 a

for i in range(num_wolves):
for j in range(dim):
r1, r2 = np.random.rand(), np.random.rand()
A1 = 2 * a * r1 - a
C1 = 2 * r2
D_alpha = abs(C1 * alpha_pos[j] - wolves[i][j])
X1 = alpha_pos[j] - A1 * D_alpha

r1, r2 = np.random.rand(), np.random.rand()
A2 = 2 * a * r1 - a
C2 = 2 * r2
D_beta = abs(C2 * beta_pos[j] - wolves[i][j])
X2 = beta_pos[j] - A2 * D_beta

r1, r2 = np.random.rand(), np.random.rand()
A3 = 2 * a * r1 - a
C3 = 2 * r2
D_delta = abs(C3 * delta_pos[j] - wolves[i][j])
X3 = delta_pos[j] - A3 * D_delta

wolves[i][j] = (X1 + X2 + X3) / 3

convergence_curve.append(alpha_score)

print(f"最優解: {alpha_pos}")
print(f"最優值: {alpha_score}")

plt.figure(figsize=(15,5))
plt.plot(convergence_curve)
plt.title("收斂曲線")
plt.xlabel("迭代次數")
plt.ylabel("適應度值")
plt.show()

if dim == 2:
x = np.linspace(-5.12, 5.12, 400)
y = np.linspace(-5.12, 5.12, 400)
X, Y = np.meshgrid(x, y)
Z = 10 * 2 + (X ** 2 - 10 * np.cos(2 * np.pi * X)) + (Y ** 2 - 10 * np.cos(2 * np.pi * Y))
fig = plt.figure(figsize=(8,8))
ax = fig.add_subplot(111, projection='3d')
ax.plot_surface(X, Y, Z, cmap='viridis', alpha=0.2)
ax.scatter(alpha_pos[0], alpha_pos[1], alpha_score, c='red', label='Alpha', marker='x')
ax.scatter(beta_pos[0], beta_pos[1], beta_score, c='green', label='Beta', marker='x')
ax.scatter(delta_pos[0], delta_pos[1], delta_score, c='purple', label='Delta', marker='x')
ax.set_title("Rastrigin求解結果")
ax.legend()
plt.show()

Rastrigin函數是一種常用于測試優化算法性能的多模態函數,其數學表達式為:

4. 灰狼算法在模型上優化的運用

4.1 數據簡單預處理

import pandas as pd
import numpy as np
df = pd.read_excel('數據.xlsx',index_col=0, parse_dates=['數據時間'])

# 數據預處理
df_max = np.max(df['總有功功率(kw)'])
df_min = np.min(df['總有功功率(kw)'])
df_bz = (df['總有功功率(kw)']-df_min)/(df_max-df_min)

def prepare_data(data, win_size):
X = []
y = []
for i in range(len(data) - win_size):
temp_x = data[i:i + win_size]
temp_y = data[i + win_size]
X.append(temp_x)
y.append(temp_y)
X = np.asarray(X)
y = np.asarray(y)
X = np.expand_dims(X, axis=-1)

return X, y
win_size = 12
X, y = prepare_data(df_bz.values, win_size)
train_size = int(len(X) * 0.7)
X_train, X_test = X[:train_size], X[train_size:]
y_train, y_test = y[:train_size], y[train_size:]

4.2?灰狼算法尋找最優參數

import tensorflow.compat.v1 as tf
from tensorflow.keras.layers import Flatten, Dense
from tensorflow.keras.models import Sequential
import matplotlib.pyplot as plt
from tcn import TCN

# 關閉TensorFlow 2.x的急切執行
tf.disable_eager_execution()

# 定義目標函數
def objective_function(params):
dense_1, dense_2, filters1 = params
dense_1, dense_2, filters1 = int(dense_1), int(dense_2), int(filters1)

model = Sequential()
model.add(TCN(nb_filters=filters1, kernel_size=6, activation='relu', input_shape=(win_size, 1), dilations=[1, 2, 4, 8, 16]))
model.add(Flatten())
model.add(Dense(dense_1, activation='relu'))
model.add(Dense(dense_2, activation='relu'))
model.add(Dense(1, activation='sigmoid'))

model.compile(optimizer='adam', loss='mse')
history = model.fit(X_train, y_train, epochs=10, batch_size=32, validation_data=(X_test, y_test), verbose=0)
val_loss = min(history.history['val_loss'])

return val_loss

# 初始化GWO參數
dim = 3 # 超參數的數量
num_wolves = 5 # 灰狼種群的大小
max_iter = 20 # 最大迭代次數
lower_bound = [32, 64, 32] # 超參數的下界
upper_bound = [128, 256, 128] # 超參數的上界

# 初始化灰狼種群的位置
wolves = np.random.uniform(lower_bound, upper_bound, (num_wolves, dim))

# 初始化 alpha、beta、delta 狼的位置
alpha_pos = np.zeros(dim)
beta_pos = np.zeros(dim)
delta_pos = np.zeros(dim)
alpha_score = float("inf")
beta_score = float("inf")
delta_score = float("inf")

# 開始迭代
a = 2 # 控制參數,逐漸減小
convergence_curve = []

for t in range(max_iter):
for i in range(num_wolves):
fitness = objective_function(wolves[i])

if fitness < alpha_score:
alpha_score = fitness
alpha_pos = wolves[i].copy()
elif fitness < beta_score:
beta_score = fitness
beta_pos = wolves[i].copy()
elif fitness < delta_score:
delta_score = fitness
delta_pos = wolves[i].copy()

a = 2 - t * (2 / max_iter) # 線性減少 a

for i in range(num_wolves):
for j in range(dim):
r1, r2 = np.random.rand(), np.random.rand()
A1 = 2 * a * r1 - a
C1 = 2 * r2
D_alpha = abs(C1 * alpha_pos[j] - wolves[i][j])
X1 = alpha_pos[j] - A1 * D_alpha

r1, r2 = np.random.rand(), np.random.rand()
A2 = 2 * a * r1 - a
C2 = 2 * r2
D_beta = abs(C2 * beta_pos[j] - wolves[i][j])
X2 = beta_pos[j] - A2 * D_beta

r1, r2 = np.random.rand(), np.random.rand()
A3 = 2 * a * r1 - a
C3 = 2 * r2
D_delta = abs(C3 * delta_pos[j] - wolves[i][j])
X3 = delta_pos[j] - A3 * D_delta

wolves[i][j] = np.clip((X1 + X2 + X3) / 3, lower_bound[j], upper_bound[j])

convergence_curve.append(alpha_score)

print(f"最優解: {alpha_pos}")
print(f"最優值: {alpha_score}")

plt.plot(convergence_curve)
plt.title("收斂曲線")
plt.xlabel("迭代次數")
plt.ylabel("驗證損失")
plt.show()

在這里目標函數 objective_function(params) 負責創建和訓練模型,并返回驗證集上的最小損失值(驗證損失),它的輸入 params 是一個包含超參數的列表,灰狼算法初始化值如下:

dim = 3  # 超參數的數量
num_wolves = 5 # 灰狼種群的大小
max_iter = 20 # 最大迭代次數
lower_bound = [32, 64, 32] # 超參數的下界
upper_bound = [128, 256, 128] # 超參數的上界

這里的參數值都設置的比較小,實際上應該根據任務復雜度進行調整,通常較大的種群、較大迭代次數,可以提供更好的解決結果,當然計算成本也會增加,這里只是為了演示如何利用灰狼算法進行超參數搜索,通過算法我們輸出了當前搜索范圍,迭代次數下的最優參數,接下來使用該參數進行模型訓練

4.3?最優參數下的模型訓練

# 使用最優超參數重新訓練模型
dense_1, dense_2, filters1 = map(int, alpha_pos)

model = Sequential()
model.add(TCN(nb_filters=filters1, kernel_size=6, activation='relu', input_shape=(win_size, 1), dilations=[1, 2, 4, 8, 16]))
model.add(Flatten())
model.add(Dense(dense_1, activation='relu'))
model.add(Dense(dense_2, activation='relu'))
model.add(Dense(1, activation='sigmoid'))

model.compile(optimizer='adam', loss='mse')

history = model.fit(X_train, y_train, epochs=100, batch_size=32, validation_data=(X_test, y_test), verbose=0)

# 可視化訓練集和測試集的損失
plt.plot(history.history['loss'], label='Training Loss')
plt.plot(history.history['val_loss'], label='Validation Loss')
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.legend()
plt.show()

文章轉自微信公眾號@Python機器學習AI

上一篇:

利用Pytorch框架構建lstm時間序列預測模型

下一篇:

SVM多分類分析:SHAP解釋各類別下各特征對模型的影響力

我們有何不同?

API服務商零注冊

多API并行試用

數據驅動選型,提升決策效率

查看全部API→
??

熱門場景實測,選對API

#AI文本生成大模型API

對比大模型API的內容創意新穎性、情感共鳴力、商業轉化潛力

25個渠道
一鍵對比試用API 限時免費

#AI深度推理大模型API

對比大模型API的邏輯推理準確性、分析深度、可視化建議合理性

10個渠道
一鍵對比試用API 限時免費