1.4 基于模拟退火改进蛇算法优化VGG13SE网络超参数的故障诊断模型
本博客来源于CSDN机器鱼,未同意任何人转载。
更多内容,欢迎点击本专栏,查看更多内容。
目录
0 引言
1 改进原理
2 本文改进方法
3 改进蛇优化VGG13SE的故障诊断模型
4 结语
0 引言
在【博客】中,我们采用了蛇算法来对VGG13SE网络的15个超参数进行优化,为进一步提高论文的充实性,体现工作量,我们将对原始的蛇算法进行改进,具体是在蛇算法中融入模拟退火的思路。
1 改进原理
我个人认为所有的智能优化算法都是以下步骤组成:
步骤1.初始化。种群随机初始化获得初始最优解与初始最优适应度。
步骤2.寻优过程。进入for循环,利用更新公式对种群中的每个个体进行的位置(解)移动,并计算更新后的解对应的新适应度值。如果新适应度比旧的适应度更优,则更新每个个体的解与其适应度值。
步骤3.最优解更新。将种群的每个个体的适应度与最优适应度进行比较,如果个体的适应度更优,则更新最优适应度与最优解。
步骤4.寻优结束。一般是for结束退出,或者是达到了需要的值退出。
其中步骤3、4是固定的,没办法改。因此常见的改进都是对步骤1与步骤2改进。
改进步骤1的文章认为随机初始化并不是真正的随机,初始种群不会都遍布寻优空间,就跟吃鸡跳伞一样,最理想的情况肯定是整个地图均匀分布,但实际上很多人会集中往某个区域跳,那万一98k就在那些没得人覆盖的地方喃。因此改进步骤1就是用更均匀的方法让初始化解遍布寻优空间。
改进步骤2的一般有四种情况,①发现了原作者的公式存在某些弊端,显然咱只是用一下而已,根本不去管公式啥样,从3月29日写代码到4月2日写到这篇博客,蛇算法我都没看过公式与原理;②针对算法的某些固定的参数进行动态更新,就像吃鸡找装备一样,在空旷的区域可以快速跑动找建筑物,但是进建筑物之后要慢慢走,才能找到好的装备。③给算法加上随机变异,此部分人认为算法在后期可能会陷入局部最优解,就像吃鸡要是一开始方向就跑错了,结果玩半天都只找到一个波波枪,要是能随机将自己传送到其他建筑物里面该多好,说不定就能找到好的装备。④就是继续堆公式,在算法里面加入其他算法的思想,本来人家循环一次已经完成一次更新了,但在后面再加个公式,让其再更新一次,这样当然效果更好,但同时消耗的时间也更长。
2 本文改进方法
本文分别对步骤1与2进行一次改进,步骤1的随机初始化加上Tent映射,让初始化分布更均匀,步骤2在更新完毕之后,再进行一次模拟退火更新。具体代码如下:
'''tent映射'''
def tent(dim):
x=np.zeros([dim])
x[0]=np.random.rand()#初始点
a=0.7 #参数a的值
for i in range(dim-1):
if x[i]<a:
x[i+1]=x[i]/a
else:
x[i+1]=(1-x[i]) / (1 - a)
return x
''' Tent种群初始化函数 '''
def initialnew(pop, dim, ub, lb):
X = np.zeros([pop, dim])
for i in range(pop):
tentvalue=tent(dim)
for j in range(dim):
X[i, j] = tentvalue[j]*(ub - lb) + lb
return X
# 修正后的邻域生成函数
def neighbor(x, solution_bound):
perturbation = np.random.uniform(-1, 1, size=x.shape)
x_new = x + perturbation
# 确保扰动后仍在边界内
x_new = np.clip(x_new, solution_bound[0], solution_bound[1])
return x_new
def sa_snake_optimization(search_agents_no, max_iter, dim, solution_bound):
# 参数初始化
T = 1000
T_min = 0.01
alpha = 0.9
vec_flag = [1, -1]
food_threshold = 0.25
temp_threshold = 0.6
c1 = 0.5
model_threshold = 0.6
c2 = 0.5
c3 = 2
# 种群初始化(使用numpy数组代替矩阵)
#X = solution_bound[0] + np.random.rand(search_agents_no, dim) * (solution_bound[1] - solution_bound[0])
X = initialnew(search_agents_no, dim, solution_bound[1] , solution_bound[0]) #初始化种群
# 适应度计算
fitness = np.array([chung_reynolds(x) for x in X])
g_best_idx = np.argmin(fitness)
food = X[g_best_idx].copy()
gy_best = fitness[g_best_idx]
# 性别分组
male_number = search_agents_no // 2
female_number = search_agents_no - male_number
male = X[:male_number].copy()
female = X[male_number:].copy()
# 性别相关参数
male_fitness = fitness[:male_number]
female_fitness = fitness[male_number:]
male_best_idx = np.argmin(male_fitness)
male_best = male_fitness[male_best_idx]
male_best_solution = male[male_best_idx].copy()
female_best_idx = np.argmin(female_fitness)
female_best = female_fitness[female_best_idx]
female_best_solution = female[female_best_idx].copy()
gene_best = np.zeros(max_iter)
for t in range(max_iter):
temp = math.exp(-t / max_iter)
quantity = c1 * math.exp((t - max_iter) / max_iter)
quantity = min(quantity, 1)
new_male = male.copy()
new_female = female.copy()
if quantity < food_threshold:
# 无食物模式
for i in range(male_number):
leader = random.choice(male)
am = math.exp(-(chung_reynolds(leader) / (male_fitness[i] + 1e-30)))
direction = random.choice(vec_flag)
new_male[i] = leader + direction * c2 * am * np.random.rand(dim) * (
solution_bound[1] - solution_bound[0])
for i in range(female_number):
leader = random.choice(female)
am = math.exp(-(chung_reynolds(leader) / (female_fitness[i] + 1e-30)))
direction = random.choice(vec_flag)
new_female[i] = leader + direction * c2 * am * np.random.rand(dim) * (
solution_bound[1] - solution_bound[0])
else:
if temp > temp_threshold:
# 热态探索
for i in range(male_number):
direction = random.choice(vec_flag)
new_male[i] = food + direction * c3 * temp * np.random.rand(dim) * (food - male[i])
for i in range(female_number):
direction = random.choice(vec_flag)
new_female[i] = food + direction * c3 * temp * np.random.rand(dim) * (food - female[i])
else:
if random.random() < model_threshold:
# 战斗模式
for i in range(male_number):
fm = math.exp(-female_best / (male_fitness[i] + 1e-30))
direction = random.choice(vec_flag)
new_male[i] = male[i] + direction * c3 * fm * np.random.rand(dim) * (
quantity * male_best_solution - male[i])
for i in range(female_number):
ff = math.exp(-male_best / (female_fitness[i] + 1e-30))
direction = random.choice(vec_flag)
new_female[i] = female[i] + direction * c3 * ff * np.random.rand(dim) * (
quantity * female_best_solution - female[i])
else:
# 交配模式
for i in range(male_number):
mm = math.exp(-female_fitness[i % female_number] / (male_fitness[i] + 1e-30))
direction = random.choice(vec_flag)
new_male[i] = male[i] + direction * c3 * np.random.rand() * mm * (
quantity * female[i % female_number] - male[i])
for i in range(female_number):
mf = math.exp(-male_fitness[i % male_number] / (female_fitness[i] + 1e-30))
direction = random.choice(vec_flag)
new_female[i] = female[i] + direction * c3 * np.random.rand() * mf * (
quantity * male[i % male_number] - female[i])
if random.random() < 0.5:
worst_male = np.argmax(male_fitness)
new_male[worst_male] = solution_bound[0] + np.random.rand(dim) * (
solution_bound[1] - solution_bound[0])
worst_female = np.argmax(female_fitness)
new_female[worst_female] = solution_bound[0] + np.random.rand(dim) * (
solution_bound[1] - solution_bound[0])
# 边界处理
new_male = np.clip(new_male, solution_bound[0], solution_bound[1])
new_female = np.clip(new_female, solution_bound[0], solution_bound[1])
# 更新雄性种群
for i in range(male_number):
new_fit = chung_reynolds(new_male[i])
if new_fit < male_fitness[i]:
male[i] = new_male[i]
male_fitness[i] = new_fit
# 更新雌性种群
for i in range(female_number):
new_fit = chung_reynolds(new_female[i])
if new_fit < female_fitness[i]:
female[i] = new_female[i]
female_fitness[i] = new_fit
# 更新全局最优
current_male_best = np.min(male_fitness)
current_female_best = np.min(female_fitness)
gene_best[t] = min(current_male_best, current_female_best)
if current_male_best < current_female_best:
if current_male_best < gy_best:
gy_best = current_male_best
food[:] = male[np.argmin(male_fitness)]
else:
if current_female_best < gy_best:
gy_best = current_female_best
food[:] = female[np.argmin(female_fitness)]
# 模拟退火
if T > T_min:
food_new = neighbor(food, solution_bound)
f_new = chung_reynolds(food_new)
delta = f_new - gy_best
if delta < 0 or np.random.rand() < math.exp(-delta / T):
food[:] = food_new
gy_best = f_new
T *= alpha
return food, gy_best, gene_best
if __name__ == "__main__":
# Problem settings
dim = 10
search_agents_no = 26
bounds = (-100, 100)
max_iter = 100
initial_temp = 1000
cooling_rate = 0.98
best_solution2, best_fitness2, fitness_history2 = snake_optimization(
search_agents_no, max_iter, dim, bounds
)
best_solution3, best_fitness3, fitness_history3 = sa_snake_optimization(
search_agents_no, max_iter, dim, bounds
)
# Plot optimization process
plt.figure(figsize=(10, 6))
plt.plot(fitness_history2, linewidth=2,label='SO')
plt.plot(fitness_history3, linewidth=2,label='SASO')
plt.legend()
plt.title("Optimization Process")
plt.xlabel("Iteration")
plt.ylabel("Best Fitness")
plt.grid(True)
plt.show()
print("SO最佳解决方案:", best_solution2)
print("SO最佳适应度:", best_fitness2)
print("SASO最佳解决方案:", best_solution3)
print("SASO最佳适应度:", best_fitness3)
SO最佳解决方案: [-7.18304079e-04 2.99050463e-04 4.11682735e-04 9.49958913e-05
-3.24086231e-04 1.01366699e-03 -3.25997173e-04 1.86127080e-03
2.60402360e-04 -5.85704982e-04]
SO最佳适应度: 1.3505001036507069e-11
SASO最佳解决方案: [ 2.46793435e-05 1.43884017e-04 1.11257355e-04 8.70514697e-05
1.46319530e-05 2.40548315e-04 -3.72922538e-05 -1.02563608e-05
-5.73090196e-05 2.23889093e-04]
SASO最佳适应度: 6.5132243165577145e-15
3 改进蛇优化VGG13SE的故障诊断模型
4月3日更新