【超参数寻优】粒子群算法(PSO) 超参数寻优的python实现


粒子群优化算法(Particle swarm optimization,PSO)是模拟鸟群捕食行为的优化算法。不同于遗传算法(Genetic Alogrithm,GA),粒子群算法是有记忆的,之前迭代过程中的最优位置和最优方向都会保留下来并作用于粒子群的更新【参考资料1】。

一、算法原理

1、粒子群算法的名词解释

粒子群长度:粒子群长度等于每一个参数取值范围的大小。
粒子群维度:粒子群维度等于待寻优参数的数量。
粒子群位置:粒子群位置包含参数取值的具体数值。
粒子群方向:粒子群方向表示参数取值的变化方向。
适应度函数:表征粒子对应的模型评价指标。
pbest:(局部最优)pbest的长度等于粒子群长度,表示每一个参数取值的变化过程中,到目前为止最优适应度函数值对应的取值。
gbest:(全局最优)gbest的长度为1,表示到目前为止所有适应度函数值中最优的那个对应的参数取值。
惯性因子 w w w:惯性因子表示粒子保持的运动惯性。
局部学习因子 c 1 {c_1} c1:表示每个粒子向该粒子目前为止最优位置运动加速项的权重。
全局学习因子 c 2 {c_2} c2:表示每个粒子向目前为止全局最优位置运动加速项的权重。

2、粒子更新

粒子方向更新方程为:

v i = w × v i + c 1 × r a n d ( ) × ( p b e s t i − x i ) + c 2 × r a n d ( ) × ( g b e s t − x i ) {v_i} = w \times {v_i} + {c_1} \times rand() \times (pbes{t_i} - {x_i}) + {c_2} \times rand() \times (gbest - {x_i}) vi=w×vi+c1×rand()×(pbestixi)+c2×rand()×(gbestxi)

其中 v i {v_i} vi表示第i个粒子的方向, p b e s t i pbes{t_i} pbesti表示第i个粒子当前最优参数, g b e s t gbest gbest表示当前的全局最优参数, x i x_i xi表示第i个粒子的参数值, r a n d ( ) rand() rand()表示介于 ( 0 , 1 ) (0,1) (0,1)之间的随机数。

粒子位置更新方程为:

x i = x i + v i {x_i} = {x_i} + {v_i} xi=xi+vi

w w w取值越大说明粒子更新更多受到粒子历史方向的影响, w = 0 w=0 w=0表示粒子更新只取决于粒子当前位置,局部最优粒子位置和全局最优粒子位置,粒子方向本身没有记忆性。 c 1 {c_1} c1表示粒子更新受到局部最优粒子的影响程度, c 1 = 0 {c_1}=0 c1=0表示粒子只有全局搜索能力,但缺少局部搜索能力。 c 2 {c_2} c2表示粒子更新受到全局最优粒子的影响程度, c 2 = 0 {c_2}=0 c2=0表示粒子只有局部搜索能力,但缺少全局搜索能力。

二、PSO算法参数寻优的python实现

完整python代码和样本地址:https://github.com/shiluqiang/PSO_python

本博文以非线性SVM为待优化模型,待优化参数为正则化参数 C C C和核参数 σ \sigma σ,适应度函数值为3-fold交叉验证平均值。

## 2. PSO优化算法
class PSO(object):
    def __init__(self,particle_num,particle_dim,iter_num,c1,c2,w,max_value,min_value):
        '''参数初始化
        particle_num(int):粒子群的粒子数量
        particle_dim(int):粒子维度,对应待寻优参数的个数
        iter_num(int):最大迭代次数
        c1(float):局部学习因子,表示粒子移动到该粒子历史最优位置(pbest)的加速项的权重
        c2(float):全局学习因子,表示粒子移动到所有粒子最优位置(gbest)的加速项的权重
        w(float):惯性因子,表示粒子之前运动方向在本次方向上的惯性
        max_value(float):参数的最大值
        min_value(float):参数的最小值
        '''
        self.particle_num = particle_num
        self.particle_dim = particle_dim
        self.iter_num = iter_num
        self.c1 = c1  ##通常设为2.0
        self.c2 = c2  ##通常设为2.0
        self.w = w    
        self.max_value = max_value
        self.min_value = min_value
        
        
