在testAll(位于solver.cpp)函数中进入---->test()
其中 test()进行对权重初始化后的LOSS检测并返回
其中包含函数
即将配置文件中的写好的net复制分享给程序创建网络,具体实现见函数
然后进入test()中调用的
Forward(net.cpp)
---> ForwardFromTo (net.cpp)
然后不断循环 Forward函数,进入各个层的forward函数计算损失
---> (layer.hpp)Forward()分别运行每一层的forward函数
layer[i] 就是第i层的转播函数
如mnist(lenet) i = 0:
即 训练集数据层
由于debug使用的是cpu模式(GPU无法debug 为.cu文件)
因此接下来的步骤为进入此层Forward中的:
---> Forward_cpu() (base_data_layer)
实现了数据和标签复制 然后回到layer.cpp的Forword计算损失
由于此层不产生损失 所以此时层损失为0
然后返回loss回到net.cpp中的ForwordFromTo(源码见上文)函数,并赋值给layer_loss记录为当前层的损失,加到总损失中。
然后根据for循环,进入下一层Forward()(layer.hpp)
---->Forward_cpu()(split_layer)
实现了shareData
然后回到layer.cpp的Forword计算损失
由于此层不产生损失 所以此时层损失为0
然后返回loss回到net.cpp中的ForwordFromTo(源码见上文)函数,并赋值给layer_loss记录为当前层的损失,加到总损失中。
然后根据for循环,进入下一层Forward()(layer.hpp)
---->Forward_cpu(conv_layer.cpp)
(其中包含的函数)
--->
--->
Im2col简单理解:
上一个Forward_cpu为多线程读取边读取边转换
继续往下走,当结束一次forward_cpu函数时,回到layer.cpp的Forword计算损失
损失为0
然后返回loss回到net.cpp中的ForwordFromTo(源码见上文)函数,并赋值给layer_loss记录为当前层的损失,加到总损失中。
然后根据for循环,进入下一层Forward()(layer.hpp)
---->Forward_cpu(pooling_layer.cpp)
代码较长,初始化部分:
part PoolingParameter_PoolMethod_MAX :
回到Layer的Forword计算损失,由于不是随后一层,所以损失为0,不计算
然后继续下一层的Forword, conv2 同conv1,计算权重和偏置,然后是pool2,同pool1
根据网络定义的层来不断进入下一层,不断卷积和池化。
然后返回loss回到net.cpp中的ForwordFromTo(源码见上文)函数,并赋值给layer_loss记录为当前层的损失,加到总损失中。
然后根据for循环,进入下一层Forward()(layer.hpp)
---->Forward_cpu(pooling_layer.cpp)
继续往下走,当结束一次forward_cpu函数时,回到layer.cpp的Forword计算损失
损失为0
然后返回loss回到net.cpp中的ForwordFromTo(源码见上文)函数,并赋值给layer_loss记录为当前层的损失,加到总损失中。
根据网络参数文件中定义,下一层为relu,进行神经元激活。
根据for循环,进入下一层Forward()(layer.hpp)
---->Forward_cpu(relu_layer.cpp)
其中主要为最后的for循环,即relu的定义,此循环为一个很大的for循环,因为对每一个神经元铺平后都要进行激活。
继续往下走,当结束一次forward_cpu函数时,回到layer.cpp的Forword计算损失
损失为0
然后返回loss回到net.cpp中的ForwordFromTo(源码见上文)函数,并赋值给layer_loss记录为当前层的损失,加到总损失中。
然后根据for循环,进入下一层Forward()(layer.hpp)
继续进入全连接层,进行多次全连接层运算(数量根据参数文件中所定义的网络确定),即普通隐藏层。
然后返回loss回到net.cpp中的ForwordFromTo(源码见上文)函数,并赋值给layer_loss记录为当前层的损失,加到总损失中。
然后根据for循环,进入下一层Forward()(layer.hpp)
---->Forward_cpu()(split_layer)
实现了shareData
然后回到layer.cpp的Forword计算损失
由于此层不产生损失 所以此时层损失为0
然后返回loss回到net.cpp中的ForwordFromTo(源码见上文)函数,并赋值给layer_loss记录为当前层的损失,加到总损失中。
根据for循环,进入下一层Forward()(layer.hpp)
---->Forward_cpu(accuracy_layer.cpp)
accuracy_layer具体功能如下:
使用的是最后一个全连接层的输出和真是数据做比较。
继续往下走,当结束一次forward_cpu函数时,回到layer.cpp的Forword计算损失
损失为0
然后返回loss回到net.cpp中的ForwordFromTo(源码见上文)函数,并赋值给layer_loss记录为当前层的损失,加到总损失中。
然后根据for循环,进入下一层Forward()(layer.hpp)
--------->Forword_cpu(softmax_loss_layer.cpp)(循环中的最后一层)
由上图中的forword函数进入softmax_layer.cpp中的Forward_cpu函数
在此处进行softmax计算
并且在softmax_loss中计算损失。此时计算的损失是真正的损失,是整个网络的损失,并且返回给layer中的loss。
此时的loss不再是0,而是具体数值。饭后返回给net.cpp中layer_loss。至此 定义的LeNet前向传播执行完毕。
ForwardFromTo函数执行完毕,
回到net.cpp中的Forward函数继续接下来的操作。返回net_output_blobs_。将其返回给solver.cpp中的Forward函数。
然后继续执行solver.cpp中函数。继续其他优化步骤。
在进行完proto文件中定义的迭代次数后退出Test(solver)函数,退出TestAll(solver)函数
回到solver.cpp中的Step函数中
至此一次前向传播Forward函数优化网络结束。