【故障诊断】基于PSO优化VMD参数(自适应VMD)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 前言
  • 一、基于粒子群优化的变分模态分解
  • 二、实现代码
    • 1.引入库
    • 2.读入数据
  • 总结


前言

提示:对文章代码的复现:

[1]唐贵基,王晓龙.参数优化变分模态分解方法在滚动轴承早期故障诊断中的应用[J].西安交通大学学报,2015,49(05):73-81.
摘要:针对滚动轴承早期故障特征提取困难的问题,提出一种基于参数优化变分模态分解的轴承早期故障诊断方法。首先利用粒子群优化算法对变分模态分解算法的最佳影响参数组合进行搜索,搜索结束后根据所得结果设定变分模态分解算法的惩罚参数和分量个数,并利用参数优化变分模态分解算法对故障信号进行处理。原故障信号经过处理后被分解为若干本征模态函数分量,由此筛选出最佳信号分量并进行包络解调运算,最终通过分析信号的包络谱可判断轴承的故障类型。利用参数优化变分模态分解方法对轴承故障仿真和实测信号进行分析,均成功提取出微弱特征频率信息,表明参数优化变分模态分解方法可实现滚动轴承早期故障的有效判别,具有一定的可靠性和应用价值。


提示:以下是本篇文章正文内容,下面案例可供参考

一、基于粒子群优化的变分模态分解

利用粒子群算法 搜寻VMD算法的影 响参数时,需确定一个适应度函数,粒子每次更新位置时计算一次适应度值,通过对比新粒子适应度值进行更新。使用包络熵的概念,将信号解调运算后得到的包络信号处理成一个概率分布序列pj, 由它计算得到的熵值就反映了原始信号的稀疏特性。零均值信号x(j)(j=1,2,…,N)的包络熵Ep可表示成:
【故障诊断】基于PSO优化VMD参数(自适应VMD)_第1张图片式中:pj是a(j)的归一化形式;a(j)是信号x(j)经Hilbert解调后得到的包络信号。
轴承早期故障信号经VMD算法处理后,如果所得IMF分量中包含的噪声较多,与故障相关的周期性冲击特征不明显,则分量信号的稀疏性较弱,包络熵值较大。如果IMF分量中包含的故障特征信息较多,波形中出现规律性冲击脉冲,则信号将呈现出较强的稀疏特性,包络熵值较小。当第i个粒子处于某一位置Xi(对应一组影响参数组合α 和K) 时,计算此位置条件下VMD处理得到的所有IMF分量的包络熵值,将包络熵值中最小的一个称为局部极小熵值,用minLEIpMF表示,与局部极小熵值相对应的IMF分量即是该组IMF分量中包含丰富故障特征信息的最佳分量,然而该分量仅为局部最佳分量。为了搜索到全局最佳分量,即从轴承故障信号中剥离出包含特征信息最为丰富的IMF分量,本文将局部极小熵值作为寻优过程中的适应度值,以局部极小熵值最小化作为最终的寻优目标。

二、实现代码

1.引入库

代码如下(示例):

import numpy as np
from scipy.signal import hilbert
import matplotlib.pyplot as plt
from vmdpy import VMD

2.读入数据

以西储大学轴承数据为例:

data = np.loadtxt(r'F:\12k\0HP\0.007B.txt')[:8192]

tau = 0.            # noise-tolerance (no strict fidelity enforcement)               # 3 modes  
DC = 0             # no DC part imposed  
init = 1           # initialize omegas uniformly  
tol = 1e-7 

# 计算每个IMF分量的包络熵
def calculate_entropy(imf):
    #每个分量的包络信号为env
    env = np.abs(hilbert(imf))
    # 将每个包络信号归一化到 [0, 1] 区间内
    env_norm = env / np.max(env)#在计算包络熵的过程中,需要对包络信号进行归一化处理,以确保不同幅度的包络信号具有可比性。
    # 根据信息熵的定义,可以通过将包络信号的概率分布进行估计,
    #并计算该概率分布的熵值来度量其不确定性。因此,在这段代码中,将归一化后的包络信号作为概率分布,通过p = env_norm / np.sum(env_norm)计算其概率分布。
    p = env_norm / np.sum(env_norm)
    return -np.sum(p * np.log2(p))