### 2.1 粒子群初始化
    def swarm_origin(self):
        '''粒子群初始化
        input:self(object):PSO类
        output:particle_loc(list):粒子群位置列表
               particle_dir(list):粒子群方向列表
        '''
        particle_loc = []
        particle_dir = []
        for i in range(self.particle_num):
            tmp1 = []
            tmp2 = []
            for j in range(self.particle_dim):
                a = random.random()
                b = random.random()
                tmp1.append(a * (self.max_value - self.min_value) + self.min_value)
                tmp2.append(b)
            particle_loc.append(tmp1)
            particle_dir.append(tmp2)
        
        return particle_loc,particle_dir

## 2.2 计算适应度函数数值列表;初始化pbest_parameters和gbest_parameter   
    def fitness(self,particle_loc):
        '''计算适应度函数值
        input:self(object):PSOparticle_loc(list):粒子群位置列表
        output:fitness_value(list):适应度函数值列表
        '''
        fitness_value = []
        ### 1.适应度函数为RBF_SVM3_fold交叉校验平均值
        for i in range(self.particle_num):
            rbf_svm = svm.SVC(kernel = 'rbf', C = particle_loc[i][0], gamma = particle_loc[i][1])
            cv_scores = cross_validation.cross_val_score(rbf_svm,trainX,trainY,cv =3,scoring = 'accuracy')
            fitness_value.append(cv_scores.mean())
        ### 2. 当前粒子群最优适应度函数值和对应的参数
        current_fitness = 0.0
        current_parameter = []
        for i in range(self.particle_num):
            if current_fitness < fitness_value[i]:
                current_fitness = fitness_value[i]
                current_parameter = particle_loc[i]

        return fitness_value,current_fitness,current_parameter 
        

## 2.3  粒子位置更新 
    def updata(self,particle_loc,particle_dir,gbest_parameter,pbest_parameters):
        '''粒子群位置更新
        input:self(object):PSOparticle_loc(list):粒子群位置列表
              particle_dir(list):粒子群方向列表
              gbest_parameter(list):全局最优参数
              pbest_parameters(list):每个粒子的历史最优值
        output:particle_loc(list):新的粒子群位置列表
               particle_dir(list):新的粒子群方向列表
        '''
        ## 1.计算新的量子群方向和粒子群位置
        for i in range(self.particle_num): 
            a1 = [x * self.w for x in particle_dir[i]]
            a2 = [y * self.c1 * random.random() for y in list(np.array(pbest_parameters[i]) - np.array(particle_loc[i]))]
            a3 = [z * self.c2 * random.random() for z in list(np.array(gbest_parameter) - np.array(particle_dir[i]))]
            particle_dir[i] = list(np.array(a1) + np.array(a2) + np.array(a3))
#            particle_dir[i] = self.w * particle_dir[i] + self.c1 * random.random() * (pbest_parameters[i] - particle_loc[i]) + self.c2 * random.random() * (gbest_parameter - particle_dir[i])
            particle_loc[i] = list(np.array(particle_loc[i]) + np.array(particle_dir[i]))
            
        ## 2.将更新后的量子位置参数固定在[min_value,max_value]内 
        ### 2.1 每个参数的取值列表
        parameter_list = []
        for i in range(self.particle_dim):
            tmp1 = []
            for j in range(self.particle_num):
                tmp1.append(particle_loc[j][i])
            parameter_list.append(tmp1)
        ### 2.2 每个参数取值的最大值、最小值、平均值   
        value = []
        for i in range(self.particle_dim):
            tmp2 = []
            tmp2.append(max(parameter_list[i]))
            tmp2.append(min(parameter_list[i]))
            value.append(tmp2)
        
        for i in range(self.particle_num):
            for j in range(self.particle_dim):
                particle_loc[i][j] = (particle_loc[i][j] - value[j][1])/(value[j][0] - value[j][1]) * (self.max_value - self.min_value) + self.min_value
                
        return particle_loc,particle_dir

