Darknet学习笔记1:代码预处理

1. 代码清理

1. 文件目录清理
.
├── [data]
│   └── [labels]
├── [examples]
├── [include]
├── [src]
└── Makefile

只保留./data/labels目录下所有文件与其余目录下的*.c,*.h文件

2. 条件编译清理

由于Darknet有针对GPU的优化与使用了OpenCV,可以先排除掉这一部分,让主体代码逻辑更清楚。这里使用unifdef工具来删去相关代码。

apt-get install unifdef

安装unifdef工具包

unifdef -K -U CONFIG_XXXX /path/to/file

这里,-K 是防止 unifdef 处理一些带常数的条件编译,比如 #if 0。-U 就是指定某个宏是 undefined。

#!/bin/bash

filelist=`find . -name *.c -o -name *.h`

for file in $filelist
do
  unifdef -K -U GPU CUDNN OPENCV $file > $file.out
  cmp --silent $file $file.out || cp $file.out $file
  rm -f $file.out
done

编译测试一下,看否精简得有问题

3. 文件结构归一

.c,.h 文件归一到一个文件夹下面,写个Makefile

EXEC = darknet

CC = gcc

CFLAGS  = -Wall -Wno-unused-result -Wno-unknown-pragmas -Wfatal-errors
LDFLAGS = -lm -pthread

OBJS = gemm.o utils.o cuda.o deconvolutional_layer.o convolutional_layer.o list.o image.o activations.o im2col.o col2im.o blas.o crop_layer.o dropout_layer.o maxpool_layer.o softmax_layer.o data.o matrix.o network.o connected_layer.o cost_layer.o parser.o option_list.o detection_layer.o route_layer.o upsample_layer.o box.o normalization_layer.o avgpool_layer.o layer.o local_layer.o shortcut_layer.o logistic_layer.o activation_layer.o rnn_layer.o gru_layer.o crnn_layer.o demo.o batchnorm_layer.o region_layer.o reorg_layer.o tree.o  lstm_layer.o l2norm_layer.o yolo_layer.o iseg_layer.o \
captcha.o lsd.o super.o art.o tag.o cifar.o go.o rnn.o segmenter.o regressor.o classifier.o coco.o yolo.o detector.o nightmare.o instance-segmenter.o darknet.o

all: $(EXEC)

$(EXEC): $(OBJS)
    $(CC) $(OBJS) -o $(EXEC) $(LDFLAGS)

$(OBJS):
    $(CC) -c $(CFLAGS) $*.c -o $*.o

.PHONY: clean

clean:
    rm -rf $(EXEC) $(OBJS)

make编译一下,执行测试命令(没有权重文件先在官网下载好):

./darknet detect cfg/yolov3.cfg yolov3.weights data/dog.jpg

可以看到结果没问题,至于预测时间嘛,也是相当感人的。。。。。(主频4.2GHz情况下,3分钟)

这是清理过后源代码,欢迎Watch、Star、Fork三连:
https://github.com/SimpleDoger/Darknet_CPU_Only(这个版本是做了指针和对象错误修复过后的版本,并测试过与原版执行结果相同)

2. 创建VS2013工程

接下来即便是耗费大力气为什么都要推到Windows系统上呢,因为Windows系统上有宇宙最强IDE加持。。。能事半功倍

1. 代码修复

由于MSVC与GCC编译的差异,在GCC下能编译通过,但是在MSVC下报错。主要报错的地方有:

  1. 相关头文件未找到(除了pthread.h,其余都能找到替代)
  2. what_time_is_it_now()函数实现修复
  3. 指针和对象错误(这个应该属于原作者书写不规范,遗留下的bug,虽然不严格的gcc编译能通过。刚刚看了下原作者简历,拿Vim撸的。。。。)
  4. 清理掉文件:captcha.c、lsd.c、super.c、art.c、tag.c、cifar.c、go.c、rnn.c、segmenter.c、regressor.c、classifier.c、coco.c、yolo.c、nightmare.c、instance-segmenter.c。并备注掉darknet.c里面相关调用代码。这些算是对Darknet框架应用层上的东西了,和detector.c完成功能同级。

1) what_time_is_it_now()函数实现修复

double what_time_is_it_now()
{
    double time_now = clock() / 1000.0;
    return time_now;
}

2)关于net报错的地方,将对象改为指针

2. 添加VC版pthread支持(已废除)

后来发现在运行的时候有动态内存分配溢出,会导致后面的calloc失败?不知道,反正移除了过后能正常运行了。很诡异,在有调试器加持的情况下没问题。。。

  1. 下载Win32的pthread发行版

  2. 解压

Pre-built.2\dll\x86\pthreadVC2.dll 到程序生成目录
Pre-built.2\lib\x86\pthreadVC2.lib 到程序生成目录
Pre-built.2\include\pthread.h 到工程目录
Pre-built.2\include\sched.h 到工程目录
Pre-built.2\include\semaphore.h 到工程目录

工程包含对应头文件

  1. 修改pthread.h
    在42行添加:
#pragma comment(lib,"pthreadVC2.lib")

修改300行为:

#include "sched.h"
2. 移除pthread相关代码

pthread相关代码经过分析主要用在了数据加载上。通过多线程加载图片,标签数据源到内存,相关函数包含在swag.c、voxel.c、writing.c、attention.c、compare.c、data.c、detector.c文件里面。

待续....

终于可以运行调试了,Bingo~

借助强大的IDE,能很方便的生成函数调用逻辑关系图:


代码的分析将在随后的文章详解

-----逃-----

你可能感兴趣的:(Darknet学习笔记1:代码预处理)