视觉机器学习20讲-MATLAB源码示例(19)-遗传算法
1. 遗传算法
遗传算法(Genetic Algorithm,GA)最早是由美国的 John holland于20世纪70年代提出,该算法是根据大自然中生物体进化规律而设计提出的。是模拟达尔文生物进化论的自然选择和遗传学机理的生物进化过程的计算模型,是一种通过模拟自然进化过程搜索最优解的方法。该算法通过数学的方式,利用计算机仿真运算,将问题的求解过程转换成类似生物进化中的染色体基因的交叉、变异等过程。在求解较为复杂的组合优化问题时,相对一些常规的优化算法,通常能够较快地获得较好的优化结果。遗传算法已被人们广泛地应用于组合优化、机器学习、信号处理、自适应控制等领域。
其主要特点是直接对结构对象进行操作,不存在求导和函数连续性的限定;具有内在的隐并行性和更好的全局寻优能力;采用概率化的寻优方法,不需要确定的规则就能自动获取和指导优化的搜索空间,自适应地调整搜索方向。
遗传算法以一种群体中的所有个体为对象,并利用随机化技术指导对一个被编码的参数空间进行高效搜索。其中,选择、交叉和变异构成了遗传算法的遗传操作;参数编码、初始群体的设定、适应度函数的设计、遗传操作设计、控制参数设定五个要素组成了遗传算法的核心内容。
2. Matlab仿真
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%功能:演示遗传算法在计算机视觉中的应用
%实现如何利用遗传算法实现车牌定位;
%环境:Win7,Matlab2018a
%Modi: C.S
%时间:2022-04-05
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function main
clc;clear all;close all;
img=imread('testcard.jpg');
defaultConfig.xy = 10*rand(50,2);
defaultConfig.dmat = [];
defaultConfig.popSize = 100;
defaultConfig.numIter = 1e4;
defaultConfig.showProg = true;
defaultConfig.showResult = true;
defaultConfig.showWaitbar = false;
% define the position of the plate number;
aa=[157,226];bb=[140,140];cc=[163,163];dd=[141,163];ee=[157,157];ff=[226,226];
% Interpret user configuration inputs
if ~nargin
userConfig = struct();
elseif isstruct(varargin{1})
userConfig = varargin{1};
else
try
userConfig = struct(varargin{:});
catch
error('Expected inputs are either a structure or parameter/value pairs');
end
end
% Override default configuration with user inputs
configStruct = get_config(defaultConfig,userConfig);
% Extract configuration
xy = configStruct.xy;
dmat = configStruct.dmat;
popSize = configStruct.popSize;
numIter = configStruct.numIter;
showProg = configStruct.showProg;
showResult = configStruct.showResult;
showWaitbar = configStruct.showWaitbar;
if isempty(dmat)
nPoints = size(xy,1);
a = meshgrid(1:nPoints);
dmat = reshape(sqrt(sum((xy(a,:)-xy(a',:)).^2,2)),nPoints,nPoints);
end
% Verify Inputs
[N,dims] = size(xy);
[nr,nc] = size(dmat);
if N ~= nr || N ~= nc
error('Invalid XY or DMAT inputs!')
end
n = N;
% Sanity Checks
popSize = 4*ceil(popSize/4);
numIter = max(1,round(real(numIter(1))));
showProg = logical(showProg(1));
showResult = logical(showResult(1));
showWaitbar = logical(showWaitbar(1));
% Initialize the Population
pop = zeros(popSize,n);
pop(1,:) = (1:n);
for k = 2:popSize
pop(k,:) = randperm(n);
end
% Run the GA
globalMin = Inf;
totalDist = zeros(1,popSize);
distHistory = zeros(1,numIter);
tmpPop = zeros(4,n);
newPop = zeros(popSize,n);
if showProg
% figure('Name','TSP_GA | Current Best Solution','Numbertitle','off');
hAx = gca;
end
if showWaitbar
hWait = waitbar(0,'Searching for near-optimal solution ...');
end
for iter = 1:numIter
% Evaluate Each Population Member (Calculate Total Distance)
for p = 1:popSize
d = dmat(pop(p,n),pop(p,1)); % Closed Path
for k = 2:n
d = d + dmat(pop(p,k-1),pop(p,k));
end
totalDist(p) = d;
end
% Find the Best Route in the Population
[minDist,index] = min(totalDist);
distHistory(iter) = minDist;
if minDist < globalMin
globalMin = minDist;
optRoute = pop(index,:);
if showProg
% Plot the Best Route
rte = optRoute([1:n 1]);
% if dims > 2, plot3(hAx,xy(rte,1),xy(rte,2),xy(rte,3),'r.-');
% else plot(hAx,xy(rte,1),xy(rte,2),'r.-'); end
% title(hAx,sprintf('Total Distance = %1.4f, Iteration = %d',minDist,iter));
drawnow;
end
end
% Genetic Algorithm Operators
randomOrder = randperm(popSize);
for p = 4:4:popSize
rtes = pop(randomOrder(p-3:p),:);
dists = totalDist(randomOrder(p-3:p));
[ignore,idx] = min(dists); %#ok
bestOf4Route = rtes(idx,:);
routeInsertionPoints = sort(ceil(n*rand(1,2)));
I = routeInsertionPoints(1);
J = routeInsertionPoints(2);
for k = 1:4 % Mutate the Best to get Three New Routes
tmpPop(k,:) = bestOf4Route;
switch k
case 2 % Flip
tmpPop(k,I:J) = tmpPop(k,J:-1:I);
case 3 % Swap
tmpPop(k,[I J]) = tmpPop(k,[J I]);
case 4 % Slide
tmpPop(k,I:J) = tmpPop(k,[I+1:J I]);
otherwise % Do Nothing
end
end
newPop(p-3:p,:) = tmpPop;
end
pop = newPop;
% Update the waitbar
if showWaitbar && ~mod(iter,ceil(numIter/325))
waitbar(iter/numIter,hWait);
end
end
if showWaitbar
close(hWait);
end
% if showResult
% % Plots the GA Results
% % figure('Name','TSP_GA | Results','Numbertitle','off');
% % subplot(2,2,1);
% pclr = ~get(0,'DefaultAxesColor');
% if dims > 2, plot3(xy(:,1),xy(:,2),xy(:,3),'.','Color',pclr);
% else plot(xy(:,1),xy(:,2),'.','Color',pclr); end
% title('City Locations');
% subplot(2,2,2);
% imagesc(dmat(optRoute,optRoute));
% title('Distance Matrix');
% subplot(2,2,3);
% rte = optRoute([1:n 1]);
% if dims > 2, plot3(xy(rte,1),xy(rte,2),xy(rte,3),'r.-');
% else plot(xy(rte,1),xy(rte,2),'r.-'); end
% title(sprintf('Total Distance = %1.4f',minDist));
% subplot(2,2,4);
% plot(distHistory,'b','LineWidth',2);
% title('Best Solution History');
% set(gca,'XLim',[0 numIter+1],'YLim',[0 1.1*max([1 distHistory])]);
% end
imshow(img);hold on;
plot(aa,bb,'w.-',aa,cc,'w.-',ee,dd,'w.-',ff,dd,'w.-');
% Return Output
if nargout
resultStruct = struct( ...
'xy', xy, ...
'dmat', dmat, ...
'popSize', popSize, ...
'numIter', numIter, ...
'showProg', showProg, ...
'showResult', showResult, ...
'showWaitbar', showWaitbar, ...
'optRoute', optRoute, ...
'minDist', minDist);
varargout = {resultStruct};
end
figure(2);
subimg=img(dd(1):dd(2),aa(1):aa(2)); imshow(subimg);
end
% Subfunction to override the default configuration with user inputs
function config = get_config(defaultConfig,userConfig)
% Initialize the configuration structure as the default
config = defaultConfig;
% Extract the field names of the default configuration structure
defaultFields = fieldnames(defaultConfig);
% Extract the field names of the user configuration structure
userFields = fieldnames(userConfig);
nUserFields = length(userFields);
% Override any default configuration fields with user values
for i = 1:nUserFields
userField = userFields{i};
isField = strcmpi(defaultFields,userField);
if nnz(isField) == 1
thisField = defaultFields{isField};
config.(thisField) = userConfig.(userField);
end
end
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%功能:演示遗传算法在计算机视觉中的应用
%实现如何利用遗传算法实现车牌图像的分割;
%环境:Win7,Matlab2018a
%Modi: C.S
%时间:2022-04-05
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% read demo image
a=imread('testcard.jpg');
% disp demo image
figure(1),imshow(a),title('Original Image')
% get dimension of image
[m,n]=size(a);
a0=double(a);
h=1;
a1=zeros(m,n);
% Calculate 1D histogram
for i=1:m
for j=1:n
for k=-h:h
for w=-h:h;
p=i+k;
q=j+w;
if (p<=0)|( p>m)
p=i;
end
if (q<=0)|(q>n)
q=j;
end
a1(i,j)=a0(p,q)+a1(i,j);
end
end
a2(i,j)=uint8(1/9*a1(i,j));
end
end
fxy=zeros(256,256);
% Calculate 2D histogram
for i=1:m
for j=1:n
c=a0(i,j);
d=double(a2(i,j));
fxy(c+1,d+1)=fxy(c+1,d+1)+1;
end
end
Pxy=fxy/m/n;
P0=zeros(256,256);
Ui=zeros(256,256);
Uj=zeros(256,256);
P0(1,1)=Pxy(1,1);
for i=2:256
P0(1,i)=P0(1,i-1)+Pxy(1,i);
end
for i=2:256
P0(i,1)=P0(i-1,1)+Pxy(i,1);
end
for i=2:256
for j=2:256
P0(i,j)=P0(i,j-1)+P0(i-1,j)-P0(i-1,j-1)+Pxy(i,j);
end
end
P1=ones(256,256)-P0;
Ui(1,1)=0;
for i=2:256
Ui(1,i)=Ui(1,i-1)+(1-1)*Pxy(1,i);
end
for i=2:256
Ui(i,1)=Ui(i-1,1)+(i-1)*Pxy(i,1);
end
for i=2:256
for j=2:256
Ui(i,j)=Ui(i,j-1)+Ui(i-1,j)-Ui(i-1,j-1)+(i-1)*Pxy(i,j);
end
end
Uj(1,1)=0;
for i=2:256
Uj(1,i)=Uj(1,i-1)+(i-1)*Pxy(1,i);
end
for i=2:256
Uj(i,1)=Uj(i-1,1)+(1-1)*Pxy(i,1);
end
for i=2:256
for j=2:256
Uj(i,j)=Uj(i,j-1)+Uj(i-1,j)-Uj(i-1,j-1)+(j-1)*Pxy(i,j);
end
end
uti=0;
utj=0;
for i=1:256
for j=1:256
uti=uti+(i-1)*Pxy(i,j);
utj=utj+(j-1)*Pxy(i,j);
end
end
% Calculate max variance
hmax=0;
for i=1:256
for j=1:256
if P0(i,j)~=0&P1(i,j)~=0
h(i,j)=((uti*P0(i,j)-Ui(i,j))^2+(utj*P0(i,j)-Uj(i,j))^2)/(P1(i,j)*P0(i,j));
else
h(i,j)=0;
end
end
end
hmax=max(h(:));
for i=1:256
for j=1:256
if h(i,j)==hmax
s=i-1;
t=j-1;
continue;
end
end
end
% the result
z=ones(m,n);
for i=1:m
for j=1:n
if a(i,j)<=s&a2(i,j)<=t
z(i,j)=0;
end
end
end
% disp the result image
figure(2),imshow(z),title('GA-based car plate number segmentation');
3. 仿真结果
4. 小结
遗传算法的不足在于:
(1)编码不规范及编码存在表示的不准确性。
(2)单一的遗传算法编码不能全面地将优化问题的约束表示出来。考虑约束的一个方法就是对不可行解采用阈值,这样,计算的时间必然增加。
(3)遗传算法通常的效率比其他传统的优化方法低。
(4)遗传算法容易过早收敛。
(5)遗传算法对算法的精度、可行度、计算复杂性等方面,还没有有效的定量分析方法。
关于遗传算法,记得研究生求学期间,扫地机器人相关研究方向的师姐曾采用过遗传算法对其进行路劲规划,有兴趣深入了解原理模型的推荐去仔细查看全文《机器学习20讲》中第十九讲内容,后期如果有在相关领域应用到遗传算法,也会记录分享出来。