# 定义适应度函数,即最大包络熵
def fitness_func(x):

    if x[1] < 0:
        x[1] = np.random.choice([3, 12])
    u, u_hat, omega = VMD(data,  int(round(x[0])), tau, int(round(x[1])), DC, init, tol)
    num_modes = u.shape[0]
    entropy = np.zeros(num_modes)
    for i in range(num_modes):
        entropy[i] = calculate_entropy(u[i,:])
    
    
    # 找到最小的包络熵对应的模态
    min_entropy_index = np.argmin(entropy)
    min_entropy_mode = u[min_entropy_index]


#     print("最小包络熵对应的模态:", min_entropy_index)
    # x为VMD参数向量
    # signal为要分解的信号
    # 分解信号并计算最大包络熵
    # 返回最大包络熵值
    return entropy[min_entropy_index]

# 定义PSO算法
def pso_optimization(num_particles, num_dimensions, fitness_func, max_iter):
    # 初始化粒子位置和速度
    particles_pos = np.zeros((num_particles, num_dimensions))
    
    for i in range(num_particles):
        particles_pos[i, 0] = np.random.uniform(500, 3000)
        particles_pos[i, 1] = np.random.uniform(3, 12)
    particles_vel = np.zeros((num_particles, num_dimensions))
    # 记录每个粒子的最佳位置和适应度值
    particles_best_pos = np.copy(particles_pos)
    particles_best_fit = np.zeros(num_particles)
    # 记录整个群体的最佳位置和适应度值
    global_best_pos = np.zeros(num_dimensions)
    global_best_fit = float('inf')
    
        

    # 迭代更新
    for i in range(max_iter):
        # 计算每个粒子的适应度值
        particles_fitness = np.array([fitness_func(p) for p in particles_pos])

        # 更新每个粒子的最佳位置和适应度值
        for j in range(num_particles):
            if particles_fitness[j] < particles_best_fit[j]:
                particles_best_fit[j] = particles_fitness[j]
                particles_best_pos[j] = np.copy(particles_pos[j])

        # 更新整个群体的最佳位置和适应度值
        global_best_idx = np.argmin(particles_fitness)
        if particles_fitness[global_best_idx] < global_best_fit:
            global_best_fit = particles_fitness[global_best_idx]
            global_best_pos = np.copy(particles_pos[global_best_idx])

        # 更新每个粒子的速度和位置
        for j in range(num_particles):
            # 计算新速度
            r1 = np.random.rand(num_dimensions)
            r2 = np.random.rand(num_dimensions)
            cognitive_vel = 2.0 * r1 * (particles_best_pos[j] - particles_pos[j])
            social_vel = 2.0 * r2 * (global_best_pos - particles_pos[j])
            particles_vel[j] = particles_vel[j] + cognitive_vel + social_vel
            # 更新位置
            particles_pos[j] = particles_pos[j] + particles_vel[j]

        # 记录每次迭代的global_best_pos和global_best_fit
        global_best_pos_list.append(global_best_pos)
        global_best_fit_list.append(global_best_fit)
        print("第:"+str(i)+'次迭代')
    # 返回全局最优位置和适应度值
    return global_best_pos, global_best_fit

# 初始化空列表用于存储每次迭代的global_best_pos和global_best_fit
global_best_pos_list = []
global_best_fit_list = []
# 使用PSO算法优化VMD参数
num_particles = 2
num_dimensions = 2 # 假设有5个VMD参数
max_iter = 20
best_pos, best_fit = pso_optimization(num_particles, num_dimensions, fitness_func, max_iter)

# 输出结果
print("Best VMD parameters:", best_pos)
print("Best fitness value:", best_fit)

# 使用 matplotlib 绘制 global_best_pos 和 global_best_fit 的图形
fig, ax = plt.subplots(nrows=3, ncols=1, figsize=(8, 6))
ax[0].scatter(range(max_iter),np.array(global_best_pos_list)[:,0])
ax[0].set_xlabel('Iteration')
ax[0].set_ylabel('Global Best Position')
ax[0].legend(['a'])
ax[1].scatter(range(max_iter),np.array(global_best_pos_list)[:,1])
ax[1].set_xlabel('Iteration')
ax[1].set_ylabel('Global Best Position')
ax[1].legend(['k'])
ax[2].scatter(range(max_iter),global_best_fit_list)
ax[2].set_xlabel('Iteration')
ax[2].set_ylabel('Global Best Fitness')
plt.show()

输出结果为:
【故障诊断】基于PSO优化VMD参数(自适应VMD)_第2张图片这里只是简单迭代了20次,可以根据需要调整参数。


总结

以西储大学轴承数据为例,使用pso对VMD 参数优化,适应度函数选用最小包络熵,代码复现。

你可能感兴趣的:(python,scikit-learn,scipy)