一、caffe如何将卷积层或网络层的权值blob给保存下来的?
首先Solver类在Step(intiters)中调用了Snapshot()函数,在voidSolver<Dtype>::Snapshot()函数中能看到保存caffemodel文件的重要函数 SnapshotToBinaryProto(),该函数详细如下:
可看到该函数里初始化了NetParameternet_param ; 之后调用net_->ToProto(&net_param,param_.snapshot_diff())进行初始化, 该函数详细如下:
在该函数中初始化了NetParameter 类对象net_param, 可看出net_param调用了 add_layer()函数将net_的所有层的参数作了处理,可理解为所有层的参数均加载到这个net_param, 采用遍历的方法使各个层layers_[i]调用 ToProto(layer_param,write_diff); write_diff 为 bool类型,表示是否需要保存偏差;看看各个层的 ToProto函数:
可看到在这个函数里,各个层的 layer_param又将使用add_blobs()将 层里的所有blob给加载进去,看看 blobs_[i]的 ToProto函数:
可看到指向BlobProto类指针的proto(来自layer_param的add_blobs()) 将会通过for循环的方式调用 add_double_data(data_vec[i])将blob的data数组加载起来.
综上所述,一个net_的所有层里的所有blob的data数据将被用于初始化 NetParameter类对象net_param, 又调用了WriteProtoToBinaryFile(net_param,model_filename) 将其中重要的权参保存为caffemodel文件,如下所示:
实质是调用了下面这个,最终保存为caffemodel文件
二、caffe是如何读入caffemodel文件的?
caffemodel文件通常被用于初始化Net类对象,使用Net类中的相关函数如下:
对于caffemodel文件,将被调用voidCopyTrainedLayersFromBinaryProto(const string trained_filename);该函数如下:
可看到内部调用了ReadNetParamsFromBinaryFileOrDie(trained_filename,¶m) 初始化了
NetParameter类对象param;param 又将被用于初始化Net类的中各个层的blob;
先看看ReadNetParamsFromBinaryFileOrDie(trained_filename,¶m) ,定义在 upgrade_proto.cpp:
内部主要调用了ReadProtoFromBinaryFile(param_file,param) , 该函数具体如下:
看看定义在io.cpp的函数ReadProtoFromBinaryFile:
大致也即是从caffemodel文件写入proto, 回到voidCopyTrainedLayersFromBinaryProto(const string trained_filename)函数:
看下另一个函数CopyTrainedLayersFrom(param)的实现:
可由该函数得到,已被初始化的NetParameter类对象 param将被用于初始化Net类中各个层的blob;具体方法是先遍历 param中的各个LayerParameter对象 ,先找到名字相同的层的层id号,再获取这个id号的层的blob,再判断该blob的形状是否与LayerParameter对象中的blob一致,如果一致则开始调用FromProto复制,否则会报错,FromProto函数如下:
在Net类的各个层初始化的时候均会调用setup函数,在这个时候会对blobs_进行判断,如果是已初始化的则不进行权值参数填充,例如卷积层,在 base_conv_layer.cpp中的LayerSetUp函数中有:
今天的文章.caffemodel文件_本地缓存caffeine分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/89133.html