近期学习整理2(优化算法)
免疫算法
概念
待优化的问题 → 抗原
可行解 → B细胞(产生的抗体)
可行解质量 → 免疫细胞与抗原的亲和度
寻优过程 → 免疫系统识别抗原并进行抗体进化
算法主要包括以下模块:
(1)初始化:抗原识别和初始抗原产生。对待优化的问题设计合适的编码规则,并产生初始抗体群体。
(2)抗体评价与更新。评判抗体亲和度和个体浓度,对优质抗体进行进化,更新劣质抗体。
抗体浓度评价算子 den
d e n ( a b i ) = 1 N ∑ j = 1 N S ( a b i , a b j ) den(ab_i) = \frac 1 N \sum \limits^N_{j = 1}S(ab_i, ab_j) den(abi)=N1j=1∑NS(abi,abj)式中,N为种群规模,S(abi, abj) 表示抗体 i 与抗体 j 的相似度:
S ( a b i , a b j ) = { 1 , a f f ( a b i , a b j ) < δ s 0 , a f f ( a b i , a b j ) ≥ δ s S(ab_i,ab_j)=\begin{cases} 1, \ aff(ab_i, ab_j) < \delta_s \\0, \ aff(ab_i, ab_j) \geq \delta_s \end{cases} S(abi,abj)={1, aff(abi,abj)<δs0, aff(abi,abj)≥δs
其中,δs 为相似度阈值,aff(abi, abj) 为抗体 i 与抗体 j 的亲和度(指的是两抗体之间的亲和度,和亲和度评价算子不同):
- 基于欧氏距离的抗体间亲和度计算方法(实数编码):
a f f ( a b i , a b j ) = ∑ k = 1 L ( a b i , k − a b j , k ) 2 aff(ab_i, ab_j) = \sqrt{\sum \limits^L_{k = 1}(ab_{i, k}-ab_{j, k})^2} aff(abi,abj)=k=1∑L(abi,k−abj,k)2
- 基于海明距离的抗体-抗体亲和度计算方法(离散编码):
a f f ( a b i , a b j ) = ∑ k = 1 L ∂ k aff(ab_i, ab_j)=\sum \limits^L_{k = 1}\partial_k aff(abi,abj)=k=1∑L∂k
其中,
∂ k = { 1 , a b i , k = a b j , k 0 , a b i , k ≠ a b j , k \partial_k = \begin{cases} 1,\ ab_{i, k} = ab_{j, k} \\ 0, \ ab_{i, k} \neq ab_{j, k} \end{cases} ∂k={1, abi,k=abj,k0, abi,k=abj,k
abi, k 和 abj, k 分别为抗体 i 的第 k 位和抗体 j 的第 k 位;L为抗体编码长度。
抗体激励度计算算子 sim
抗体激励度是对抗体质量的最终评价结果,需要综合考虑抗体亲和度和抗体浓度,通常亲和度大、浓度低的抗体会得到较大的激励度。
s i m ( a b i ) = α ⋅ a f f ( a b i ) − β ⋅ d e n ( a b i ) sim(ab_i) = \alpha · aff(ab_i) - \beta · den(ab_i) sim(abi)=α⋅aff(abi)−β⋅den(abi)
(3)免疫操作。形成基于克隆选择原理的进化规则和方法,实现寻优搜索,具体操作包括免疫选择,克隆、变异和克隆抑制。
免疫选择:根据种群中抗体激励度选择优质抗体,使其活化。
克隆:对活化的抗体进行克隆复制,得到若干副本。
变异:对克隆得到的副本进行变异操作,使其发生亲和度突变,进行局部搜索。
变异算子 Tm
实数编码算法的变异策略是在变异源个体中加入小扰动,使其稍微偏离落入邻域的另一个位置,实现变异源邻域的搜索。
T m ( a b i , j , m ) = { a b i , j , m + ( r a n d − 0.5 ) ⋅ δ , r a n d < p m a b i , j , m T_m(ab_{i, j, m}) = \begin {cases} ab_{i, j, m}+(rand-0.5)· \delta, \ rand<p_m \\ ab_{i, j, m} \end {cases} Tm(abi,j,m)={abi,j,m+(rand−0.5)⋅δ, rand<pmabi,j,m
式中,abi, j, m 是抗体 abi 的第 m 个克隆体的第 j 维;δ为定义的邻域范围;pm为变异概率。
克隆抑制:对变异结果进行再选择,抑制亲和度低的抗体,保留亲和度高的变异结果。
算法流程
以例题4.3为例。求函数 f(x, y) = 5cos(xy) + x2 + y2 的最小值,其中 x 的取值范围为[-4, 4],y 的取值范围为[-4, 4]。
函数图像:
算法流程:
亲和度进化曲线:
关键参数
(1)抗体种群大小 Np
种群越大,算法的全局搜索能力越好,但计算量相应增大。
通常 Np 取10 ~ 100,一般不超过200。
(2)免疫选择比例
免疫选择的抗体越多,可以产生更多的克隆,其搜索能力越强,但会增加每代的计算量。
一般取抗体种群大小 Np 的10% ~ 50%。
(3)抗体克隆扩增的倍数
克隆倍数决定克隆扩增的数量,影响局部搜索能力。
一般取5 ~ 10倍。
(4)种群刷新比例
影响算法的全局搜索能力。
每代更新的抗体一般不超过抗体种群的50%。
(5)最大进化代数 G
一般 G 取100 ~ 500。
禁忌算法
概念
局部邻域搜索:基于贪婪准则,持续地在当前的邻域中搜索。搜索性能依赖邻域结构和初始解,容易陷入局部极值,全局搜索能力差。
禁忌算法在局部邻域搜索的基础上,设置了禁忌表,禁忌表会记录已经搜索过的局部最优点,在之后的搜索中不再搜索,从而具有跳出局部最优的能力,逐步达到全局最优;同时设置藐视准则,奖励一些优良状态,对于优于“当前最优值”的点可以不考察其是否在禁忌表中而直接选定其为当前解。
藐视准则常用方式:
(1)基于适配值的原则:某个禁忌候选解的适配值优于“best so far”状态,则解禁此候选解为当前状态和新的“best so far”状态。
(2)基于搜索方向的准则:若禁忌对象上次被禁忌时使得适配值有所改善,并且目前该禁忌对象对应的候选解的适配值优于当前解,则对该禁忌对象解禁。
算法流程
函数图像:
算法流程:
搜索过程最优值曲线:
从例题的代码来看,以当前解为中心搜索其邻域,产生候选解(搜索邻域中的最优解)。若候选解不优于当前解,则将该候选解替换为当前解,并加入禁忌表;若候选解优于当前解:
① 若候选解并不优于全局最优解,则先判断其是否在禁忌表中:若不在,则将其更新为当前解,并加入禁忌表;若在禁忌表中,则重新进行新一轮的邻域搜索。
② 若候选解也优于当前最优解,则基于藐视准则,不管是否在禁忌表,直接将其更新为当前解与当前最优解,并加入禁忌表。
由藐视准则,使优于当前最优解的候选解直接更新为当前最优解是保证邻域搜索的步骤,而为了摆脱局部最优,算法中最关键的部分就在于 “若候选解不优于当前解,则将该候选解替换为当前解,并加入禁忌表”,此处虽然看似无理,但是在算法一直徘徊在某个极值的情况下,可以慢慢地脱离出来,去寻找下一个极值,直到达到停止条件。
神经网络算法
神经网络结构主要可分为:(1)前馈神经网络;(2)反馈神经网络;(3)自组织网络。
其中,属于前馈神经网络的BP神经网络是非常常用的神经网络模型。
设BP神经网络的输入为 n 个学习样本:
x
=
(
x
1
,
x
2
,
.
.
.
,
x
n
)
T
x = (x_1, x_2, ..., x_n)^T
x=(x1,x2,...,xn)T
隐含层有 h 个单元,隐含层的输出为:
y
=
(
y
1
,
y
2
,
.
.
.
y
h
)
T
y = (y_1, y_2, ... y_h)^T
y=(y1,y2,...yh)T
设隐含层的传递函数为 f,即(θ为隐含层神经元的偏置)
y
i
=
f
(
∑
i
=
1
n
w
i
j
x
i
−
θ
)
=
f
(
∑
i
=
0
n
w
i
j
x
i
)
y_i = f(\sum \limits^n_{i = 1} w_{ij}x_i-\theta)=f(\sum \limits^n_{i = 0}w_{ij}x_i)
yi=f(i=1∑nwijxi−θ)=f(i=0∑nwijxi)
输出层有 m 个单元,输出层的输出为:
z
(
z
1
,
z
2
,
.
.
.
,
z
m
)
T
z(z_1, z_2, ..., z_m)^T
z(z1,z2,...,zm)T
设输出层的传递函数为 g ,即
z
k
=
g
(
∑
j
=
0
h
w
j
k
y
j
)
z_k=g(\sum \limits^h_{j = 0}w_{jk}y_j)
zk=g(j=0∑hwjkyj)
网络输出与目标输出的误差为
ϵ
=
1
2
∑
k
=
1
m
(
t
k
−
z
k
)
2
\epsilon=\frac 1 2 \sum \limits^m_{k = 1}(t_k-z_k)^2
ϵ=21k=1∑m(tk−zk)2
BP神经网络的主要思想,即用网络的实际输出 (z1, z2, …, zm) 与目标矢量 (t1, t2, …, tm)之间的误差 ε 来逆向修改前面各层神经元的权值,迭代使网络输出层的误差平方和达到最小。
由于负梯度方向是函数值减小最快的方向,可设定步长 η,每次沿负梯度方向调整 η 个单位,即每次权值的调整为
Δ
w
p
g
=
−
η
∂
ϵ
∂
w
p
g
\Delta w_{pg} = -\eta \frac {\partial{\epsilon }} {\partial{w_{pg}}}
Δwpg=−η∂wpg∂ϵ
在神经网络算法中,η 称为学习速率。
先调整隐含层到输出层的权值
w
j
k
(
t
+
1
)
=
w
j
k
(
t
)
+
η
δ
k
y
j
w_{jk}(t + 1) = w_{jk}(t) + \eta\delta_k y_j
wjk(t+1)=wjk(t)+ηδkyj
再调整输入层到隐含层的权值
w
i
j
(
t
+
1
)
=
w
i
j
(
t
)
+
η
δ
j
x
i
w_{ij}(t + 1) = w_{ij}(t) + \eta\delta_j x_i
wij(t+1)=wij(t)+ηδjxi
(具体推导省略)
算法步骤
(1)数据预处理
为了加快收敛,通常对数据进行归一化处理,将其映射到 [0, 1] 或 [-1, 1] 区间。常用线性转换方式。
若归一到 [0, 1]区间,可做 y = (x - min) / (max - min),激活函数采用S形函数适用。
若归一到 [-1, 1] 区间,可做 y = 2(x - min) / (max - min) - 1,激活函数采用双极S形函数适用。
(2)构建神经网络
net = newff(P, T, [S1 S2 ...S(N-1)], {TF1 TF2 ... TFN}, BTF, BLF, PF, IPF, OPF, DDF);
P:输入矩阵(向量)
T:目标矩阵(向量)
[S1 S2 … S(N - 1)]:神经网络前 N - 1 层每层神经元数
{TF1 TF2 … TFN}:神经网络激活函数,默认为“tansig”
BTF:学习规则采用的训练算法,默认为“trainlm”
BLF:BP权值/偏差学习函数,默认为“mse”
IPF:输入处理函数
OPF:输出处理函数
DDF:验证数据划分函数
(一般设置前7个参数,后3个参数采用系统默认)
常用的激活函数
1)线性函数(字符串为“purelin”)
f ( x ) = x f(x) = x f(x)=x
2)对数S形函数(字符串为“logsig”)
f ( x ) = 1 1 + e − x ( 0 < f ( x ) < 1 ) f(x) = \frac 1 {1 + e^{-x}}\ (0<f(x)<1) f(x)=1+e−x1 (0<f(x)<1)
3)双曲正切S形函数(字符串为“tansig”)
f ( x ) = 2 1 + e − x − 1 ( − 1 < f ( x ) < 1 ) f(x) = \frac 2 {1+e^{-x}}-1\ (-1<f(x)<1) f(x)=1+e−x2−1 (−1<f(x)<1)
一般情况下,在隐含层采用双曲正切S形激活函数,在输出层采用线性激活函数。
(3)配置参数
net.trainParam.show
—— 显示中间结果的周期
net.trainParam.lr
—— 学习率
net.trainParam.epochs
—— 最大迭代次数
net.trainParam.goal
—— 目标误差
(4)训练神经网络
[net, tr, Y1, E] = train(net, P, T);
tr:训练跟踪信息
Y1:网络实际输出
E:误差矩阵
(5)使用神经网络进行仿真
Y = sim(net, P);
Y:预测结果矩阵
以例题9.2为例练习代码,利用BP神经网络预测销量,构建3层BP神经网络,每次用前3个月的销售量预测第4个月的销售量。
clear all;
close all;
clc;
%% 原始数据
p = [2056 2395 2600 2298 1634 1600 1873 1478 1900
2395 2600 2298 1634 1600 1873 1478 1900 1500
2600 2298 1634 1600 1873 1478 1900 1500 2046];
t = [2298 1634 1600 1873 1478 1900 1500 2046 1556];
%% 原始数据归一化
pmax = max(max(p));
pmin = min(min(p));
P = (p - pmin)./(pmax - pmin); % 输入数据矩阵
tmax = max(t);
tmin = min(t);
T = (t - tmin)./(tmax - tmin); % 目标数据向量
%% 创建前向神经网络
net = newff(P, T, 5, {'tansig', 'purelin'}, 'traingdx');
%% 设置训练参数
net.trainParam.show = 50; % 显示中间结果的周期
net.trainParam.lr = 0.05; % 学习率
net.trainParam.epochs = 1000; % 最大迭代次数
net.trainParam.goal = 1e-3; % 目标误差
net.divideFcn = ''; % 清除样本数据分为训练集、验证集和测试集命令
%% 调用TRAINGDM算法训练BP网络
[net, tr] = train(net, P, T);
%% 对BP网络进行仿真
A = sim(net, P);
%% 计算预测数据原始值
a = A.*(tmax - tmin) + tmin;
%% 绘制实际值和预测值曲线
x = 4:12;
figure
plot(x, t, '+');
hold on;
plot(x, a, 'or');
hold off
xlabel('月份')
ylabel('销量')
legend('实际销量', '预测销量');
预测结果:
个人想法
说实话,不是很明白为什么神经网络算法会和前面所述的算法一起放在书里。
之前所罗列的各种算法,比如遗传算法,蚁群算法、粒子群算法,是针对某类优化问题,试图找到最优解。
而神经网络算法,是构建模型,更多的解决预测、分类等问题;若要讲优化,则是如何优化模型,比如设置网络层数、每层的节点数、学习速率等,以更好地解决问题。