├── save
└── README.md
├── weights
└── readme.md
├── demo.mlx
├── images
├── dog.jpg
├── giraffe.jpg
├── mynet.png
├── person.jpg
├── yolov4.jpg
├── lgraphLayer.png
├── lgraphWeight.png
├── rec_result.png
├── yolov4Detect.jpg
├── dogYolov4Detect.jpg
├── importerExporter.png
├── importDarknetLayers.png
├── importDarknetNetwork.png
└── importDarknetWeights.png
├── .gitignore
├── utils
├── getClasses.m
├── preprocessTrainData.m
├── getGIOU.m
├── yolov3v4Predict.m
├── importDarknetNetwork.m
├── importDarknetWeights.m
├── exportDarkNetNetwork.m
├── importDarkNetLayers.m
└── synset_words.txt
├── CustomLayers
├── mycheckLayer.m
├── empty2dLayer.m
├── mishLayer.m
├── upsample2dLayer.m
├── sliceLayer.m
├── prnAdditionLayer.m
└── yolov3Layer.m
├── coco.names
├── README.md
├── detect.m
├── cfg
├── yolov3-tiny.cfg
├── yolov3-tiny-prn.cfg
├── darknet19.cfg
├── yolov4-tiny.cfg
├── mobilenetv2.cfg
├── yolov3.cfg
├── yolov4.cfg
└── matlabExportYoloV4.cfg
└── train.m
/save/README.md:
--------------------------------------------------------------------------------
1 | 此目录保存的checkpoint模型
2 |
--------------------------------------------------------------------------------
/weights/readme.md:
--------------------------------------------------------------------------------
1 | 此处存放darknet模型权重文件 “*.weights”
--------------------------------------------------------------------------------
/demo.mlx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cuixing158/yolov3-yolov4-matlab/HEAD/demo.mlx
--------------------------------------------------------------------------------
/images/dog.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cuixing158/yolov3-yolov4-matlab/HEAD/images/dog.jpg
--------------------------------------------------------------------------------
/images/giraffe.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cuixing158/yolov3-yolov4-matlab/HEAD/images/giraffe.jpg
--------------------------------------------------------------------------------
/images/mynet.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cuixing158/yolov3-yolov4-matlab/HEAD/images/mynet.png
--------------------------------------------------------------------------------
/images/person.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cuixing158/yolov3-yolov4-matlab/HEAD/images/person.jpg
--------------------------------------------------------------------------------
/images/yolov4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cuixing158/yolov3-yolov4-matlab/HEAD/images/yolov4.jpg
--------------------------------------------------------------------------------
/images/lgraphLayer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cuixing158/yolov3-yolov4-matlab/HEAD/images/lgraphLayer.png
--------------------------------------------------------------------------------
/images/lgraphWeight.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cuixing158/yolov3-yolov4-matlab/HEAD/images/lgraphWeight.png
--------------------------------------------------------------------------------
/images/rec_result.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cuixing158/yolov3-yolov4-matlab/HEAD/images/rec_result.png
--------------------------------------------------------------------------------
/images/yolov4Detect.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cuixing158/yolov3-yolov4-matlab/HEAD/images/yolov4Detect.jpg
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.mat
2 | *.jpg
3 | *.png
4 | *.pdf
5 | *.asv
6 | *.weights
7 |
8 | !images/*.jpg
9 | !images/*.png
--------------------------------------------------------------------------------
/images/dogYolov4Detect.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cuixing158/yolov3-yolov4-matlab/HEAD/images/dogYolov4Detect.jpg
--------------------------------------------------------------------------------
/images/importerExporter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cuixing158/yolov3-yolov4-matlab/HEAD/images/importerExporter.png
--------------------------------------------------------------------------------
/images/importDarknetLayers.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cuixing158/yolov3-yolov4-matlab/HEAD/images/importDarknetLayers.png
--------------------------------------------------------------------------------
/images/importDarknetNetwork.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cuixing158/yolov3-yolov4-matlab/HEAD/images/importDarknetNetwork.png
--------------------------------------------------------------------------------
/images/importDarknetWeights.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cuixing158/yolov3-yolov4-matlab/HEAD/images/importDarknetWeights.png
--------------------------------------------------------------------------------
/utils/getClasses.m:
--------------------------------------------------------------------------------
1 | function classes = getClasses(labelsPath)
2 | fid = fopen(labelsPath,'r');
3 | s = textscan(fid,'%s', 'Delimiter',{' '});
4 | s = s{1};
5 | % classes =cellfun(@(x)x(11:end),s,'UniformOutput',false);
6 | classes = s;
7 | fclose(fid);
--------------------------------------------------------------------------------
/CustomLayers/mycheckLayer.m:
--------------------------------------------------------------------------------
1 | validInputSize = [3,3,18,1];
2 | layer = yolov3Layer('yolov3', rand(3,2),1,1,[416,416],'default');
3 | checkLayer(layer,validInputSize,'ObservationDimension' ,4)
4 |
5 | %%
6 | layer = mishLayer('mishACT');
7 | validInputSize = [24 24 20];
8 | checkLayer(layer,validInputSize,'ObservationDimension',4)
9 |
10 |
11 |
--------------------------------------------------------------------------------
/CustomLayers/empty2dLayer.m:
--------------------------------------------------------------------------------
1 | classdef empty2dLayer < nnet.layer.Layer
2 | % 主要想用于导入yolov3中route层的单个跳层连接
3 | % 2019.9.8
4 | % 2020.4.29加入属性connectID,用于连接前面的层
5 | properties
6 | connectID %connectID 是以cfg文件中第一个非[net]开始的module为0开始的计数
7 | end
8 |
9 | methods
10 | function layer = empty2dLayer(name,con)
11 | layer.Name = name;
12 | text = ['[', num2str(1), ' ', num2str(1), '] emptyLayer '];
13 | layer.Description = text;
14 | layer.Type = 'empty2dLayer';
15 | layer.connectID= con;
16 | end
17 |
18 | function Z = predict(layer, X)
19 | Z = X;
20 | end
21 |
22 | function [dX] = backward( layer, X, ~, dZ, ~ )
23 | dX = dZ;
24 | end
25 | end
26 | end
27 | %%
28 | % 参考:https://ww2.mathworks.cn/matlabcentral/fileexchange/71277-deep-learning-darknet-importer
--------------------------------------------------------------------------------
/CustomLayers/mishLayer.m:
--------------------------------------------------------------------------------
1 | classdef mishLayer < nnet.layer.Layer
2 | % custom MishLayer layer.激活函数优于relu
3 | % 参考:https://arxiv.org/abs/1908.08681
4 | % 《Mish: A Self Regularized Non-Monotonic Neural Activation Function》
5 | % cuixingxing150@gmail.com
6 | % 2020.4.29
7 | %
8 | properties
9 |
10 | end
11 |
12 | methods
13 | function layer = mishLayer(name)
14 | % Set layer name.
15 | layer.Name = name;
16 |
17 | % Set layer description.
18 | layer.Description = "mishLayer activation layer";
19 |
20 | layer.Type = 'mishLayer';
21 | end
22 |
23 | function Z = predict(~, X)
24 | % Z = predict(layer, X) forwards the input data X through the
25 | % layer and outputs the result Z.
26 | Z = X.*tanh(log(1+exp(X)));
27 | end
28 | end
29 | end
--------------------------------------------------------------------------------
/CustomLayers/upsample2dLayer.m:
--------------------------------------------------------------------------------
1 | classdef upsample2dLayer < nnet.layer.Layer
2 | properties
3 | size % 标量,一般为2
4 | end
5 |
6 | methods
7 | function layer = upsample2dLayer(name, size)
8 | layer.Name = name;
9 | text = ['[', num2str(size), ' ', num2str(size), '] upsampling for YOLOv3'];
10 | layer.Description = text;
11 | layer.Type = 'upsample2dLayer';
12 | layer.size = size;
13 | end
14 |
15 | function Z = predict(layer, X)
16 | Z = repelem(X, layer.size, layer.size);
17 | end
18 |
19 | function [dX] = backward( layer, X, ~, dZ, ~ )
20 | dX = dZ(1:layer.size:end, 1:layer.size:end, :, :);
21 | end
22 | end
23 | end
24 | %%
25 | % 参考:https://ww2.mathworks.cn/matlabcentral/fileexchange/71277-deep-learning-darknet-importer
26 | % 官方文档:Define Custom Deep Learning Layers
27 |
--------------------------------------------------------------------------------
/coco.names:
--------------------------------------------------------------------------------
1 | person
2 | bicycle
3 | car
4 | motorbike
5 | aeroplane
6 | bus
7 | train
8 | truck
9 | boat
10 | traffic light
11 | fire hydrant
12 | stop sign
13 | parking meter
14 | bench
15 | bird
16 | cat
17 | dog
18 | horse
19 | sheep
20 | cow
21 | elephant
22 | bear
23 | zebra
24 | giraffe
25 | backpack
26 | umbrella
27 | handbag
28 | tie
29 | suitcase
30 | frisbee
31 | skis
32 | snowboard
33 | sports ball
34 | kite
35 | baseball bat
36 | baseball glove
37 | skateboard
38 | surfboard
39 | tennis racket
40 | bottle
41 | wine glass
42 | cup
43 | fork
44 | knife
45 | spoon
46 | bowl
47 | banana
48 | apple
49 | sandwich
50 | orange
51 | broccoli
52 | carrot
53 | hot dog
54 | pizza
55 | donut
56 | cake
57 | chair
58 | sofa
59 | pottedplant
60 | bed
61 | diningtable
62 | toilet
63 | tvmonitor
64 | laptop
65 | mouse
66 | remote
67 | keyboard
68 | cell phone
69 | microwave
70 | oven
71 | toaster
72 | sink
73 | refrigerator
74 | book
75 | clock
76 | vase
77 | scissors
78 | teddy bear
79 | hair drier
80 | toothbrush
81 |
--------------------------------------------------------------------------------
/CustomLayers/sliceLayer.m:
--------------------------------------------------------------------------------
1 | classdef sliceLayer < nnet.layer.Layer
2 | % 对应于yolov4-tiny.cfg中的route的group层,用于通道分组
3 | % https://github.com/AlexeyAB/darknet
4 | %
5 | % cuixingxing150@gmail.com
6 | % 2020.6.29
7 | properties
8 | connectID %connectID 是以cfg文件中第一个非[net]开始的module为0开始的计数,用于用于连接前面的层,目的方便exportDarkNetwork函数使用
9 | groups % 与cfg中的route的group一致
10 | group_id % 与cfg中的route的group_id一致,group_id在cfg中是从0开始的索引,matlab中为从1开始
11 | end
12 |
13 | methods
14 | function layer = sliceLayer(name,con,groups,group_id)
15 | layer.Name = name;
16 | text = [ num2str(groups), ' groups,group_id: ', num2str(group_id), ' sliceLayer '];
17 | layer.Description = text;
18 | layer.Type = 'sliceLayer';
19 | layer.connectID= con;
20 | layer.groups= groups;
21 | layer.group_id= group_id;
22 | assert(group_id>0,'group_id must great zero! it must start index from 1');
23 | end
24 |
25 | function Z = predict(layer, X) %输出Z保证是4维
26 | X = reshape(X,[size(X),1]);
27 | channels = size(X,3);
28 | deltaChannels = channels/layer.groups;
29 | selectStart = (layer.group_id-1)*deltaChannels+1;
30 | selectEnd = layer.group_id*deltaChannels;
31 | Z = X(:,:,selectStart:selectEnd,:);
32 | end
33 | end
34 | end
35 |
--------------------------------------------------------------------------------
/utils/preprocessTrainData.m:
--------------------------------------------------------------------------------
1 | function out = preprocessTrainData(data,networkInputSize,structNamesIDs)
2 | % 功能:对输入数据图像进行预处理,大小一致,加入bbox标签
3 | % 输入:
4 | % data:bs*3大小的cell array,第一列cell存储图像,第二列cell存储[x,y,w,h],第三列cell存储classID
5 | % networkInputSize:输入网络统一大小,[height,width]
6 | % structNamesIDs: 结构体,类别映射到数字ID
7 | % 输出:
8 | % out:table类型,1*2大小,第一个为图像数据,第二个为bbox label,形式为[x,y,w,h,classID]
9 | %
10 | % email:cuixingxing150@gmail.com
11 | % 2020.4.22
12 | %
13 |
14 | nums = size(data,1);% batchSize大小
15 | XTrain = zeros([networkInputSize,nums],'single');
16 | YTrain = cell(nums,1);% 每个值存储label,x,y,w,h,classID
17 |
18 | invalidBboxInd = [];% bbox is invalid and will not be considered in the training set!
19 | for ii = 1:nums
20 | I = data{ii,1};
21 | imgSize = size(I);
22 |
23 | % Convert an input image with single channel to 3 channels.
24 | if numel(imgSize) == 1
25 | I = repmat(I,1,1,3);
26 | end
27 | bboxes = data{ii,2};
28 | I = im2single(imresize(I,networkInputSize(1:2)));
29 | scale = networkInputSize(1:2)./imgSize(1:2);
30 |
31 | try
32 | bboxes = bboxresize(bboxes,scale);
33 | catch
34 | invalidBboxInd = [invalidBboxInd;ii];
35 | end
36 |
37 | % bbox label
38 | idxs = zeros(size(bboxes,1),1);
39 | for jj = 1:size(bboxes,1)
40 | labels = string(data{ii,3});
41 | idxs(jj) = structNamesIDs.(labels(jj));
42 | end
43 |
44 | XTrain(:,:,:,ii) = I;
45 | YTrain{ii} = [bboxes,idxs];
46 | end
47 |
48 | % remove invalid bbox and label
49 | XTrain(:,:,:,invalidBboxInd) = [];
50 | YTrain(invalidBboxInd) = [];
51 |
52 | out = table({XTrain},{YTrain});
53 | end
--------------------------------------------------------------------------------
/CustomLayers/prnAdditionLayer.m:
--------------------------------------------------------------------------------
1 | classdef prnAdditionLayer < nnet.layer.Layer
2 | % 对应于yolov3-tiny-prn.cfg中的shortcut层,通道部分相加
3 | % https://github.com/WongKinYiu/PartialResidualNetworks
4 | %
5 | % cuixingxing150@gmail.com
6 | % 2020.6.29
7 | methods
8 | function layer = prnAdditionLayer(numInputs,name)
9 | % layer = prnAdditionLayer(numInputs,name) creates a
10 | % prn addition layer and specifies the number of inputs
11 | % and the layer name.
12 |
13 | % Set number of inputs.
14 | layer.NumInputs = numInputs;
15 |
16 | % Set layer name.
17 | layer.Name = name;
18 |
19 | % Set layer description.
20 | layer.Description = "Prn addition of " + numInputs + ...
21 | " inputs";
22 | end
23 |
24 | function Z = predict(layer, varargin)
25 | % Z = predict(layer, X1, ..., Xn) forwards the input data X1,
26 | % ..., Xn through the layer and outputs the result Z.
27 | X = varargin;
28 |
29 | % Initialize output
30 | [minChannels,ind] = min(cellfun(@(x)min(size(x,3)),X));
31 | X1 = X{1};
32 | [h,w,~,n] = size(X1);
33 | Z = zeros([h,w,minChannels,n],'like',X1);
34 |
35 | % prn addition
36 | for i = 1:layer.NumInputs
37 | item = X{i};
38 | if i ~= ind
39 | startInd = 1;
40 | endInd = minChannels;
41 | item = item(:,:,startInd:endInd,:);
42 | end
43 | Z = Z + item;
44 | end
45 | end
46 | end
47 | end
48 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | This repo has been deprecated. Please see [MATLAB Deep Learning Model Hub](https://github.com/matlab-deep-learning/MATLAB-Deep-Learning-Model-Hub), which includes an implementation of [YOLOV3/V4](https://github.com/matlab-deep-learning/MATLAB-Deep-Learning-Model-Hub#object-detection-).
2 | ---
3 |
4 | 
5 | 
6 | 
7 |
8 | # yoloV3/yolov4 matlab
9 | This respository uses simplified and minimal code to reproduce the yolov3 / yolov4 detection networks and darknet classification networks. The highlights are as follows:
10 | - Support original version of darknet model
11 | - Support training, inference, import and export of "* .cfg", "* .weights" models
12 | - Support the latest [yolov3, yolov4](https://github.com/AlexeyAB/darknet) models
13 | - Support darknet classification model
14 | - Support all kinds of indicators such as feature map size calculation, flops calculation and so on.
15 |
16 | ---
17 | 本库代码比pytorch和tensorflow等其他框架更具可读性和精简性!
18 | These code is highly readable and more brief than other frameworks such as pytorch and tensorflow!
19 | 但是不包含各种训练数据增强tricks!
20 | But it does not contain various training data augmentation tricks!
21 |
22 | # Requirements
23 | Matlab R2020a or higher,the newer the better,no other dependencies!!!
24 |
25 | # How to use
26 | 训练使用train.m,推理测试使用detect.m,demo.mlx
27 | 百度网盘yolov3/4,[weights文件](https://pan.baidu.com/s/1UvPKSlT7K3hzeXof4ovN_A) 提取码:dbbo
28 |
--------------------------------------------------------------------------------
/utils/getGIOU.m:
--------------------------------------------------------------------------------
1 | function [giouRatio,iouRatio] = getGIOU(bboxA,bboxB)
2 | % 功能:获取bboxA和bboxB之间的GIOU或IOU,两两组合计算GIOU值
3 | % 输入:
4 | % bboxA, M*4大小矩阵,形式为[x,y,w,h]
5 | % bboxB, N*4大小矩阵,形式为[x,y,w,h]
6 | % 输出:
7 | % giouRatio:M*N大小矩阵,每个元素的值表示所在的行列(i,j)分别表示来自bboxA,bboxB的第i,j个bbox的GIOU值
8 | % iouRatio:M*N大小矩阵,每个元素的值表示所在的行列(i,j)分别表示来自bboxA,bboxB的第i,j个bbox的IOU值
9 | %
10 | % 参考:1、https://arxiv.org/abs/1902.09630,CVPR2019,
11 | % 《Generalized Intersection over Union: A Metric and A Loss for Bounding Box Regression 》
12 | % https://zhuanlan.zhihu.com/p/57992040
13 | %
14 | % cuixingxing150@gmail.com
15 | % 2020.4.25
16 | %
17 | M = size(bboxA,1);
18 | N = size(bboxB,1);
19 | giouRatio = zeros(M,N,'like',bboxA);
20 | iouRatio = zeros(M,N,'like',bboxA);
21 |
22 | areasA = bboxA(:,3).*bboxA(:,4);
23 | areasB = bboxB(:,3).*bboxB(:,4);
24 | xyxyA = [bboxA(:,1:2),bboxA(:,1)+bboxA(:,3),bboxA(:,2)+bboxA(:,4)];
25 | xyxyB = [bboxB(:,1:2),bboxB(:,1)+bboxB(:,3),bboxB(:,2)+bboxB(:,4)];
26 |
27 | for i = 1:M
28 | for j = 1:N
29 | x1 = max(xyxyA(i,1),xyxyB(j,1));
30 | x2 = min(xyxyA(i,3),xyxyB(j,3));
31 | y1 = max(xyxyA(i,2),xyxyB(j,2));
32 | y2 = min(xyxyA(i,4),xyxyB(j,4));
33 | Intersection = max(0,(x2-x1)).*max(0,(y2-y1));
34 | Union = areasA(i)+areasB(j)-Intersection;
35 | iouRatio(i,j) = Intersection./Union;
36 |
37 | x1 = min(xyxyA(i,1),xyxyB(j,1));
38 | x2 = max(xyxyA(i,3),xyxyB(j,3));
39 | y1 = min(xyxyA(i,2),xyxyB(j,2));
40 | y2 = max(xyxyA(i,4),xyxyB(j,4));
41 | Convex = (x2-x1).*(y2-y1);
42 | giouRatio(i,j) = iouRatio(i,j) - (Convex-Union)./Convex;
43 | end
44 | end
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/detect.m:
--------------------------------------------------------------------------------
1 | %% custom input
2 | addpath('./CustomLayers/','./utils/')
3 | % clear all % 如果更换模型,需重置静态函数(影响性能),否则可以不用清理
4 | cfg_file = 'cfg/yolov4-tiny.cfg';
5 | weight_file = 'weights/yolov4-tiny.weights';
6 | throushold = 0.1;
7 | NMS = 0.4;
8 |
9 | %% import all classes
10 | fid = fopen('coco.names','r');
11 | names = textscan(fid, '%s', 'Delimiter',{' '});
12 | fclose(fid);classesNames = categorical(names{1});
13 | RGB = randi(255,length(classesNames),3);
14 |
15 | %% 摄像头视频流识别
16 | cap = webcam();
17 | player = vision.DeployableVideoPlayer();
18 | image = cap.snapshot();
19 | step(player, image);
20 |
21 | while player.isOpen()
22 | image = cap.snapshot();
23 | t1 = tic;
24 | outFeatures = yolov3v4Predict(cfg_file,weight_file,image);% M*(5+nc) ,为[x,y,w,h,Pobj,p1,p2,...,pn]
25 | fprintf('预测耗时:%.2f 秒\n',toc(t1));% yolov4大概0.4秒,yolov3大概0.2秒,yolov3-tiny大概0.06秒,yolov4-tiny大概0.07秒,yolov3-tiny-prn大概0.06秒
26 |
27 | %% 阈值过滤+NMS处理
28 | scores = outFeatures(:,5);
29 | outFeatures = outFeatures(scores>throushold,:);
30 |
31 | allBBoxes = outFeatures(:,1:4);
32 | allScores = outFeatures(:,5);
33 | [maxScores,indxs] = max(outFeatures(:,6:end),[],2);
34 | allScores = allScores.*maxScores;
35 | allLabels = classesNames(indxs);
36 |
37 | % NMS非极大值抑制
38 | if ~isempty(allBBoxes)
39 | [bboxes,scores,labels] = selectStrongestBboxMulticlass(allBBoxes,allScores,allLabels,...
40 | 'RatioType','Min','OverlapThreshold',NMS);
41 | annotations = string(labels) + ": " + string(scores);
42 | [~,ids] = ismember(labels,classesNames);
43 | colors = RGB(ids,:);
44 | image = insertObjectAnnotation(image,...
45 | 'rectangle',bboxes,cellstr(annotations),...
46 | 'Color',colors,...
47 | 'LineWidth',3);
48 | end
49 | step(player,image);
50 | end
51 | release(player);
52 |
53 |
54 |
55 |
--------------------------------------------------------------------------------
/cfg/yolov3-tiny.cfg:
--------------------------------------------------------------------------------
1 | [net]
2 | # Testing
3 | batch=1
4 | subdivisions=1
5 | # Training
6 | # batch=64
7 | # subdivisions=2
8 | width=416
9 | height=416
10 | channels=3
11 | momentum=0.9
12 | decay=0.0005
13 | angle=0
14 | saturation = 1.5
15 | exposure = 1.5
16 | hue=.1
17 |
18 | learning_rate=0.001
19 | burn_in=1000
20 | max_batches = 500200
21 | policy=steps
22 | steps=400000,450000
23 | scales=.1,.1
24 |
25 | [convolutional]
26 | batch_normalize=1
27 | filters=16
28 | size=3
29 | stride=1
30 | pad=1
31 | activation=leaky
32 |
33 | [maxpool]
34 | size=2
35 | stride=2
36 |
37 | [convolutional]
38 | batch_normalize=1
39 | filters=32
40 | size=3
41 | stride=1
42 | pad=1
43 | activation=leaky
44 |
45 | [maxpool]
46 | size=2
47 | stride=2
48 |
49 | [convolutional]
50 | batch_normalize=1
51 | filters=64
52 | size=3
53 | stride=1
54 | pad=1
55 | activation=leaky
56 |
57 | [maxpool]
58 | size=2
59 | stride=2
60 |
61 | [convolutional]
62 | batch_normalize=1
63 | filters=128
64 | size=3
65 | stride=1
66 | pad=1
67 | activation=leaky
68 |
69 | [maxpool]
70 | size=2
71 | stride=2
72 |
73 | [convolutional]
74 | batch_normalize=1
75 | filters=256
76 | size=3
77 | stride=1
78 | pad=1
79 | activation=leaky
80 |
81 | [maxpool]
82 | size=2
83 | stride=2
84 |
85 | [convolutional]
86 | batch_normalize=1
87 | filters=512
88 | size=3
89 | stride=1
90 | pad=1
91 | activation=leaky
92 |
93 | [maxpool]
94 | size=2
95 | stride=1
96 |
97 | [convolutional]
98 | batch_normalize=1
99 | filters=1024
100 | size=3
101 | stride=1
102 | pad=1
103 | activation=leaky
104 |
105 | ###########
106 |
107 | [convolutional]
108 | batch_normalize=1
109 | filters=256
110 | size=1
111 | stride=1
112 | pad=1
113 | activation=leaky
114 |
115 | [convolutional]
116 | batch_normalize=1
117 | filters=512
118 | size=3
119 | stride=1
120 | pad=1
121 | activation=leaky
122 |
123 | [convolutional]
124 | size=1
125 | stride=1
126 | pad=1
127 | filters=255
128 | activation=linear
129 |
130 |
131 |
132 | [yolo]
133 | mask = 3,4,5
134 | anchors = 10,14, 23,27, 37,58, 81,82, 135,169, 344,319
135 | classes=80
136 | num=6
137 | jitter=.3
138 | ignore_thresh = .7
139 | truth_thresh = 1
140 | random=1
141 |
142 | [route]
143 | layers = -4
144 |
145 | [convolutional]
146 | batch_normalize=1
147 | filters=128
148 | size=1
149 | stride=1
150 | pad=1
151 | activation=leaky
152 |
153 | [upsample]
154 | stride=2
155 |
156 | [route]
157 | layers = -1, 8
158 |
159 | [convolutional]
160 | batch_normalize=1
161 | filters=256
162 | size=3
163 | stride=1
164 | pad=1
165 | activation=leaky
166 |
167 | [convolutional]
168 | size=1
169 | stride=1
170 | pad=1
171 | filters=255
172 | activation=linear
173 |
174 | [yolo]
175 | mask = 0,1,2
176 | anchors = 10,14, 23,27, 37,58, 81,82, 135,169, 344,319
177 | classes=80
178 | num=6
179 | jitter=.3
180 | ignore_thresh = .7
181 | truth_thresh = 1
182 | random=1
183 |
--------------------------------------------------------------------------------
/cfg/yolov3-tiny-prn.cfg:
--------------------------------------------------------------------------------
1 | [net]
2 | # Testing
3 | batch=1
4 | subdivisions=1
5 | # Training
6 | #batch=64
7 | #subdivisions=8
8 | width=416
9 | height=416
10 | channels=3
11 | momentum=0.9
12 | decay=0.0005
13 | angle=0
14 | saturation = 1.5
15 | exposure = 1.5
16 | hue=.1
17 |
18 | learning_rate=0.001
19 | burn_in=1000
20 | max_batches = 500200
21 | policy=steps
22 | steps=400000,450000
23 | scales=.1,.1
24 |
25 | [convolutional]
26 | batch_normalize=1
27 | filters=16
28 | size=3
29 | stride=1
30 | pad=1
31 | activation=leaky
32 |
33 | [maxpool]
34 | size=2
35 | stride=2
36 |
37 | [convolutional]
38 | batch_normalize=1
39 | filters=32
40 | size=3
41 | stride=1
42 | pad=1
43 | activation=leaky
44 |
45 | [maxpool]
46 | size=2
47 | stride=2
48 |
49 | [convolutional]
50 | batch_normalize=1
51 | filters=64
52 | size=3
53 | stride=1
54 | pad=1
55 | activation=leaky
56 |
57 | [maxpool]
58 | size=2
59 | stride=2
60 |
61 | [convolutional]
62 | batch_normalize=1
63 | filters=128
64 | size=3
65 | stride=1
66 | pad=1
67 | activation=leaky
68 |
69 | [maxpool]
70 | size=2
71 | stride=2
72 |
73 | [convolutional]
74 | batch_normalize=1
75 | filters=256
76 | size=3
77 | stride=1
78 | pad=1
79 | activation=leaky
80 |
81 | [maxpool]
82 | size=2
83 | stride=2
84 |
85 | [convolutional]
86 | batch_normalize=1
87 | filters=512
88 | size=3
89 | stride=1
90 | pad=1
91 | activation=leaky
92 |
93 | [maxpool]
94 | size=2
95 | stride=1
96 |
97 | [convolutional]
98 | batch_normalize=1
99 | filters=512
100 | size=3
101 | stride=1
102 | pad=1
103 | activation=leaky
104 |
105 | [shortcut]
106 | activation=leaky
107 | from=-3
108 |
109 | ###########
110 |
111 | [convolutional]
112 | batch_normalize=1
113 | filters=256
114 | size=1
115 | stride=1
116 | pad=1
117 | activation=leaky
118 |
119 | [convolutional]
120 | batch_normalize=1
121 | filters=256
122 | size=3
123 | stride=1
124 | pad=1
125 | activation=leaky
126 |
127 | [shortcut]
128 | activation=leaky
129 | from=-2
130 |
131 | [convolutional]
132 | size=1
133 | stride=1
134 | pad=1
135 | filters=255
136 | activation=linear
137 |
138 |
139 |
140 | [yolo]
141 | mask = 3,4,5
142 | anchors = 10,14, 23,27, 37,58, 81,82, 135,169, 344,319
143 | classes=80
144 | num=6
145 | jitter=.3
146 | ignore_thresh = .7
147 | truth_thresh = 1
148 | random=1
149 |
150 | [route]
151 | layers = -4
152 |
153 | [convolutional]
154 | batch_normalize=1
155 | filters=128
156 | size=1
157 | stride=1
158 | pad=1
159 | activation=leaky
160 |
161 | [upsample]
162 | stride=2
163 |
164 | [shortcut]
165 | activation=leaky
166 | from=8
167 |
168 | [convolutional]
169 | batch_normalize=1
170 | filters=128
171 | size=3
172 | stride=1
173 | pad=1
174 | activation=leaky
175 |
176 | [shortcut]
177 | activation=leaky
178 | from=-3
179 |
180 | [shortcut]
181 | activation=leaky
182 | from=8
183 |
184 | [convolutional]
185 | size=1
186 | stride=1
187 | pad=1
188 | filters=255
189 | activation=linear
190 |
191 | [yolo]
192 | mask = 1,2,3
193 | anchors = 10,14, 23,27, 37,58, 81,82, 135,169, 344,319
194 | classes=80
195 | num=6
196 | jitter=.3
197 | ignore_thresh = .7
198 | truth_thresh = 1
199 | random=1
--------------------------------------------------------------------------------
/cfg/darknet19.cfg:
--------------------------------------------------------------------------------
1 | [net]
2 | # Training
3 | #batch=128
4 | #subdivisions=2
5 |
6 | # Testing
7 | batch=1
8 | subdivisions=1
9 |
10 | height=256
11 | width=256
12 | min_crop=128
13 | max_crop=448
14 | channels=3
15 | momentum=0.9
16 | decay=0.0005
17 |
18 | burn_in=1000
19 | learning_rate=0.1
20 | policy=poly
21 | power=4
22 | max_batches=800000
23 |
24 | angle=7
25 | hue=.1
26 | saturation=.75
27 | exposure=.75
28 | aspect=.75
29 |
30 | [convolutional]
31 | batch_normalize=1
32 | filters=32
33 | size=3
34 | stride=1
35 | pad=1
36 | activation=leaky
37 |
38 | [maxpool]
39 | size=2
40 | stride=2
41 |
42 | [convolutional]
43 | batch_normalize=1
44 | filters=64
45 | size=3
46 | stride=1
47 | pad=1
48 | activation=leaky
49 |
50 | [maxpool]
51 | size=2
52 | stride=2
53 |
54 | [convolutional]
55 | batch_normalize=1
56 | filters=128
57 | size=3
58 | stride=1
59 | pad=1
60 | activation=leaky
61 |
62 | [convolutional]
63 | batch_normalize=1
64 | filters=64
65 | size=1
66 | stride=1
67 | pad=1
68 | activation=leaky
69 |
70 | [convolutional]
71 | batch_normalize=1
72 | filters=128
73 | size=3
74 | stride=1
75 | pad=1
76 | activation=leaky
77 |
78 | [maxpool]
79 | size=2
80 | stride=2
81 |
82 | [convolutional]
83 | batch_normalize=1
84 | filters=256
85 | size=3
86 | stride=1
87 | pad=1
88 | activation=leaky
89 |
90 | [convolutional]
91 | batch_normalize=1
92 | filters=128
93 | size=1
94 | stride=1
95 | pad=1
96 | activation=leaky
97 |
98 | [convolutional]
99 | batch_normalize=1
100 | filters=256
101 | size=3
102 | stride=1
103 | pad=1
104 | activation=leaky
105 |
106 | [maxpool]
107 | size=2
108 | stride=2
109 |
110 | [convolutional]
111 | batch_normalize=1
112 | filters=512
113 | size=3
114 | stride=1
115 | pad=1
116 | activation=leaky
117 |
118 | [convolutional]
119 | batch_normalize=1
120 | filters=256
121 | size=1
122 | stride=1
123 | pad=1
124 | activation=leaky
125 |
126 | [convolutional]
127 | batch_normalize=1
128 | filters=512
129 | size=3
130 | stride=1
131 | pad=1
132 | activation=leaky
133 |
134 | [convolutional]
135 | batch_normalize=1
136 | filters=256
137 | size=1
138 | stride=1
139 | pad=1
140 | activation=leaky
141 |
142 | [convolutional]
143 | batch_normalize=1
144 | filters=512
145 | size=3
146 | stride=1
147 | pad=1
148 | activation=leaky
149 |
150 | [maxpool]
151 | size=2
152 | stride=2
153 |
154 | [convolutional]
155 | batch_normalize=1
156 | filters=1024
157 | size=3
158 | stride=1
159 | pad=1
160 | activation=leaky
161 |
162 | [convolutional]
163 | batch_normalize=1
164 | filters=512
165 | size=1
166 | stride=1
167 | pad=1
168 | activation=leaky
169 |
170 | [convolutional]
171 | batch_normalize=1
172 | filters=1024
173 | size=3
174 | stride=1
175 | pad=1
176 | activation=leaky
177 |
178 | [convolutional]
179 | batch_normalize=1
180 | filters=512
181 | size=1
182 | stride=1
183 | pad=1
184 | activation=leaky
185 |
186 | [convolutional]
187 | batch_normalize=1
188 | filters=1024
189 | size=3
190 | stride=1
191 | pad=1
192 | activation=leaky
193 |
194 | [convolutional]
195 | filters=1000
196 | size=1
197 | stride=1
198 | pad=1
199 | activation=linear
200 |
201 | [avgpool]
202 |
203 | [softmax]
204 | groups=1
205 |
206 |
--------------------------------------------------------------------------------
/CustomLayers/yolov3Layer.m:
--------------------------------------------------------------------------------
1 | classdef yolov3Layer < nnet.layer.Layer
2 | % 该自定义类仍有很大不灵活性,表现在1、predict函数输出不能自由控制;2、类属性在predict函数里面无法改变;3、训练阶段forward函数不执行
3 | % 4、该类无法自定义其他普通成员函数。
4 | % 参考官方文档:Define Custom Deep Learning Layers
5 | properties
6 | mask % 如当前yolov3层mask为[1,2,3],matlab中从1开始,对应cfg文件中以0开始的mask
7 | anchors % 所有的anchors,形如[width1,height1; weight2,height2; ...],对应cfg文件中的anchors,大小为allnumAnchors*2
8 | num % total number of anchors,所有anchors的数量,对应cfg文件中的num
9 | ignore_thresh % keeps duplicated detections if IoU(detect, truth) >ignore_thresh, which will be fused during NMS (is used for training only)
10 | truth_thresh % adjusts duplicated detections if IoU(detect, truth) > truth_thresh, which will be fused during NMS (is used for training only)
11 | jitter % randomly crops and resizes images with changing aspect ratio from x(1 - 2*jitter) to x(1 + 2*jitter) (data augmentation parameter is used only from the last layer)
12 | random % randomly resizes network for each 10 iterations from 1/1.4 to 1.4(data augmentation parameter is used only from the last layer)
13 | classes % 目标检测总共类别数量,对应cfg文件中的classes
14 |
15 | anchorsUse %当前yolov3层的anchors,n*2大小,[width, height],宽高为相对输入原图大小,注意这个与matlab官网estimateAnchorBoxes的宽高顺序相反
16 | nAnchors % 当前yolov3层使用anchors的数量,一般为3
17 | numX % 传入到该yolov3层特征图的宽,像素
18 | numY % 传入到该yolov3层特征图的宽,像素
19 | imageSize % 网络输入图像大小,[imageHeight,imageWidth]
20 | arc % 方式,取'default'、'uCE'、'uBCE'中的一种
21 | stride % 传入到该yolov3层特征下采样率,[w,h],如输入网络大小是416*416宽乘高,该特征层为13*13,则stride = 32
22 | end
23 |
24 | methods
25 | function layer = yolov3Layer(name, mask,allAnchors,nClasses,yoloIndex,imageSize,arc)
26 | % 输入参数:
27 | % name: 字符向量或字符串,层名字
28 | % mask: 见上面properties说明
29 | % allAnchors:同上面properties之anchors说明
30 | % nClasses: 1*1 标量,检测的类别数量
31 | % imageSize:[imageHeight,imageWidth],输入网络的图像大小
32 | % yoloIndex:1*1标量,从1开始的索引,输出yolo检测层的序号
33 | % arc:字符向量或字符串,计算损失的方式
34 | %
35 | % cuixingxing150@gmail.com
36 | % 2020.4.20
37 | %
38 | assert(size(allAnchors,2)==2,'allAnchors must have n*2 shape!');% nAchors*2,形如[width,height]
39 |
40 | layer.mask = mask;
41 | layer.anchors = allAnchors;
42 | layer.num = numel(allAnchors)/2;
43 | layer.classes = nClasses;
44 | layer.ignore_thresh = .7;
45 | layer.truth_thresh = 1;
46 | layer.jitter = .3;
47 | layer.random = 1;
48 |
49 | anchorsUse = allAnchors(mask,:);% na*2, 注意matlab中mask是从1开始的索引
50 | layer.Name = name;
51 | text = ['all number classes:', num2str(nClasses),...
52 | ',used anchor box:',mat2str(round(anchorsUse)),...
53 | ', yoloLayerID:',num2str(yoloIndex),...
54 | ', arc:',arc];
55 | layer.Description = text;
56 | layer.Type = 'yoloV3Layer';
57 |
58 | layer.numY = 1;
59 | layer.numX = 1;
60 | layer.stride =1;
61 |
62 | layer.anchorsUse = anchorsUse;
63 | layer.nAnchors = size(anchorsUse,1);
64 | layer.imageSize = imageSize;
65 | layer.arc = arc;
66 | end
67 |
68 | function Z = predict(layer, X) % training
69 | % matlab中上一层输入的特征X为H*W*C*N,即h*w*c*bs
70 | X = dlarray(X);
71 | layer.numY = size(X,1);
72 | layer.numX = size(X,2);
73 | bs = size(X,4);
74 | layer.stride = max(layer.imageSize)./max(layer.numX,layer.numY);
75 |
76 | Z = X;
77 | % 2020.4.23 实际写下面2行的话,待整个yolov3网络predict时候报错!!!故移到外面写
78 | % Z = X.reshape(layer.numY,layer.numX,layer.nAnchors,(5+layer.nClasses),bs);
79 | % Z = permute(Z,[5,3,1,2,4]);% 输出特征图,Z=bs*na*h*w*(5+nc),
80 | end
81 |
82 | end
83 | end
84 |
--------------------------------------------------------------------------------
/cfg/yolov4-tiny.cfg:
--------------------------------------------------------------------------------
1 | [net]
2 | # Testing
3 | #batch=1
4 | #subdivisions=1
5 | # Training
6 | batch=64
7 | subdivisions=1
8 | width=416
9 | height=416
10 | channels=3
11 | momentum=0.9
12 | decay=0.0005
13 | angle=0
14 | saturation = 1.5
15 | exposure = 1.5
16 | hue=.1
17 |
18 | learning_rate=0.00261
19 | burn_in=1000
20 | max_batches = 500200
21 | policy=steps
22 | steps=400000,450000
23 | scales=.1,.1
24 |
25 | [convolutional]
26 | batch_normalize=1
27 | filters=32
28 | size=3
29 | stride=2
30 | pad=1
31 | activation=leaky
32 |
33 | [convolutional]
34 | batch_normalize=1
35 | filters=64
36 | size=3
37 | stride=2
38 | pad=1
39 | activation=leaky
40 |
41 | [convolutional]
42 | batch_normalize=1
43 | filters=64
44 | size=3
45 | stride=1
46 | pad=1
47 | activation=leaky
48 |
49 | [route]
50 | layers=-1
51 | groups=2
52 | group_id=1
53 |
54 | [convolutional]
55 | batch_normalize=1
56 | filters=32
57 | size=3
58 | stride=1
59 | pad=1
60 | activation=leaky
61 |
62 | [convolutional]
63 | batch_normalize=1
64 | filters=32
65 | size=3
66 | stride=1
67 | pad=1
68 | activation=leaky
69 |
70 | [route]
71 | layers = -1,-2
72 |
73 | [convolutional]
74 | batch_normalize=1
75 | filters=64
76 | size=1
77 | stride=1
78 | pad=1
79 | activation=leaky
80 |
81 | [route]
82 | layers = -6,-1
83 |
84 | [maxpool]
85 | size=2
86 | stride=2
87 |
88 | [convolutional]
89 | batch_normalize=1
90 | filters=128
91 | size=3
92 | stride=1
93 | pad=1
94 | activation=leaky
95 |
96 | [route]
97 | layers=-1
98 | groups=2
99 | group_id=1
100 |
101 | [convolutional]
102 | batch_normalize=1
103 | filters=64
104 | size=3
105 | stride=1
106 | pad=1
107 | activation=leaky
108 |
109 | [convolutional]
110 | batch_normalize=1
111 | filters=64
112 | size=3
113 | stride=1
114 | pad=1
115 | activation=leaky
116 |
117 | [route]
118 | layers = -1,-2
119 |
120 | [convolutional]
121 | batch_normalize=1
122 | filters=128
123 | size=1
124 | stride=1
125 | pad=1
126 | activation=leaky
127 |
128 | [route]
129 | layers = -6,-1
130 |
131 | [maxpool]
132 | size=2
133 | stride=2
134 |
135 | [convolutional]
136 | batch_normalize=1
137 | filters=256
138 | size=3
139 | stride=1
140 | pad=1
141 | activation=leaky
142 |
143 | [route]
144 | layers=-1
145 | groups=2
146 | group_id=1
147 |
148 | [convolutional]
149 | batch_normalize=1
150 | filters=128
151 | size=3
152 | stride=1
153 | pad=1
154 | activation=leaky
155 |
156 | [convolutional]
157 | batch_normalize=1
158 | filters=128
159 | size=3
160 | stride=1
161 | pad=1
162 | activation=leaky
163 |
164 | [route]
165 | layers = -1,-2
166 |
167 | [convolutional]
168 | batch_normalize=1
169 | filters=256
170 | size=1
171 | stride=1
172 | pad=1
173 | activation=leaky
174 |
175 | [route]
176 | layers = -6,-1
177 |
178 | [maxpool]
179 | size=2
180 | stride=2
181 |
182 | [convolutional]
183 | batch_normalize=1
184 | filters=512
185 | size=3
186 | stride=1
187 | pad=1
188 | activation=leaky
189 |
190 | ##################################
191 |
192 | [convolutional]
193 | batch_normalize=1
194 | filters=256
195 | size=1
196 | stride=1
197 | pad=1
198 | activation=leaky
199 |
200 | [convolutional]
201 | batch_normalize=1
202 | filters=512
203 | size=3
204 | stride=1
205 | pad=1
206 | activation=leaky
207 |
208 | [convolutional]
209 | size=1
210 | stride=1
211 | pad=1
212 | filters=255
213 | activation=linear
214 |
215 |
216 |
217 | [yolo]
218 | mask = 3,4,5
219 | anchors = 10,14, 23,27, 37,58, 81,82, 135,169, 344,319
220 | classes=80
221 | num=6
222 | jitter=.3
223 | scale_x_y = 1.05
224 | cls_normalizer=1.0
225 | iou_normalizer=0.07
226 | iou_loss=ciou
227 | ignore_thresh = .7
228 | truth_thresh = 1
229 | random=0
230 | resize=1.5
231 | nms_kind=greedynms
232 | beta_nms=0.6
233 |
234 | [route]
235 | layers = -4
236 |
237 | [convolutional]
238 | batch_normalize=1
239 | filters=128
240 | size=1
241 | stride=1
242 | pad=1
243 | activation=leaky
244 |
245 | [upsample]
246 | stride=2
247 |
248 | [route]
249 | layers = -1, 23
250 |
251 | [convolutional]
252 | batch_normalize=1
253 | filters=256
254 | size=3
255 | stride=1
256 | pad=1
257 | activation=leaky
258 |
259 | [convolutional]
260 | size=1
261 | stride=1
262 | pad=1
263 | filters=255
264 | activation=linear
265 |
266 | [yolo]
267 | mask = 1,2,3
268 | anchors = 10,14, 23,27, 37,58, 81,82, 135,169, 344,319
269 | classes=80
270 | num=6
271 | jitter=.3
272 | scale_x_y = 1.05
273 | cls_normalizer=1.0
274 | iou_normalizer=0.07
275 | iou_loss=ciou
276 | ignore_thresh = .7
277 | truth_thresh = 1
278 | random=0
279 | resize=1.5
280 | nms_kind=greedynms
281 | beta_nms=0.6
282 |
--------------------------------------------------------------------------------
/utils/yolov3v4Predict.m:
--------------------------------------------------------------------------------
1 | function outPutFeatures = yolov3v4Predict(cfg_file,weight_file,image)
2 | % 功能:yolov3快速输出检测特征,同darknet官网输出结果方式保持一致
3 | % 输入:
4 | % cfg_file, 指定的cfg后缀的模型描述文件
5 | % weight_file, 指定的.weights后缀的二进制文件
6 | % image :输入网络的图像数据,单张图像(H*W*C)或者批量图像(H*W*C*bs)
7 | % 输出:
8 | % outPutFeatures: M*(5+nc)或者bs*M*(5+nc)大小
9 | % ,为bs*M*[x,y,w,h,Pobj,p1,p2,...,pn]大小的形式矩阵,如果是单张图像检测,则输出大小为M*(5+nc),否则是bs*M*(5+nc),
10 | % 其中,M为检测框的数量,bs为图片数量,nc为训练网络dlnet类别数量,x,y,w,h分别是输入图片上对应的x,y,width,height,Pobj
11 | % 为物体概率,p1,p2,...,pn分别为对应coco.names类别概率
12 | %
13 | % author: cuixingxing
14 | % email:cuixingxing150@gmail.com
15 | % 2020.4.22创建
16 | % 2020.5.2 修改
17 | % 2020.5.13 minor fix
18 | %
19 |
20 | persistent dlnet yolovLayerArray netInputSize
21 | if isempty(dlnet)
22 |
23 | %% import network and predict
24 | [layerGraphYolo,hyperParams] = importDarknetWeights(cfg_file,weight_file);
25 | dlnet = dlnetwork(layerGraphYolo); % 65秒左右
26 | % analyzeNetwork(layerGraphYolo)% visualize network
27 | % exportDarkNetNetwork(dlnet,hyperParams,'temp.cfg','temp.weights')
28 |
29 | %% get yolo index
30 | yoloIdx = [];
31 | for i = 1:length(dlnet.Layers)
32 | currentLayerType = class(dlnet.Layers(i));
33 | if strcmpi(currentLayerType,'yoloV3Layer')
34 | yoloIdx = [yoloIdx;i];
35 | end
36 | end
37 | assert(~isempty(yoloIdx),'输入网络非yolov3/4网络!')
38 |
39 | yolovLayerArray = dlnet.Layers(yoloIdx);
40 | netInputSize = dlnet.Layers(1).InputSize(1:2);
41 | end
42 |
43 | inputSize = [size(image,1),size(image,2)];
44 | scale = inputSize./netInputSize;% [heightScale,widthScale]
45 |
46 | img = imresize(im2single(image),netInputSize);% [0,1]数据,保持与训练时候同大小和类型
47 | dlX = dlarray(img,'SSCB');% 大小为h*w*c*bs,注意是否归一化要看与训练时候图像一致
48 | if(canUseGPU())
49 | dlX = gpuArray(dlX);% 推送到GPU上
50 | end
51 |
52 | numsYOLO = length(yolovLayerArray);
53 | outFeatureMaps = cell(numsYOLO,1);
54 | [outFeatureMaps{:}] = predict(dlnet,dlX,'Outputs',dlnet.OutputNames);% h*w*c*bs,matlab输出方式排列
55 | outPutFeatures = [];
56 | for i = 1:numsYOLO
57 | currentYOLOLayer = yolovLayerArray(i);
58 | currentFeatureMap = outFeatureMaps{i};
59 |
60 | % 由于yolov3Layer类里面predict函数未改变类属性,故重新给属性赋值
61 | currentYOLOLayer.numY = size(currentFeatureMap,1);
62 | currentYOLOLayer.numX = size(currentFeatureMap,2);
63 | currentYOLOLayer.stride = max(currentYOLOLayer.imageSize)./max(currentYOLOLayer.numX,...
64 | currentYOLOLayer.numY);
65 |
66 | % reshape currentFeatureMap到有意义的维度,h*w*c*bs --> h*w*(5+nc)*na*bs
67 | % --> bs*na*h*w*(5+nc),最终的维度方式与darknet官网兼容
68 | bs = size(currentFeatureMap,4);
69 | h = currentYOLOLayer.numY;
70 | w = currentYOLOLayer.numX;
71 | na = currentYOLOLayer.nAnchors;
72 | nc = currentYOLOLayer.classes;
73 | currentFeatureMap = reshape(currentFeatureMap,h,w,5+nc,na,bs);% h*w*(5+nc)*na*bs
74 | currentFeatureMap = permute(currentFeatureMap,[5,4,1,2,3]);% bs*na*h*w*(5+nc)
75 |
76 | [~,~,yv,xv] = ndgrid(1:bs,1:na,0:h-1,0:w-1);% yv,xv大小都为bs*na*h*w,注意顺序,后面做加法维度标签要对应
77 | gridXY = cat(5,xv,yv);% 第5维上扩展,大小为bs*na*h*w*2, x,y从1开始的索引
78 | currentFeatureMap(:,:,:,:,1:2) = sigmoid(currentFeatureMap(:,:,:,:,1:2)) + gridXY; % 大小为bs*na*h*w*2,预测对应xy
79 | anchor_grid = currentYOLOLayer.anchorsUse/currentYOLOLayer.stride; % 此处anchor_grid大小为na*2
80 | anchor_grid = reshape(anchor_grid,1,currentYOLOLayer.nAnchors,1,1,2);% 此处anchor_grid大小为1*na*1*1*2,方便下面相乘
81 | currentFeatureMap(:,:,:,:,3:4) = exp(currentFeatureMap(:,:,:,:,3:4)).*anchor_grid;% 大小为bs*na*h*w*2
82 | currentFeatureMap(:,:,:,:,1:4) = currentFeatureMap(:,:,:,:,1:4)*currentYOLOLayer.stride; % 预测的bboxes
83 | currentFeatureMap(:,:,:,:,5:end) = sigmoid(currentFeatureMap(:,:,:,:,5:end)); % 预测的scores
84 |
85 | if currentYOLOLayer.classes == 1
86 | currentFeatureMap(:,:,:,:,6) = 1;
87 | end
88 | currentFeatureMap = reshape(currentFeatureMap,bs,[],5+currentYOLOLayer.classes);% bs*N*(5+nc)
89 |
90 | if isempty(outPutFeatures)
91 | outPutFeatures = currentFeatureMap;
92 | else
93 | outPutFeatures = cat(2,outPutFeatures,currentFeatureMap);% bs*M*(5+nc)
94 | end
95 | end
96 |
97 | %% 坐标转换到原始图像上
98 | outPutFeatures = extractdata(outPutFeatures);% bs*M*(5+nc) ,为[x_center,y_center,w,h,Pobj,p1,p2,...,pn]
99 | outPutFeatures(:,:,[1,3]) = outPutFeatures(:,:,[1,3])*scale(2);% x_center,width
100 | outPutFeatures(:,:,[2,4]) = outPutFeatures(:,:,[2,4])*scale(1);% y_center,height
101 | outPutFeatures(:,:,1) = outPutFeatures(:,:,1) -outPutFeatures(:,:,3)/2;% x
102 | outPutFeatures(:,:,2) = outPutFeatures(:,:,2) -outPutFeatures(:,:,4)/2; % y
103 | outPutFeatures = squeeze(outPutFeatures); % 如果是单张图像检测,则输出大小为M*(5+nc),否则是bs*M*(5+nc)
104 | if(canUseGPU())
105 | outPutFeatures = gather(outPutFeatures); % 推送到CPU上
106 | end
107 | end
108 |
--------------------------------------------------------------------------------
/utils/importDarknetNetwork.m:
--------------------------------------------------------------------------------
1 | function [net,hyperParams,numsNetParams,FLOPs] = importDarknetNetwork(cfgfile,weightsfile)
2 | % IMPORTDARKNETNETWORK
3 | % 功能:导入指定的cfgfile,weightsfile到matlab中,本函数适合导入darknet分类网络,yolov3/yolov4请使用importDarknetWeights函数
4 | % 输入:cfgfile, 指定的cfg后缀的模型描述文件
5 | % weighfile, 指定的.weights后缀的二进制文件
6 | % 输出:net, matlab深度学习模型
7 | % hyperParams,结构体,超参配置文件
8 | % numsReadParams,权重参数个数
9 | % FLOPs, 模型计算力
10 | % 注意:1、适合2019b版本及以上
11 | % 2、darknet weights保存顺序依次为BN层offset,scale,mean,variance,Conv层的bias,weights
12 | % 特征图输出output Size = (Input Size – ((Filter Size – 1)*Dilation Factor + 1) + 2*Padding)/Stride + 1
13 | % 参考:1、官方文档,Specify Layers of Convolutional Neural Network
14 | % 2、https://www.zhihu.com/question/65305385
15 | % 3、https://github.com/ultralytics/yolov3/blob/master/models.py
16 | % cuixingxing150@gmail.com
17 | % 2019.8.19
18 | %
19 | arguments
20 | cfgfile (1,:) char
21 | weightsfile (1,:) char
22 | end
23 |
24 | [lgraph,hyperParams,numsNetParams,FLOPs,...
25 | moduleTypeList,moduleInfoList,layerToModuleIndex] = importDarkNetLayers(cfgfile);
26 | assert(length(moduleTypeList)==length(moduleInfoList));
27 |
28 | %% 读取权重参数文件
29 | fid_w = fopen(weightsfile,'rb');
30 | if fid_w == -1
31 | error('Author:Function:OpenFile', 'Cannot open file: %s', weightsfile);
32 | end
33 | header = fread(fid_w, 3, '*int32');
34 | if header(2) > 1
35 | header2 = fread(fid_w, 1, '*int64'); % int64占用8个字节
36 | else
37 | header2 = fread(fid_w, 1, '*int32'); % int32占用4个字节
38 | end
39 | fprintf('Major :%d, Minor :%d,Revision :%d,number of images during training:%d,reading params...\n',...
40 | header(1),header(2),header(3),header2);
41 | weights = fread(fid_w,'*single');
42 | fclose(fid_w);
43 |
44 | numsWeightsParams = numel(weights);
45 | readSize = 1;
46 | numsModule = length(moduleTypeList);
47 |
48 | for i = 1:numsModule
49 | currentModuleType = moduleTypeList{i};
50 | currentModuleInfo = moduleInfoList{i};
51 | if strcmp(currentModuleType,'[convolutional]')
52 | currentModule = lgraph.Layers(i==layerToModuleIndex);
53 | filterSize = str2double(currentModuleInfo.size);
54 | numFilters = str2double(currentModuleInfo.filters);
55 | channels_in = moduleInfoList{i-1}.channels;
56 |
57 | if isfield(currentModuleInfo,'batch_normalize')
58 | % bn bias
59 | bn_bias = weights(readSize:readSize+numFilters-1);
60 | bn_bias = reshape(bn_bias,[1,1,numFilters]);
61 | currentModule(2).Offset = bn_bias;
62 | readSize = readSize+numFilters;
63 | % bn weight
64 | bn_weight = weights(readSize:readSize+numFilters-1);
65 | bn_weight = reshape(bn_weight,[1,1,numFilters]);
66 | currentModule(2).Scale = bn_weight;
67 | readSize = readSize+numFilters;
68 | % bn trainedMean
69 | bn_mean = weights(readSize:readSize+numFilters-1);
70 | bn_mean = reshape(bn_mean,[1,1,numFilters]);
71 | currentModule(2).TrainedMean = bn_mean;
72 | readSize = readSize+numFilters;
73 | % bn trainedVariance
74 | bn_var = weights(readSize:readSize+numFilters-1);
75 | bn_var = reshape(bn_var,[1,1,numFilters]);
76 | if any(bn_var<-0.01)
77 | error("方差应该大于0!");
78 | end
79 | currentModule(2).TrainedVariance = abs(bn_var); % 防止接近于0的数是负数
80 | readSize = readSize+numFilters;
81 | % conv bias 为0
82 | if isfield(currentModuleInfo,'groups')
83 | numGroups = str2double(currentModuleInfo.groups);
84 | numFiltersPerGroup_out = numFilters/numGroups;
85 | currentModule(1).Bias = zeros(1,1,numFiltersPerGroup_out,numGroups,'single');
86 | else
87 | currentModule(1).Bias = zeros(1,1,numFilters,'single');
88 | end
89 | else
90 | % load conv bias
91 | conv_bias = weights(readSize:readSize+numFilters-1);
92 | if isfield(currentModuleInfo,'groups')
93 | numGroups = str2double(currentModuleInfo.groups);
94 | numFiltersPerGroup_out = numFilters/numGroups;
95 | conv_bias = reshape(conv_bias,1,1,numFiltersPerGroup_out,numGroups);
96 | else
97 | conv_bias = reshape(conv_bias,1,1,numFilters);
98 | end
99 | currentModule(1).Bias = conv_bias;
100 | readSize = readSize+numFilters;
101 | end % end of is bn
102 | % load conv weights
103 | if isfield(currentModuleInfo,'groups')
104 | numGroups = str2double(currentModuleInfo.groups);
105 | numFiltersPerGroup_out = numFilters/numGroups;
106 | nums_conv_w = filterSize*filterSize*channels_in/numGroups*numFiltersPerGroup_out*numGroups;
107 | conv_weights = weights(readSize:readSize+nums_conv_w-1);
108 | conv_weights = reshape(conv_weights,filterSize,filterSize,channels_in/numGroups,numFiltersPerGroup_out,numGroups);
109 | conv_weights = permute(conv_weights,[2,1,3,4,5]);
110 | currentModule(1).Weights = conv_weights;
111 | readSize = readSize+nums_conv_w;
112 | else
113 | nums_conv_w = filterSize*filterSize*channels_in*numFilters;% weights
114 | conv_weights = weights(readSize:readSize+nums_conv_w-1);
115 | conv_weights = reshape(conv_weights,filterSize,filterSize,channels_in,numFilters);
116 | conv_weights = permute(conv_weights,[2,1,3,4]);
117 | currentModule(1).Weights = conv_weights;
118 | readSize = readSize+nums_conv_w;
119 | end % end of load conv weights
120 | % 更新参数
121 | % lgraph.Layers(i==layerToModuleIndex) = currentModule;
122 | for replaceInd = 1:length(currentModule)
123 | layerName = currentModule(replaceInd).Name;
124 | lgraph = replaceLayer(lgraph,layerName,currentModule(replaceInd));
125 | end
126 | end % end of module '[convolutional]'
127 |
128 | % fullyConnectedLayer
129 | if strcmp(currentModuleType,'[connected]')
130 | currentModule = lgraph.Layers(i==layerToModuleIndex);
131 | numFilters = str2double(currentModuleInfo.output);
132 | % load fc bias
133 | numBias = numFilters;
134 | fl_bias = weights(readSize:readSize+numBias-1);
135 | fl_bias = reshape(fl_bias,numBias,1);
136 | currentModule(1).Bias = fl_bias;
137 | readSize = readSize+numBias;
138 | % load fc weights
139 | input_all_neurons = prod(moduleInfoList{i-1}.mapSize)*moduleInfoList{i-1}.channels;
140 | numWeights = numFilters*input_all_neurons; % help fullyConnectedLayer weights
141 | fl_weights = weights(readSize:readSize+numWeights-1);
142 | fl_weights = reshape(fl_weights,input_all_neurons,numFilters);
143 | fl_weights = permute(fl_weights,[2,1]);% fc不需要permute?
144 | currentModule(1).Weights = fl_weights;
145 | readSize = readSize+numWeights;
146 | % 更新参数
147 | for replaceInd = 1:length(currentModule)
148 | layerName = currentModule(replaceInd).Name;
149 | lgraph = replaceLayer(lgraph,layerName,currentModule(replaceInd));
150 | end
151 | end % end of module '[connected]'
152 | end % end of nums of module
153 |
154 | if isa(lgraph.Layers(end),'nnet.cnn.layer.SoftmaxLayer')
155 | lastLayerName = lgraph.Layers(end).Name;
156 | classifyLayer = classificationLayer('Name','classify');
157 | lgraph = addLayers(lgraph,classifyLayer);
158 | lgraph = connectLayers(lgraph,lastLayerName,'classify');
159 | end
160 |
161 | assert(readSize-1==numsWeightsParams);
162 | fprintf('Load parameters succfully! now start to assemble Network...\n')
163 | warning('off');
164 | net = assembleNetwork(lgraph);
165 | fprintf('Assemble Network succfully!\n')
166 |
--------------------------------------------------------------------------------
/utils/importDarknetWeights.m:
--------------------------------------------------------------------------------
1 | function [lgraph,hyperParams,numsNetParams,FLOPs] = importDarknetWeights(cfgfile,weightsfile,cutoffModule)
2 | % IMPORTDARKNETWEIGHTS 功能:指定导入部分module的darknet模型
3 | % 输入:cfgfile, 指定的cfg后缀的模型描述文件
4 | % weighfile, 指定的.weights后缀的二进制文件
5 | % cutoffModule,(可选项)1*1的正整数,(可选项)1*1的正整数,指定导出darknet前cutoffModule个module。以cfg文件中第一个非[net]开始的module为0开始的计数,没有该项则导出整个网络
6 | % 输出:lgraph, matlab深度学习模型计算图
7 | % hyperParams,结构体,超参配置文件
8 | % numsReadParams,权重参数个数
9 | % FLOPs, 模型计算力
10 | % 注意:1、适合2019b版本及以上
11 | % 2、leaky阈值darknet为0.1
12 | % 3、如果某个module中有bn层,则conv的bias为0,因为darknet是这种存储形式
13 | % 4、darknet weights保存顺序依次为BN层offset,scale,mean,variance,Conv层的bias,weights
14 | % 特征图输出output Size = (Input Size – ((Filter Size – 1)*Dilation Factor + 1) + 2*Padding)/Stride + 1
15 | % 参考:1、官方文档,Specify Layers of Convolutional Neural Network
16 | % 2、https://www.zhihu.com/question/65305385
17 | % 3、https://github.com/ultralytics/yolov3/blob/master/models.py
18 | % cuixingxing150@gmail.com
19 | % 2019.8.19
20 | % 2019.9.4修改,由原来的darknet中[net]为0开始的索引改为以cfg文件中第一个非[net]开始的module为0开始的计数的索引
21 | % 2020.4.25修改函数默认输入参数
22 | %
23 | arguments
24 | cfgfile (1,:) char
25 | weightsfile (1,:) char
26 | cutoffModule {mustBeNonnegative} = 0 % 默认导入所有的层
27 | end
28 |
29 | [lgraph,hyperParams,numsNetParams,FLOPs,...
30 | moduleTypeList,moduleInfoList,layerToModuleIndex] = importDarkNetLayers(cfgfile);% only weights需要cutoff,layer都导入
31 | assert(length(moduleTypeList)==length(moduleInfoList));
32 |
33 | %% 读取权重参数文件
34 | fid_w = fopen(weightsfile,'rb');
35 | if fid_w == -1
36 | error('Author:Function:OpenFile', 'Cannot open file: %s', weightsfile);
37 | end
38 | header = fread(fid_w, 3, '*int32');
39 | if header(2) > 1
40 | header2 = fread(fid_w, 1, '*int64'); % int64占用8个字节
41 | else
42 | header2 = fread(fid_w, 1, '*int32'); % int32占用4个字节
43 | end
44 | fprintf('Major :%d, Minor :%d,Revision :%d,number of images during training:%d,reading params...\n',...
45 | header(1),header(2),header(3),header2);
46 | weights = fread(fid_w,'*single');
47 | fclose(fid_w);
48 |
49 | % numsWeightsParams = numel(weights);
50 | readSize = 1;
51 | numsModule = length(moduleTypeList);
52 | if cutoffModule>0
53 | numsModule = cutoffModule+1;% [net] plus 1
54 | end
55 |
56 | for i = 1:numsModule
57 | currentModuleType = moduleTypeList{i};
58 | currentModuleInfo = moduleInfoList{i};
59 | if strcmp(currentModuleType,'[convolutional]')
60 | currentModule = lgraph.Layers(i==layerToModuleIndex);
61 | filterSize = str2double(currentModuleInfo.size);
62 | numFilters = str2double(currentModuleInfo.filters);
63 | channels_in = moduleInfoList{i-1}.channels;
64 |
65 | if isfield(currentModuleInfo,'batch_normalize')
66 | % bn bias
67 | bn_bias = weights(readSize:readSize+numFilters-1);
68 | bn_bias = reshape(bn_bias,[1,1,numFilters]);
69 | currentModule(2).Offset = bn_bias;
70 | readSize = readSize+numFilters;
71 | % bn weight
72 | bn_weight = weights(readSize:readSize+numFilters-1);
73 | bn_weight = reshape(bn_weight,[1,1,numFilters]);
74 | currentModule(2).Scale = bn_weight;
75 | readSize = readSize+numFilters;
76 | % bn trainedMean
77 | bn_mean = weights(readSize:readSize+numFilters-1);
78 | bn_mean = reshape(bn_mean,[1,1,numFilters]);
79 | currentModule(2).TrainedMean = bn_mean;
80 | readSize = readSize+numFilters;
81 | % bn trainedVariance
82 | bn_var = weights(readSize:readSize+numFilters-1);
83 | bn_var = reshape(bn_var,[1,1,numFilters]);
84 | if any(bn_var<-0.01)
85 | error("方差应该大于0!");
86 | end
87 | currentModule(2).TrainedVariance = abs(bn_var); % 防止接近于0的数是负数
88 | readSize = readSize+numFilters;
89 | % conv bias 为0
90 | if isfield(currentModuleInfo,'groups')
91 | numGroups = str2double(currentModuleInfo.groups);
92 | numFiltersPerGroup_out = numFilters/numGroups;
93 | currentModule(1).Bias = zeros(1,1,numFiltersPerGroup_out,numGroups,'single');
94 | else
95 | currentModule(1).Bias = zeros(1,1,numFilters,'single');
96 | end
97 | else
98 | % load conv bias
99 | conv_bias = weights(readSize:readSize+numFilters-1);
100 | if isfield(currentModuleInfo,'groups')
101 | numGroups = str2double(currentModuleInfo.groups);
102 | numFiltersPerGroup_out = numFilters/numGroups;
103 | conv_bias = reshape(conv_bias,1,1,numFiltersPerGroup_out,numGroups);
104 | else
105 | conv_bias = reshape(conv_bias,1,1,numFilters);
106 | end
107 | currentModule(1).Bias = conv_bias;
108 | readSize = readSize+numFilters;
109 | end % end of is bn
110 | % load conv weights
111 | if isfield(currentModuleInfo,'groups')
112 | numGroups = str2double(currentModuleInfo.groups);
113 | numFiltersPerGroup_out = numFilters/numGroups;
114 | nums_conv_w = filterSize*filterSize*channels_in/numGroups*numFiltersPerGroup_out*numGroups;
115 | conv_weights = weights(readSize:readSize+nums_conv_w-1);
116 | conv_weights = reshape(conv_weights,filterSize,filterSize,channels_in/numGroups,numFiltersPerGroup_out,numGroups);
117 | conv_weights = permute(conv_weights,[2,1,3,4,5]);
118 | currentModule(1).Weights = conv_weights;
119 | readSize = readSize+nums_conv_w;
120 | else
121 | nums_conv_w = filterSize*filterSize*channels_in*numFilters;% weights
122 | conv_weights = weights(readSize:readSize+nums_conv_w-1);
123 | conv_weights = reshape(conv_weights,filterSize,filterSize,channels_in,numFilters);
124 | conv_weights = permute(conv_weights,[2,1,3,4]);
125 | currentModule(1).Weights = conv_weights;
126 | readSize = readSize+nums_conv_w;
127 | end % end of load conv weights
128 | % 更新参数
129 | % lgraph.Layers(i==layerToModuleIndex) = currentModule;
130 | for replaceInd = 1:length(currentModule)
131 | layerName = currentModule(replaceInd).Name;
132 | lgraph = replaceLayer(lgraph,layerName,currentModule(replaceInd));
133 | end
134 | end % end of module '[convolutional]'
135 |
136 | % fullyConnectedLayer
137 | if strcmp(currentModuleType,'[connected]')
138 | currentModule = lgraph.Layers(i==layerToModuleIndex);
139 | numFilters = str2double(currentModuleInfo.output);
140 | % load fc bias
141 | numBias = numFilters;
142 | fl_bias = weights(readSize:readSize+numBias-1);
143 | fl_bias = reshape(fl_bias,numBias,1);
144 | currentModule(1).Bias = fl_bias;
145 | readSize = readSize+numBias;
146 | % load fc weights
147 | input_all_neurons = prod(moduleInfoList{i-1}.mapSize)*moduleInfoList{i-1}.channels;
148 | numWeights = numFilters*input_all_neurons; % help fullyConnectedLayer weights
149 | fl_weights = weights(readSize:readSize+numWeights-1);
150 | fl_weights = reshape(fl_weights,input_all_neurons,numFilters);
151 | fl_weights = permute(fl_weights,[2,1]);% fc不需要permute?
152 | currentModule(1).Weights = fl_weights;
153 | readSize = readSize+numWeights;
154 | % 更新参数
155 | for replaceInd = 1:length(currentModule)
156 | layerName = currentModule(replaceInd).Name;
157 | lgraph = replaceLayer(lgraph,layerName,currentModule(replaceInd));
158 | end
159 | end % end of module '[connected]'
160 | end % end of nums of module
161 |
162 | if isa(lgraph.Layers(end),'nnet.cnn.layer.SoftmaxLayer')
163 | lastLayerName = lgraph.Layers(end).Name;
164 | classifyLayer = classificationLayer('Name','classify');
165 | lgraph = addLayers(lgraph,classifyLayer);
166 | lgraph = connectLayers(lgraph,lastLayerName,'classify');
167 | end
168 |
169 | fprintf('Load parameters succfully!\n')
170 |
171 |
--------------------------------------------------------------------------------
/cfg/mobilenetv2.cfg:
--------------------------------------------------------------------------------
1 | # This file is automatically generated by MATLAB and may require you to modify it manually
2 | [net]
3 | angle=7
4 | aspect=0.75
5 | batch=64
6 | channels=3
7 | exposure=0.75
8 | height=224
9 | learning_rate=0.01
10 | max_batches=600000
11 | max_crop=256
12 | momentum=0.9
13 | policy=poly
14 | power=4
15 | saturation=0.75
16 | subdivisiions=1
17 | width=224
18 |
19 | # darknet module ID:0
20 | [convolutional]
21 | batch_normalize=1
22 | filters=32
23 | pad=0
24 | size=3
25 | stride=2
26 | activation=relu6
27 |
28 | # darknet module ID:1
29 | [convolutional]
30 | batch_normalize=1
31 | filters=32
32 | groups=32
33 | pad=1
34 | size=3
35 | stride=1
36 | activation=relu6
37 |
38 | # darknet module ID:2
39 | [convolutional]
40 | batch_normalize=1
41 | filters=16
42 | pad=1
43 | size=1
44 | stride=1
45 | activation=linear
46 |
47 | # darknet module ID:3
48 | [convolutional]
49 | batch_normalize=1
50 | filters=96
51 | pad=1
52 | size=1
53 | stride=1
54 | activation=relu6
55 |
56 | # darknet module ID:4
57 | [convolutional]
58 | batch_normalize=1
59 | filters=96
60 | groups=96
61 | pad=0
62 | size=3
63 | stride=2
64 | activation=relu6
65 |
66 | # darknet module ID:5
67 | [convolutional]
68 | batch_normalize=1
69 | filters=24
70 | pad=1
71 | size=1
72 | stride=1
73 | activation=linear
74 |
75 | # darknet module ID:6
76 | [convolutional]
77 | batch_normalize=1
78 | filters=144
79 | pad=1
80 | size=1
81 | stride=1
82 | activation=relu6
83 |
84 | # darknet module ID:7
85 | [convolutional]
86 | batch_normalize=1
87 | filters=144
88 | groups=144
89 | pad=1
90 | size=3
91 | stride=1
92 | activation=relu6
93 |
94 | # darknet module ID:8
95 | [convolutional]
96 | batch_normalize=1
97 | filters=24
98 | pad=1
99 | size=1
100 | stride=1
101 | activation=linear
102 |
103 | # darknet module ID:9
104 | [shortcut]
105 | from=5
106 | activation=linear
107 |
108 | # darknet module ID:10
109 | [convolutional]
110 | batch_normalize=1
111 | filters=144
112 | pad=1
113 | size=1
114 | stride=1
115 | activation=relu6
116 |
117 | # darknet module ID:11
118 | [convolutional]
119 | batch_normalize=1
120 | filters=144
121 | groups=144
122 | pad=0
123 | size=3
124 | stride=2
125 | activation=relu6
126 |
127 | # darknet module ID:12
128 | [convolutional]
129 | batch_normalize=1
130 | filters=32
131 | pad=1
132 | size=1
133 | stride=1
134 | activation=linear
135 |
136 | # darknet module ID:13
137 | [convolutional]
138 | batch_normalize=1
139 | filters=192
140 | pad=1
141 | size=1
142 | stride=1
143 | activation=relu6
144 |
145 | # darknet module ID:14
146 | [convolutional]
147 | batch_normalize=1
148 | filters=192
149 | groups=192
150 | pad=1
151 | size=3
152 | stride=1
153 | activation=relu6
154 |
155 | # darknet module ID:15
156 | [convolutional]
157 | batch_normalize=1
158 | filters=32
159 | pad=1
160 | size=1
161 | stride=1
162 | activation=linear
163 |
164 | # darknet module ID:16
165 | [shortcut]
166 | from=12
167 | activation=linear
168 |
169 | # darknet module ID:17
170 | [convolutional]
171 | batch_normalize=1
172 | filters=192
173 | pad=1
174 | size=1
175 | stride=1
176 | activation=relu6
177 |
178 | # darknet module ID:18
179 | [convolutional]
180 | batch_normalize=1
181 | filters=192
182 | groups=192
183 | pad=1
184 | size=3
185 | stride=1
186 | activation=relu6
187 |
188 | # darknet module ID:19
189 | [convolutional]
190 | batch_normalize=1
191 | filters=32
192 | pad=1
193 | size=1
194 | stride=1
195 | activation=linear
196 |
197 | # darknet module ID:20
198 | [shortcut]
199 | from=16
200 | activation=linear
201 |
202 | # darknet module ID:21
203 | [convolutional]
204 | batch_normalize=1
205 | filters=192
206 | pad=1
207 | size=1
208 | stride=1
209 | activation=relu6
210 |
211 | # darknet module ID:22
212 | [convolutional]
213 | batch_normalize=1
214 | filters=192
215 | groups=192
216 | pad=0
217 | size=3
218 | stride=2
219 | activation=relu6
220 |
221 | # darknet module ID:23
222 | [convolutional]
223 | batch_normalize=1
224 | filters=64
225 | pad=1
226 | size=1
227 | stride=1
228 | activation=linear
229 |
230 | # darknet module ID:24
231 | [convolutional]
232 | batch_normalize=1
233 | filters=384
234 | pad=1
235 | size=1
236 | stride=1
237 | activation=relu6
238 |
239 | # darknet module ID:25
240 | [convolutional]
241 | batch_normalize=1
242 | filters=384
243 | groups=384
244 | pad=1
245 | size=3
246 | stride=1
247 | activation=relu6
248 |
249 | # darknet module ID:26
250 | [convolutional]
251 | batch_normalize=1
252 | filters=64
253 | pad=1
254 | size=1
255 | stride=1
256 | activation=linear
257 |
258 | # darknet module ID:27
259 | [shortcut]
260 | from=23
261 | activation=linear
262 |
263 | # darknet module ID:28
264 | [convolutional]
265 | batch_normalize=1
266 | filters=384
267 | pad=1
268 | size=1
269 | stride=1
270 | activation=relu6
271 |
272 | # darknet module ID:29
273 | [convolutional]
274 | batch_normalize=1
275 | filters=384
276 | groups=384
277 | pad=1
278 | size=3
279 | stride=1
280 | activation=relu6
281 |
282 | # darknet module ID:30
283 | [convolutional]
284 | batch_normalize=1
285 | filters=64
286 | pad=1
287 | size=1
288 | stride=1
289 | activation=linear
290 |
291 | # darknet module ID:31
292 | [shortcut]
293 | from=27
294 | activation=linear
295 |
296 | # darknet module ID:32
297 | [convolutional]
298 | batch_normalize=1
299 | filters=384
300 | pad=1
301 | size=1
302 | stride=1
303 | activation=relu6
304 |
305 | # darknet module ID:33
306 | [convolutional]
307 | batch_normalize=1
308 | filters=384
309 | groups=384
310 | pad=1
311 | size=3
312 | stride=1
313 | activation=relu6
314 |
315 | # darknet module ID:34
316 | [convolutional]
317 | batch_normalize=1
318 | filters=64
319 | pad=1
320 | size=1
321 | stride=1
322 | activation=linear
323 |
324 | # darknet module ID:35
325 | [shortcut]
326 | from=31
327 | activation=linear
328 |
329 | # darknet module ID:36
330 | [convolutional]
331 | batch_normalize=1
332 | filters=384
333 | pad=1
334 | size=1
335 | stride=1
336 | activation=relu6
337 |
338 | # darknet module ID:37
339 | [convolutional]
340 | batch_normalize=1
341 | filters=384
342 | groups=384
343 | pad=1
344 | size=3
345 | stride=1
346 | activation=relu6
347 |
348 | # darknet module ID:38
349 | [convolutional]
350 | batch_normalize=1
351 | filters=96
352 | pad=1
353 | size=1
354 | stride=1
355 | activation=linear
356 |
357 | # darknet module ID:39
358 | [convolutional]
359 | batch_normalize=1
360 | filters=576
361 | pad=1
362 | size=1
363 | stride=1
364 | activation=relu6
365 |
366 | # darknet module ID:40
367 | [convolutional]
368 | batch_normalize=1
369 | filters=576
370 | groups=576
371 | pad=1
372 | size=3
373 | stride=1
374 | activation=relu6
375 |
376 | # darknet module ID:41
377 | [convolutional]
378 | batch_normalize=1
379 | filters=96
380 | pad=1
381 | size=1
382 | stride=1
383 | activation=linear
384 |
385 | # darknet module ID:42
386 | [shortcut]
387 | from=38
388 | activation=linear
389 |
390 | # darknet module ID:43
391 | [convolutional]
392 | batch_normalize=1
393 | filters=576
394 | pad=1
395 | size=1
396 | stride=1
397 | activation=relu6
398 |
399 | # darknet module ID:44
400 | [convolutional]
401 | batch_normalize=1
402 | filters=576
403 | groups=576
404 | pad=1
405 | size=3
406 | stride=1
407 | activation=relu6
408 |
409 | # darknet module ID:45
410 | [convolutional]
411 | batch_normalize=1
412 | filters=96
413 | pad=1
414 | size=1
415 | stride=1
416 | activation=linear
417 |
418 | # darknet module ID:46
419 | [shortcut]
420 | from=42
421 | activation=linear
422 |
423 | # darknet module ID:47
424 | [convolutional]
425 | batch_normalize=1
426 | filters=576
427 | pad=1
428 | size=1
429 | stride=1
430 | activation=relu6
431 |
432 | # darknet module ID:48
433 | [convolutional]
434 | batch_normalize=1
435 | filters=576
436 | groups=576
437 | pad=0
438 | size=3
439 | stride=2
440 | activation=relu6
441 |
442 | # darknet module ID:49
443 | [convolutional]
444 | batch_normalize=1
445 | filters=160
446 | pad=1
447 | size=1
448 | stride=1
449 | activation=linear
450 |
451 | # darknet module ID:50
452 | [convolutional]
453 | batch_normalize=1
454 | filters=960
455 | pad=1
456 | size=1
457 | stride=1
458 | activation=relu6
459 |
460 | # darknet module ID:51
461 | [convolutional]
462 | batch_normalize=1
463 | filters=960
464 | groups=960
465 | pad=1
466 | size=3
467 | stride=1
468 | activation=relu6
469 |
470 | # darknet module ID:52
471 | [convolutional]
472 | batch_normalize=1
473 | filters=160
474 | pad=1
475 | size=1
476 | stride=1
477 | activation=linear
478 |
479 | # darknet module ID:53
480 | [shortcut]
481 | from=49
482 | activation=linear
483 |
484 | # darknet module ID:54
485 | [convolutional]
486 | batch_normalize=1
487 | filters=960
488 | pad=1
489 | size=1
490 | stride=1
491 | activation=relu6
492 |
493 | # darknet module ID:55
494 | [convolutional]
495 | batch_normalize=1
496 | filters=960
497 | groups=960
498 | pad=1
499 | size=3
500 | stride=1
501 | activation=relu6
502 |
503 | # darknet module ID:56
504 | [convolutional]
505 | batch_normalize=1
506 | filters=160
507 | pad=1
508 | size=1
509 | stride=1
510 | activation=linear
511 |
512 | # darknet module ID:57
513 | [shortcut]
514 | from=53
515 | activation=linear
516 |
517 | # darknet module ID:58
518 | [convolutional]
519 | batch_normalize=1
520 | filters=960
521 | pad=1
522 | size=1
523 | stride=1
524 | activation=relu6
525 |
526 | # darknet module ID:59
527 | [convolutional]
528 | batch_normalize=1
529 | filters=960
530 | groups=960
531 | pad=1
532 | size=3
533 | stride=1
534 | activation=relu6
535 |
536 | # darknet module ID:60
537 | [convolutional]
538 | batch_normalize=1
539 | filters=320
540 | pad=1
541 | size=1
542 | stride=1
543 | activation=linear
544 |
545 | # darknet module ID:61
546 | [convolutional]
547 | batch_normalize=1
548 | filters=1280
549 | pad=1
550 | size=1
551 | stride=1
552 | activation=relu6
553 |
554 | # darknet module ID:62
555 | [avgpool]
556 |
557 | # darknet module ID:63
558 | [connected]
559 | output=1000
560 | activation=linear
561 |
562 | # darknet module ID:64
563 | [softmax]
564 | groups=1
565 |
566 |
--------------------------------------------------------------------------------
/utils/exportDarkNetNetwork.m:
--------------------------------------------------------------------------------
1 | function exportDarkNetNetwork(net,hyperParams,cfgfileName,weightfileName,cutoffModule)
2 | % EXPORTDARKETNetNetwork 功能:把matlab深度学习模型导出为darknet的模型weights文件
3 | % 输入:net, matlab深度学习模型,SeriesNetwork,DAGNetwork,dlnetwork之一类型
4 | % hyperParams,结构体,超参配置文件,对应cfg文件中的[net]参数
5 | % cutoffModule,(可选项)1*1的正整数,指定导出darknet前cutoffModule个module。cutoffModule是以cfg文件中第一个[convolutional]为0开始的module计数,没有该项则导出整个网络
6 | % 输出:
7 | % cfgfile, 指定的cfg后缀的模型描述文件
8 | % weightfile,制定对应的weights权重文件
9 | %
10 | % 注意:1、relu6用relu激活函数代替,因为clip relu不知道darknet是否实现
11 | % 2、matlab中module以[net]为1开始计数,而darknet中cfg以[convolutional]第一个为0开始计数
12 | % cuixingxing150@gmail.com
13 | % 2019.8.22
14 | % 2019.8.29修改,支持导出relu6
15 | % 2019.9.4修改,由原来的darknet中[net]为0开始的索引改为以cfg文件中第一个非[net]开始的module为0开始的计数的索引
16 | % 2020.4.28修改,加入[yolo]、[upsample]、[route]支持;输入参数限定
17 | % 2020.4.29加入mishLayer导出层支持
18 | % 2020.6.29 加入导出yolov4-tiny支持
19 | %
20 |
21 | arguments
22 | net (1,1)
23 | hyperParams (1,1) struct
24 | cfgfileName (1,:) char
25 | weightfileName (1,:) char
26 | cutoffModule {mustBeNonnegative} = 0 % 默认导出所有的层
27 | end
28 |
29 | %% init
30 | moduleTypeList = []; % cell array,每个cell存储字符向量的模块类型,如'[convolutional]'
31 | moduleInfoList = []; % cell array,每个cell存储结构图的模块信息
32 | layerToModuleIndex = []; % 正整数n*1的vector,每个值代表matlab中从layers映射到module的类别
33 |
34 | %% 1、解析net中模块
35 | module_idx = 1;
36 | layerNames = [];% 字符向量n*1的vector,每个值存储每个层的名字,后面shortcut,route要用到
37 | numsLayers = length(net.Layers);
38 | for i = 1:numsLayers
39 | is_new_module = true;st = struct();
40 | layerNames = [layerNames;{net.Layers(i).Name}];
41 | currentLayerType = class(net.Layers(i));
42 | if strcmpi(currentLayerType,'nnet.cnn.layer.ImageInputLayer')
43 | moduleTypeList = [moduleTypeList;{'[net]'}];
44 | st = hyperParams;
45 | elseif strcmpi(currentLayerType,'nnet.cnn.layer.Convolution2DLayer')
46 | moduleTypeList = [moduleTypeList;{'[convolutional]'}];
47 | layer = net.Layers(i);
48 | st = struct('filters',sum(layer.NumFilters),...
49 | 'size',layer.FilterSize(1),...
50 | 'pad',floor(layer.FilterSize(1)/2),...% 2020.5.7修改
51 | 'stride',layer.Stride(1),...
52 | 'activation','linear');
53 | elseif strcmpi(currentLayerType, 'nnet.cnn.layer.GroupedConvolution2DLayer')
54 | moduleTypeList = [moduleTypeList;{'[convolutional]'}];
55 | layer = net.Layers(i);
56 | st = struct('groups',layer.NumGroups,...
57 | 'filters',layer.NumGroups*layer.NumFiltersPerGroup,...
58 | 'size',layer.FilterSize(1),...
59 | 'pad',floor(layer.FilterSize(1)/2),...% 2020.5.7修改
60 | 'stride',layer.Stride(1),...
61 | 'activation','linear');
62 | elseif strcmpi(currentLayerType,'nnet.cnn.layer.FullyConnectedLayer')
63 | moduleTypeList = [moduleTypeList;{'[connected]'}];
64 | layer = net.Layers(i);
65 | st = struct('output',layer.OutputSize,...
66 | 'activation','linear');
67 | elseif strcmpi(currentLayerType,'nnet.cnn.layer.BatchNormalizationLayer')
68 | module_idx = module_idx-1;
69 | moduleInfoList{end}.batch_normalize = 1;
70 | is_new_module = false;
71 | elseif strcmpi(currentLayerType,'nnet.cnn.layer.ReLULayer')
72 | module_idx = module_idx-1;
73 | moduleInfoList{end}.activation = 'relu';
74 | is_new_module = false;
75 | elseif strcmpi(currentLayerType,'nnet.cnn.layer.LeakyReLULayer')
76 | module_idx = module_idx-1;
77 | moduleInfoList{end}.activation = 'leaky';
78 | is_new_module = false;
79 | elseif strcmpi(currentLayerType,'mishLayer') % 2020.4.29新加入
80 | module_idx = module_idx-1;
81 | moduleInfoList{end}.activation = 'mish';
82 | is_new_module = false;
83 | elseif strcmpi(currentLayerType,'nnet.onnx.layer.ClipLayer')%当作阈值为6导出
84 | module_idx = module_idx-1;
85 | moduleInfoList{end}.activation = 'relu6'; %实际上类似于matlab的clippedReluLayer,6
86 | is_new_module = false;
87 | elseif strcmpi(currentLayerType,'nnet.cnn.layer.ClippedReLULayer') %当作阈值为6导出
88 | module_idx = module_idx-1;
89 | moduleInfoList{end}.activation = 'relu6'; %实际上类似于matlab的clippedReluLayer,6
90 | is_new_module = false;
91 | elseif strcmpi(currentLayerType,'nnet.cnn.layer.MaxPooling2DLayer')
92 | moduleTypeList = [moduleTypeList;{'[maxpool]'}];
93 | layer = net.Layers(i);
94 | if i==numsLayers-3||i==numsLayers-2 % 最后一层,留作自动推断特征图大小
95 | st = struct();
96 | else
97 | if strcmp(layer.PaddingMode,'manual')
98 | st = struct('size',layer.PoolSize(1),...
99 | 'stride',layer.Stride(1),...
100 | 'padding',layer.PaddingSize(1));
101 | else
102 | st = struct('size',layer.PoolSize(1),...
103 | 'stride',layer.Stride(1));
104 | end
105 | end
106 | elseif strcmpi(currentLayerType,'nnet.cnn.layer.GlobalMaxPooling2DLayer')
107 | moduleTypeList = [moduleTypeList;{'[maxpool]'}];
108 | if i==numsLayers-3||i==numsLayers-2% 最后一层,留作自动推断特征图大小
109 | st = struct();
110 | end
111 | elseif strcmpi(currentLayerType,'nnet.cnn.layer.AveragePooling2DLayer')
112 | moduleTypeList = [moduleTypeList;{'[avgpool]'}];
113 | layer = net.Layers(i);
114 | if i==numsLayers-3||i==numsLayers-2% 最后一层,留作自动推断特征图大小
115 | st = struct();
116 | else
117 | if strcmp(layer.PaddingMode,'manual')
118 | st = struct('size',layer.PoolSize(1),...
119 | 'stride',layer.Stride(1),...
120 | 'padding',layer.PaddingSize(1));
121 | else
122 | st = struct('size',layer.PoolSize(1),...
123 | 'stride',layer.Stride(1));
124 | end
125 | end
126 | elseif strcmpi(currentLayerType,'nnet.cnn.layer.GlobalAveragePooling2DLayer')
127 | moduleTypeList = [moduleTypeList;{'[avgpool]'}];
128 | if i==numsLayers-3||i==numsLayers-2% 最后一层,留作自动推断特征图大小
129 | st = struct();
130 | end
131 | elseif strcmpi(currentLayerType,'nnet.cnn.layer.SoftmaxLayer')
132 | moduleTypeList = [moduleTypeList;{'[softmax]'}];
133 | st = struct('groups',1);
134 | elseif strcmpi(currentLayerType,'nnet.cnn.layer.AdditionLayer')
135 | moduleTypeList = [moduleTypeList;{'[shortcut]'}];
136 | st = struct('from',[],'activation','linear');
137 | layer_name = layerNames{i};
138 | index_Dlogical = startsWith(net.Connections.Destination,[layer_name,'/']);
139 | source = net.Connections.Source(index_Dlogical);
140 | index_Slogical = contains(layerNames(1:end-1),source);
141 | st.from = layerToModuleIndex(index_Slogical)-2; % -2 darknet module 是以第一个非[net]开始的module为0的计数
142 | st.from = num2str(min(st.from)); % 2019.8.29修改
143 | elseif strcmpi(currentLayerType,'nnet.cnn.layer.DepthConcatenationLayer')
144 | moduleTypeList = [moduleTypeList;{'[route]'}];
145 | st = struct('layers',[]);
146 | layer_name = layerNames{i};
147 | index_Dlogical = startsWith(net.Connections.Destination,[layer_name,'/']);
148 | source = net.Connections.Source(index_Dlogical);
149 | index_Slogical = ismember(layerNames(1:end-1),source); % 2020.4.29日contains改为ismember
150 | st.layers = layerToModuleIndex(index_Slogical)-2; % -2 darknet module 是以第一个非[net]开始的module为0的计数
151 | st.layers = join(string(flip(st.layers)),','); % 注意route多个层连接顺序,先连接最近的层,再连接较远的层
152 | elseif strcmpi(currentLayerType,'nnet.cnn.layer.DropoutLayer')
153 | moduleTypeList = [moduleTypeList;{'[dropout]'}];
154 | layer = net.Layers(i);
155 | st = struct('probability',layer.Probability);
156 | elseif strcmpi(currentLayerType,'upsample2dLayer')
157 | moduleTypeList = [moduleTypeList;{'[upsample]'}];
158 | layer = net.Layers(i);
159 | st = struct('stride',layer.size);
160 | elseif strcmpi(currentLayerType,'empty2dLayer')
161 | moduleTypeList = [moduleTypeList;{'[route]'}];
162 | layer = net.Layers(i);
163 | st = struct('layers',[]);
164 | st.layers = layer.connectID;
165 | elseif strcmpi(currentLayerType,'sliceLayer')
166 | moduleTypeList = [moduleTypeList;{'[route]'}];
167 | layer = net.Layers(i);
168 | st = struct('layers',layer.connectID,...
169 | 'groups',layer.groups,...
170 | 'group_id',layer.group_id-1);
171 | elseif strcmpi(currentLayerType,'yoloV3Layer')
172 | moduleTypeList = [moduleTypeList;{'[yolo]'}];
173 | layer = net.Layers(i);
174 | anchors = layer.anchors';% 2*n
175 | anchors = reshape(anchors(:),1,[]); % 1*m
176 | st = struct('mask',join(string(layer.mask-1),','),...
177 | 'anchors',join(string(anchors),','),...
178 | 'classes',num2str(layer.classes),...
179 | 'num',num2str(layer.num),...
180 | 'jitter',num2str(layer.jitter),...
181 | 'ignore_thresh',num2str(layer.ignore_thresh),...
182 | 'truth_thresh',num2str(layer.truth_thresh),...
183 | 'random',num2str(layer.random));
184 | elseif strcmpi(currentLayerType, 'nnet.cnn.layer.ClassificationOutputLayer')
185 | continue;
186 | else
187 | moduleTypeList = [moduleTypeList;{'[unknow]'}];% 这里需要手动在cfg文件中修改
188 | st = struct('error',['unsupported this type:',currentLayerType,...
189 | ',you should manully modify it!']);
190 | end
191 | % 更新
192 | if is_new_module
193 | moduleInfoList = [moduleInfoList;{st}];
194 | end
195 | layerToModuleIndex = [layerToModuleIndex;module_idx];
196 | module_idx = module_idx+1;
197 | end % 终止解析
198 |
199 | %% cutoff
200 | if cutoffModule
201 | moduleTypeList(cutoffModule+2:end) = [];
202 | moduleInfoList(cutoffModule+2:end) = [];
203 | end
204 |
205 | %% 2、写入cfg模型描述文件
206 | assert(length(moduleTypeList)==length(moduleInfoList));
207 | nums_module = length(moduleTypeList);
208 | fid_cfg = fopen(cfgfileName,'w');
209 | for i = 1:nums_module
210 | currentModuleType = moduleTypeList{i};% currentModuleType是字符向量类型
211 | currentModuleInfo = moduleInfoList{i}; % currentModuleInfo是struct类型
212 | % 逐个module参数写入
213 | if i==1
214 | fprintf(fid_cfg,'%s\n','# This file is automatically generated by MATLAB and may require you to modify it manually');% 注释部分
215 | fprintf(fid_cfg,'%s\n',currentModuleType);% module的名字
216 | else
217 | fprintf(fid_cfg,'%s\n',['# darknet module ID:',num2str(i-2)]); %cfg中正式部分
218 | fprintf(fid_cfg,'%s\n',currentModuleType);% module的名字
219 | end
220 | fields = sort(fieldnames(currentModuleInfo));
221 | if (~isempty(fields)) && contains(fields{1},'activation')
222 | fields = circshift(fields,-1);% 左移一位,即移到最后
223 | end
224 | for j = 1:length(fields) %写入module的结构体信息
225 | fieldname = fields{j};
226 | fieldvalue = currentModuleInfo.(fieldname);
227 | fprintf(fid_cfg,'%s=%s\n',fieldname,num2str(fieldvalue));% module的名字
228 | end
229 | fprintf(fid_cfg,'\n');
230 | end
231 | fclose(fid_cfg);
232 |
233 | %% 3、保存weights权重
234 | fid_weight = fopen(weightfileName,'wb');
235 | fwrite(fid_weight,[0,2,5],'int32');% version
236 | fwrite(fid_weight,0,'int64'); % number images in train
237 | nums_module = length(moduleTypeList);
238 | for module_index = 1:nums_module
239 | currentModuleType = moduleTypeList{module_index};% 字符向量
240 | currentModuleInfo = moduleInfoList{module_index}; % struct
241 | currentModule = net.Layers(module_index == layerToModuleIndex);
242 | if strcmp(currentModuleType,'[convolutional]')||strcmp(currentModuleType,'[connected]')
243 | conv_layer = currentModule(1);
244 | % 如果该module有BN,首先存储BN的参数
245 | if isfield(currentModuleInfo,'batch_normalize') % darknet一个弊端,丢弃了conv bias的参数
246 | bn_layer = currentModule(2);
247 | bn_bias = bn_layer.Offset;
248 | fwrite(fid_weight,bn_bias(:),'single');
249 | bn_weights = bn_layer.Scale;
250 | fwrite(fid_weight,bn_weights(:),'single');
251 | bn_mean = bn_layer.TrainedMean;
252 | fwrite(fid_weight,bn_mean(:),'single');
253 | bn_var = bn_layer.TrainedVariance;
254 | fwrite(fid_weight,bn_var(:),'single');
255 | else
256 | % conv bias
257 | conv_bias = conv_layer.Bias;
258 | conv_bias = permute(conv_bias,[2,1,3,4]);% 支持 groupedConvolution2dLayer
259 | fwrite(fid_weight,conv_bias(:),'single');
260 | end
261 | % conv weights
262 | conv_weights = conv_layer.Weights;
263 | conv_weights = permute(conv_weights,[2,1,3,4,5]);% 支持 groupedConvolution2dLayer
264 | fwrite(fid_weight,conv_weights(:),'single');
265 | end
266 | end
267 | fclose(fid_weight);
268 |
269 |
--------------------------------------------------------------------------------
/cfg/yolov3.cfg:
--------------------------------------------------------------------------------
1 | [net]
2 | # Testing
3 | # batch=1
4 | # subdivisions=1
5 | # Training
6 | batch=64
7 | subdivisions=16
8 | width=416
9 | height=416
10 | channels=3
11 | momentum=0.9
12 | decay=0.0005
13 | angle=0
14 | saturation = 1.5
15 | exposure = 1.5
16 | hue=.1
17 |
18 | learning_rate=0.001
19 | burn_in=1000
20 | max_batches = 500200
21 | policy=steps
22 | steps=400000,450000
23 | scales=.1,.1
24 |
25 | [convolutional]
26 | batch_normalize=1
27 | filters=32
28 | size=3
29 | stride=1
30 | pad=1
31 | activation=leaky
32 |
33 | # Downsample
34 |
35 | [convolutional]
36 | batch_normalize=1
37 | filters=64
38 | size=3
39 | stride=2
40 | pad=1
41 | activation=leaky
42 |
43 | [convolutional]
44 | batch_normalize=1
45 | filters=32
46 | size=1
47 | stride=1
48 | pad=1
49 | activation=leaky
50 |
51 | [convolutional]
52 | batch_normalize=1
53 | filters=64
54 | size=3
55 | stride=1
56 | pad=1
57 | activation=leaky
58 |
59 | [shortcut]
60 | from=-3
61 | activation=linear
62 |
63 | # Downsample
64 |
65 | [convolutional]
66 | batch_normalize=1
67 | filters=128
68 | size=3
69 | stride=2
70 | pad=1
71 | activation=leaky
72 |
73 | [convolutional]
74 | batch_normalize=1
75 | filters=64
76 | size=1
77 | stride=1
78 | pad=1
79 | activation=leaky
80 |
81 | [convolutional]
82 | batch_normalize=1
83 | filters=128
84 | size=3
85 | stride=1
86 | pad=1
87 | activation=leaky
88 |
89 | [shortcut]
90 | from=-3
91 | activation=linear
92 |
93 | [convolutional]
94 | batch_normalize=1
95 | filters=64
96 | size=1
97 | stride=1
98 | pad=1
99 | activation=leaky
100 |
101 | [convolutional]
102 | batch_normalize=1
103 | filters=128
104 | size=3
105 | stride=1
106 | pad=1
107 | activation=leaky
108 |
109 | [shortcut]
110 | from=-3
111 | activation=linear
112 |
113 | # Downsample
114 |
115 | [convolutional]
116 | batch_normalize=1
117 | filters=256
118 | size=3
119 | stride=2
120 | pad=1
121 | activation=leaky
122 |
123 | [convolutional]
124 | batch_normalize=1
125 | filters=128
126 | size=1
127 | stride=1
128 | pad=1
129 | activation=leaky
130 |
131 | [convolutional]
132 | batch_normalize=1
133 | filters=256
134 | size=3
135 | stride=1
136 | pad=1
137 | activation=leaky
138 |
139 | [shortcut]
140 | from=-3
141 | activation=linear
142 |
143 | [convolutional]
144 | batch_normalize=1
145 | filters=128
146 | size=1
147 | stride=1
148 | pad=1
149 | activation=leaky
150 |
151 | [convolutional]
152 | batch_normalize=1
153 | filters=256
154 | size=3
155 | stride=1
156 | pad=1
157 | activation=leaky
158 |
159 | [shortcut]
160 | from=-3
161 | activation=linear
162 |
163 | [convolutional]
164 | batch_normalize=1
165 | filters=128
166 | size=1
167 | stride=1
168 | pad=1
169 | activation=leaky
170 |
171 | [convolutional]
172 | batch_normalize=1
173 | filters=256
174 | size=3
175 | stride=1
176 | pad=1
177 | activation=leaky
178 |
179 | [shortcut]
180 | from=-3
181 | activation=linear
182 |
183 | [convolutional]
184 | batch_normalize=1
185 | filters=128
186 | size=1
187 | stride=1
188 | pad=1
189 | activation=leaky
190 |
191 | [convolutional]
192 | batch_normalize=1
193 | filters=256
194 | size=3
195 | stride=1
196 | pad=1
197 | activation=leaky
198 |
199 | [shortcut]
200 | from=-3
201 | activation=linear
202 |
203 |
204 | [convolutional]
205 | batch_normalize=1
206 | filters=128
207 | size=1
208 | stride=1
209 | pad=1
210 | activation=leaky
211 |
212 | [convolutional]
213 | batch_normalize=1
214 | filters=256
215 | size=3
216 | stride=1
217 | pad=1
218 | activation=leaky
219 |
220 | [shortcut]
221 | from=-3
222 | activation=linear
223 |
224 | [convolutional]
225 | batch_normalize=1
226 | filters=128
227 | size=1
228 | stride=1
229 | pad=1
230 | activation=leaky
231 |
232 | [convolutional]
233 | batch_normalize=1
234 | filters=256
235 | size=3
236 | stride=1
237 | pad=1
238 | activation=leaky
239 |
240 | [shortcut]
241 | from=-3
242 | activation=linear
243 |
244 | [convolutional]
245 | batch_normalize=1
246 | filters=128
247 | size=1
248 | stride=1
249 | pad=1
250 | activation=leaky
251 |
252 | [convolutional]
253 | batch_normalize=1
254 | filters=256
255 | size=3
256 | stride=1
257 | pad=1
258 | activation=leaky
259 |
260 | [shortcut]
261 | from=-3
262 | activation=linear
263 |
264 | [convolutional]
265 | batch_normalize=1
266 | filters=128
267 | size=1
268 | stride=1
269 | pad=1
270 | activation=leaky
271 |
272 | [convolutional]
273 | batch_normalize=1
274 | filters=256
275 | size=3
276 | stride=1
277 | pad=1
278 | activation=leaky
279 |
280 | [shortcut]
281 | from=-3
282 | activation=linear
283 |
284 | # Downsample
285 |
286 | [convolutional]
287 | batch_normalize=1
288 | filters=512
289 | size=3
290 | stride=2
291 | pad=1
292 | activation=leaky
293 |
294 | [convolutional]
295 | batch_normalize=1
296 | filters=256
297 | size=1
298 | stride=1
299 | pad=1
300 | activation=leaky
301 |
302 | [convolutional]
303 | batch_normalize=1
304 | filters=512
305 | size=3
306 | stride=1
307 | pad=1
308 | activation=leaky
309 |
310 | [shortcut]
311 | from=-3
312 | activation=linear
313 |
314 |
315 | [convolutional]
316 | batch_normalize=1
317 | filters=256
318 | size=1
319 | stride=1
320 | pad=1
321 | activation=leaky
322 |
323 | [convolutional]
324 | batch_normalize=1
325 | filters=512
326 | size=3
327 | stride=1
328 | pad=1
329 | activation=leaky
330 |
331 | [shortcut]
332 | from=-3
333 | activation=linear
334 |
335 |
336 | [convolutional]
337 | batch_normalize=1
338 | filters=256
339 | size=1
340 | stride=1
341 | pad=1
342 | activation=leaky
343 |
344 | [convolutional]
345 | batch_normalize=1
346 | filters=512
347 | size=3
348 | stride=1
349 | pad=1
350 | activation=leaky
351 |
352 | [shortcut]
353 | from=-3
354 | activation=linear
355 |
356 |
357 | [convolutional]
358 | batch_normalize=1
359 | filters=256
360 | size=1
361 | stride=1
362 | pad=1
363 | activation=leaky
364 |
365 | [convolutional]
366 | batch_normalize=1
367 | filters=512
368 | size=3
369 | stride=1
370 | pad=1
371 | activation=leaky
372 |
373 | [shortcut]
374 | from=-3
375 | activation=linear
376 |
377 | [convolutional]
378 | batch_normalize=1
379 | filters=256
380 | size=1
381 | stride=1
382 | pad=1
383 | activation=leaky
384 |
385 | [convolutional]
386 | batch_normalize=1
387 | filters=512
388 | size=3
389 | stride=1
390 | pad=1
391 | activation=leaky
392 |
393 | [shortcut]
394 | from=-3
395 | activation=linear
396 |
397 |
398 | [convolutional]
399 | batch_normalize=1
400 | filters=256
401 | size=1
402 | stride=1
403 | pad=1
404 | activation=leaky
405 |
406 | [convolutional]
407 | batch_normalize=1
408 | filters=512
409 | size=3
410 | stride=1
411 | pad=1
412 | activation=leaky
413 |
414 | [shortcut]
415 | from=-3
416 | activation=linear
417 |
418 |
419 | [convolutional]
420 | batch_normalize=1
421 | filters=256
422 | size=1
423 | stride=1
424 | pad=1
425 | activation=leaky
426 |
427 | [convolutional]
428 | batch_normalize=1
429 | filters=512
430 | size=3
431 | stride=1
432 | pad=1
433 | activation=leaky
434 |
435 | [shortcut]
436 | from=-3
437 | activation=linear
438 |
439 | [convolutional]
440 | batch_normalize=1
441 | filters=256
442 | size=1
443 | stride=1
444 | pad=1
445 | activation=leaky
446 |
447 | [convolutional]
448 | batch_normalize=1
449 | filters=512
450 | size=3
451 | stride=1
452 | pad=1
453 | activation=leaky
454 |
455 | [shortcut]
456 | from=-3
457 | activation=linear
458 |
459 | # Downsample
460 |
461 | [convolutional]
462 | batch_normalize=1
463 | filters=1024
464 | size=3
465 | stride=2
466 | pad=1
467 | activation=leaky
468 |
469 | [convolutional]
470 | batch_normalize=1
471 | filters=512
472 | size=1
473 | stride=1
474 | pad=1
475 | activation=leaky
476 |
477 | [convolutional]
478 | batch_normalize=1
479 | filters=1024
480 | size=3
481 | stride=1
482 | pad=1
483 | activation=leaky
484 |
485 | [shortcut]
486 | from=-3
487 | activation=linear
488 |
489 | [convolutional]
490 | batch_normalize=1
491 | filters=512
492 | size=1
493 | stride=1
494 | pad=1
495 | activation=leaky
496 |
497 | [convolutional]
498 | batch_normalize=1
499 | filters=1024
500 | size=3
501 | stride=1
502 | pad=1
503 | activation=leaky
504 |
505 | [shortcut]
506 | from=-3
507 | activation=linear
508 |
509 | [convolutional]
510 | batch_normalize=1
511 | filters=512
512 | size=1
513 | stride=1
514 | pad=1
515 | activation=leaky
516 |
517 | [convolutional]
518 | batch_normalize=1
519 | filters=1024
520 | size=3
521 | stride=1
522 | pad=1
523 | activation=leaky
524 |
525 | [shortcut]
526 | from=-3
527 | activation=linear
528 |
529 | [convolutional]
530 | batch_normalize=1
531 | filters=512
532 | size=1
533 | stride=1
534 | pad=1
535 | activation=leaky
536 |
537 | [convolutional]
538 | batch_normalize=1
539 | filters=1024
540 | size=3
541 | stride=1
542 | pad=1
543 | activation=leaky
544 |
545 | [shortcut]
546 | from=-3
547 | activation=linear
548 |
549 | ######################
550 |
551 | [convolutional]
552 | batch_normalize=1
553 | filters=512
554 | size=1
555 | stride=1
556 | pad=1
557 | activation=leaky
558 |
559 | [convolutional]
560 | batch_normalize=1
561 | size=3
562 | stride=1
563 | pad=1
564 | filters=1024
565 | activation=leaky
566 |
567 | [convolutional]
568 | batch_normalize=1
569 | filters=512
570 | size=1
571 | stride=1
572 | pad=1
573 | activation=leaky
574 |
575 | [convolutional]
576 | batch_normalize=1
577 | size=3
578 | stride=1
579 | pad=1
580 | filters=1024
581 | activation=leaky
582 |
583 | [convolutional]
584 | batch_normalize=1
585 | filters=512
586 | size=1
587 | stride=1
588 | pad=1
589 | activation=leaky
590 |
591 | [convolutional]
592 | batch_normalize=1
593 | size=3
594 | stride=1
595 | pad=1
596 | filters=1024
597 | activation=leaky
598 |
599 | [convolutional]
600 | size=1
601 | stride=1
602 | pad=1
603 | filters=255
604 | activation=linear
605 |
606 |
607 | [yolo]
608 | mask = 6,7,8
609 | anchors = 10,13, 16,30, 33,23, 30,61, 62,45, 59,119, 116,90, 156,198, 373,326
610 | classes=80
611 | num=9
612 | jitter=.3
613 | ignore_thresh = .7
614 | truth_thresh = 1
615 | random=1
616 |
617 |
618 | [route]
619 | layers = -4
620 |
621 | [convolutional]
622 | batch_normalize=1
623 | filters=256
624 | size=1
625 | stride=1
626 | pad=1
627 | activation=leaky
628 |
629 | [upsample]
630 | stride=2
631 |
632 | [route]
633 | layers = -1, 61
634 |
635 |
636 |
637 | [convolutional]
638 | batch_normalize=1
639 | filters=256
640 | size=1
641 | stride=1
642 | pad=1
643 | activation=leaky
644 |
645 | [convolutional]
646 | batch_normalize=1
647 | size=3
648 | stride=1
649 | pad=1
650 | filters=512
651 | activation=leaky
652 |
653 | [convolutional]
654 | batch_normalize=1
655 | filters=256
656 | size=1
657 | stride=1
658 | pad=1
659 | activation=leaky
660 |
661 | [convolutional]
662 | batch_normalize=1
663 | size=3
664 | stride=1
665 | pad=1
666 | filters=512
667 | activation=leaky
668 |
669 | [convolutional]
670 | batch_normalize=1
671 | filters=256
672 | size=1
673 | stride=1
674 | pad=1
675 | activation=leaky
676 |
677 | [convolutional]
678 | batch_normalize=1
679 | size=3
680 | stride=1
681 | pad=1
682 | filters=512
683 | activation=leaky
684 |
685 | [convolutional]
686 | size=1
687 | stride=1
688 | pad=1
689 | filters=255
690 | activation=linear
691 |
692 |
693 | [yolo]
694 | mask = 3,4,5
695 | anchors = 10,13, 16,30, 33,23, 30,61, 62,45, 59,119, 116,90, 156,198, 373,326
696 | classes=80
697 | num=9
698 | jitter=.3
699 | ignore_thresh = .7
700 | truth_thresh = 1
701 | random=1
702 |
703 |
704 |
705 | [route]
706 | layers = -4
707 |
708 | [convolutional]
709 | batch_normalize=1
710 | filters=128
711 | size=1
712 | stride=1
713 | pad=1
714 | activation=leaky
715 |
716 | [upsample]
717 | stride=2
718 |
719 | [route]
720 | layers = -1, 36
721 |
722 |
723 |
724 | [convolutional]
725 | batch_normalize=1
726 | filters=128
727 | size=1
728 | stride=1
729 | pad=1
730 | activation=leaky
731 |
732 | [convolutional]
733 | batch_normalize=1
734 | size=3
735 | stride=1
736 | pad=1
737 | filters=256
738 | activation=leaky
739 |
740 | [convolutional]
741 | batch_normalize=1
742 | filters=128
743 | size=1
744 | stride=1
745 | pad=1
746 | activation=leaky
747 |
748 | [convolutional]
749 | batch_normalize=1
750 | size=3
751 | stride=1
752 | pad=1
753 | filters=256
754 | activation=leaky
755 |
756 | [convolutional]
757 | batch_normalize=1
758 | filters=128
759 | size=1
760 | stride=1
761 | pad=1
762 | activation=leaky
763 |
764 | [convolutional]
765 | batch_normalize=1
766 | size=3
767 | stride=1
768 | pad=1
769 | filters=256
770 | activation=leaky
771 |
772 | [convolutional]
773 | size=1
774 | stride=1
775 | pad=1
776 | filters=255
777 | activation=linear
778 |
779 |
780 | [yolo]
781 | mask = 0,1,2
782 | anchors = 10,13, 16,30, 33,23, 30,61, 62,45, 59,119, 116,90, 156,198, 373,326
783 | classes=80
784 | num=9
785 | jitter=.3
786 | ignore_thresh = .7
787 | truth_thresh = 1
788 | random=1
--------------------------------------------------------------------------------
/train.m:
--------------------------------------------------------------------------------
1 | addpath('./CustomLayers/','./utils/')
2 | %% 1、准备数据,适合yolov3,yolov4,无需VOC-xml格式
3 | % 数据问题参考,满足以下其一即可:
4 | % 1、matlab中标注参考 https://ww2.mathworks.cn/help/vision/ug/get-started-with-the-image-labeler.html?requestedDomain=cn
5 | % 2、外部标注文件导入到matlab参考 https://github.com/cuixing158/imageLabeler-API.git
6 | load gTruth.mat % 自己bbox标注文件,格式参考上面链接,最终为table类型,看起来直观
7 | cfg_file = './cfg/yolov3-tiny.cfg';
8 | weight_file = './weights/yolov3-tiny.weights'; %预训练backbone权重,其他类型也OK
9 | annotateImgHeight = 416; % 自己标注的图像原始高度
10 | annotateImgWeight = 416; % 自己标注的图像原始宽度
11 |
12 | % 类别名字和对应的ID序号
13 | classesNames = gTruth.Properties.VariableNames(2:end);
14 | classIDs = (0:length(classesNames)-1);% 从0开始标注,保持与darknet官网一致
15 | numClasses = length(classesNames);
16 | structNamesIDs = struct();
17 | for i = 1:numClasses
18 | structNamesIDs.(classesNames{i}) = classIDs(i);
19 | end
20 |
21 | % 创建可迭代的数据集
22 | bldsTrain = boxLabelDatastore(gTruth(:, 2:end));
23 | imdsTrain = imageDatastore(gTruth.imageFilename);
24 | miniBatch = 16;
25 | imdsTrain.ReadSize = miniBatch;
26 | bldsTrain.ReadSize = miniBatch;
27 | trainingData = combine(imdsTrain, bldsTrain);
28 |
29 | %% 设定超参数,导入训练权重或者导入matlab其他官方预训练权重,这里以darknet中的".weight"二进制权重
30 | [lgModel,hyperParams] = importDarknetWeights(cfg_file,weight_file);
31 | % analyzeNetwork(lgModel);
32 |
33 | inputWeight = str2double(hyperParams.width);
34 | inputHeight = str2double(hyperParams.height);
35 | networkInputSize = [inputHeight inputWeight 3];
36 | preprocessedTrainingData = transform(trainingData,@(data)preprocessTrainData(data,networkInputSize,structNamesIDs));
37 |
38 | % 预览数据
39 | for k = 1:1
40 | data = read(preprocessedTrainingData);
41 | I = data{1,1}{1};
42 | bbox = data{1,2}{1};
43 | annotatedImage = zeros(size(I),'like',I);
44 | for i = 1:size(I,4)
45 | annotatedImage(:,:,:,i) = insertShape(I(:,:,:,i),'Rectangle',bbox{i}(:,1:4));
46 | end
47 | annotatedImage = imresize(annotatedImage,2);
48 | figure
49 | montage(annotatedImage)
50 | end
51 |
52 | numAnchors = 6;
53 | anchorBoxes = estimateAnchorBoxes(trainingData,numAnchors);% anchorBoxes是networkInputSize上的大小,但是 estimateAnchorBoxes函数输入参数限制太死,无法把preprocessedTrainingData传入
54 | area = anchorBoxes(:, 1).*anchorBoxes(:, 2);
55 | [~, idx] = sort(area, 'descend');
56 | anchorBoxes = anchorBoxes(idx, :);
57 | anchorBoxes = round(anchorBoxes);
58 | anchorBoxMasks = {[1,2,3],[4,5,6]};% 面积大的anchor结合特征图较小的yolov3层,面积小的anchor结合特征图较大的yolov3层
59 |
60 |
61 | %% 2,搭建darknet网络,加入yolov3Layer
62 | anchorBoxes(:,[2,1]) = anchorBoxes(:,[1,2]);% anchorBoxes现在是宽高,与darknet官网保持一致
63 | imageSize = lgModel.Layers(1).InputSize(1:2);
64 | yoloModule1 = [convolution2dLayer(1,length(anchorBoxMasks{1})*(5+numClasses),'Name','yoloconv1');
65 | yolov3Layer('yolov3layer1',anchorBoxMasks{1},anchorBoxes,numClasses,1,imageSize)];
66 | yoloModule2 = [convolution2dLayer(1,length(anchorBoxMasks{2})*(5+numClasses),'Name','yoloconv2');
67 | yolov3Layer('yolov3layer2',anchorBoxMasks{2},anchorBoxes,numClasses,2,imageSize)];
68 | lgModel = removeLayers(lgModel,{'yolo_v3_id1','yolo_v3_id2'});
69 | lgModel = replaceLayer(lgModel,'conv_17',yoloModule1);
70 | lgModel = replaceLayer(lgModel,'conv_24',yoloModule2);
71 |
72 | analyzeNetwork(lgModel);
73 | yoloLayerNumber = [36,47];% yolov3层在layers数组中的位置,看模型图得出!!!
74 | model = dlnetwork(lgModel); % dlnetwork函数耗时过长!一个转换操作而已
75 |
76 | %% 3,for loop循环迭代更新模型
77 | % 训练选项
78 | learningRate = 0.001;
79 | scheduler = @(epoch,epochs)0.5*(1+cos(epoch*pi/epochs));% cosine https://arxiv.org/pdf/1812.01187.pdf
80 | l2Regularization = 0.0005;
81 | velocity = [];
82 |
83 | executionEnvironment = "auto";
84 | figure;
85 | ax1 = subplot(211);
86 | ax2 = subplot(212);
87 | lossPlotter = animatedline(ax1);
88 | learningRatePlotter = animatedline(ax2);
89 |
90 | nEpochs = 10;
91 | allIteration = 0;
92 | cumLoss = 0;
93 | meanLoss = 0;
94 | for numEpoch = 1:nEpochs
95 | reset(preprocessedTrainingData);% Reset datastore.
96 | iteration = 0;
97 | while hasdata(preprocessedTrainingData)
98 | t_start = tic;
99 | % Custom training loop.
100 | % Read batch of data and create batch of images and
101 | % ground truths.
102 | outDataTable = read(preprocessedTrainingData);
103 | XTrain = outDataTable{1,1}{1};
104 | YTrain = outDataTable{1,2}{1};
105 | if isempty(YTrain)
106 | continue;
107 | end
108 |
109 | % Convert mini-batch of data to dlarray.
110 | XTrain = dlarray(single(XTrain),'SSCB');
111 |
112 | % If training on a GPU, then convert data to gpuArray.
113 | if (executionEnvironment == "auto" && canUseGPU) || executionEnvironment == "gpu"
114 | XTrain = gpuArray(XTrain);
115 | end
116 |
117 | % Evaluate the model gradients and loss using dlfeval and the
118 | % modelGradients function.
119 | [gradients,boxLoss,objLoss,clsLoss,totalLoss,state] = dlfeval(@modelGradients, model, XTrain, YTrain,yoloLayerNumber);
120 |
121 | % Apply L2 regularization.
122 | gradients = dlupdate(@(g,w) g + l2Regularization*w, gradients, model.Learnables);
123 |
124 | % Update the network learnable parameters using the SGDM optimizer.
125 | [model, velocity] = sgdmupdate(model, gradients, velocity, learningRate);
126 |
127 | % Update the state parameters of dlnetwork.
128 | model.State = state;
129 | fprintf('[%d][%d/%d]\t BatchTime(s):%.2f , LR:%.5f, boxLoss:%-12.3f, objLoss:%-12.3f, clsLoss:%-12.3f, totalLoss:%-12.5f, meanLoss:%-12.5f\n',...
130 | numEpoch,iteration+1,floor(numpartitions(preprocessedTrainingData)/miniBatch),...
131 | toc(t_start),learningRate,boxLoss,objLoss,clsLoss,totalLoss,cumLoss/(allIteration+1));
132 | if isnan(totalLoss)
133 | fprintf('loss is nan!');
134 | return
135 | end
136 |
137 | cumLoss = cumLoss+totalLoss;
138 | iteration = iteration +1;
139 | allIteration = allIteration+1;
140 | end
141 | meanLoss = cumLoss/allIteration;
142 |
143 | % save model
144 | if (mod(numEpoch,5)==0) % 设置每5个epoch保存下权重
145 | timeStr = datestr(now,'yyyy_mm_dd_HH_MM_SS');
146 | matlabModel = fullfile('./save',[timeStr,'.mat']);
147 | save(matlabModel,'model');
148 |
149 | cfgFile = fullfile('./cfg',[timeStr,'.cfg']);
150 | darknetModel = fullfile('./weights',[timeStr,'.weights']);
151 | exportDarkNetNetwork(model,hyperParams,cfgFile,darknetModel);
152 | end
153 |
154 | % Update training plot with new points.
155 | addpoints(lossPlotter, numEpoch, double(meanLoss));
156 |
157 | % update scheduler
158 | learningRate = scheduler(numEpoch,nEpochs);
159 | addpoints(learningRatePlotter, numEpoch, learningRate);
160 | drawnow
161 | end
162 |
163 | %% yolov3 损失函数
164 | function [gradients, boxLoss, objLoss, clsLoss, totalLoss, state] = modelGradients(net, XTrain, YTrain,yoloLayerNumber)
165 | % 功能:计算模型梯度,求取损失
166 | % allYoloLayers = net.Layers(yoloLayerNumber);
167 | yolov3layerNames = net.OutputNames;
168 | outFeatureMaps = cell(size(yolov3layerNames));
169 | [outFeatureMaps{:},state] = forward(net,XTrain,'Outputs',yolov3layerNames);
170 | boxLoss = dlarray(0);
171 | objLoss = dlarray(0);
172 | clsLoss = dlarray(0);
173 | for i = 1:length(outFeatureMaps)
174 | currentYOLOV3Layer = net.Layers(yoloLayerNumber(i));
175 | currentFeatureMap = outFeatureMaps{i};
176 |
177 | % 由于yolov3Layer类里面predict函数未改变类属性,故重新给属性赋值
178 | currentYOLOV3Layer.numY = size(currentFeatureMap,1);
179 | currentYOLOV3Layer.numX = size(currentFeatureMap,2);
180 | currentYOLOV3Layer.stride = max(currentYOLOV3Layer.imageSize)./max(currentYOLOV3Layer.numX,...
181 | currentYOLOV3Layer.numY);
182 |
183 | % reshape currentFeatureMap到有意义的维度,h*w*c*bs --> h*w*(5+nc)*na*bs
184 | % --> bs*na*h*w*(5+nc),最终的维度方式与darknet官网兼容
185 | bs = size(currentFeatureMap,4);
186 | h = currentYOLOV3Layer.numY;
187 | w = currentYOLOV3Layer.numX;
188 | na = currentYOLOV3Layer.nAnchors;
189 | nc = currentYOLOV3Layer.classes;
190 | currentFeatureMap = reshape(currentFeatureMap,h,w,5+nc,na,bs);% h*w*(5+nc)*na*bs
191 | currentFeatureMap = permute(currentFeatureMap,[5,4,1,2,3]);% bs*na*h*w*(5+nc)
192 |
193 | % 构建目标值
194 | [tcls,tbox,indices,anchor_grids] = buildTargets(currentYOLOV3Layer,YTrain);
195 | N = size(tcls,1);% N<=na*YTrain中所有检测框的数量,其代表有效的数量
196 | featuresMapSize = size(currentFeatureMap);% bs*na*h*w*(5+nc)
197 | tobj = zeros(featuresMapSize(1:4),'like',currentFeatureMap);% bs*na*h*w
198 | featuresCh = zeros(N,(5+nc),'like',currentFeatureMap);
199 | if N
200 | b = indices(:,1); % N*1
201 | a = indices(:,2); % N*1
202 | gj = indices(:,3); % N*1
203 | gi = indices(:,4); % N*1
204 | for idx = 1:N
205 | featuresChannels = currentFeatureMap(b(idx),a(idx),gj(idx),gi(idx),:);% 1*1*1*1*(5+nc)
206 | featuresChannels = squeeze(featuresChannels);%(5+nc)*1
207 | featuresChannels = featuresChannels';%1*(5+nc)
208 | featuresCh(idx,:) = featuresChannels; % N*(5+nc)
209 | tobj(b(idx),a(idx),gj(idx),gi(idx)) = 1.0;
210 | end
211 |
212 | % mse or GIoU loss
213 | predictXY = sigmoid(featuresCh(:,1:2)); % 大小为N*2,预测对应xy
214 | predictWH = exp(featuresCh(:,3:4)).*anchor_grids;% 大小为N*2
215 | predictBboxs = cat(2,predictXY,predictWH);% 大小为N*4
216 | isUseGIOU = 0;
217 | if isUseGIOU
218 | giouRatio = getGIOU(predictBboxs,tbox);%梯度需要计算,然而反向传播非常耗时
219 | boxLoss = boxLoss+mean(1-giouRatio,'all');
220 | else
221 | boxLoss = boxLoss+mse(predictBboxs,tbox,'DataFormat','BC');
222 | end
223 |
224 | if (nc>1)
225 | tcls_ = zeros('like',featuresCh(:,6:end));
226 | for idx = 1:N
227 | tcls_(idx,tcls+1) = 1.0;% 确保类别标签是从0开始标注的索引,否则这里会超出维度
228 | end
229 | clsLoss = clsLoss + crossentropy(sigmoid(featuresCh(:,6:end)),tcls_,...
230 | 'DataFormat','BC',...
231 | 'TargetCategories','independent');
232 | end
233 | end
234 |
235 | if N
236 | objLoss = objLoss+crossentropy(sigmoid(currentFeatureMap(:,:,:,:,5)),tobj,...
237 | 'DataFormat','BUSS',...
238 | 'TargetCategories','independent');
239 | end
240 | end
241 | totalLoss = boxLoss+objLoss+clsLoss;
242 |
243 | % Compute gradients of learnables with regard to loss.
244 | gradients = dlgradient(totalLoss, net.Learnables);
245 |
246 | boxLoss = gather(extractdata(boxLoss));
247 | objLoss = gather(extractdata(objLoss));
248 | clsLoss = gather(extractdata(clsLoss));
249 | totalLoss = gather(extractdata(totalLoss));
250 | end
251 |
252 | function [tcls,tbox,indices,anchor_grids] = buildTargets(currentYOLOV3Layer,YTrain)
253 | % 功能:构建目标值
254 | % 输入:
255 | % currentYOLOV3Layer:网络中yolo输出层之一
256 | % YTrain:网络目标值,bs*1大小的cell类型,每个cell下包含Mi*[x,y,width,height,classID]大小的矩阵,Mi为第i张图片含有目标的检测数量,
257 | % 注意其存储的坐标值是相对网络输入图像上的坐标,并无归一化
258 | % 输出:
259 | % tcls:目标真实类别classID,N*1大小,每一项存储classID,其中N<=na*sum(Mi),只输出有效数量的类别N
260 | % tbox:目标的boundingBox,存储真实目标在特征图上的位置(除去x,y整数部分,保留小数),N*4大小,每项形式为[Xdecimal,Ydecimal,gw,gh]
261 | % indices:目标检测框在高维数组中的位置,N*4大小,每一项存储检测框的位置,其形式为[bs,na,gy,gx],他们都是从1开始的索引,与Python不同
262 | % anchor_grids:所用有效的在特征图上的anchor,N*2大小,每项形式为[anchor_w,anchor_h]
263 | % 注意:
264 | % 此函数是核心,用于产生各个yolov3损失类型的目标,输出每个参数维度都有意义,顺序要保持一致,总的高维顺序为bs*na*h*w*(5+nc),此顺序为darknet
265 | % 官网的顺序一致,非matlab官方一致
266 | %
267 | % author:cuixingxing
268 | % emalil:cuixingxing150@email.com
269 | % 2020.4.25
270 | %
271 | h = currentYOLOV3Layer.numY;
272 | w = currentYOLOV3Layer.numX;
273 | stride = currentYOLOV3Layer.stride;
274 | bs = size(YTrain,1);
275 |
276 | % 把targets转换成nt*[imageIDs,classIDs,gx,gy,gw,gh]二维矩阵
277 | scalex = w/currentYOLOV3Layer.imageSize(2);
278 | scaley = h/currentYOLOV3Layer.imageSize(1);
279 | gwh = currentYOLOV3Layer.anchorsUse/stride; % 此处anchor_grids大小为na*2
280 | targets = cat(1,YTrain{:}); % nt*5大小矩阵,nt为该bach下目标检测框数量
281 | output = cellfun(@(x)size(x,1),YTrain);
282 | imageIDs = repelem((1:bs)',output);
283 | classIDs = targets(:,5);
284 | targets = [imageIDs,classIDs,targets(:,1:end-1)];% nt*6大小,[imageIDs,classIDs,x,y,w,h]
285 |
286 | % 计算目标检测框在特征图上的大小
287 | targets(:,[3,5]) = targets(:,[3,5]).*scalex;% gx,gw
288 | targets(:,[4,6]) = targets(:,[4,6]).*scaley;% nt*6大小,[imageIDs,classIDs,gx,gy,gw,gh]
289 |
290 | % 分别获取每个anchor每个bbox的target
291 | if ~isempty(targets)
292 | iou = getMaxIOUPredictedWithGroundTruth(gwh,targets(:,5:6));
293 | iouThresh = 0.1;
294 |
295 | reject = true;
296 | if reject
297 | iou(iou2
162 | error('unsupport more than 2 inputs');
163 | end
164 | if length(connectID)==1
165 | module_idx1 = i-1;
166 | temp = str2double(connectID);
167 | module_idx2 = getModuleIdx(i,temp);
168 | else
169 | temp1 = str2double(connectID(1));temp2 = str2double(connectID(2));
170 | module_idx1 = getModuleIdx(i,temp1);
171 | module_idx2 = getModuleIdx(i,temp2);
172 | end
173 | if moduleInfoList{module_idx1}.channels~=moduleInfoList{module_idx2}.channels % yolov3-tiny-prn.cfg https://github.com/WongKinYiu/PartialResidualNetworks
174 | add_layer = prnAdditionLayer(2,['prn_add_',num2str(i)]);
175 | moduleInfoList{i}.channels =min(moduleInfoList{module_idx1}.channels,...
176 | moduleInfoList{module_idx2}.channels);
177 | else
178 | add_layer = additionLayer(2,'Name',['add_',num2str(i)]);
179 | moduleInfoList{i}.channels =moduleInfoList{module_idx1}.channels;
180 | end
181 | moduleInfoList{i}.mapSize = moduleInfoList{module_idx1}.mapSize;
182 |
183 | % 添加relu层
184 | if strcmp(currentModuleInfo.activation,'relu')
185 | relu_layer = reluLayer('Name',['relu_',num2str(i)]);
186 | elseif strcmp(currentModuleInfo.activation,'relu6')
187 | relu_layer = clippedReluLayer(6,'Name',['clipRelu_',num2str(i)]);
188 | elseif strcmp(currentModuleInfo.activation,'leaky')
189 | relu_layer = leakyReluLayer('Name',['leaky_',num2str(i)]);
190 | elseif strcmp(currentModuleInfo.activation,'mish')
191 | relu_layer = mishLayer(['mish_',num2str(i)]);
192 | end
193 | moduleLayers = [add_layer;relu_layer];
194 | lgraph = addLayers(lgraph,moduleLayers);
195 | lgraph = connectLayers(lgraph,...
196 | lastModuleNames{module_idx1},[moduleLayers(1).Name,'/in1']);
197 | lgraph = connectLayers(lgraph,...
198 | lastModuleNames{module_idx2},[moduleLayers(1).Name,'/in2']);
199 | case '[route]'
200 | moduleLayers = [];depth_layer = [];
201 | connectID = strip(split(currentModuleInfo.layers,','));
202 | numberCon = length(connectID);
203 | if numberCon==1 % 只有一个连接的时候,可能为empty Layer也可能为yolov4-tiny的分组通道layer,在matlab中自定义sliceLayer
204 | temp = str2double(connectID);
205 | module_idx = getModuleIdx(i,temp);
206 | if all(isfield(currentModuleInfo,{'groups','group_id'}))
207 | numGroups = str2double(currentModuleInfo.groups);
208 | groupID = str2double(currentModuleInfo.group_id);
209 | depth_layer = sliceLayer(['slice_',num2str(i)],module_idx-2,numGroups,groupID+1);
210 | moduleInfoList{i}.channels = moduleInfoList{module_idx}.channels/numGroups;
211 | moduleInfoList{i}.mapSize = moduleInfoList{module_idx}.mapSize;
212 | else % 只有一个连接的时候,并且只有'layers'关键字,另一个不是默认上一层,与shortcut层单个值不同,此时为empty Layer
213 | depth_layer = empty2dLayer(['empty_',num2str(i)],module_idx-2);
214 | moduleInfoList{i}.channels = moduleInfoList{module_idx}.channels;
215 | moduleInfoList{i}.mapSize = moduleInfoList{module_idx}.mapSize;
216 | end
217 | else % 此时为depthConcatenation Layer
218 | depth_layer = depthConcatenationLayer(numberCon,'Name',['concat_',num2str(i)]);
219 | module_idx = ones(numberCon,1);
220 | channels_add = zeros(numberCon,1);
221 | for routeii = 1:numberCon % 注意通道连接有顺序要求!不能搞反
222 | temp = str2double(connectID(routeii));
223 | module_idx(routeii) = getModuleIdx(i,temp);
224 | channels_add(routeii) = moduleInfoList{module_idx(routeii)}.channels;
225 | end
226 | moduleInfoList{i}.channels = sum(channels_add);
227 | moduleInfoList{i}.mapSize = moduleInfoList{module_idx(1)}.mapSize;
228 | end
229 |
230 | moduleLayers = [depth_layer;];
231 | lgraph = addLayers(lgraph,moduleLayers);
232 | if numberCon == 1
233 | lgraph = connectLayers(lgraph,...
234 | lastModuleNames{module_idx},moduleLayers(1).Name);
235 | else
236 | for routeii = 1:numberCon
237 | lgraph = connectLayers(lgraph,...
238 | lastModuleNames{module_idx(routeii)},[moduleLayers(1).Name,'/in',num2str(routeii)]);
239 | end
240 | end
241 | case '[avgpool]'
242 | moduleLayers = [];avg_layer = [];
243 | poolsize = moduleInfoList{i-1}.mapSize;
244 | pad =0;stride=1;
245 | if isempty(currentModuleInfo) % 为空时候,自动推断大小,即为上一层特征图大小
246 | avg_layer = averagePooling2dLayer(poolsize,'Padding',pad,...
247 | 'Stride',stride,'Name',['avgPool_',num2str(i)]);
248 | else
249 | poolsize = str2double(currentModuleInfo.size);
250 | stride = str2double(currentModuleInfo.stride);
251 | pad = 'same'; % 确保stride为1时候,特征图大小不变
252 | if isfield(currentModuleInfo,'padding')
253 | pad = str2double(currentModuleInfo.padding);
254 | end
255 | avg_layer = averagePooling2dLayer(poolsize,'Padding',pad,...
256 | 'Stride',stride,'Name',['avgPool_',num2str(i)]);
257 | end
258 | moduleInfoList{i}.channels = moduleInfoList{i-1}.channels;
259 | if ischar(pad)&&stride==1
260 | moduleInfoList{i}.mapSize = moduleInfoList{i-1}.mapSize;
261 | elseif ischar(pad)
262 | moduleInfoList{i}.mapSize = ceil(moduleInfoList{i-1}.mapSize/stride);
263 | else
264 | moduleInfoList{i}.mapSize = floor((moduleInfoList{i-1}.mapSize-poolsize+2*pad)/stride+1);
265 | end
266 |
267 | moduleLayers= avg_layer;
268 | lgraph = addLayers(lgraph,moduleLayers);
269 | lgraph = connectLayers(lgraph,...
270 | lastModuleNames{i-1},moduleLayers(1).Name);
271 | case '[maxpool]'
272 | moduleLayers = [];maxp_layer = [];
273 | poolsize = moduleInfoList{i-1}.mapSize;
274 | pad =0;stride=1;
275 | if isempty(currentModuleInfo) % 为空时候,自动推断大小,即为上一层特征图大小
276 | maxp_layer = maxPooling2dLayer(poolsize,'Padding',pad,...
277 | 'Stride',stride,'Name',['avgPool_',num2str(i)]);
278 | else
279 | poolsize = str2double(currentModuleInfo.size);
280 | stride = str2double(currentModuleInfo.stride);
281 | pad = 'same'; % 确保stride为1时候,特征图大小不变
282 | if isfield(currentModuleInfo,'padding')
283 | pad = str2double(currentModuleInfo.padding);
284 | end
285 | maxp_layer = maxPooling2dLayer(poolsize,'Padding',pad,...
286 | 'Stride',stride,'Name',['maxPool_',num2str(i)]);
287 | end
288 | moduleInfoList{i}.channels = moduleInfoList{i-1}.channels;
289 | if ischar(pad)&&stride==1
290 | moduleInfoList{i}.mapSize = moduleInfoList{i-1}.mapSize;
291 | elseif ischar(pad)
292 | moduleInfoList{i}.mapSize = ceil(moduleInfoList{i-1}.mapSize/stride);
293 | else
294 | moduleInfoList{i}.mapSize = floor((moduleInfoList{i-1}.mapSize-poolsize+2*pad)/stride+1);
295 | end
296 |
297 | moduleLayers= maxp_layer;
298 | lgraph = addLayers(lgraph,moduleLayers);
299 | lgraph = connectLayers(lgraph,...
300 | lastModuleNames{i-1},moduleLayers(1).Name);
301 | case '[dropout]'
302 | moduleLayers = [];drop_layer = [];
303 | probability = str2double(currentModuleInfo.probability);
304 | drop_layer = dropoutLayer(probability,'Name',['drop_',num2str(i)]);
305 | moduleInfoList{i}.channels = moduleInfoList{i-1}.channels;
306 | moduleInfoList{i}.mapSize = moduleInfoList{i-1}.mapSize;
307 |
308 | moduleLayers= drop_layer;
309 | lgraph = addLayers(lgraph,moduleLayers);
310 | lgraph = connectLayers(lgraph,...
311 | lastModuleNames{i-1},moduleLayers(1).Name);
312 | case '[connected]' % 与普通卷积最大区别是输入大小是否固定,保证全连接层参数可乘;其后没有BN
313 | moduleLayers = [];connected_layer = [];relu_layer = [];
314 | output = str2double(currentModuleInfo.output);
315 | connected_layer = fullyConnectedLayer(output,'Name',['fullyCon_',num2str(i)]);
316 | moduleInfoList{i}.channels = output;
317 | moduleInfoList{i}.mapSize = [1,1];
318 |
319 | % 添加relu层
320 | if strcmp(currentModuleInfo.activation,'relu')
321 | relu_layer = reluLayer('Name',['relu_',num2str(i)]);
322 | elseif strcmp(currentModuleInfo.activation,'relu6')
323 | relu_layer = clippedReluLayer(6,'Name',['clipRelu_',num2str(i)]);
324 | elseif strcmp(currentModuleInfo.activation,'leaky')
325 | relu_layer = leakyReluLayer(0.1,'Name',['leaky_',num2str(i)]);
326 | elseif strcmp(currentModuleInfo.activation,'mish')
327 | relu_layer = mishLayer(['mish_',num2str(i)]);
328 | end
329 |
330 | moduleLayers= [connected_layer;relu_layer];
331 | lgraph = addLayers(lgraph,moduleLayers);
332 | lgraph = connectLayers(lgraph,...
333 | lastModuleNames{i-1},moduleLayers(1).Name);
334 | case '[softmax]'
335 | moduleLayers = [];soft_layer = [];
336 | soft_layer = softmaxLayer('Name',['softmax_',num2str(i)]);
337 | moduleInfoList{i}.channels = moduleInfoList{i-1}.channels;
338 | moduleInfoList{i}.mapSize = moduleInfoList{i-1}.mapSize;
339 |
340 | moduleLayers= soft_layer;
341 | lgraph = addLayers(lgraph,moduleLayers);
342 | lgraph = connectLayers(lgraph,...
343 | lastModuleNames{i-1},moduleLayers(1).Name);
344 | case '[cost]'
345 | moduleLayers = [];clss_layer = [];
346 | clss_layer = classificationLayer('Name',['clss_',num2str(i)]);
347 | moduleInfoList{i}.channels = moduleInfoList{i-1}.channels;
348 | moduleInfoList{i}.mapSize = moduleInfoList{i-1}.mapSize;
349 |
350 | moduleLayers= clss_layer;
351 | lgraph = addLayers(lgraph,moduleLayers);
352 | lgraph = connectLayers(lgraph,...
353 | lastModuleNames{i-1},moduleLayers(1).Name);
354 | case '[upsample]' % upsample2dLayer
355 | moduleLayers = [];up_layer = [];
356 | stride = str2double(strip(currentModuleInfo.stride));% 整数标量,一般为2
357 | up_layer = upsample2dLayer(['up2d_',num2str(i)],stride);
358 | moduleInfoList{i}.channels = moduleInfoList{i-1}.channels;
359 | moduleInfoList{i}.mapSize = moduleInfoList{i-1}.mapSize*stride;
360 |
361 | moduleLayers= up_layer;
362 | lgraph = addLayers(lgraph,moduleLayers);
363 | lgraph = connectLayers(lgraph,...
364 | lastModuleNames{i-1},moduleLayers(1).Name);
365 | case '[yolo]' % yolov3Layer
366 | moduleLayers = [];yolov3_layer = [];
367 | allAnchors = reshape(str2double(strip(split(currentModuleInfo.anchors,','))),2,[])';%[width,height],n*2大小
368 | mask = reshape(str2double(strip(split(currentModuleInfo.mask,','))),1,[])+1;% 1*m大小,注意mask是从0开始,要加1
369 | nClasses = str2double(currentModuleInfo.classes);
370 | imageSize = imageInputSize(1:2); % [imageHeight,imageWidth]
371 | yoloIndex = yoloIndex + 1;
372 | yolov3_layer = yolov3Layer(['yolo_v3_id',num2str(yoloIndex)],...
373 | mask,allAnchors,nClasses,yoloIndex,imageSize);
374 | moduleInfoList{i}.channels = moduleInfoList{i-1}.channels;
375 | moduleInfoList{i}.mapSize = moduleInfoList{i-1}.mapSize;
376 |
377 | moduleLayers= yolov3_layer;
378 | lgraph = addLayers(lgraph,moduleLayers);
379 | lgraph = connectLayers(lgraph,...
380 | lastModuleNames{i-1},moduleLayers(1).Name);
381 | otherwise
382 | error("we currently can't support this layer: "+currentModuleType);
383 | end
384 |
385 | if i==1
386 | fprintf('This module No:%2d %-16s,have #params:%-10d,FLops:%-12d,feature map size:(%-3d*%-3d),channels in:%-12s,channels out:%-12d\n',...
387 | i,currentModuleType,numsNetParams-nums_p,FLOPs_perConv,moduleInfoList{i}.mapSize, '-',moduleInfoList{i}.channels);
388 | else
389 | fprintf('This module No:%2d %-16s,have #params:%-10d,FLops:%-12d,feature map size:(%-3d*%-3d),channels in:%-12d,channels out:%-12d\n',...
390 | i,currentModuleType,numsNetParams-nums_p,FLOPs_perConv,moduleInfoList{i}.mapSize,moduleInfoList{i-1}.channels,moduleInfoList{i}.channels);
391 | end
392 | nums_p=numsNetParams;
393 | FLOPs_perConv = 0;
394 | lastModuleNames{i} = moduleLayers(end).Name;
395 | layerToModuleIndex = [layerToModuleIndex;i*ones(length(moduleLayers),1)];
396 | end
397 |
398 | function matlab_module_idx = getModuleIdx(current_matlab_ind,cfg_value)
399 | % route,或者shortcut层转换为以1为起始索引的标量值
400 | % 输入:current_matlab_ind,1*1的正整数,读入到当前层module的索引标量(current_matlab_ind中是以[net]以1为起始值),darknet是以第一个非[net]开始的module为0开始的计数的索引
401 | % cfg_value,1*1的整数,shortcut层的from值或者route的layers的某一个值
402 | % 输出:module_idx,连接到上一层module的索引值(正整数,以[net]为起始索引1)
403 | %
404 | % cuixingxing150@gmail.com
405 | % 2019.8.19
406 | % 2019.9.4修改索引
407 | if cfg_value<0
408 | matlab_module_idx = current_matlab_ind+cfg_value;
409 | else
410 | matlab_module_idx = 2+cfg_value;
411 | end
412 | end % end of getModuleIdx
413 |
414 | end % end of importDarknetLayers
415 |
--------------------------------------------------------------------------------
/cfg/matlabExportYoloV4.cfg:
--------------------------------------------------------------------------------
1 | # This file is automatically generated by MATLAB and may require you to modify it manually
2 | [net]
3 | angle=0
4 | batch=64
5 | burn_in=1000
6 | channels=3
7 | decay=0.0005
8 | exposure=1.5
9 | height=608
10 | hue=.1
11 | learning_rate=0.00261
12 | max_batches=500500
13 | momentum=0.949
14 | mosaic=1
15 | policy=steps
16 | saturation=1.5
17 | scales=.1,.1
18 | steps=400000,450000
19 | subdivisions=8
20 | width=608
21 |
22 | # darknet module ID:0
23 | [convolutional]
24 | batch_normalize=1
25 | filters=32
26 | pad=1
27 | size=3
28 | stride=1
29 | activation=mish
30 |
31 | # darknet module ID:1
32 | [convolutional]
33 | batch_normalize=1
34 | filters=64
35 | pad=1
36 | size=3
37 | stride=2
38 | activation=mish
39 |
40 | # darknet module ID:2
41 | [convolutional]
42 | batch_normalize=1
43 | filters=64
44 | pad=1
45 | size=1
46 | stride=1
47 | activation=mish
48 |
49 | # darknet module ID:3
50 | [route]
51 | layers=1
52 |
53 | # darknet module ID:4
54 | [convolutional]
55 | batch_normalize=1
56 | filters=64
57 | pad=1
58 | size=1
59 | stride=1
60 | activation=mish
61 |
62 | # darknet module ID:5
63 | [convolutional]
64 | batch_normalize=1
65 | filters=32
66 | pad=1
67 | size=1
68 | stride=1
69 | activation=mish
70 |
71 | # darknet module ID:6
72 | [convolutional]
73 | batch_normalize=1
74 | filters=64
75 | pad=1
76 | size=3
77 | stride=1
78 | activation=mish
79 |
80 | # darknet module ID:7
81 | [shortcut]
82 | from=4
83 | activation=linear
84 |
85 | # darknet module ID:8
86 | [convolutional]
87 | batch_normalize=1
88 | filters=64
89 | pad=1
90 | size=1
91 | stride=1
92 | activation=mish
93 |
94 | # darknet module ID:9
95 | [route]
96 | layers=8,2
97 |
98 | # darknet module ID:10
99 | [convolutional]
100 | batch_normalize=1
101 | filters=64
102 | pad=1
103 | size=1
104 | stride=1
105 | activation=mish
106 |
107 | # darknet module ID:11
108 | [convolutional]
109 | batch_normalize=1
110 | filters=128
111 | pad=1
112 | size=3
113 | stride=2
114 | activation=mish
115 |
116 | # darknet module ID:12
117 | [convolutional]
118 | batch_normalize=1
119 | filters=64
120 | pad=1
121 | size=1
122 | stride=1
123 | activation=mish
124 |
125 | # darknet module ID:13
126 | [route]
127 | layers=11
128 |
129 | # darknet module ID:14
130 | [convolutional]
131 | batch_normalize=1
132 | filters=64
133 | pad=1
134 | size=1
135 | stride=1
136 | activation=mish
137 |
138 | # darknet module ID:15
139 | [convolutional]
140 | batch_normalize=1
141 | filters=64
142 | pad=1
143 | size=1
144 | stride=1
145 | activation=mish
146 |
147 | # darknet module ID:16
148 | [convolutional]
149 | batch_normalize=1
150 | filters=64
151 | pad=1
152 | size=3
153 | stride=1
154 | activation=mish
155 |
156 | # darknet module ID:17
157 | [shortcut]
158 | from=14
159 | activation=linear
160 |
161 | # darknet module ID:18
162 | [convolutional]
163 | batch_normalize=1
164 | filters=64
165 | pad=1
166 | size=1
167 | stride=1
168 | activation=mish
169 |
170 | # darknet module ID:19
171 | [convolutional]
172 | batch_normalize=1
173 | filters=64
174 | pad=1
175 | size=3
176 | stride=1
177 | activation=mish
178 |
179 | # darknet module ID:20
180 | [shortcut]
181 | from=17
182 | activation=linear
183 |
184 | # darknet module ID:21
185 | [convolutional]
186 | batch_normalize=1
187 | filters=64
188 | pad=1
189 | size=1
190 | stride=1
191 | activation=mish
192 |
193 | # darknet module ID:22
194 | [route]
195 | layers=21,12
196 |
197 | # darknet module ID:23
198 | [convolutional]
199 | batch_normalize=1
200 | filters=128
201 | pad=1
202 | size=1
203 | stride=1
204 | activation=mish
205 |
206 | # darknet module ID:24
207 | [convolutional]
208 | batch_normalize=1
209 | filters=256
210 | pad=1
211 | size=3
212 | stride=2
213 | activation=mish
214 |
215 | # darknet module ID:25
216 | [convolutional]
217 | batch_normalize=1
218 | filters=128
219 | pad=1
220 | size=1
221 | stride=1
222 | activation=mish
223 |
224 | # darknet module ID:26
225 | [route]
226 | layers=24
227 |
228 | # darknet module ID:27
229 | [convolutional]
230 | batch_normalize=1
231 | filters=128
232 | pad=1
233 | size=1
234 | stride=1
235 | activation=mish
236 |
237 | # darknet module ID:28
238 | [convolutional]
239 | batch_normalize=1
240 | filters=128
241 | pad=1
242 | size=1
243 | stride=1
244 | activation=mish
245 |
246 | # darknet module ID:29
247 | [convolutional]
248 | batch_normalize=1
249 | filters=128
250 | pad=1
251 | size=3
252 | stride=1
253 | activation=mish
254 |
255 | # darknet module ID:30
256 | [shortcut]
257 | from=27
258 | activation=linear
259 |
260 | # darknet module ID:31
261 | [convolutional]
262 | batch_normalize=1
263 | filters=128
264 | pad=1
265 | size=1
266 | stride=1
267 | activation=mish
268 |
269 | # darknet module ID:32
270 | [convolutional]
271 | batch_normalize=1
272 | filters=128
273 | pad=1
274 | size=3
275 | stride=1
276 | activation=mish
277 |
278 | # darknet module ID:33
279 | [shortcut]
280 | from=30
281 | activation=linear
282 |
283 | # darknet module ID:34
284 | [convolutional]
285 | batch_normalize=1
286 | filters=128
287 | pad=1
288 | size=1
289 | stride=1
290 | activation=mish
291 |
292 | # darknet module ID:35
293 | [convolutional]
294 | batch_normalize=1
295 | filters=128
296 | pad=1
297 | size=3
298 | stride=1
299 | activation=mish
300 |
301 | # darknet module ID:36
302 | [shortcut]
303 | from=33
304 | activation=linear
305 |
306 | # darknet module ID:37
307 | [convolutional]
308 | batch_normalize=1
309 | filters=128
310 | pad=1
311 | size=1
312 | stride=1
313 | activation=mish
314 |
315 | # darknet module ID:38
316 | [convolutional]
317 | batch_normalize=1
318 | filters=128
319 | pad=1
320 | size=3
321 | stride=1
322 | activation=mish
323 |
324 | # darknet module ID:39
325 | [shortcut]
326 | from=36
327 | activation=linear
328 |
329 | # darknet module ID:40
330 | [convolutional]
331 | batch_normalize=1
332 | filters=128
333 | pad=1
334 | size=1
335 | stride=1
336 | activation=mish
337 |
338 | # darknet module ID:41
339 | [convolutional]
340 | batch_normalize=1
341 | filters=128
342 | pad=1
343 | size=3
344 | stride=1
345 | activation=mish
346 |
347 | # darknet module ID:42
348 | [shortcut]
349 | from=39
350 | activation=linear
351 |
352 | # darknet module ID:43
353 | [convolutional]
354 | batch_normalize=1
355 | filters=128
356 | pad=1
357 | size=1
358 | stride=1
359 | activation=mish
360 |
361 | # darknet module ID:44
362 | [convolutional]
363 | batch_normalize=1
364 | filters=128
365 | pad=1
366 | size=3
367 | stride=1
368 | activation=mish
369 |
370 | # darknet module ID:45
371 | [shortcut]
372 | from=42
373 | activation=linear
374 |
375 | # darknet module ID:46
376 | [convolutional]
377 | batch_normalize=1
378 | filters=128
379 | pad=1
380 | size=1
381 | stride=1
382 | activation=mish
383 |
384 | # darknet module ID:47
385 | [convolutional]
386 | batch_normalize=1
387 | filters=128
388 | pad=1
389 | size=3
390 | stride=1
391 | activation=mish
392 |
393 | # darknet module ID:48
394 | [shortcut]
395 | from=45
396 | activation=linear
397 |
398 | # darknet module ID:49
399 | [convolutional]
400 | batch_normalize=1
401 | filters=128
402 | pad=1
403 | size=1
404 | stride=1
405 | activation=mish
406 |
407 | # darknet module ID:50
408 | [convolutional]
409 | batch_normalize=1
410 | filters=128
411 | pad=1
412 | size=3
413 | stride=1
414 | activation=mish
415 |
416 | # darknet module ID:51
417 | [shortcut]
418 | from=48
419 | activation=linear
420 |
421 | # darknet module ID:52
422 | [convolutional]
423 | batch_normalize=1
424 | filters=128
425 | pad=1
426 | size=1
427 | stride=1
428 | activation=mish
429 |
430 | # darknet module ID:53
431 | [route]
432 | layers=52,25
433 |
434 | # darknet module ID:54
435 | [convolutional]
436 | batch_normalize=1
437 | filters=256
438 | pad=1
439 | size=1
440 | stride=1
441 | activation=mish
442 |
443 | # darknet module ID:55
444 | [convolutional]
445 | batch_normalize=1
446 | filters=512
447 | pad=1
448 | size=3
449 | stride=2
450 | activation=mish
451 |
452 | # darknet module ID:56
453 | [convolutional]
454 | batch_normalize=1
455 | filters=256
456 | pad=1
457 | size=1
458 | stride=1
459 | activation=mish
460 |
461 | # darknet module ID:57
462 | [route]
463 | layers=55
464 |
465 | # darknet module ID:58
466 | [convolutional]
467 | batch_normalize=1
468 | filters=256
469 | pad=1
470 | size=1
471 | stride=1
472 | activation=mish
473 |
474 | # darknet module ID:59
475 | [convolutional]
476 | batch_normalize=1
477 | filters=256
478 | pad=1
479 | size=1
480 | stride=1
481 | activation=mish
482 |
483 | # darknet module ID:60
484 | [convolutional]
485 | batch_normalize=1
486 | filters=256
487 | pad=1
488 | size=3
489 | stride=1
490 | activation=mish
491 |
492 | # darknet module ID:61
493 | [shortcut]
494 | from=58
495 | activation=linear
496 |
497 | # darknet module ID:62
498 | [convolutional]
499 | batch_normalize=1
500 | filters=256
501 | pad=1
502 | size=1
503 | stride=1
504 | activation=mish
505 |
506 | # darknet module ID:63
507 | [convolutional]
508 | batch_normalize=1
509 | filters=256
510 | pad=1
511 | size=3
512 | stride=1
513 | activation=mish
514 |
515 | # darknet module ID:64
516 | [shortcut]
517 | from=61
518 | activation=linear
519 |
520 | # darknet module ID:65
521 | [convolutional]
522 | batch_normalize=1
523 | filters=256
524 | pad=1
525 | size=1
526 | stride=1
527 | activation=mish
528 |
529 | # darknet module ID:66
530 | [convolutional]
531 | batch_normalize=1
532 | filters=256
533 | pad=1
534 | size=3
535 | stride=1
536 | activation=mish
537 |
538 | # darknet module ID:67
539 | [shortcut]
540 | from=64
541 | activation=linear
542 |
543 | # darknet module ID:68
544 | [convolutional]
545 | batch_normalize=1
546 | filters=256
547 | pad=1
548 | size=1
549 | stride=1
550 | activation=mish
551 |
552 | # darknet module ID:69
553 | [convolutional]
554 | batch_normalize=1
555 | filters=256
556 | pad=1
557 | size=3
558 | stride=1
559 | activation=mish
560 |
561 | # darknet module ID:70
562 | [shortcut]
563 | from=67
564 | activation=linear
565 |
566 | # darknet module ID:71
567 | [convolutional]
568 | batch_normalize=1
569 | filters=256
570 | pad=1
571 | size=1
572 | stride=1
573 | activation=mish
574 |
575 | # darknet module ID:72
576 | [convolutional]
577 | batch_normalize=1
578 | filters=256
579 | pad=1
580 | size=3
581 | stride=1
582 | activation=mish
583 |
584 | # darknet module ID:73
585 | [shortcut]
586 | from=70
587 | activation=linear
588 |
589 | # darknet module ID:74
590 | [convolutional]
591 | batch_normalize=1
592 | filters=256
593 | pad=1
594 | size=1
595 | stride=1
596 | activation=mish
597 |
598 | # darknet module ID:75
599 | [convolutional]
600 | batch_normalize=1
601 | filters=256
602 | pad=1
603 | size=3
604 | stride=1
605 | activation=mish
606 |
607 | # darknet module ID:76
608 | [shortcut]
609 | from=73
610 | activation=linear
611 |
612 | # darknet module ID:77
613 | [convolutional]
614 | batch_normalize=1
615 | filters=256
616 | pad=1
617 | size=1
618 | stride=1
619 | activation=mish
620 |
621 | # darknet module ID:78
622 | [convolutional]
623 | batch_normalize=1
624 | filters=256
625 | pad=1
626 | size=3
627 | stride=1
628 | activation=mish
629 |
630 | # darknet module ID:79
631 | [shortcut]
632 | from=76
633 | activation=linear
634 |
635 | # darknet module ID:80
636 | [convolutional]
637 | batch_normalize=1
638 | filters=256
639 | pad=1
640 | size=1
641 | stride=1
642 | activation=mish
643 |
644 | # darknet module ID:81
645 | [convolutional]
646 | batch_normalize=1
647 | filters=256
648 | pad=1
649 | size=3
650 | stride=1
651 | activation=mish
652 |
653 | # darknet module ID:82
654 | [shortcut]
655 | from=79
656 | activation=linear
657 |
658 | # darknet module ID:83
659 | [convolutional]
660 | batch_normalize=1
661 | filters=256
662 | pad=1
663 | size=1
664 | stride=1
665 | activation=mish
666 |
667 | # darknet module ID:84
668 | [route]
669 | layers=83,56
670 |
671 | # darknet module ID:85
672 | [convolutional]
673 | batch_normalize=1
674 | filters=512
675 | pad=1
676 | size=1
677 | stride=1
678 | activation=mish
679 |
680 | # darknet module ID:86
681 | [convolutional]
682 | batch_normalize=1
683 | filters=1024
684 | pad=1
685 | size=3
686 | stride=2
687 | activation=mish
688 |
689 | # darknet module ID:87
690 | [convolutional]
691 | batch_normalize=1
692 | filters=512
693 | pad=1
694 | size=1
695 | stride=1
696 | activation=mish
697 |
698 | # darknet module ID:88
699 | [route]
700 | layers=86
701 |
702 | # darknet module ID:89
703 | [convolutional]
704 | batch_normalize=1
705 | filters=512
706 | pad=1
707 | size=1
708 | stride=1
709 | activation=mish
710 |
711 | # darknet module ID:90
712 | [convolutional]
713 | batch_normalize=1
714 | filters=512
715 | pad=1
716 | size=1
717 | stride=1
718 | activation=mish
719 |
720 | # darknet module ID:91
721 | [convolutional]
722 | batch_normalize=1
723 | filters=512
724 | pad=1
725 | size=3
726 | stride=1
727 | activation=mish
728 |
729 | # darknet module ID:92
730 | [shortcut]
731 | from=89
732 | activation=linear
733 |
734 | # darknet module ID:93
735 | [convolutional]
736 | batch_normalize=1
737 | filters=512
738 | pad=1
739 | size=1
740 | stride=1
741 | activation=mish
742 |
743 | # darknet module ID:94
744 | [convolutional]
745 | batch_normalize=1
746 | filters=512
747 | pad=1
748 | size=3
749 | stride=1
750 | activation=mish
751 |
752 | # darknet module ID:95
753 | [shortcut]
754 | from=92
755 | activation=linear
756 |
757 | # darknet module ID:96
758 | [convolutional]
759 | batch_normalize=1
760 | filters=512
761 | pad=1
762 | size=1
763 | stride=1
764 | activation=mish
765 |
766 | # darknet module ID:97
767 | [convolutional]
768 | batch_normalize=1
769 | filters=512
770 | pad=1
771 | size=3
772 | stride=1
773 | activation=mish
774 |
775 | # darknet module ID:98
776 | [shortcut]
777 | from=95
778 | activation=linear
779 |
780 | # darknet module ID:99
781 | [convolutional]
782 | batch_normalize=1
783 | filters=512
784 | pad=1
785 | size=1
786 | stride=1
787 | activation=mish
788 |
789 | # darknet module ID:100
790 | [convolutional]
791 | batch_normalize=1
792 | filters=512
793 | pad=1
794 | size=3
795 | stride=1
796 | activation=mish
797 |
798 | # darknet module ID:101
799 | [shortcut]
800 | from=98
801 | activation=linear
802 |
803 | # darknet module ID:102
804 | [convolutional]
805 | batch_normalize=1
806 | filters=512
807 | pad=1
808 | size=1
809 | stride=1
810 | activation=mish
811 |
812 | # darknet module ID:103
813 | [route]
814 | layers=102,87
815 |
816 | # darknet module ID:104
817 | [convolutional]
818 | batch_normalize=1
819 | filters=1024
820 | pad=1
821 | size=1
822 | stride=1
823 | activation=mish
824 |
825 | # darknet module ID:105
826 | [convolutional]
827 | batch_normalize=1
828 | filters=512
829 | pad=1
830 | size=1
831 | stride=1
832 | activation=leaky
833 |
834 | # darknet module ID:106
835 | [convolutional]
836 | batch_normalize=1
837 | filters=1024
838 | pad=1
839 | size=3
840 | stride=1
841 | activation=leaky
842 |
843 | # darknet module ID:107
844 | [convolutional]
845 | batch_normalize=1
846 | filters=512
847 | pad=1
848 | size=1
849 | stride=1
850 | activation=leaky
851 |
852 | # darknet module ID:108
853 | [maxpool]
854 | size=5
855 | stride=1
856 |
857 | # darknet module ID:109
858 | [route]
859 | layers=107
860 |
861 | # darknet module ID:110
862 | [maxpool]
863 | size=9
864 | stride=1
865 |
866 | # darknet module ID:111
867 | [route]
868 | layers=107
869 |
870 | # darknet module ID:112
871 | [maxpool]
872 | size=13
873 | stride=1
874 |
875 | # darknet module ID:113
876 | [route]
877 | layers=112,110,108,107
878 |
879 | # darknet module ID:114
880 | [convolutional]
881 | batch_normalize=1
882 | filters=512
883 | pad=1
884 | size=1
885 | stride=1
886 | activation=leaky
887 |
888 | # darknet module ID:115
889 | [convolutional]
890 | batch_normalize=1
891 | filters=1024
892 | pad=1
893 | size=3
894 | stride=1
895 | activation=leaky
896 |
897 | # darknet module ID:116
898 | [convolutional]
899 | batch_normalize=1
900 | filters=512
901 | pad=1
902 | size=1
903 | stride=1
904 | activation=leaky
905 |
906 | # darknet module ID:117
907 | [convolutional]
908 | batch_normalize=1
909 | filters=256
910 | pad=1
911 | size=1
912 | stride=1
913 | activation=leaky
914 |
915 | # darknet module ID:118
916 | [upsample]
917 | stride=2
918 |
919 | # darknet module ID:119
920 | [route]
921 | layers=85
922 |
923 | # darknet module ID:120
924 | [convolutional]
925 | batch_normalize=1
926 | filters=256
927 | pad=1
928 | size=1
929 | stride=1
930 | activation=leaky
931 |
932 | # darknet module ID:121
933 | [route]
934 | layers=120,118
935 |
936 | # darknet module ID:122
937 | [convolutional]
938 | batch_normalize=1
939 | filters=256
940 | pad=1
941 | size=1
942 | stride=1
943 | activation=leaky
944 |
945 | # darknet module ID:123
946 | [convolutional]
947 | batch_normalize=1
948 | filters=512
949 | pad=1
950 | size=3
951 | stride=1
952 | activation=leaky
953 |
954 | # darknet module ID:124
955 | [convolutional]
956 | batch_normalize=1
957 | filters=256
958 | pad=1
959 | size=1
960 | stride=1
961 | activation=leaky
962 |
963 | # darknet module ID:125
964 | [convolutional]
965 | batch_normalize=1
966 | filters=512
967 | pad=1
968 | size=3
969 | stride=1
970 | activation=leaky
971 |
972 | # darknet module ID:126
973 | [convolutional]
974 | batch_normalize=1
975 | filters=256
976 | pad=1
977 | size=1
978 | stride=1
979 | activation=leaky
980 |
981 | # darknet module ID:127
982 | [convolutional]
983 | batch_normalize=1
984 | filters=128
985 | pad=1
986 | size=1
987 | stride=1
988 | activation=leaky
989 |
990 | # darknet module ID:128
991 | [upsample]
992 | stride=2
993 |
994 | # darknet module ID:129
995 | [route]
996 | layers=54
997 |
998 | # darknet module ID:130
999 | [convolutional]
1000 | batch_normalize=1
1001 | filters=128
1002 | pad=1
1003 | size=1
1004 | stride=1
1005 | activation=leaky
1006 |
1007 | # darknet module ID:131
1008 | [route]
1009 | layers=130,128
1010 |
1011 | # darknet module ID:132
1012 | [convolutional]
1013 | batch_normalize=1
1014 | filters=128
1015 | pad=1
1016 | size=1
1017 | stride=1
1018 | activation=leaky
1019 |
1020 | # darknet module ID:133
1021 | [convolutional]
1022 | batch_normalize=1
1023 | filters=256
1024 | pad=1
1025 | size=3
1026 | stride=1
1027 | activation=leaky
1028 |
1029 | # darknet module ID:134
1030 | [convolutional]
1031 | batch_normalize=1
1032 | filters=128
1033 | pad=1
1034 | size=1
1035 | stride=1
1036 | activation=leaky
1037 |
1038 | # darknet module ID:135
1039 | [convolutional]
1040 | batch_normalize=1
1041 | filters=256
1042 | pad=1
1043 | size=3
1044 | stride=1
1045 | activation=leaky
1046 |
1047 | # darknet module ID:136
1048 | [convolutional]
1049 | batch_normalize=1
1050 | filters=128
1051 | pad=1
1052 | size=1
1053 | stride=1
1054 | activation=leaky
1055 |
1056 | # darknet module ID:137
1057 | [convolutional]
1058 | batch_normalize=1
1059 | filters=256
1060 | pad=1
1061 | size=3
1062 | stride=1
1063 | activation=leaky
1064 |
1065 | # darknet module ID:138
1066 | [convolutional]
1067 | filters=255
1068 | pad=1
1069 | size=1
1070 | stride=1
1071 | activation=linear
1072 |
1073 | # darknet module ID:139
1074 | [yolo]
1075 | anchors=12,16,19,36,40,28,36,75,76,55,72,146,142,110,192,243,459,401
1076 | classes=80
1077 | ignore_thresh=0.7
1078 | jitter=0.3
1079 | mask=0,1,2
1080 | num=9
1081 | random=1
1082 | truth_thresh=1
1083 |
1084 | # darknet module ID:140
1085 | [route]
1086 | layers=136
1087 |
1088 | # darknet module ID:141
1089 | [convolutional]
1090 | batch_normalize=1
1091 | filters=256
1092 | pad=1
1093 | size=3
1094 | stride=2
1095 | activation=leaky
1096 |
1097 | # darknet module ID:142
1098 | [route]
1099 | layers=141,126
1100 |
1101 | # darknet module ID:143
1102 | [convolutional]
1103 | batch_normalize=1
1104 | filters=256
1105 | pad=1
1106 | size=1
1107 | stride=1
1108 | activation=leaky
1109 |
1110 | # darknet module ID:144
1111 | [convolutional]
1112 | batch_normalize=1
1113 | filters=512
1114 | pad=1
1115 | size=3
1116 | stride=1
1117 | activation=leaky
1118 |
1119 | # darknet module ID:145
1120 | [convolutional]
1121 | batch_normalize=1
1122 | filters=256
1123 | pad=1
1124 | size=1
1125 | stride=1
1126 | activation=leaky
1127 |
1128 | # darknet module ID:146
1129 | [convolutional]
1130 | batch_normalize=1
1131 | filters=512
1132 | pad=1
1133 | size=3
1134 | stride=1
1135 | activation=leaky
1136 |
1137 | # darknet module ID:147
1138 | [convolutional]
1139 | batch_normalize=1
1140 | filters=256
1141 | pad=1
1142 | size=1
1143 | stride=1
1144 | activation=leaky
1145 |
1146 | # darknet module ID:148
1147 | [convolutional]
1148 | batch_normalize=1
1149 | filters=512
1150 | pad=1
1151 | size=3
1152 | stride=1
1153 | activation=leaky
1154 |
1155 | # darknet module ID:149
1156 | [convolutional]
1157 | filters=255
1158 | pad=1
1159 | size=1
1160 | stride=1
1161 | activation=linear
1162 |
1163 | # darknet module ID:150
1164 | [yolo]
1165 | anchors=12,16,19,36,40,28,36,75,76,55,72,146,142,110,192,243,459,401
1166 | classes=80
1167 | ignore_thresh=0.7
1168 | jitter=0.3
1169 | mask=3,4,5
1170 | num=9
1171 | random=1
1172 | truth_thresh=1
1173 |
1174 | # darknet module ID:151
1175 | [route]
1176 | layers=147
1177 |
1178 | # darknet module ID:152
1179 | [convolutional]
1180 | batch_normalize=1
1181 | filters=512
1182 | pad=1
1183 | size=3
1184 | stride=2
1185 | activation=leaky
1186 |
1187 | # darknet module ID:153
1188 | [route]
1189 | layers=152,116
1190 |
1191 | # darknet module ID:154
1192 | [convolutional]
1193 | batch_normalize=1
1194 | filters=512
1195 | pad=1
1196 | size=1
1197 | stride=1
1198 | activation=leaky
1199 |
1200 | # darknet module ID:155
1201 | [convolutional]
1202 | batch_normalize=1
1203 | filters=1024
1204 | pad=1
1205 | size=3
1206 | stride=1
1207 | activation=leaky
1208 |
1209 | # darknet module ID:156
1210 | [convolutional]
1211 | batch_normalize=1
1212 | filters=512
1213 | pad=1
1214 | size=1
1215 | stride=1
1216 | activation=leaky
1217 |
1218 | # darknet module ID:157
1219 | [convolutional]
1220 | batch_normalize=1
1221 | filters=1024
1222 | pad=1
1223 | size=3
1224 | stride=1
1225 | activation=leaky
1226 |
1227 | # darknet module ID:158
1228 | [convolutional]
1229 | batch_normalize=1
1230 | filters=512
1231 | pad=1
1232 | size=1
1233 | stride=1
1234 | activation=leaky
1235 |
1236 | # darknet module ID:159
1237 | [convolutional]
1238 | batch_normalize=1
1239 | filters=1024
1240 | pad=1
1241 | size=3
1242 | stride=1
1243 | activation=leaky
1244 |
1245 | # darknet module ID:160
1246 | [convolutional]
1247 | filters=255
1248 | pad=1
1249 | size=1
1250 | stride=1
1251 | activation=linear
1252 |
1253 | # darknet module ID:161
1254 | [yolo]
1255 | anchors=12,16,19,36,40,28,36,75,76,55,72,146,142,110,192,243,459,401
1256 | classes=80
1257 | ignore_thresh=0.7
1258 | jitter=0.3
1259 | mask=6,7,8
1260 | num=9
1261 | random=1
1262 | truth_thresh=1
1263 |
1264 |
--------------------------------------------------------------------------------
/utils/synset_words.txt:
--------------------------------------------------------------------------------
1 | n01440764 tench, Tinca tinca
2 | n01443537 goldfish, Carassius auratus
3 | n01484850 great white shark, white shark, man-eater, man-eating shark, Carcharodon carcharias
4 | n01491361 tiger shark, Galeocerdo cuvieri
5 | n01494475 hammerhead, hammerhead shark
6 | n01496331 electric ray, crampfish, numbfish, torpedo
7 | n01498041 stingray
8 | n01514668 cock
9 | n01514859 hen
10 | n01518878 ostrich, Struthio camelus
11 | n01530575 brambling, Fringilla montifringilla
12 | n01531178 goldfinch, Carduelis carduelis
13 | n01532829 house finch, linnet, Carpodacus mexicanus
14 | n01534433 junco, snowbird
15 | n01537544 indigo bunting, indigo finch, indigo bird, Passerina cyanea
16 | n01558993 robin, American robin, Turdus migratorius
17 | n01560419 bulbul
18 | n01580077 jay
19 | n01582220 magpie
20 | n01592084 chickadee
21 | n01601694 water ouzel, dipper
22 | n01608432 kite
23 | n01614925 bald eagle, American eagle, Haliaeetus leucocephalus
24 | n01616318 vulture
25 | n01622779 great grey owl, great gray owl, Strix nebulosa
26 | n01629819 European fire salamander, Salamandra salamandra
27 | n01630670 common newt, Triturus vulgaris
28 | n01631663 eft
29 | n01632458 spotted salamander, Ambystoma maculatum
30 | n01632777 axolotl, mud puppy, Ambystoma mexicanum
31 | n01641577 bullfrog, Rana catesbeiana
32 | n01644373 tree frog, tree-frog
33 | n01644900 tailed frog, bell toad, ribbed toad, tailed toad, Ascaphus trui
34 | n01664065 loggerhead, loggerhead turtle, Caretta caretta
35 | n01665541 leatherback turtle, leatherback, leathery turtle, Dermochelys coriacea
36 | n01667114 mud turtle
37 | n01667778 terrapin
38 | n01669191 box turtle, box tortoise
39 | n01675722 banded gecko
40 | n01677366 common iguana, iguana, Iguana iguana
41 | n01682714 American chameleon, anole, Anolis carolinensis
42 | n01685808 whiptail, whiptail lizard
43 | n01687978 agama
44 | n01688243 frilled lizard, Chlamydosaurus kingi
45 | n01689811 alligator lizard
46 | n01692333 Gila monster, Heloderma suspectum
47 | n01693334 green lizard, Lacerta viridis
48 | n01694178 African chameleon, Chamaeleo chamaeleon
49 | n01695060 Komodo dragon, Komodo lizard, dragon lizard, giant lizard, Varanus komodoensis
50 | n01697457 African crocodile, Nile crocodile, Crocodylus niloticus
51 | n01698640 American alligator, Alligator mississipiensis
52 | n01704323 triceratops
53 | n01728572 thunder snake, worm snake, Carphophis amoenus
54 | n01728920 ringneck snake, ring-necked snake, ring snake
55 | n01729322 hognose snake, puff adder, sand viper
56 | n01729977 green snake, grass snake
57 | n01734418 king snake, kingsnake
58 | n01735189 garter snake, grass snake
59 | n01737021 water snake
60 | n01739381 vine snake
61 | n01740131 night snake, Hypsiglena torquata
62 | n01742172 boa constrictor, Constrictor constrictor
63 | n01744401 rock python, rock snake, Python sebae
64 | n01748264 Indian cobra, Naja naja
65 | n01749939 green mamba
66 | n01751748 sea snake
67 | n01753488 horned viper, cerastes, sand viper, horned asp, Cerastes cornutus
68 | n01755581 diamondback, diamondback rattlesnake, Crotalus adamanteus
69 | n01756291 sidewinder, horned rattlesnake, Crotalus cerastes
70 | n01768244 trilobite
71 | n01770081 harvestman, daddy longlegs, Phalangium opilio
72 | n01770393 scorpion
73 | n01773157 black and gold garden spider, Argiope aurantia
74 | n01773549 barn spider, Araneus cavaticus
75 | n01773797 garden spider, Aranea diademata
76 | n01774384 black widow, Latrodectus mactans
77 | n01774750 tarantula
78 | n01775062 wolf spider, hunting spider
79 | n01776313 tick
80 | n01784675 centipede
81 | n01795545 black grouse
82 | n01796340 ptarmigan
83 | n01797886 ruffed grouse, partridge, Bonasa umbellus
84 | n01798484 prairie chicken, prairie grouse, prairie fowl
85 | n01806143 peacock
86 | n01806567 quail
87 | n01807496 partridge
88 | n01817953 African grey, African gray, Psittacus erithacus
89 | n01818515 macaw
90 | n01819313 sulphur-crested cockatoo, Kakatoe galerita, Cacatua galerita
91 | n01820546 lorikeet
92 | n01824575 coucal
93 | n01828970 bee eater
94 | n01829413 hornbill
95 | n01833805 hummingbird
96 | n01843065 jacamar
97 | n01843383 toucan
98 | n01847000 drake
99 | n01855032 red-breasted merganser, Mergus serrator
100 | n01855672 goose
101 | n01860187 black swan, Cygnus atratus
102 | n01871265 tusker
103 | n01872401 echidna, spiny anteater, anteater
104 | n01873310 platypus, duckbill, duckbilled platypus, duck-billed platypus, Ornithorhynchus anatinus
105 | n01877812 wallaby, brush kangaroo
106 | n01882714 koala, koala bear, kangaroo bear, native bear, Phascolarctos cinereus
107 | n01883070 wombat
108 | n01910747 jellyfish
109 | n01914609 sea anemone, anemone
110 | n01917289 brain coral
111 | n01924916 flatworm, platyhelminth
112 | n01930112 nematode, nematode worm, roundworm
113 | n01943899 conch
114 | n01944390 snail
115 | n01945685 slug
116 | n01950731 sea slug, nudibranch
117 | n01955084 chiton, coat-of-mail shell, sea cradle, polyplacophore
118 | n01968897 chambered nautilus, pearly nautilus, nautilus
119 | n01978287 Dungeness crab, Cancer magister
120 | n01978455 rock crab, Cancer irroratus
121 | n01980166 fiddler crab
122 | n01981276 king crab, Alaska crab, Alaskan king crab, Alaska king crab, Paralithodes camtschatica
123 | n01983481 American lobster, Northern lobster, Maine lobster, Homarus americanus
124 | n01984695 spiny lobster, langouste, rock lobster, crawfish, crayfish, sea crawfish
125 | n01985128 crayfish, crawfish, crawdad, crawdaddy
126 | n01986214 hermit crab
127 | n01990800 isopod
128 | n02002556 white stork, Ciconia ciconia
129 | n02002724 black stork, Ciconia nigra
130 | n02006656 spoonbill
131 | n02007558 flamingo
132 | n02009229 little blue heron, Egretta caerulea
133 | n02009912 American egret, great white heron, Egretta albus
134 | n02011460 bittern
135 | n02012849 crane
136 | n02013706 limpkin, Aramus pictus
137 | n02017213 European gallinule, Porphyrio porphyrio
138 | n02018207 American coot, marsh hen, mud hen, water hen, Fulica americana
139 | n02018795 bustard
140 | n02025239 ruddy turnstone, Arenaria interpres
141 | n02027492 red-backed sandpiper, dunlin, Erolia alpina
142 | n02028035 redshank, Tringa totanus
143 | n02033041 dowitcher
144 | n02037110 oystercatcher, oyster catcher
145 | n02051845 pelican
146 | n02056570 king penguin, Aptenodytes patagonica
147 | n02058221 albatross, mollymawk
148 | n02066245 grey whale, gray whale, devilfish, Eschrichtius gibbosus, Eschrichtius robustus
149 | n02071294 killer whale, killer, orca, grampus, sea wolf, Orcinus orca
150 | n02074367 dugong, Dugong dugon
151 | n02077923 sea lion
152 | n02085620 Chihuahua
153 | n02085782 Japanese spaniel
154 | n02085936 Maltese dog, Maltese terrier, Maltese
155 | n02086079 Pekinese, Pekingese, Peke
156 | n02086240 Shih-Tzu
157 | n02086646 Blenheim spaniel
158 | n02086910 papillon
159 | n02087046 toy terrier
160 | n02087394 Rhodesian ridgeback
161 | n02088094 Afghan hound, Afghan
162 | n02088238 basset, basset hound
163 | n02088364 beagle
164 | n02088466 bloodhound, sleuthhound
165 | n02088632 bluetick
166 | n02089078 black-and-tan coonhound
167 | n02089867 Walker hound, Walker foxhound
168 | n02089973 English foxhound
169 | n02090379 redbone
170 | n02090622 borzoi, Russian wolfhound
171 | n02090721 Irish wolfhound
172 | n02091032 Italian greyhound
173 | n02091134 whippet
174 | n02091244 Ibizan hound, Ibizan Podenco
175 | n02091467 Norwegian elkhound, elkhound
176 | n02091635 otterhound, otter hound
177 | n02091831 Saluki, gazelle hound
178 | n02092002 Scottish deerhound, deerhound
179 | n02092339 Weimaraner
180 | n02093256 Staffordshire bullterrier, Staffordshire bull terrier
181 | n02093428 American Staffordshire terrier, Staffordshire terrier, American pit bull terrier, pit bull terrier
182 | n02093647 Bedlington terrier
183 | n02093754 Border terrier
184 | n02093859 Kerry blue terrier
185 | n02093991 Irish terrier
186 | n02094114 Norfolk terrier
187 | n02094258 Norwich terrier
188 | n02094433 Yorkshire terrier
189 | n02095314 wire-haired fox terrier
190 | n02095570 Lakeland terrier
191 | n02095889 Sealyham terrier, Sealyham
192 | n02096051 Airedale, Airedale terrier
193 | n02096177 cairn, cairn terrier
194 | n02096294 Australian terrier
195 | n02096437 Dandie Dinmont, Dandie Dinmont terrier
196 | n02096585 Boston bull, Boston terrier
197 | n02097047 miniature schnauzer
198 | n02097130 giant schnauzer
199 | n02097209 standard schnauzer
200 | n02097298 Scotch terrier, Scottish terrier, Scottie
201 | n02097474 Tibetan terrier, chrysanthemum dog
202 | n02097658 silky terrier, Sydney silky
203 | n02098105 soft-coated wheaten terrier
204 | n02098286 West Highland white terrier
205 | n02098413 Lhasa, Lhasa apso
206 | n02099267 flat-coated retriever
207 | n02099429 curly-coated retriever
208 | n02099601 golden retriever
209 | n02099712 Labrador retriever
210 | n02099849 Chesapeake Bay retriever
211 | n02100236 German short-haired pointer
212 | n02100583 vizsla, Hungarian pointer
213 | n02100735 English setter
214 | n02100877 Irish setter, red setter
215 | n02101006 Gordon setter
216 | n02101388 Brittany spaniel
217 | n02101556 clumber, clumber spaniel
218 | n02102040 English springer, English springer spaniel
219 | n02102177 Welsh springer spaniel
220 | n02102318 cocker spaniel, English cocker spaniel, cocker
221 | n02102480 Sussex spaniel
222 | n02102973 Irish water spaniel
223 | n02104029 kuvasz
224 | n02104365 schipperke
225 | n02105056 groenendael
226 | n02105162 malinois
227 | n02105251 briard
228 | n02105412 kelpie
229 | n02105505 komondor
230 | n02105641 Old English sheepdog, bobtail
231 | n02105855 Shetland sheepdog, Shetland sheep dog, Shetland
232 | n02106030 collie
233 | n02106166 Border collie
234 | n02106382 Bouvier des Flandres, Bouviers des Flandres
235 | n02106550 Rottweiler
236 | n02106662 German shepherd, German shepherd dog, German police dog, alsatian
237 | n02107142 Doberman, Doberman pinscher
238 | n02107312 miniature pinscher
239 | n02107574 Greater Swiss Mountain dog
240 | n02107683 Bernese mountain dog
241 | n02107908 Appenzeller
242 | n02108000 EntleBucher
243 | n02108089 boxer
244 | n02108422 bull mastiff
245 | n02108551 Tibetan mastiff
246 | n02108915 French bulldog
247 | n02109047 Great Dane
248 | n02109525 Saint Bernard, St Bernard
249 | n02109961 Eskimo dog, husky
250 | n02110063 malamute, malemute, Alaskan malamute
251 | n02110185 Siberian husky
252 | n02110341 dalmatian, coach dog, carriage dog
253 | n02110627 affenpinscher, monkey pinscher, monkey dog
254 | n02110806 basenji
255 | n02110958 pug, pug-dog
256 | n02111129 Leonberg
257 | n02111277 Newfoundland, Newfoundland dog
258 | n02111500 Great Pyrenees
259 | n02111889 Samoyed, Samoyede
260 | n02112018 Pomeranian
261 | n02112137 chow, chow chow
262 | n02112350 keeshond
263 | n02112706 Brabancon griffon
264 | n02113023 Pembroke, Pembroke Welsh corgi
265 | n02113186 Cardigan, Cardigan Welsh corgi
266 | n02113624 toy poodle
267 | n02113712 miniature poodle
268 | n02113799 standard poodle
269 | n02113978 Mexican hairless
270 | n02114367 timber wolf, grey wolf, gray wolf, Canis lupus
271 | n02114548 white wolf, Arctic wolf, Canis lupus tundrarum
272 | n02114712 red wolf, maned wolf, Canis rufus, Canis niger
273 | n02114855 coyote, prairie wolf, brush wolf, Canis latrans
274 | n02115641 dingo, warrigal, warragal, Canis dingo
275 | n02115913 dhole, Cuon alpinus
276 | n02116738 African hunting dog, hyena dog, Cape hunting dog, Lycaon pictus
277 | n02117135 hyena, hyaena
278 | n02119022 red fox, Vulpes vulpes
279 | n02119789 kit fox, Vulpes macrotis
280 | n02120079 Arctic fox, white fox, Alopex lagopus
281 | n02120505 grey fox, gray fox, Urocyon cinereoargenteus
282 | n02123045 tabby, tabby cat
283 | n02123159 tiger cat
284 | n02123394 Persian cat
285 | n02123597 Siamese cat, Siamese
286 | n02124075 Egyptian cat
287 | n02125311 cougar, puma, catamount, mountain lion, painter, panther, Felis concolor
288 | n02127052 lynx, catamount
289 | n02128385 leopard, Panthera pardus
290 | n02128757 snow leopard, ounce, Panthera uncia
291 | n02128925 jaguar, panther, Panthera onca, Felis onca
292 | n02129165 lion, king of beasts, Panthera leo
293 | n02129604 tiger, Panthera tigris
294 | n02130308 cheetah, chetah, Acinonyx jubatus
295 | n02132136 brown bear, bruin, Ursus arctos
296 | n02133161 American black bear, black bear, Ursus americanus, Euarctos americanus
297 | n02134084 ice bear, polar bear, Ursus Maritimus, Thalarctos maritimus
298 | n02134418 sloth bear, Melursus ursinus, Ursus ursinus
299 | n02137549 mongoose
300 | n02138441 meerkat, mierkat
301 | n02165105 tiger beetle
302 | n02165456 ladybug, ladybeetle, lady beetle, ladybird, ladybird beetle
303 | n02167151 ground beetle, carabid beetle
304 | n02168699 long-horned beetle, longicorn, longicorn beetle
305 | n02169497 leaf beetle, chrysomelid
306 | n02172182 dung beetle
307 | n02174001 rhinoceros beetle
308 | n02177972 weevil
309 | n02190166 fly
310 | n02206856 bee
311 | n02219486 ant, emmet, pismire
312 | n02226429 grasshopper, hopper
313 | n02229544 cricket
314 | n02231487 walking stick, walkingstick, stick insect
315 | n02233338 cockroach, roach
316 | n02236044 mantis, mantid
317 | n02256656 cicada, cicala
318 | n02259212 leafhopper
319 | n02264363 lacewing, lacewing fly
320 | n02268443 dragonfly, darning needle, devil's darning needle, sewing needle, snake feeder, snake doctor, mosquito hawk, skeeter hawk
321 | n02268853 damselfly
322 | n02276258 admiral
323 | n02277742 ringlet, ringlet butterfly
324 | n02279972 monarch, monarch butterfly, milkweed butterfly, Danaus plexippus
325 | n02280649 cabbage butterfly
326 | n02281406 sulphur butterfly, sulfur butterfly
327 | n02281787 lycaenid, lycaenid butterfly
328 | n02317335 starfish, sea star
329 | n02319095 sea urchin
330 | n02321529 sea cucumber, holothurian
331 | n02325366 wood rabbit, cottontail, cottontail rabbit
332 | n02326432 hare
333 | n02328150 Angora, Angora rabbit
334 | n02342885 hamster
335 | n02346627 porcupine, hedgehog
336 | n02356798 fox squirrel, eastern fox squirrel, Sciurus niger
337 | n02361337 marmot
338 | n02363005 beaver
339 | n02364673 guinea pig, Cavia cobaya
340 | n02389026 sorrel
341 | n02391049 zebra
342 | n02395406 hog, pig, grunter, squealer, Sus scrofa
343 | n02396427 wild boar, boar, Sus scrofa
344 | n02397096 warthog
345 | n02398521 hippopotamus, hippo, river horse, Hippopotamus amphibius
346 | n02403003 ox
347 | n02408429 water buffalo, water ox, Asiatic buffalo, Bubalus bubalis
348 | n02410509 bison
349 | n02412080 ram, tup
350 | n02415577 bighorn, bighorn sheep, cimarron, Rocky Mountain bighorn, Rocky Mountain sheep, Ovis canadensis
351 | n02417914 ibex, Capra ibex
352 | n02422106 hartebeest
353 | n02422699 impala, Aepyceros melampus
354 | n02423022 gazelle
355 | n02437312 Arabian camel, dromedary, Camelus dromedarius
356 | n02437616 llama
357 | n02441942 weasel
358 | n02442845 mink
359 | n02443114 polecat, fitch, foulmart, foumart, Mustela putorius
360 | n02443484 black-footed ferret, ferret, Mustela nigripes
361 | n02444819 otter
362 | n02445715 skunk, polecat, wood pussy
363 | n02447366 badger
364 | n02454379 armadillo
365 | n02457408 three-toed sloth, ai, Bradypus tridactylus
366 | n02480495 orangutan, orang, orangutang, Pongo pygmaeus
367 | n02480855 gorilla, Gorilla gorilla
368 | n02481823 chimpanzee, chimp, Pan troglodytes
369 | n02483362 gibbon, Hylobates lar
370 | n02483708 siamang, Hylobates syndactylus, Symphalangus syndactylus
371 | n02484975 guenon, guenon monkey
372 | n02486261 patas, hussar monkey, Erythrocebus patas
373 | n02486410 baboon
374 | n02487347 macaque
375 | n02488291 langur
376 | n02488702 colobus, colobus monkey
377 | n02489166 proboscis monkey, Nasalis larvatus
378 | n02490219 marmoset
379 | n02492035 capuchin, ringtail, Cebus capucinus
380 | n02492660 howler monkey, howler
381 | n02493509 titi, titi monkey
382 | n02493793 spider monkey, Ateles geoffroyi
383 | n02494079 squirrel monkey, Saimiri sciureus
384 | n02497673 Madagascar cat, ring-tailed lemur, Lemur catta
385 | n02500267 indri, indris, Indri indri, Indri brevicaudatus
386 | n02504013 Indian elephant, Elephas maximus
387 | n02504458 African elephant, Loxodonta africana
388 | n02509815 lesser panda, red panda, panda, bear cat, cat bear, Ailurus fulgens
389 | n02510455 giant panda, panda, panda bear, coon bear, Ailuropoda melanoleuca
390 | n02514041 barracouta, snoek
391 | n02526121 eel
392 | n02536864 coho, cohoe, coho salmon, blue jack, silver salmon, Oncorhynchus kisutch
393 | n02606052 rock beauty, Holocanthus tricolor
394 | n02607072 anemone fish
395 | n02640242 sturgeon
396 | n02641379 gar, garfish, garpike, billfish, Lepisosteus osseus
397 | n02643566 lionfish
398 | n02655020 puffer, pufferfish, blowfish, globefish
399 | n02666196 abacus
400 | n02667093 abaya
401 | n02669723 academic gown, academic robe, judge's robe
402 | n02672831 accordion, piano accordion, squeeze box
403 | n02676566 acoustic guitar
404 | n02687172 aircraft carrier, carrier, flattop, attack aircraft carrier
405 | n02690373 airliner
406 | n02692877 airship, dirigible
407 | n02699494 altar
408 | n02701002 ambulance
409 | n02704792 amphibian, amphibious vehicle
410 | n02708093 analog clock
411 | n02727426 apiary, bee house
412 | n02730930 apron
413 | n02747177 ashcan, trash can, garbage can, wastebin, ash bin, ash-bin, ashbin, dustbin, trash barrel, trash bin
414 | n02749479 assault rifle, assault gun
415 | n02769748 backpack, back pack, knapsack, packsack, rucksack, haversack
416 | n02776631 bakery, bakeshop, bakehouse
417 | n02777292 balance beam, beam
418 | n02782093 balloon
419 | n02783161 ballpoint, ballpoint pen, ballpen, Biro
420 | n02786058 Band Aid
421 | n02787622 banjo
422 | n02788148 bannister, banister, balustrade, balusters, handrail
423 | n02790996 barbell
424 | n02791124 barber chair
425 | n02791270 barbershop
426 | n02793495 barn
427 | n02794156 barometer
428 | n02795169 barrel, cask
429 | n02797295 barrow, garden cart, lawn cart, wheelbarrow
430 | n02799071 baseball
431 | n02802426 basketball
432 | n02804414 bassinet
433 | n02804610 bassoon
434 | n02807133 bathing cap, swimming cap
435 | n02808304 bath towel
436 | n02808440 bathtub, bathing tub, bath, tub
437 | n02814533 beach wagon, station wagon, wagon, estate car, beach waggon, station waggon, waggon
438 | n02814860 beacon, lighthouse, beacon light, pharos
439 | n02815834 beaker
440 | n02817516 bearskin, busby, shako
441 | n02823428 beer bottle
442 | n02823750 beer glass
443 | n02825657 bell cote, bell cot
444 | n02834397 bib
445 | n02835271 bicycle-built-for-two, tandem bicycle, tandem
446 | n02837789 bikini, two-piece
447 | n02840245 binder, ring-binder
448 | n02841315 binoculars, field glasses, opera glasses
449 | n02843684 birdhouse
450 | n02859443 boathouse
451 | n02860847 bobsled, bobsleigh, bob
452 | n02865351 bolo tie, bolo, bola tie, bola
453 | n02869837 bonnet, poke bonnet
454 | n02870880 bookcase
455 | n02871525 bookshop, bookstore, bookstall
456 | n02877765 bottlecap
457 | n02879718 bow
458 | n02883205 bow tie, bow-tie, bowtie
459 | n02892201 brass, memorial tablet, plaque
460 | n02892767 brassiere, bra, bandeau
461 | n02894605 breakwater, groin, groyne, mole, bulwark, seawall, jetty
462 | n02895154 breastplate, aegis, egis
463 | n02906734 broom
464 | n02909870 bucket, pail
465 | n02910353 buckle
466 | n02916936 bulletproof vest
467 | n02917067 bullet train, bullet
468 | n02927161 butcher shop, meat market
469 | n02930766 cab, hack, taxi, taxicab
470 | n02939185 caldron, cauldron
471 | n02948072 candle, taper, wax light
472 | n02950826 cannon
473 | n02951358 canoe
474 | n02951585 can opener, tin opener
475 | n02963159 cardigan
476 | n02965783 car mirror
477 | n02966193 carousel, carrousel, merry-go-round, roundabout, whirligig
478 | n02966687 carpenter's kit, tool kit
479 | n02971356 carton
480 | n02974003 car wheel
481 | n02977058 cash machine, cash dispenser, automated teller machine, automatic teller machine, automated teller, automatic teller, ATM
482 | n02978881 cassette
483 | n02979186 cassette player
484 | n02980441 castle
485 | n02981792 catamaran
486 | n02988304 CD player
487 | n02992211 cello, violoncello
488 | n02992529 cellular telephone, cellular phone, cellphone, cell, mobile phone
489 | n02999410 chain
490 | n03000134 chainlink fence
491 | n03000247 chain mail, ring mail, mail, chain armor, chain armour, ring armor, ring armour
492 | n03000684 chain saw, chainsaw
493 | n03014705 chest
494 | n03016953 chiffonier, commode
495 | n03017168 chime, bell, gong
496 | n03018349 china cabinet, china closet
497 | n03026506 Christmas stocking
498 | n03028079 church, church building
499 | n03032252 cinema, movie theater, movie theatre, movie house, picture palace
500 | n03041632 cleaver, meat cleaver, chopper
501 | n03042490 cliff dwelling
502 | n03045698 cloak
503 | n03047690 clog, geta, patten, sabot
504 | n03062245 cocktail shaker
505 | n03063599 coffee mug
506 | n03063689 coffeepot
507 | n03065424 coil, spiral, volute, whorl, helix
508 | n03075370 combination lock
509 | n03085013 computer keyboard, keypad
510 | n03089624 confectionery, confectionary, candy store
511 | n03095699 container ship, containership, container vessel
512 | n03100240 convertible
513 | n03109150 corkscrew, bottle screw
514 | n03110669 cornet, horn, trumpet, trump
515 | n03124043 cowboy boot
516 | n03124170 cowboy hat, ten-gallon hat
517 | n03125729 cradle
518 | n03126707 crane
519 | n03127747 crash helmet
520 | n03127925 crate
521 | n03131574 crib, cot
522 | n03133878 Crock Pot
523 | n03134739 croquet ball
524 | n03141823 crutch
525 | n03146219 cuirass
526 | n03160309 dam, dike, dyke
527 | n03179701 desk
528 | n03180011 desktop computer
529 | n03187595 dial telephone, dial phone
530 | n03188531 diaper, nappy, napkin
531 | n03196217 digital clock
532 | n03197337 digital watch
533 | n03201208 dining table, board
534 | n03207743 dishrag, dishcloth
535 | n03207941 dishwasher, dish washer, dishwashing machine
536 | n03208938 disk brake, disc brake
537 | n03216828 dock, dockage, docking facility
538 | n03218198 dogsled, dog sled, dog sleigh
539 | n03220513 dome
540 | n03223299 doormat, welcome mat
541 | n03240683 drilling platform, offshore rig
542 | n03249569 drum, membranophone, tympan
543 | n03250847 drumstick
544 | n03255030 dumbbell
545 | n03259280 Dutch oven
546 | n03271574 electric fan, blower
547 | n03272010 electric guitar
548 | n03272562 electric locomotive
549 | n03290653 entertainment center
550 | n03291819 envelope
551 | n03297495 espresso maker
552 | n03314780 face powder
553 | n03325584 feather boa, boa
554 | n03337140 file, file cabinet, filing cabinet
555 | n03344393 fireboat
556 | n03345487 fire engine, fire truck
557 | n03347037 fire screen, fireguard
558 | n03355925 flagpole, flagstaff
559 | n03372029 flute, transverse flute
560 | n03376595 folding chair
561 | n03379051 football helmet
562 | n03384352 forklift
563 | n03388043 fountain
564 | n03388183 fountain pen
565 | n03388549 four-poster
566 | n03393912 freight car
567 | n03394916 French horn, horn
568 | n03400231 frying pan, frypan, skillet
569 | n03404251 fur coat
570 | n03417042 garbage truck, dustcart
571 | n03424325 gasmask, respirator, gas helmet
572 | n03425413 gas pump, gasoline pump, petrol pump, island dispenser
573 | n03443371 goblet
574 | n03444034 go-kart
575 | n03445777 golf ball
576 | n03445924 golfcart, golf cart
577 | n03447447 gondola
578 | n03447721 gong, tam-tam
579 | n03450230 gown
580 | n03452741 grand piano, grand
581 | n03457902 greenhouse, nursery, glasshouse
582 | n03459775 grille, radiator grille
583 | n03461385 grocery store, grocery, food market, market
584 | n03467068 guillotine
585 | n03476684 hair slide
586 | n03476991 hair spray
587 | n03478589 half track
588 | n03481172 hammer
589 | n03482405 hamper
590 | n03483316 hand blower, blow dryer, blow drier, hair dryer, hair drier
591 | n03485407 hand-held computer, hand-held microcomputer
592 | n03485794 handkerchief, hankie, hanky, hankey
593 | n03492542 hard disc, hard disk, fixed disk
594 | n03494278 harmonica, mouth organ, harp, mouth harp
595 | n03495258 harp
596 | n03496892 harvester, reaper
597 | n03498962 hatchet
598 | n03527444 holster
599 | n03529860 home theater, home theatre
600 | n03530642 honeycomb
601 | n03532672 hook, claw
602 | n03534580 hoopskirt, crinoline
603 | n03535780 horizontal bar, high bar
604 | n03538406 horse cart, horse-cart
605 | n03544143 hourglass
606 | n03584254 iPod
607 | n03584829 iron, smoothing iron
608 | n03590841 jack-o'-lantern
609 | n03594734 jean, blue jean, denim
610 | n03594945 jeep, landrover
611 | n03595614 jersey, T-shirt, tee shirt
612 | n03598930 jigsaw puzzle
613 | n03599486 jinrikisha, ricksha, rickshaw
614 | n03602883 joystick
615 | n03617480 kimono
616 | n03623198 knee pad
617 | n03627232 knot
618 | n03630383 lab coat, laboratory coat
619 | n03633091 ladle
620 | n03637318 lampshade, lamp shade
621 | n03642806 laptop, laptop computer
622 | n03649909 lawn mower, mower
623 | n03657121 lens cap, lens cover
624 | n03658185 letter opener, paper knife, paperknife
625 | n03661043 library
626 | n03662601 lifeboat
627 | n03666591 lighter, light, igniter, ignitor
628 | n03670208 limousine, limo
629 | n03673027 liner, ocean liner
630 | n03676483 lipstick, lip rouge
631 | n03680355 Loafer
632 | n03690938 lotion
633 | n03691459 loudspeaker, speaker, speaker unit, loudspeaker system, speaker system
634 | n03692522 loupe, jeweler's loupe
635 | n03697007 lumbermill, sawmill
636 | n03706229 magnetic compass
637 | n03709823 mailbag, postbag
638 | n03710193 mailbox, letter box
639 | n03710637 maillot
640 | n03710721 maillot, tank suit
641 | n03717622 manhole cover
642 | n03720891 maraca
643 | n03721384 marimba, xylophone
644 | n03724870 mask
645 | n03729826 matchstick
646 | n03733131 maypole
647 | n03733281 maze, labyrinth
648 | n03733805 measuring cup
649 | n03742115 medicine chest, medicine cabinet
650 | n03743016 megalith, megalithic structure
651 | n03759954 microphone, mike
652 | n03761084 microwave, microwave oven
653 | n03763968 military uniform
654 | n03764736 milk can
655 | n03769881 minibus
656 | n03770439 miniskirt, mini
657 | n03770679 minivan
658 | n03773504 missile
659 | n03775071 mitten
660 | n03775546 mixing bowl
661 | n03776460 mobile home, manufactured home
662 | n03777568 Model T
663 | n03777754 modem
664 | n03781244 monastery
665 | n03782006 monitor
666 | n03785016 moped
667 | n03786901 mortar
668 | n03787032 mortarboard
669 | n03788195 mosque
670 | n03788365 mosquito net
671 | n03791053 motor scooter, scooter
672 | n03792782 mountain bike, all-terrain bike, off-roader
673 | n03792972 mountain tent
674 | n03793489 mouse, computer mouse
675 | n03794056 mousetrap
676 | n03796401 moving van
677 | n03803284 muzzle
678 | n03804744 nail
679 | n03814639 neck brace
680 | n03814906 necklace
681 | n03825788 nipple
682 | n03832673 notebook, notebook computer
683 | n03837869 obelisk
684 | n03838899 oboe, hautboy, hautbois
685 | n03840681 ocarina, sweet potato
686 | n03841143 odometer, hodometer, mileometer, milometer
687 | n03843555 oil filter
688 | n03854065 organ, pipe organ
689 | n03857828 oscilloscope, scope, cathode-ray oscilloscope, CRO
690 | n03866082 overskirt
691 | n03868242 oxcart
692 | n03868863 oxygen mask
693 | n03871628 packet
694 | n03873416 paddle, boat paddle
695 | n03874293 paddlewheel, paddle wheel
696 | n03874599 padlock
697 | n03876231 paintbrush
698 | n03877472 pajama, pyjama, pj's, jammies
699 | n03877845 palace
700 | n03884397 panpipe, pandean pipe, syrinx
701 | n03887697 paper towel
702 | n03888257 parachute, chute
703 | n03888605 parallel bars, bars
704 | n03891251 park bench
705 | n03891332 parking meter
706 | n03895866 passenger car, coach, carriage
707 | n03899768 patio, terrace
708 | n03902125 pay-phone, pay-station
709 | n03903868 pedestal, plinth, footstall
710 | n03908618 pencil box, pencil case
711 | n03908714 pencil sharpener
712 | n03916031 perfume, essence
713 | n03920288 Petri dish
714 | n03924679 photocopier
715 | n03929660 pick, plectrum, plectron
716 | n03929855 pickelhaube
717 | n03930313 picket fence, paling
718 | n03930630 pickup, pickup truck
719 | n03933933 pier
720 | n03935335 piggy bank, penny bank
721 | n03937543 pill bottle
722 | n03938244 pillow
723 | n03942813 ping-pong ball
724 | n03944341 pinwheel
725 | n03947888 pirate, pirate ship
726 | n03950228 pitcher, ewer
727 | n03954731 plane, carpenter's plane, woodworking plane
728 | n03956157 planetarium
729 | n03958227 plastic bag
730 | n03961711 plate rack
731 | n03967562 plow, plough
732 | n03970156 plunger, plumber's helper
733 | n03976467 Polaroid camera, Polaroid Land camera
734 | n03976657 pole
735 | n03977966 police van, police wagon, paddy wagon, patrol wagon, wagon, black Maria
736 | n03980874 poncho
737 | n03982430 pool table, billiard table, snooker table
738 | n03983396 pop bottle, soda bottle
739 | n03991062 pot, flowerpot
740 | n03992509 potter's wheel
741 | n03995372 power drill
742 | n03998194 prayer rug, prayer mat
743 | n04004767 printer
744 | n04005630 prison, prison house
745 | n04008634 projectile, missile
746 | n04009552 projector
747 | n04019541 puck, hockey puck
748 | n04023962 punching bag, punch bag, punching ball, punchball
749 | n04026417 purse
750 | n04033901 quill, quill pen
751 | n04033995 quilt, comforter, comfort, puff
752 | n04037443 racer, race car, racing car
753 | n04039381 racket, racquet
754 | n04040759 radiator
755 | n04041544 radio, wireless
756 | n04044716 radio telescope, radio reflector
757 | n04049303 rain barrel
758 | n04065272 recreational vehicle, RV, R.V.
759 | n04067472 reel
760 | n04069434 reflex camera
761 | n04070727 refrigerator, icebox
762 | n04074963 remote control, remote
763 | n04081281 restaurant, eating house, eating place, eatery
764 | n04086273 revolver, six-gun, six-shooter
765 | n04090263 rifle
766 | n04099969 rocking chair, rocker
767 | n04111531 rotisserie
768 | n04116512 rubber eraser, rubber, pencil eraser
769 | n04118538 rugby ball
770 | n04118776 rule, ruler
771 | n04120489 running shoe
772 | n04125021 safe
773 | n04127249 safety pin
774 | n04131690 saltshaker, salt shaker
775 | n04133789 sandal
776 | n04136333 sarong
777 | n04141076 sax, saxophone
778 | n04141327 scabbard
779 | n04141975 scale, weighing machine
780 | n04146614 school bus
781 | n04147183 schooner
782 | n04149813 scoreboard
783 | n04152593 screen, CRT screen
784 | n04153751 screw
785 | n04154565 screwdriver
786 | n04162706 seat belt, seatbelt
787 | n04179913 sewing machine
788 | n04192698 shield, buckler
789 | n04200800 shoe shop, shoe-shop, shoe store
790 | n04201297 shoji
791 | n04204238 shopping basket
792 | n04204347 shopping cart
793 | n04208210 shovel
794 | n04209133 shower cap
795 | n04209239 shower curtain
796 | n04228054 ski
797 | n04229816 ski mask
798 | n04235860 sleeping bag
799 | n04238763 slide rule, slipstick
800 | n04239074 sliding door
801 | n04243546 slot, one-armed bandit
802 | n04251144 snorkel
803 | n04252077 snowmobile
804 | n04252225 snowplow, snowplough
805 | n04254120 soap dispenser
806 | n04254680 soccer ball
807 | n04254777 sock
808 | n04258138 solar dish, solar collector, solar furnace
809 | n04259630 sombrero
810 | n04263257 soup bowl
811 | n04264628 space bar
812 | n04265275 space heater
813 | n04266014 space shuttle
814 | n04270147 spatula
815 | n04273569 speedboat
816 | n04275548 spider web, spider's web
817 | n04277352 spindle
818 | n04285008 sports car, sport car
819 | n04286575 spotlight, spot
820 | n04296562 stage
821 | n04310018 steam locomotive
822 | n04311004 steel arch bridge
823 | n04311174 steel drum
824 | n04317175 stethoscope
825 | n04325704 stole
826 | n04326547 stone wall
827 | n04328186 stopwatch, stop watch
828 | n04330267 stove
829 | n04332243 strainer
830 | n04335435 streetcar, tram, tramcar, trolley, trolley car
831 | n04336792 stretcher
832 | n04344873 studio couch, day bed
833 | n04346328 stupa, tope
834 | n04347754 submarine, pigboat, sub, U-boat
835 | n04350905 suit, suit of clothes
836 | n04355338 sundial
837 | n04355933 sunglass
838 | n04356056 sunglasses, dark glasses, shades
839 | n04357314 sunscreen, sunblock, sun blocker
840 | n04366367 suspension bridge
841 | n04367480 swab, swob, mop
842 | n04370456 sweatshirt
843 | n04371430 swimming trunks, bathing trunks
844 | n04371774 swing
845 | n04372370 switch, electric switch, electrical switch
846 | n04376876 syringe
847 | n04380533 table lamp
848 | n04389033 tank, army tank, armored combat vehicle, armoured combat vehicle
849 | n04392985 tape player
850 | n04398044 teapot
851 | n04399382 teddy, teddy bear
852 | n04404412 television, television system
853 | n04409515 tennis ball
854 | n04417672 thatch, thatched roof
855 | n04418357 theater curtain, theatre curtain
856 | n04423845 thimble
857 | n04428191 thresher, thrasher, threshing machine
858 | n04429376 throne
859 | n04435653 tile roof
860 | n04442312 toaster
861 | n04443257 tobacco shop, tobacconist shop, tobacconist
862 | n04447861 toilet seat
863 | n04456115 torch
864 | n04458633 totem pole
865 | n04461696 tow truck, tow car, wrecker
866 | n04462240 toyshop
867 | n04465501 tractor
868 | n04467665 trailer truck, tractor trailer, trucking rig, rig, articulated lorry, semi
869 | n04476259 tray
870 | n04479046 trench coat
871 | n04482393 tricycle, trike, velocipede
872 | n04483307 trimaran
873 | n04485082 tripod
874 | n04486054 triumphal arch
875 | n04487081 trolleybus, trolley coach, trackless trolley
876 | n04487394 trombone
877 | n04493381 tub, vat
878 | n04501370 turnstile
879 | n04505470 typewriter keyboard
880 | n04507155 umbrella
881 | n04509417 unicycle, monocycle
882 | n04515003 upright, upright piano
883 | n04517823 vacuum, vacuum cleaner
884 | n04522168 vase
885 | n04523525 vault
886 | n04525038 velvet
887 | n04525305 vending machine
888 | n04532106 vestment
889 | n04532670 viaduct
890 | n04536866 violin, fiddle
891 | n04540053 volleyball
892 | n04542943 waffle iron
893 | n04548280 wall clock
894 | n04548362 wallet, billfold, notecase, pocketbook
895 | n04550184 wardrobe, closet, press
896 | n04552348 warplane, military plane
897 | n04553703 washbasin, handbasin, washbowl, lavabo, wash-hand basin
898 | n04554684 washer, automatic washer, washing machine
899 | n04557648 water bottle
900 | n04560804 water jug
901 | n04562935 water tower
902 | n04579145 whiskey jug
903 | n04579432 whistle
904 | n04584207 wig
905 | n04589890 window screen
906 | n04590129 window shade
907 | n04591157 Windsor tie
908 | n04591713 wine bottle
909 | n04592741 wing
910 | n04596742 wok
911 | n04597913 wooden spoon
912 | n04599235 wool, woolen, woollen
913 | n04604644 worm fence, snake fence, snake-rail fence, Virginia fence
914 | n04606251 wreck
915 | n04612504 yawl
916 | n04613696 yurt
917 | n06359193 web site, website, internet site, site
918 | n06596364 comic book
919 | n06785654 crossword puzzle, crossword
920 | n06794110 street sign
921 | n06874185 traffic light, traffic signal, stoplight
922 | n07248320 book jacket, dust cover, dust jacket, dust wrapper
923 | n07565083 menu
924 | n07579787 plate
925 | n07583066 guacamole
926 | n07584110 consomme
927 | n07590611 hot pot, hotpot
928 | n07613480 trifle
929 | n07614500 ice cream, icecream
930 | n07615774 ice lolly, lolly, lollipop, popsicle
931 | n07684084 French loaf
932 | n07693725 bagel, beigel
933 | n07695742 pretzel
934 | n07697313 cheeseburger
935 | n07697537 hotdog, hot dog, red hot
936 | n07711569 mashed potato
937 | n07714571 head cabbage
938 | n07714990 broccoli
939 | n07715103 cauliflower
940 | n07716358 zucchini, courgette
941 | n07716906 spaghetti squash
942 | n07717410 acorn squash
943 | n07717556 butternut squash
944 | n07718472 cucumber, cuke
945 | n07718747 artichoke, globe artichoke
946 | n07720875 bell pepper
947 | n07730033 cardoon
948 | n07734744 mushroom
949 | n07742313 Granny Smith
950 | n07745940 strawberry
951 | n07747607 orange
952 | n07749582 lemon
953 | n07753113 fig
954 | n07753275 pineapple, ananas
955 | n07753592 banana
956 | n07754684 jackfruit, jak, jack
957 | n07760859 custard apple
958 | n07768694 pomegranate
959 | n07802026 hay
960 | n07831146 carbonara
961 | n07836838 chocolate sauce, chocolate syrup
962 | n07860988 dough
963 | n07871810 meat loaf, meatloaf
964 | n07873807 pizza, pizza pie
965 | n07875152 potpie
966 | n07880968 burrito
967 | n07892512 red wine
968 | n07920052 espresso
969 | n07930864 cup
970 | n07932039 eggnog
971 | n09193705 alp
972 | n09229709 bubble
973 | n09246464 cliff, drop, drop-off
974 | n09256479 coral reef
975 | n09288635 geyser
976 | n09332890 lakeside, lakeshore
977 | n09399592 promontory, headland, head, foreland
978 | n09421951 sandbar, sand bar
979 | n09428293 seashore, coast, seacoast, sea-coast
980 | n09468604 valley, vale
981 | n09472597 volcano
982 | n09835506 ballplayer, baseball player
983 | n10148035 groom, bridegroom
984 | n10565667 scuba diver
985 | n11879895 rapeseed
986 | n11939491 daisy
987 | n12057211 yellow lady's slipper, yellow lady-slipper, Cypripedium calceolus, Cypripedium parviflorum
988 | n12144580 corn
989 | n12267677 acorn
990 | n12620546 hip, rose hip, rosehip
991 | n12768682 buckeye, horse chestnut, conker
992 | n12985857 coral fungus
993 | n12998815 agaric
994 | n13037406 gyromitra
995 | n13040303 stinkhorn, carrion fungus
996 | n13044778 earthstar
997 | n13052670 hen-of-the-woods, hen of the woods, Polyporus frondosus, Grifola frondosa
998 | n13054560 bolete
999 | n13133613 ear, spike, capitulum
1000 | n15075141 toilet tissue, toilet paper, bathroom tissue
1001 |
--------------------------------------------------------------------------------