手机网站怎么上传图片,太原seo外包平台,中国互联网协会电话多少,动易网站迁移训练
我们主要以3000fps matlab实现为叙述主体。
总体目标 我们需要为68个特征点的每一个特征点训练5棵随机树#xff0c;每棵树4层深#xff0c;即为所谓的随机森林。 开始训练
分配样本 事实上#xff0c;对于每个特征点#xff0c;要训练随机森林#xff0c;我们需…训练
我们主要以3000fps matlab实现为叙述主体。
总体目标 我们需要为68个特征点的每一个特征点训练5棵随机树每棵树4层深即为所谓的随机森林。 开始训练
分配样本 事实上对于每个特征点要训练随机森林我们需要从现有的样本和特征中抽取一部分训练成若干个树。 现在我们有N此处N1622个样本图片和shape和无数个像素差特征。训练时对于每棵树我们从N个样本采取有放回抽样的方法随机选取若干样本再随机选取M个特征点。然后使用这些素材加以训练。这是一般的方法。不过为了简化我们将N个样本平均分成5份且允许彼此之间有重叠。然后分配好的样本用来作为68个特征点的共同素材。
示意图 代码 dbsize length(Tr_Data);% rf cell(1, params.max_numtrees);overlap_ratio params.bagging_overlap;%重叠比例Q floor(double(dbsize)/((1-params.bagging_overlap)*(params.max_numtrees))); %每颗树分配的样本个数Data cell(1, params.max_numtrees); %为训练每棵树准备的样本数据
for t 1:params.max_numtrees% calculate the number of samples for each random tree% train t-th random treeis max(floor((t-1)*Q - (t-1)*Q*overlap_ratio 1), 1); ie min(is Q, dbsize);Data{t} Tr_Data(is:ie);
end
2.随机森林训练全程 代码
% divide local region into grid
params.radius ([0:1/30:1]);
params.angles 2*pi*[0:1/36:1];rfs cell(length(params.meanshape), params.max_numtrees); %随机森林的大小为68*5%parfor i 1:length(params.meanshape)
for i 1:length(params.meanshape)rf cell(1, params.max_numtrees);disp(strcat(num2str(i), th landmark is processing...));for t 1:params.max_numtrees% disp(strcat(training, {}, num2str(t), -th tree for, {}, num2str(lmarkID), -th landmark));% calculate the number of samples for each random tree% train t-th random treeis max(floor((t-1)*Q - (t-1)*Q*overlap_ratio 1), 1); %样本的序号ie min(is Q, dbsize);max_numnodes 2^params.max_depth - 1; %最大的节点数自然是满二叉树的节点个数rf{t}.ind_samples cell(max_numnodes, 1); %节点包含的样本序号rf{t}.issplit zeros(max_numnodes, 1);%是否分割rf{t}.pnode zeros(max_numnodes, 1);rf{t}.depth zeros(max_numnodes, 1);%当前深度rf{t}.cnodes zeros(max_numnodes, 2);%当前节点的左右子节点序号rf{t}.isleafnode zeros(max_numnodes, 1); %判断节点是否是叶子节点rf{t}.feat zeros(max_numnodes, 4); %围绕特征点随机选取的2个点的坐标r1,a1,r2,a2rf{t}.thresh zeros(max_numnodes, 1); %分割节点的阈值rf{t}.ind_samples{1} 1:(ie - is 1)*(params.augnumber); %第t棵树的样本序号也是根节点包含的样本序号rf{t}.issplit(1) 0;rf{t}.pnode(1) 0;rf{t}.depth(1) 1;rf{t}.cnodes(1, 1:2) [0 0];rf{t}.isleafnode(1) 1;rf{t}.feat(1, :) zeros(1, 4);rf{t}.thresh(1) 0;num_nodes 1; %num_nodes为现有的节点个数num_leafnodes 1;%num_leafnodes为现有的叶子节点个数stop 0;while(~stop) %这个循环用于产生随机树直到没有再可以分割的点num_nodes_iter num_nodes; %num_nodes为现有的节点个数num_split 0; %分割节点的个数for n 1:num_nodes_iterif ~rf{t}.issplit(n) %如果第t棵树第n个节点已经分过就跳过去if rf{t}.depth(n) params.max_depth % || length(rf{t}.ind_samples{n}) 20if rf{t}.depth(n) 1 %应该去掉吧????????????????rf{t}.depth(n) 1;endrf{t}.issplit(n) 1; else% separate the samples into left and right path[thresh, feat, lcind, rcind, isvalid] splitnode(i, rf{t}.ind_samples{n}, Data{t}, params, stage);%{if ~isvalidrf{t}.feat(n, :) [0 0 0 0];rf{t}.thresh(n) 0;rf{t}.issplit(n) 1;rf{t}.cnodes(n, :) [0 0];rf{t}.isleafnode(n) 1;continue;end%}% set the threshold and featture for current noderf{t}.feat(n, :) feat;rf{t}.thresh(n) thresh;rf{t}.issplit(n) 1;rf{t}.cnodes(n, :) [num_nodes1 num_nodes2]; %当前节点的左右子节点序号rf{t}.isleafnode(n) 0;% add left and right child nodes into the random treerf{t}.ind_samples{num_nodes1} lcind;rf{t}.issplit(num_nodes1) 0;rf{t}.pnode(num_nodes1) n;rf{t}.depth(num_nodes1) rf{t}.depth(n) 1;rf{t}.cnodes(num_nodes1, :) [0 0];rf{t}.isleafnode(num_nodes1) 1;rf{t}.ind_samples{num_nodes2} rcind;rf{t}.issplit(num_nodes2) 0;rf{t}.pnode(num_nodes2) n;rf{t}.depth(num_nodes2) rf{t}.depth(n) 1;rf{t}.cnodes(num_nodes2, :) [0 0];rf{t}.isleafnode(num_nodes2) 1;num_split num_split 1; %分割节点的次数,实际上一层分割节点的个数num_leafnodes num_leafnodes 1;num_nodes num_nodes 2;endendendif num_split 0stop 1;elserf{t}.num_leafnodes num_leafnodes;rf{t}.num_nodes num_nodes; rf{t}.id_leafnodes find(rf{t}.isleafnode 1); end endend% disp(strcat(num2str(i), th landmark is over));rfs(i, :) rf;
end
3.分裂节点全程 流程图: 代码
function [thresh, feat, lcind, rcind, isvalid] splitnode(lmarkID, ind_samples, Tr_Data, params, stage)if isempty(ind_samples)thresh 0;feat [0 0 0 0];rcind [];lcind [];isvalid 1;return;
end% generate params.max_rand cndidate feature
% anglepairs samplerandfeat(params.max_numfeat);
% radiuspairs [rand([params.max_numfeat, 1]) rand([params.max_numfeat, 1])];
[radiuspairs, anglepairs] getproposals(params.max_numfeats(stage), params.radius, params.angles);angles_cos cos(anglepairs);
angles_sin sin(anglepairs);% extract pixel difference features from pairspdfeats zeros(params.max_numfeats(stage), length(ind_samples)); %所有的样本均要提取相应阶段的像素差特征即比如说1000*541shapes_residual zeros(length(ind_samples), 2);for i 1:length(ind_samples)s floor((ind_samples(i)-1)/(params.augnumber)) 1; %共用样本的序号k mod(ind_samples(i)-1, (params.augnumber)) 1; %不能共用盒子而是对于同一张图片的不同shape使用各自的盒子使用余运算显然小于params.augnumber又加1所以答案从1params.augnumber% calculate the relative location under the coordinate of meanshape %x1angles_cos(:, 1)).*radiuspairs(:, 1)pixel_a_x_imgcoord (angles_cos(:, 1)).*radiuspairs(:, 1)*params.max_raio_radius(stage)*Tr_Data{s}.intermediate_bboxes{stage}(k, 3);pixel_a_y_imgcoord (angles_sin(:, 1)).*radiuspairs(:, 1)*params.max_raio_radius(stage)*Tr_Data{s}.intermediate_bboxes{stage}(k, 4);pixel_b_x_imgcoord (angles_cos(:, 2)).*radiuspairs(:, 2)*params.max_raio_radius(stage)*Tr_Data{s}.intermediate_bboxes{stage}(k, 3);pixel_b_y_imgcoord (angles_sin(:, 2)).*radiuspairs(:, 2)*params.max_raio_radius(stage)*Tr_Data{s}.intermediate_bboxes{stage}(k, 4);% no transformation%{pixel_a_x_lmcoord pixel_a_x_imgcoord;pixel_a_y_lmcoord pixel_a_y_imgcoord;pixel_b_x_lmcoord pixel_b_x_imgcoord;pixel_b_y_lmcoord pixel_b_y_imgcoord;%}% transform the pixels from image coordinate (meanshape) to coordinate of current shape%以下计算出的都是中心化的坐标[pixel_a_x_lmcoord, pixel_a_y_lmcoord] transformPointsForward(Tr_Data{s}.meanshape2tf{k}, pixel_a_x_imgcoord, pixel_a_y_imgcoord); pixel_a_x_lmcoord pixel_a_x_lmcoord;pixel_a_y_lmcoord pixel_a_y_lmcoord;[pixel_b_x_lmcoord, pixel_b_y_lmcoord] transformPointsForward(Tr_Data{s}.meanshape2tf{k}, pixel_b_x_imgcoord, pixel_b_y_imgcoord);pixel_b_x_lmcoord pixel_b_x_lmcoord;pixel_b_y_lmcoord pixel_b_y_lmcoord; %转化为绝对坐标pixel_a_x int32(bsxfun(plus, pixel_a_x_lmcoord, Tr_Data{s}.intermediate_shapes{stage}(lmarkID, 1, k)));pixel_a_y int32(bsxfun(plus, pixel_a_y_lmcoord, Tr_Data{s}.intermediate_shapes{stage}(lmarkID, 2, k)));pixel_b_x int32(bsxfun(plus, pixel_b_x_lmcoord, Tr_Data{s}.intermediate_shapes{stage}(lmarkID, 1, k)));pixel_b_y int32(bsxfun(plus, pixel_b_y_lmcoord, Tr_Data{s}.intermediate_shapes{stage}(lmarkID, 2, k)));width (Tr_Data{s}.width);height (Tr_Data{s}.height);pixel_a_x max(1, min(pixel_a_x, width)); %意思是 pixel_a_x应该介于1和width之间pixel_a_y max(1, min(pixel_a_y, height));pixel_b_x max(1, min(pixel_b_x, width));pixel_b_y max(1, min(pixel_b_y, height));%取像素两种方法一是img_gray(i,j)二是img_gray(k)k是按列数第k个元素pdfeats(:, i) double(Tr_Data{s}.img_gray(pixel_a_y (pixel_a_x-1)*height)) - double(Tr_Data{s}.img_gray(pixel_b_y (pixel_b_x-1)*height));%./ double(Tr_Data{s}.img_gray(pixel_a_y (pixel_a_x-1)*height)) double(Tr_Data{s}.img_gray(pixel_b_y (pixel_b_x-1)*height));% drawshapes(Tr_Data{s}.img_gray, [pixel_a_x pixel_a_y pixel_b_x pixel_b_y]);% hold off;shapes_residual(i, :) Tr_Data{s}.shapes_residual(lmarkID, :, k);
endE_x_2 mean(shapes_residual(:, 1).^2);
E_x mean(shapes_residual(:, 1));E_y_2 mean(shapes_residual(:, 2).^2);
E_y mean(shapes_residual(:, 2));
% 整体方差其中使用了方差的经典公式DxEx^2-(Ex)^2
var_overall length(ind_samples)*((E_x_2 - E_x^2) (E_y_2 - E_y^2));% var_overall length(ind_samples)*(var(shapes_residual(:, 1)) var(shapes_residual(:, 2)));% max_step min(length(ind_samples), params.max_numthreshs);
% step floor(length(ind_samples)/max_step);
max_step 1;var_reductions zeros(params.max_numfeats(stage), max_step);
thresholds zeros(params.max_numfeats(stage), max_step);[pdfeats_sorted] sort(pdfeats, 2); %将数据打乱顺序防止过拟合% shapes_residual shapes_residual(ind, :);for i 1:params.max_numfeats(stage) %暴力选举法选出最合适的feature% for t 1:max_stept 1;ind ceil(length(ind_samples)*(0.5 0.9*(rand(1) - 0.5)));threshold pdfeats_sorted(i, ind); % pdfeats_sorted(i, t*step); % thresholds(i, t) threshold;ind_lc (pdfeats(i, :) threshold); %逻辑数组ind_rc (pdfeats(i, :) threshold);% figure, hold on, plot(shapes_residual(ind_lc, 1), shapes_residual(ind_lc, 2), r.)% plot(shapes_residual(ind_rc, 1), shapes_residual(ind_rc, 2), g.)% close;% compute E_x_2_lc mean(shapes_residual(ind_lc, 1).^2); %选出逻辑数组中为1的那些残差E_x_lc mean(shapes_residual(ind_lc, 1));E_y_2_lc mean(shapes_residual(ind_lc, 2).^2);E_y_lc mean(shapes_residual(ind_lc, 2));var_lc (E_x_2_lc E_y_2_lc)- (E_x_lc^2 E_y_lc^2);E_x_2_rc (E_x_2*length(ind_samples) - E_x_2_lc*sum(ind_lc))/sum(ind_rc);E_x_rc (E_x*length(ind_samples) - E_x_lc*sum(ind_lc))/sum(ind_rc);E_y_2_rc (E_y_2*length(ind_samples) - E_y_2_lc*sum(ind_lc))/sum(ind_rc);E_y_rc (E_y*length(ind_samples) - E_y_lc*sum(ind_lc))/sum(ind_rc);var_rc (E_x_2_rc E_y_2_rc)- (E_x_rc^2 E_y_rc^2);var_reduce var_overall - sum(ind_lc)*var_lc - sum(ind_rc)*var_rc;% var_reduce var_overall - sum(ind_lc)*(var(shapes_residual(ind_lc, 1)) var(shapes_residual(ind_lc, 2))) - sum(ind_rc)*(var(shapes_residual(ind_rc, 1)) var(shapes_residual(ind_rc, 2)));var_reductions(i, t) var_reduce;% end% plot(var_reductions(i, :));
end[~, ind_colmax] max(var_reductions);%寻找最大差的序号
ind_max 1;%{
if var_max 0isvalid 0;
elseisvalid 1;
end
%}
isvalid 1;thresh thresholds(ind_colmax(ind_max), ind_max); %当前阈值feat [anglepairs(ind_colmax(ind_max), :) radiuspairs(ind_colmax(ind_max), :)];lcind ind_samples(find(pdfeats(ind_colmax(ind_max), :) thresh));
rcind ind_samples(find(pdfeats(ind_colmax(ind_max), :) thresh));end
问题训练时默认一旦可以分割节点则必然分割成两部分。那么会不会出现选取一个阈值将剩余的样本都归于一类呢 说明: 如图所示外面有一个current 坐标系里面有mean_shape的中心化归一化的坐标。最里面是以一个特征点为中心取的极坐标。这份代码取rr,θ\theta来标注在特征点附近取到的任意两个像素点的坐标.可以说有三个坐标系按前面顺序分别称为坐标系一、二、三。里面两个坐标系的尺寸一样但是坐标原点不一样。
假定在坐标系三下取到一像素点坐标为x,y而特征点在坐标系二的坐标为x0,y0x_0,y_0,则像素点在坐标系二的坐标为(x˜,y˜\widetilde{x},\widetilde{y}),则有:
(x˜,y˜)(x,y)(x0,y0)(\widetilde{x},\widetilde{y})=(x,y)+(x_0,y_0). 又由前面一篇文章
《face alignment by 3000 fps系列学习总结二》中间进行的相似性变换我们知道将当前坐标由mean_shape的归一化中心化坐标转换为current_shape的中心化坐标需要使用meanshape2tf变换。 即 (x˜,y˜)/cR
(\widetilde{x},\widetilde{y})/cR 进一步的取中心化后得 (x˜,y˜)/cRmean(immediateshape)(x,y)(x0,y0)cRmean(immediateshape)(x,y)cR(x0,y0)cRmean(immediateshape)(x,y)cRimmediate_shape_at(x0,y0)\begin{align*}
(\widetilde{x},\widetilde{y})/cR +mean(immediate_shape) cRc˜R˜/immediate_bbox
cR=\widetilde{c}\widetilde{R}/immediate\_bbox 所以上式(x,y)∗immediate_bbox/{c˜R˜}immediate_shape_at(x0,y0)(x,y)*immediate\_bbox/\{\widetilde{c}\widetilde{R}\}+immediate\_shape\_at(x_0,y_0) 最后一句就解析清了代码的步骤% calculate the relative location under the coordinate of meanshape %x1angles_cos(:, 1)).*radiuspairs(:, 1)pixel_a_x_imgcoord (angles_cos(:, 1)).*radiuspairs(:, 1)*params.max_raio_radius(stage)*Tr_Data{s}.intermediate_bboxes{stage}(k, 3);pixel_a_y_imgcoord (angles_sin(:, 1)).*radiuspairs(:, 1)*params.max_raio_radius(stage)*Tr_Data{s}.intermediate_bboxes{stage}(k, 4);pixel_b_x_imgcoord (angles_cos(:, 2)).*radiuspairs(:, 2)*params.max_raio_radius(stage)*Tr_Data{s}.intermediate_bboxes{stage}(k, 3);pixel_b_y_imgcoord (angles_sin(:, 2)).*radiuspairs(:, 2)*params.max_raio_radius(stage)*Tr_Data{s}.intermediate_bboxes{stage}(k, 4);% no transformation%{pixel_a_x_lmcoord pixel_a_x_imgcoord;pixel_a_y_lmcoord pixel_a_y_imgcoord;pixel_b_x_lmcoord pixel_b_x_imgcoord;pixel_b_y_lmcoord pixel_b_y_imgcoord;%}% transform the pixels from image coordinate (meanshape) to coordinate of current shape%以下计算出的都是中心化的坐标[pixel_a_x_lmcoord, pixel_a_y_lmcoord] transformPointsForward(Tr_Data{s}.meanshape2tf{k}, pixel_a_x_imgcoord, pixel_a_y_imgcoord); pixel_a_x_lmcoord pixel_a_x_lmcoord;pixel_a_y_lmcoord pixel_a_y_lmcoord;[pixel_b_x_lmcoord, pixel_b_y_lmcoord] transformPointsForward(Tr_Data{s}.meanshape2tf{k}, pixel_b_x_imgcoord, pixel_b_y_imgcoord);pixel_b_x_lmcoord pixel_b_x_lmcoord;pixel_b_y_lmcoord pixel_b_y_lmcoord; %转化为绝对坐标pixel_a_x int32(bsxfun(plus, pixel_a_x_lmcoord, Tr_Data{s}.intermediate_shapes{stage}(lmarkID, 1, k)));pixel_a_y int32(bsxfun(plus, pixel_a_y_lmcoord, Tr_Data{s}.intermediate_shapes{stage}(lmarkID, 2, k)));pixel_b_x int32(bsxfun(plus, pixel_b_x_lmcoord, Tr_Data{s}.intermediate_shapes{stage}(lmarkID, 1, k)));pixel_b_y int32(bsxfun(plus, pixel_b_y_lmcoord, Tr_Data{s}.intermediate_shapes{stage}(lmarkID, 2, k)));width (Tr_Data{s}.width);height (Tr_Data{s}.height);pixel_a_x max(1, min(pixel_a_x, width)); %意思是 pixel_a_x应该介于1和width之间pixel_a_y max(1, min(pixel_a_y, height));pixel_b_x max(1, min(pixel_b_x, width));pixel_b_y max(1, min(pixel_b_y, height));%取像素两种方法一是img_gray(i,j)二是img_gray(k)k是按列数第k个元素pdfeats(:, i) double(Tr_Data{s}.img_gray(pixel_a_y (pixel_a_x-1)*height)) - double(Tr_Data{s}.img_gray(pixel_b_y (pixel_b_x-1)*height));
如此我们训练全程就搞懂了。