【问题标题】:Caffe layer creation failureCaffe 层创建失败
【发布时间】:2015-07-31 06:00:59
【问题描述】:

我正在尝试在测试阶段加载一个网络配置,该配置首先具有一个内存数据层,然后是一个卷积层。 MemoryData 层创建成功, 但是卷积层的创建在以下位置失败:

LOG(INFO) << "Creating layer " << param.name();
const string& type = param.type();
CreatorRegistry& registry = Registry();
CHECK_EQ(registry.count(type), 1) << "Unknown layer type: " << type
<< " (known types: " << LayerTypeList() << ")";

打印的错误是:

F0519 14:54:12.494139 14504 layer_factory.hpp:77] 检查失败: registry.count(t ype) == 1 (0 vs. 1) 未知层类型:卷积 (已知类型:MemoryData)

registry 只有一个条目,实际上是 MemoryData。 进入注册表创建函数时,它看起来像是从

REGISTER_LAYER_CLASS(MemoryData);

在 memory_data_later.cpp 中。

我看到类似的REGISTER_LAYER_CLASS 调用其他受支持的层,但看起来它们从未被调用过。 我该如何解决?

谢谢!

【问题讨论】:

    标签: c++ layer deep-learning caffe


    【解决方案1】:

    尝试将 caffe 静态链接到可执行文件时会发生此错误。您需要传递额外的链接器标志以确保包含层注册代码。

    如果您使用 cmake,请查看 Targets.cmake:

    ###########################################################################################
    # Defines global Caffe_LINK flag, This flag is required to prevent linker from excluding
    # some objects which are not addressed directly but are registered via static constructors
    if(BUILD_SHARED_LIBS)
      set(Caffe_LINK caffe)
    else()
      if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
        set(Caffe_LINK -Wl,-force_load caffe)
      elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
        set(Caffe_LINK -Wl,--whole-archive caffe -Wl,--no-whole-archive)
      endif()
    endif()
    

    然后你在哪里创建你的目标:

    # target
    add_executable(${name} ${source})
    target_link_libraries(${name} ${Caffe_LINK})
    

    一个快速的解决方案是将 caffe 构建和链接为共享库而不是静态库。

    另见this post

    只是为了在 Windows 上完成 MSVC 编译: 在目标可执行文件或 dll 上使用 /OPT:NOREF/INCLUDE 链接器选项。

    【讨论】:

    • 这正是问题所在。我首先通过强制链接器以一种丑陋的丑陋方式包含“未使用的”(=几乎所有层)obj文件来克服它 - 您的建议肯定是正确的做法。谢谢!
    • 在 IOS 中不支持动态库。我为 Caffe 创建了静态库。我在 IOS 中遇到了同样的错误。你是怎么解决这个错误的?
    • @balajichinna:您可以通过例如在头文件(例如 layer_factory.hpp)中对虚拟函数进行原型设计来强制链接,在其代码未链接的 cpp 中实现它(例如 layer_factory.cpp,并在其原型所在的头文件中静态调用它。例如:在 layer_factory.hpp:int lf_foo();静态 int lf_dummy = lf_foo();在 layer_factory.cpp:int lf_foo() { return 0; }。丑陋,但有效。
    • 实际上 /OPT:NOREF 将“使用库依赖输入”设置为 true 对我有用。我在这里读到了social.msdn.microsoft.com/Forums/vstudio/en-US/…
    • 对于 iOS 和静态框架,修复是在 Xcode 的构建设置中将 -all_load 添加到 OTHER_LDFLAGS
    【解决方案2】:

    在 Makefile 中的适当位置将 -l$(PROJECT) 替换为 $(STATIC_LINK_COMMAND),并删除现在不必要的运行时加载路径:-Wl,-rpath,$(ORIGIN)/../lib

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-11-06
      • 1970-01-01
      • 2018-01-20
      • 1970-01-01
      • 2017-07-18
      • 1970-01-01
      • 2017-06-20
      • 1970-01-01
      相关资源
      最近更新 更多