Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

写一点我在使用代码训练时遇到的问题以及解决办法,仅供参考 #23

Open
MikeMegamind opened this issue Jun 7, 2021 · 3 comments

Comments

@MikeMegamind
Copy link

MikeMegamind commented Jun 7, 2021

首先非常感谢cuixing大佬提供的代码,让我等新手不用费心去写相关程序。但是在运行程序的时候我遇到了一些问题,也对原代码做了些修改,在此提供一些我的见解,不一定准确,仅供参考
matlab官方yolov3教程地址:https://ww2.mathworks.cn/help/deeplearning/ug/object-detection-using-yolo-v3-deep-learning.html?searchHighlight=Object%20Detection%20Using%20YOLO%20v3%20Deep%20Learning&s_tid=srchtitle
我先用的官方提供的教程做的训练,发现效果不是很好,而且官方提供的YOLOv3网络结构不是常规的yolov3网络结构,所以我之后又跟着cuixing大佬的代码做。以下部分见解会参考到matlab官方教程。

1.数据集中的边界框要是整数,且最好进行validateInputData检验(参考官方提供的教程,需要数据全为正整数,且边界框不超过图片边界)

2.如果有灰度图,则要转RGB,否则后面会报维度不匹配的错。我在preprocessTrainData.m中添加了如下代码:
if (ndims(I)==2) %如果I(输入图像为单通道)
I=cat(3,I,I,I);
end

3.cuixing大佬给的代码中的网络构建部分用的是yolov3tiny,所以想用YOLOv3网络结构的话就要参考YOLOv3tiny的代码做一些修改
anchorBoxes(:,[2,1]) = anchorBoxes(:,[1,2]);% anchorBoxes现在是宽高,与darknet官网保持一致
imageSize = lgModel.Layers(1).InputSize(1:2);
arc = 'default';
yoloModule1 = [convolution2dLayer(1,length(anchorBoxMasks{1})(5+numClasses),'Name','yoloconv1');
yolov3Layer('yolov3layer1',anchorBoxes(anchorBoxMasks{1},:),numClasses,1,imageSize,arc)];
yoloModule2 = [convolution2dLayer(1,length(anchorBoxMasks{2})
(5+numClasses),'Name','yoloconv2');
yolov3Layer('yolov3layer2',anchorBoxes(anchorBoxMasks{2},:),numClasses,2,imageSize,arc)];
yoloModule3 = [convolution2dLayer(1,length(anchorBoxMasks{3})*(5+numClasses),'Name','yoloconv3');
yolov3Layer('yolov3layer3',anchorBoxes(anchorBoxMasks{3},:),numClasses,3,imageSize,arc)];
lgModel = removeLayers(lgModel,{'yolo_v3_id1','yolo_v3_id2','yolo_v3_id3'});
lgModel = replaceLayer(lgModel,'conv_83',yoloModule1);
lgModel = replaceLayer(lgModel,'conv_95',yoloModule2);
lgModel = replaceLayer(lgModel,'conv_107',yoloModule3);
analyzeNetwork(lgModel);
yoloLayerNumber = [200,226,252];% 注意!!!!!yolov3或者yolov4层在layers数组中的位置,看模型图得出!!!!!
model = dlnetwork(lgModel);

4..[gradients,loss,state] = dlfeval(@modelGradients, model, XTrain, YTrain,yoloLayerNumber)这一步报错,我找到了这个原因:
在function [gradients, totalLoss, state] = modelGradients(net, XTrain, YTrain,yoloLayerNumber)函数中,有这样几行代码:
for idx = 1:N
tcls
(idx,tcls+1) = 1.0;% 确保类别标签是从0开始标注的索引,否则这里会超出维度
end_
这行会因为tcls_的维数可能和类别数不一致,导致后面的clsLoss = clsLoss + crossentropy(sigmoid(featuresCh(:,6:end)),tcls_, 'DataFormat', 'BC','TargetCategories','independent');出错。
我的修改办法是:
在这几行代码之前添加:
widthf=width(featuresCh(:,6:end));
for idx = 1:N
tcls
(idx,1:widthf) = 0;
end_

以及将上面所说的代码修改为:
for idx = 1:N
tcls
(idx,unique(tcls)+1) = 1.0;
end_

这种修改方式我不能确保一定是正确的,但是就我的情况来看,确实解决了报错的问题。

5.训练部分的代码是这样写的:
[gradients,loss,state] = dlfeval(@modelGradients, model, XTrain, YTrain,yoloLayerNumber);
% Apply L2 regularization.
gradients = dlupdate(@(g,w) g + l2Regularization*w, gradients, model.Learnables);
% Update the network learnable parameters using the SGDM optimizer.
[model, velocity] = sgdmupdate(model, gradients, velocity, learningRate);

参数learningRate是没有变化的,我参考matlab官网的代码做了如下修改,增加了学习率的变化:
[gradients,loss,state] = dlfeval(@modelGradients, model, XTrain, YTrain,yoloLayerNumber); % Apply L2 regularization.
gradients = dlupdate(@(g,w) g + l2Regularization*w, gradients, model.Learnables);
%2021.6.1修改 增加学习率变化
% Determine the current learning rate value.
currentLR = piecewiseLearningRateWithWarmup(allIteration, numEpoch, learningRate, warmupPeriod, nEpochs);

% Update the network learnable parameters using the SGDM optimizer.
**[model, velocity] = sgdmupdate(model, gradients, velocity, currentLR);
**

暂时先写到这里,如果后面有补充再写吧。以上说明仅供参考。

@MikeMegamind
Copy link
Author

补充说明:我的训练完成之后,效果很不理想,一幅图片拿去检测,上面密密麻麻全是检测框。我推测可能是发生过拟合了,也可能是我对程序做的修改不太对。关于过拟合,我不知道怎么在训练过程中增加验证集。可能没办法了

@yangchengjian-bit
Copy link

您好,我训练自己数据集的时候提示这个错误:

错误使用 dlfeval (第 44 行)
预测参数和目标值参数的大小必须匹配。

出错 train (第 120 行)
        [gradients,loss,state] = dlfeval(@modelGradients, model, XTrain, YTrain,yoloLayerNumber);

请问您知道如何修改吗,或者您手头还有源码方便发我一下吗,麻烦您了,或者您上传git我自行下载可以吗,这个问题我挺久了解决不了。。。谢谢您

@havefunheehee
Copy link

相同请求代码,谢谢您!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants