【十问十答】粒子群算法(PSO)
目錄
1. 粒子群算法基本思想是什么?
2. 標準PSO 算法流程是什么?
3.?采用粒子群優化權值和偏差值的方式訓練模型有何優勢?
4. 速度和位置更新公式中的參數含義
5. 參數分析與設置
6. PSO偽代碼是什么
7. PSO優缺點是什么
8. PSO有什么應用
9. PSO實例1--優化神經網絡權重Python
10. PSO實例2--求解函數最值Python
1. 粒子群算法基本思想是什么?
粒子群優化算法(Particle swarm optimization, PSO)的基本思想:是通過群體中個體之間的協作和信息共享來尋找最優解。
2. 標準PSO 算法流程是什么?
1)初始化一群微粒(群體規模為N),包括隨機位置和速度;
2)評價每個微粒的適應度;
3)對每個微粒,將其適應值與其經過的最好位置pbest作比較,如果較好,則將其作為當前的最好位置pbest;
4)對每個微粒,將其適應值與其經過的最好位置gbest作比較,如果較好,則將其作為當前的最好位置gbest;
5)根據公式(2)、(3)調整微粒速度和位置;
6)未達到結束條件則轉第2)步。
迭代終止條件根據具體問題一般選為最大迭代次數Gk或(和)微粒群迄今為止搜索到的最優位置滿足預定最小適應閾值
PSO算法過程的形象展示:
??
3.?采用粒子群優化權值和偏差值的方式訓練模型有何優勢?
1). 采用粒子群優化方法獲取最佳的權值和偏差值,可以提高模型的預測精度。
2). 粒子群優化算法簡單易行,可以提高模型的訓練速度。
3.) 粒子群優化方法不容易陷入局部極值,原來的權重和偏差值更新方法容易陷入局部極值。
4. 速度和位置更新公式中的參數含義
速度更新公式為:
位置更新公式為:
其中,
- i=1,2,···,m。-----表示粒子個數
- d=1,2, ···,D. ------表示維數
- k------表示當前進化代數,或者說是當前迭代次數
- ------粒子當前的位置
- ------慣性因子, 為非負值。值較大時,全局尋優能力強,局部尋優能力弱;值較小時,全局尋優能力弱,局部尋優能力強。
計算公式為
------為慣性因子初始值,通常設置為0.4
------種群迭代到最大進化次數時的慣性因子值,通常設置為0.9
?------最大迭代次數
- ------粒子當前最優位置
- ------粒子i對應的全局最優位置
- r1和r2------隨機初始為0-1之間的數,對群體的多樣性有一定的作用
- c1和c2------學習因子(也稱加速因子),影響算法的收斂速度
5. 參數分析與設置
- 群體規模N------一般取20~40,對較難或特定類別的問題可以取到100~200。
- 最大速度Vmax------決定當前位置與最好位置之間的區域的分辨率(或精度)。如果太快,則粒子有可能越過極小點;如果太慢,則粒子不能在局部極小點之外進行足夠的探索,會陷入到局部極值區域內。這種限制可以達到防止計算溢出、決定問題空間搜索的粒度的目的。
- 慣性因子------如果=0,則速度只取決于當前位置和歷史最好位置,速度本身沒有記憶性。
- 學習因子c1和c2------c1和c2代表將每個粒子推向pbest和gbest位置的統計加速項的權值。如果令c1=c2=0,粒子將一直以當前速度的飛行,直到邊界,很難找到最優解。通常設c1=c2=2。Suganthan的實驗表明:c1和c2為常數時可以得到較好的解,但不一定必須等于2。
6. PSO偽代碼是什么
7. PSO優缺點是什么
優點:
- 不依賴于問題信息,算法通用性強。
- 需要調整的參數少,原理簡單,容易實現
- 協同搜索,同時利用個體局部信息和群體全局信息指導搜索。
- 收斂速度快, 算法對計算機內存和CPU要求不高
缺點:
- 算法局部搜索能力較差,搜索精度不夠高。
- 算法不能絕對保證搜索到全局最優解
8. PSO有什么應用
-
優化神經網絡權重
-
函數優化
-
模式分類
-
模糊控制
9. PSO實例1--優化神經網絡權重Python
#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 StandardScalerdef 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,1weights_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_1outputs_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_2outputs_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)10. PSO實例2--求解函數最值Python
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;i<n;i++){y[i]=-1*x[i]*(x[i]-2);}}public void init(){ //初始化x=new double[n];v=new double[n];y=new double[n];pbest=new double[n];/**** 本來是應該隨機產生的,為了方便演示,我這里手動隨機落兩個點,分別落在最大值兩邊*/x[0]=0.0;x[1]=2.0;v[0]=0.01;v[1]=0.02;fitnessFunction();//初始化當前個體最優位置,并找到群體最優位置for(int i=0;i<n;i++){pbest[i]=y[i];if(y[i]>gbest) 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;i<max;i++){double w=0.4;for(int j=0;j<n;j++){//更新位置和速度,下面就是我們之前重點講解的兩條公式。v[j]=w*v[j]+c1*Math.random()*(pbest[j]-x[j])+c2*Math.random()*(gbest-x[j]);if(v[j]>vmax) 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;j<n;j++){pbest[j]=getMAX(y[j],pbest[j]);if(pbest[j]>gbest) 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)
總結
以上是生活随笔為你收集整理的【十问十答】粒子群算法(PSO)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 关于你不知道的特征归一化/标准化
- 下一篇: JavaScript优化基本篇