目录
1. 粒子群算法基本思想是什么?
2. 标准PSO 算法流程是什么?
3. 采用粒子群优化权值和偏差值的方式训练模型有何优势?
4. 速度和位置更新公式中的参数含义
5. 参数分析与设置
6. PSO伪代码是什么
7. PSO优缺点是什么
8. PSO有什么应用
9. PSO实例1--优化神经网络权重Python
10. PSO实例2--求解函数最值Python
粒子群优化算法(Particle swarm optimization, PSO)的基本思想:是通过群体中个体之间的协作和信息共享来寻找最优解。
1)初始化一群微粒(群体规模为N),包括随机位置和速度;
2)评价每个微粒的适应度;
3)对每个微粒,将其适应值与其经过的最好位置pbest作比较,如果较好,则将其作为当前的最好位置pbest;
4)对每个微粒,将其适应值与其经过的最好位置gbest作比较,如果较好,则将其作为当前的最好位置gbest;
5)根据公式(2)、(3)调整微粒速度和位置;
6)未达到结束条件则转第2)步。
迭代终止条件根据具体问题一般选为最大迭代次数Gk或(和)微粒群迄今为止搜索到的最优位置满足预定最小适应阈值
PSO算法过程的形象展示:
1). 采用粒子群优化方法获取最佳的权值和偏差值,可以提高模型的预测精度。
2). 粒子群优化算法简单易行,可以提高模型的训练速度。
3.) 粒子群优化方法不容易陷入局部极值,原来的权重和偏差值更新方法容易陷入局部极值。
速度更新公式为:
位置更新公式为:
其中,
计算公式为
------为惯性因子初始值,通常设置为0.4
------种群迭代到最大进化次数时的惯性因子值,通常设置为0.9
------最大迭代次数
优点:
缺点:
优化神经网络权重
函数优化
模式分类
模糊控制
#import tensorflow.compat.v1 as tf
#tf.compat.v1.disable_v2_behavior()
#import tensorflow as tf
#第一次用上面的语句跑的时候还好好的,再跑就报错了
import tensorflow as tf
tf = tf.compat.v1
tf.disable_v2_behavior()
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import random
from sklearn.datasets import load_boston
from sklearn.model_selection import train_test_split
from sklearn.neural_network import MLPRegressor
from sklearn.preprocessing import StandardScaler
def function(x1,y1,x2,y2,W):# W是神经网络的W权重,根据这个权重设置神经网络
#定义激活函数
activation_function=tf.nn.relu
#输入输出数据集
xs=tf.placeholder(tf.float32,[None,None])
ys=tf.placeholder(tf.float32,[None,None])
#设计bp神经网络,三层,13,3,1
weights_1=tf.Variable(W[0,:,:],tf.float32)
biases_1=tf.Variable(tf.zeros([1,3])+0.1,tf.float32)
wx_plus_b_1=tf.matmul( xs, tf.cast(weights_1,tf.float32))+biases_1
outputs_1=activation_function(wx_plus_b_1)
weights_2=tf.Variable(W[1,0:3,:],tf.float32)
biases_2=tf.Variable(tf.zeros([1,3])+0.1,tf.float32)
wx_plus_b_2=tf.matmul(outputs_1 , tf.cast(weights_2,tf.float32))+biases_2
outputs_2=activation_function(wx_plus_b_2)
w3=W[2,0:3,0].reshape(3,1)
weights_3=tf.Variable(w3,tf.float32)
biases_3=tf.Variable(0.1,tf.float32)
wx_plus_b_3=tf.matmul(outputs_2,tf.cast(weights_3,tf.float32))+biases_3
#预测输出结果
prediction=wx_plus_b_3 #看来这里的数据就用行向量来输入输出
#定义损失函数
loss=tf.reduce_mean(tf.reduce_sum(tf.square(y1-prediction),reduction_indices=[1]))
#梯度下降法训练
train_step=tf.train.GradientDescentOptimizer(0.1).minimize(loss)
#初始化变量
init=tf.global_variables_initializer()
#执行会话,开始训练模型
print("开始")
with tf.Session() as sess:
sess.run(init)
for i in range (1000):
sess.run(train_step,feed_dict={ xs:x1 , ys:y1 })
end_loss=sess.run(loss,feed_dict={xs:x1,ys:y1})
print(end_loss)
# print(sess.run(prediction,feed_dict={xs:x2}))
print("结束")
return end_loss
#导入数据集
data=load_boston()
data_pd=pd.DataFrame(data.data,columns=data.feature_names)
data_pd["price"]=data.target
#dataframe导入numpy
x=np.array(data_pd.loc[:,'CRIM':'LSTAT'])
y=np.array(data_pd.loc[:,'price'])
y.shape=(506,1)
#训练集测试集
x_train,x_test,y_train,y_test=train_test_split(x,y , test_size=0.1 )
#数据标准化
SC=StandardScaler()
x_train=SC.fit_transform(x_train)
y_train=SC.fit_transform(y_train)
x_test=SC.fit_transform(x_test)
y_test=SC.fit_transform(y_test)
#粒子数量num
num = 3
#粒子位置矩阵的形状
num_x = 3
num_y = 13
num_z = 3
#p为粒子位置矩阵,初始化为标准正态分布
p = np.random.randn(num,num_x,num_y,num_z)
#初始化粒子速度,以标准正态分布随机初始化
v = np.random.randn(num,num_x,num_y,num_z)
#个体最佳位置
good_p = np.array(p, copy=True)
#全局最佳位置
best_p = np.zeros((num_x, num_y, num_z))
#每次粒子移动后所计算出新的目标函数值
new_y = np.zeros(num)
#粒子个体历史最优值
good_y = np.zeros(num)
#粒子群体历史最优值
best_y = 0
#计算出初始粒子群的目标函数值
for i in range(num):
good_y[i] = function(x_train, y_train, x_test, y_test, p[i, :, :, :])
#目标函数返回值是误差,那么最小的就是最优的
best_y = min(good_y)
#确定初始时最优位置
best_p = p[np.argmin(good_y), :, :, :]
#设置最大迭代次数
max_iter = 10
#开始迭代
for i in range(max_iter):
#速度更新公式
v = random.random() * v + 2.4 * random.random() * (best_p - p) + 1.7 * random.random() * ( good_p - p )
#粒子位置更新
p = p + v
#计算每个粒子到达新位置后所得到的目标函数值
for i in range(num):
new_y[i] = function(x_train, y_train, x_test, y_test, p[i, :, :, :])
#更新全局最优
if min(new_y) < best_y:
best_y = min(new_y)
best_p = p[np.argmin(new_y), :, :, :]
#更新个体历史最优
for i in range(num):
if new_y[i] < good_y[i]:
good_y[i] = new_y[i]
good_p[i, :, :, :] = p[i, :, :, :] # 当对切片修改时,原始numpy数据也修改
print("结束")
print('目标函数最优值:',best_y)
print('此时的粒子位置:',best_p)
public class AlgorithmPSO {
int n=2; //粒子个数,这里为了方便演示,我们只取两个,观察其运动方向
double[] y;
double[] x;
double[] v;
double c1=2;
double c2=2;
double pbest[];
double gbest;
double vmax=0.1; //速度最大值
//适应度计算函数,每个粒子都有它的适应度
public void fitnessFunction(){
for(int i=0;igbest) gbest=y[i];
}
System.out.println("算法开始,起始最优解:"+gbest);
System.out.print("\n");
}
public double getMAX(double a,double b){
return a>b?a:b;
}
//粒子群算法
public void PSO(int max){
for(int i=0;ivmax) v[j]=vmax;//控制速度不超过最大值
x[j]+=v[j];
//越界判断,范围限定在[0, 2]
if(x[j]>2) x[j]=2;
if(x[j]<0) x[j]=0;
}
fitnessFunction();
//更新个体极值和群体极值
for(int j=0;jgbest) gbest=pbest[j];
System.out.println("粒子n"+j+": x = "+x[j]+" "+"v = "+v[j]);
}
System.out.println("第"+(i+1)+"次迭代,全局最优解 gbest = "+gbest);
System.out.print("\n");
}
}
//运行我们的算法
public static void main(String[] args){
AlgorithmPSO ts=new AlgorithmPSO();
ts.init();
ts.PSO(10);//为了方便演示,我们暂时迭代10次。
}
}
输出结果:
算法开始,起始最优解:0.0
粒子n0: x = 0.004 v = 0.004
粒子n1: x = 0.0 v = -4.065770842472382
第1次迭代,全局最优解 gbest = 0.007984
粒子n0: x = 0.01778510589090629 v = 0.013785105890906289
粒子n1: x = 0.0 v = -1.625639647649872
第2次迭代,全局最优解 gbest = 0.03525390179026183
粒子n0: x = 0.0610276658084214 v = 0.04324255991751511
粒子n1: x = 0.0 v = -0.6035255880722042
第3次迭代,全局最优解 gbest = 0.11833095562281844
粒子n0: x = 0.1610276658084214 v = 0.1
粒子n1: x = 0.0 v = -0.012719944703824898
第4次迭代,全局最优解 gbest = 0.29612542246113416
粒子n0: x = 0.2610276658084214 v = 0.1
粒子n1: x = 0.06231495466940402 v = 0.06231495466940402
第5次迭代,全局最优解 gbest = 0.4539198892994499
粒子n0: x = 0.3610276658084214 v = 0.1
粒子n1: x = 0.16231495466940402 v = 0.1
第6次迭代,全局最优解 gbest = 0.5917143561377656
粒子n0: x = 0.46102766580842136 v = 0.1
粒子n1: x = 0.262314954669404 v = 0.1
第7次迭代,全局最优解 gbest = 0.7095088229760813
粒子n0: x = 0.5610276658084213 v = 0.1
粒子n1: x = 0.362314954669404 v = 0.1
第8次迭代,全局最优解 gbest = 0.8073032898143969
粒子n0: x = 0.6610276658084213 v = 0.1
粒子n1: x = 0.462314954669404 v = 0.1
第9次迭代,全局最优解 gbest = 0.8850977566527127
粒子n0: x = 0.7610276658084213 v = 0.1
粒子n1: x = 0.562314954669404 v = 0.1
第10次迭代,全局最优解 gbest = 0.9428922234910285
现在我们来观察两个粒子的位移x在每一次迭代中的变化(离食物的距离)。
1) 初始状态
粒子n0: x = 0.0 v = 0.01
粒子n1: x = 2.0 v = 0.02
两个粒子位于区间两端。
2) 第一次迭代
粒子n0: x = 0.004 v = 0.004
粒子n1: x = 0.0 v = -4.065770842472382
两个粒子都跑到原点了。
3) 第二、三……十次迭代
可以看到,两个粒子在不断靠近最优点。上面多个圈是他们聚集的过程,可以看出来,聚集过程是个越来越密集的过程。这才是10次迭代而已。如果我们加大迭代次数,很容易就找出最优解了。最后放上一个迭代100次的结果:
参考资料:
【算法】粒子群算法Particle Swarm Optimization超详细解析+代码实例讲解 - 云+社区 - 腾讯云 (tencent.com) 粒子群优化BP神经网络初始权值(python实现)_哈哈傻的博客-CSDN博客_粒子群优化bp神经网络
经典优化算法 | 粒子群算法解析 - 知乎 (zhihu.com)