darknet编译好以后相应的代码存放在
root/examples/和root/src/中
examples里面关注darknet.c和yolo.c
其实最后都指向yolo.c
yolo.c中的run_yolo函数会根据指令分成测试,训练等,我主要关注训练,可以看到它指向了
yolo.c的train_yolo函数
这个函数指向了src中的network.c中的train_network函数
这个函数中调用了network.c的train_network_dotum函数
在训练的时候调用了forward_network和backward_network函数
先说前向传递forward_network,它指向了yolo_layer.c的forward_yolo_layer函数。
这个函数是整个yolo_layer.c中最重要的函数,它一方面完成了相应值的激活,一方面计算了相应位置的梯度和损失。
首先是激活:
在该位置只激活了(x,y)和置信度(confidence)和类别概率(C1,C2,C3,...)
接着开始遍历每个预测得到的bbox,每个bbox先去和标签GT遍历,找到与之匹配的gt(取IOU最大)。完成以后所有的预测框都有了匹配的gt,但不是所有的gt都有与之匹配的预测框。接下来计算梯度,这里面有两个阈值,大于第一个阈值不计算梯度。大于第二个阈值,计算位置和类别梯度。然后遍历完所有的预测框后,开始遍历所有的GT。
对于每一个GT,首先匹配先先验框,其实就是确定哪一个位置的cell负责预测那个gt的种类和位置。
然后再去和每个预测框进行遍历,找到最大的IOU。再计算梯度。遍历完成,计算损失。
至此,前向传递完成,然后进行反向传递。因为相应的梯度已经计算完成,所以直接调用函数(network.c)的backward_network函数,这个函数调用(yolo_layer.c)的backward_yolo_layer函数,这个函数就直接调用一个底层传递函数axpy_cpu,这个函数在src/blas.c中
以上就是整个训练过程了。具体需要参照代码进行比对。