## 2.4 画出适应度函数值变化图
    def plot(self,results):
        '''画图
        '''
        X = []
        Y = []
        for i in range(self.iter_num):
            X.append(i + 1)
            Y.append(results[i])
        plt.plot(X,Y)
        plt.xlabel('Number of iteration',size = 15)
        plt.ylabel('Value of CV',size = 15)
        plt.title('PSO_RBF_SVM parameter optimization')
        plt.show() 
        
## 2.5 主函数        
    def main(self):
        '''主函数
        '''
        results = []
        best_fitness = 0.0 
        ## 1、粒子群初始化
        particle_loc,particle_dir = self.swarm_origin()
        ## 2、初始化gbest_parameter、pbest_parameters、fitness_value列表
        ### 2.1 gbest_parameter
        gbest_parameter = []
        for i in range(self.particle_dim):
            gbest_parameter.append(0.0)
        ### 2.2 pbest_parameters
        pbest_parameters = []
        for i in range(self.particle_num):
            tmp1 = []
            for j in range(self.particle_dim):
                tmp1.append(0.0)
            pbest_parameters.append(tmp1)
        ### 2.3 fitness_value
        fitness_value = []
        for i in range(self.particle_num):
            fitness_value.append(0.0)
    
        ## 3.迭代
        for i in range(self.iter_num):
            ### 3.1 计算当前适应度函数值列表
            current_fitness_value,current_best_fitness,current_best_parameter = self.fitness(particle_loc)
            ### 3.2 求当前的gbest_parameter、pbest_parameters和best_fitness
            for j in range(self.particle_num):
                if current_fitness_value[j] > fitness_value[j]:
                    pbest_parameters[j] = particle_loc[j]
            if current_best_fitness > best_fitness:
                best_fitness = current_best_fitness
                gbest_parameter = current_best_parameter
            
            print('iteration is :',i+1,';Best parameters:',gbest_parameter,';Best fitness',best_fitness)
            results.append(best_fitness)
            ### 3.3 更新fitness_value
            fitness_value = current_fitness_value
            ### 3.4 更新粒子群
            particle_loc,particle_dir = self.updata(particle_loc,particle_dir,gbest_parameter,pbest_parameters)
        ## 4.结果展示
        results.sort()
        self.plot(results)
        print('Final parameters are :',gbest_parameter)

最优适应度函数值随迭代次数的变化图如下:在这里插入图片描述

参考资料

1、https://blog.csdn.net/qq_34504481/article/details/79763824

  • 29
    点赞
  • 330
    收藏
    觉得还不错? 一键收藏
  • 24
    评论
PSO(Particle Swarm Optimization,粒子群优化)是一种基于群体智能的优化算法,BP(Back Propagation,反向传播)是一种常用的人工神经网络算法。将PSO算法与BP算法结合起来,可以用于优化BP算法的权重和偏置。 下面是PSO优化BP算法的过程分析: 1. 确定适应度函数:适应度函数用于评估神经网络的性能,通常是平均误差或均方误差。 2. 初始化粒子群:粒子群中的每个粒子都代表了一组BP算法的权重和偏置。 3. 计算粒子群的适应度值:使用适应度函数计算每个粒子的适应度值。 4. 更新粒子的速度和位置:每个粒子根据自身的速度和位置,以及整个粒子群的最优位置,更新自己的速度和位置。速度和位置的更新公式如下: 速度:V(t+1) = w * V(t) + c1 * rand() * (pbest - X(t)) + c2 * rand() * (gbest - X(t)) 位置:X(t+1) = X(t) + V(t+1) 其中,w是惯性权重,控制粒子的运动惯性;c1和c2是加速系数,控制粒子的局部搜索和全局搜索能力;rand()是一个随机数函数;pbest是粒子自身历史上最优的位置;gbest是整个粒子群历史上最优的位置。 5. 使用更新后的权重和偏置进行BP算法的训练:将每个粒子的权重和偏置应用于BP算法,进行训练。 6. 判断是否满足停止条件:如果满足停止条件,结束算法;否则,返回步骤3。 通过PSO优化BP算法,可以加速BP算法的收敛过程,提高神经网络的准确率和泛化能力。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 24
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值