• caffe学习笔记1


    博客

    http://blog.csdn.net/seven_first/article/details/47378697
    https://zhuanlan.zhihu.com/p/25127756?refer=xiaoleimlnote
    https://github.com/BUPTLdy/Caffe_Code_Analysis/tree/master/

    学习计划

    Caffe运行主要流程


    caffe.cpp

    // A simple registry for caffe commands.
    typedef int (*BrewFunction)();
    typedef std::map<caffe::string, BrewFunction> BrewMap;
    BrewMap g_brew_map;
    
    #define RegisterBrewFunction(func) 
    namespace { 
    class __Registerer_##func { 
     public: /* NOLINT */ 
      __Registerer_##func() { 
        g_brew_map[#func] = &func; 
      } 
    }; 
    __Registerer_##func g_registerer_##func; 
    }
    
    • typedef int (*BrewFunction)()
      函数指针:可用于处理一些参数和返回值一致,但是功能不一样一组函数。
      本示例:定义了一组函数指针,函数参数为(),但是返回值为int这样一组函数指针族。
    • typedef std::map<caffe::string, BrewFunction> BrewMap
      定义BrewMap为一个map,key为string,value为函数指针(参数为(),返回为int)。
    • #define RegisterBrewFunction(func)
      该宏命令完成一次注册的初始化操作; 其中在宏中#和##符号表示的意思如下: #:用来把参数转换成字符串;
      ##:用来连接前后两个参数。

    以caffe中RegisterBrewFunction(train)为例,上面代码可转换为:

    #define RegisterBrewFunction(train) 
    namespace { 
    class __Registerer_train { 
     public: /* NOLINT */ 
      __Registerer_train() { 
        g_brew_map["train"] = &train; 
      } 
    }; 
    __Registerer_train g_registerer_train; 
    }  //完成了全局变量的初始化操作
    

    接来下看caffe.cpp里的main函数代码

    int main(int argc, char** argv) {
      // Print output to stderr (while still logging).
      FLAGS_alsologtostderr = 1;
      // Set version
      gflags::SetVersionString(AS_STRING(CAFFE_VERSION));
      // Usage message.
      gflags::SetUsageMessage("command line brew
    "
          "usage: caffe <command> <args>
    
    "
          "commands:
    "
          "  train           train or finetune a model
    "
          "  test            score a model
    "
          "  device_query    show GPU diagnostic information
    "
          "  time            benchmark model execution time");
      // Run tool or show usage.
      caffe::GlobalInit(&argc, &argv);
      if (argc == 2) {
    #ifdef WITH_PYTHON_LAYER
        try {
    #endif
          return GetBrewFunction(caffe::string(argv[1]))();
    #ifdef WITH_PYTHON_LAYER
        } catch (bp::error_already_set) {
          PyErr_Print();
          return 1;
        }
    #endif
      } else {
        gflags::ShowUsageWithFlagsRestrict(argv[0], "tools/caffe");
      }
    }
    

    caffe控制台训练示例:caffe train --solver==*.prototxt
    输入完全正确的情况下,函数首先进入:

    • return GetBrewFunction(caffe::string(argv[1]))();
    static BrewFunction GetBrewFunction(const caffe::string& name) {
      if (g_brew_map.count(name)) {
        return g_brew_map[name];
      } else {
        LOG(ERROR) << "Available caffe actions:";
        for (BrewMap::iterator it = g_brew_map.begin();
             it != g_brew_map.end(); ++it) {
          LOG(ERROR) << "	" << it->first;
        }
        LOG(FATAL) << "Unknown action: " << name;
        return NULL;  // not reachable, just to suppress old compiler warnings.
      }
    }
    

    总结:

    • C++函数指针的应用;函数指针可用于解决 函数参数和返回值一致,但功能不一样的一群函数族
    • 进入主函数前,通过全局变量注册函数的方法;

    举例:

    #include <iostream>
    #include <map>
    
    typedef int (*mathfunc)(int,int);
    typedef std::map<std::string, mathfunc> BrepMap;
    BrepMap g_brew_map;
    
    #define RegisterMathFunc(func) 
    namespace { 
        class __Register_##func{ 
            public: 
                __Register_##func() { g_brew_map[#func] = &func;}};
        __Register_##func g_register_##func;}
    
    int add(int a, int b){
        return a+b;
    }
    RegisterMathFunc(add)
    
    int sub(int a, int b){
        return a-b;
    }
    RegisterMathFunc(sub)
    
    int mul(int a, int b){
        return a*b;
    }
    RegisterMathFunc(mul)
    
    
    int main()
    {
        std::cout<< "number of register functions: " << g_brew_map.size() << std::endl;
        std::string math_method = "add";
        std::cout << "23 + 12  = " << g_brew_map[math_method](23,12) << std::endl;
        return 1;
    }
    
    /*
    *******result*******
    number of register functions: 3
    23 + 12  = 35
    */
    
  • 相关阅读:
    eclipse FilteredTree
    Windows API高精度计时 C#版
    循环中响应消息,避免循环时UI线程被阻塞
    Linux rpm 包制作 使用 rpmbuild
    利用Windows API实现精确计时
    C++显示选择文件夹对话框
    android AsyncTask
    [转]Android 动画学习笔记
    eclipse 中导入android 工程时出错:The method of type must override a superclass method 解决方式
    Android 自定义对话框
  • 原文地址:https://www.cnblogs.com/zyore2013/p/7651107.html
Copyright © 2020-2023  润新知