caffe代码解读-mnist例子-前向计算

使用

./build/tools/caffe  train --solver=examples/mnist/lenet_solver.prototxt

进行调试,目的是跟踪程序的变化,了解caffe的具体执行过程。

发现在

shared_ptr<caffe::Solver<float> >
      solver(caffe::SolverRegistry<float>::CreateSolver(solver_param));

之后,除了原来的主线程,多了4个其他线程,进入其他线程,发现是DataReader相关的逻辑。

那为什么是4个?为什么每一个datareader需要一个单独的线程?

调用逻辑上,DataReader::Body::InternalThreadEntry

什么时候开始的新线程?

开始新的线程函数是StartInternalThread

两个地方用到这个函数 

设置断点 void BasePrefetchingDataLayer<Dtype>::LayerSetUp 和DataReader::Body::Body

调用栈如下:

 * frame #0: 0x000000010017d4df libcaffe.so.1.0.0-rc3`caffe::DataReader::Body::Body(this=0x000000010162d7b0, param=0x0000000101621460) + 95 at data_reader.cpp:66
    frame #1: 0x000000010017cfbd libcaffe.so.1.0.0-rc3`caffe::DataReader::Body::Body(this=0x000000010162d7b0, param=0x0000000101621460) + 29 at data_reader.cpp:65
    frame #2: 0x000000010017cd79 libcaffe.so.1.0.0-rc3`caffe::DataReader::DataReader(this=0x00000001018155e8, param=0x0000000101621460) + 505 at data_reader.cpp:27
    frame #3: 0x000000010017cfed libcaffe.so.1.0.0-rc3`caffe::DataReader::DataReader(this=0x00000001018155e8, param=0x0000000101621460) + 29 at data_reader.cpp:20
    frame #4: 0x00000001001f7d72 libcaffe.so.1.0.0-rc3`caffe::DataLayer<float>::DataLayer(this=0x0000000101815000, param=0x0000000101621460) + 82 at data_layer.cpp:17
    frame #5: 0x00000001001f7dcd libcaffe.so.1.0.0-rc3`caffe::DataLayer<float>::DataLayer(this=0x0000000101815000, param=0x0000000101621460) + 29 at data_layer.cpp:17
    frame #6: 0x00000001001fa4a3 libcaffe.so.1.0.0-rc3`boost::shared_ptr<caffe::Layer<float> > caffe::Creator_DataLayer<float>(param=0x0000000101621460) + 67 at data_layer.cpp:108
    frame #7: 0x00000001002990a5 libcaffe.so.1.0.0-rc3`caffe::LayerRegistry<float>::CreateLayer(param=0x0000000101621460) + 709 at layer_factory.hpp:83
    frame #8: 0x00000001002e06a2 libcaffe.so.1.0.0-rc3`caffe::Net<float>::Init(this=0x0000000101614170, in_param=0x0000000101610d90) + 3282 at net.cpp:97
    frame #9: 0x00000001002df6a7 libcaffe.so.1.0.0-rc3`caffe::Net<float>::Net(this=0x0000000101614170, param=0x0000000101610d90, root_net=0x0000000000000000) + 13495 at net.cpp:27
    frame #10: 0x00000001002e5a85 libcaffe.so.1.0.0-rc3`caffe::Net<float>::Net(this=0x0000000101614170, param=0x0000000101610d90, root_net=0x0000000000000000) + 37 at net.cpp:26
    frame #11: 0x000000010033400a libcaffe.so.1.0.0-rc3`caffe::Solver<float>::InitTestNets(this=0x000000010171dab0) + 4202 at solver.cpp:184
    frame #12: 0x0000000100330ef3 libcaffe.so.1.0.0-rc3`caffe::Solver<float>::Init(this=0x000000010171dab0, param=0x00007fff5fbff2c0) + 1139 at solver.cpp:59
    frame #13: 0x000000010033096f libcaffe.so.1.0.0-rc3`caffe::Solver<float>::Solver(this=0x000000010171dab0, param=0x00007fff5fbff2c0, root_solver=0x0000000000000000) + 1663 at solver.cpp:32
    frame #14: 0x0000000100356192 libcaffe.so.1.0.0-rc3`caffe::SGDSolver<float>::SGDSolver(this=0x000000010171dab0, param=0x00007fff5fbff2c0) + 66 at sgd_solvers.hpp:19
    frame #15: 0x000000010035725d libcaffe.so.1.0.0-rc3`caffe::SGDSolver<float>::SGDSolver(this=0x000000010171dab0, param=0x00007fff5fbff2c0) + 29 at sgd_solvers.hpp:19
    frame #16: 0x00000001003621b2 libcaffe.so.1.0.0-rc3`caffe::Solver<float>* caffe::Creator_SGDSolver<float>(param=0x00007fff5fbff2c0) + 50 at sgd_solver.cpp:350
    frame #17: 0x000000010000be0b caffe.bin`caffe::SolverRegistry<float>::CreateSolver(param=0x00007fff5fbff2c0) + 475 at solver_factory.hpp:78
    frame #18: 0x00000001000047d5 caffe.bin`train() + 5269 at caffe.cpp:236



 * frame #0: 0x00000001001d802b libcaffe.so.1.0.0-rc3`caffe::BasePrefetchingDataLayer<float>::LayerSetUp(this=0x0000000102806200, bottom=0x000000010170e370, top=0x000000010170e450) + 27 at base_data_layer.cpp:48
    frame #1: 0x000000010019e8cf libcaffe.so.1.0.0-rc3`caffe::Layer<float>::SetUp(this=0x0000000102806200, bottom=0x000000010170e370, top=0x000000010170e450) + 111 at layer.hpp:71
    frame #2: 0x00000001002e175d libcaffe.so.1.0.0-rc3`caffe::Net<float>::Init(this=0x000000010170a9f0, in_param=0x00007fff5fbfe200) + 7565 at net.cpp:148
    frame #3: 0x00000001002df6a7 libcaffe.so.1.0.0-rc3`caffe::Net<float>::Net(this=0x000000010170a9f0, param=0x00007fff5fbfe200, root_net=0x0000000000000000) + 13495 at net.cpp:27
    frame #4: 0x00000001002e5a85 libcaffe.so.1.0.0-rc3`caffe::Net<float>::Net(this=0x000000010170a9f0, param=0x00007fff5fbfe200, root_net=0x0000000000000000) + 37 at net.cpp:26
    frame #5: 0x0000000100332dfc libcaffe.so.1.0.0-rc3`caffe::Solver<float>::InitTrainNet(this=0x000000010171b4f0) + 2988 at solver.cpp:105
    frame #6: 0x0000000100330ed5 libcaffe.so.1.0.0-rc3`caffe::Solver<float>::Init(this=0x000000010171b4f0, param=0x00007fff5fbff2c0) + 1109 at solver.cpp:57
    frame #7: 0x000000010033096f libcaffe.so.1.0.0-rc3`caffe::Solver<float>::Solver(this=0x000000010171b4f0, param=0x00007fff5fbff2c0, root_solver=0x0000000000000000) + 1663 at solver.cpp:32
    frame #8: 0x0000000100356192 libcaffe.so.1.0.0-rc3`caffe::SGDSolver<float>::SGDSolver(this=0x000000010171b4f0, param=0x00007fff5fbff2c0) + 66 at sgd_solvers.hpp:19
    frame #9: 0x000000010035725d libcaffe.so.1.0.0-rc3`caffe::SGDSolver<float>::SGDSolver(this=0x000000010171b4f0, param=0x00007fff5fbff2c0) + 29 at sgd_solvers.hpp:19
    frame #10: 0x00000001003621b2 libcaffe.so.1.0.0-rc3`caffe::Solver<float>* caffe::Creator_SGDSolver<float>(param=0x00007fff5fbff2c0) + 50 at sgd_solver.cpp:350
    frame #11: 0x000000010000be0b caffe.bin`caffe::SolverRegistry<float>::CreateSolver(param=0x00007fff5fbff2c0) + 475 at solver_factory.hpp:78
    frame #12: 0x00000001000047d5 caffe.bin`train() + 5269 at caffe.cpp:236
    frame #13: 0x0000000100009038 caffe.bin`main(argc=2, argv=0x00007fff5fbffb50) + 600 at caffe.cpp:443


net 的下一层是layer,layer之间进行互联,layer本身分为很多种,用type标示出来,有全联接层、accuracy层等,那这些层内部如果实现?


 在lmdb中数据是以key value的形势存储下来的,估计就是key len value len的形势。

那是如何读入到内存中,又怎样在在内存中使用的?如何确定label和train数据的对应关系,在训练的过程是是一个数据点一次计算吗?


考虑到读取数据必然调用lmdb的接口,设置断点

db_lmdb.cpp:12

得到如下的程序栈:

* thread #2: tid = 0xa26a38, 0x0000000100387310 libcaffe.so.1.0.0-rc3`caffe::db::LMDB::Open(this=0x0000000102303690, source="examples/mnist/mnist_train_lmdb", mode=READ) + 64 at db_lmdb.cpp:12, stop reason = breakpoint 1.1
  * frame #0: 0x0000000100387310 libcaffe.so.1.0.0-rc3`caffe::db::LMDB::Open(this=0x0000000102303690, source="examples/mnist/mnist_train_lmdb", mode=READ) + 64 at db_lmdb.cpp:12
    frame #1: 0x000000010017d79b libcaffe.so.1.0.0-rc3`caffe::DataReader::Body::InternalThreadEntry(this=0x000000010170a350) + 203 at data_reader.cpp:75
    frame #2: 0x000000010019a3ee libcaffe.so.1.0.0-rc3`caffe::InternalThread::entry(this=0x000000010170a350, device=0, mode=CPU, rand_seed=447230961, solver_count=1, root_solver=true) + 94 at internal_thread.cpp:51
    frame #3: 0x000000010019c233 libcaffe.so.1.0.0-rc3`boost::_mfi::mf5<void, caffe::InternalThread, int, caffe::Caffe::Brew, int, int, bool>::operator(this=0x000000010170ab60, p=0x000000010170a350, a1=0, a2=CPU, a3=447230961, a4=1, a5=true)(caffe::InternalThread*, int, caffe::Caffe::Brew, int, int, bool) const + 163 at mem_fn_template.hpp:619
    frame #4: 0x000000010019c161 libcaffe.so.1.0.0-rc3`void boost::_bi::list6<boost::_bi::value<caffe::InternalThread*>, boost::_bi::value<int>, boost::_bi::value<caffe::Caffe::Brew>, boost::_bi::value<int>, boost::_bi::value<int>, boost::_bi::value<bool> >::operator(this=0x000000010170ab70, (null)=type<void> @ 0x0000700000080e48, f=0x000000010170ab60, a=0x0000700000080e70, (null)=0)<boost::_mfi::mf5<void, caffe::InternalThread, int, caffe::Caffe::Brew, int, int, bool>, boost::_bi::list0>(boost::_bi::type<void>, boost::_mfi::mf5<void, caffe::InternalThread, int, caffe::Caffe::Brew, int, int, bool>&, boost::_bi::list0&, int) + 241 at bind.hpp:602
    frame #5: 0x000000010019c06a libcaffe.so.1.0.0-rc3`boost::_bi::bind_t<void, boost::_mfi::mf5<void, caffe::InternalThread, int, caffe::Caffe::Brew, int, int, bool>, boost::_bi::list6<boost::_bi::value<caffe::InternalThread*>, boost::_bi::value<int>, boost::_bi::value<caffe::Caffe::Brew>, boost::_bi::value<int>, boost::_bi::value<int>, boost::_bi::value<bool> > >::operator(this=0x000000010170ab60)() + 58 at bind_template.hpp:20
    frame #6: 0x000000010019b6ac libcaffe.so.1.0.0-rc3`boost::detail::thread_data<boost::_bi::bind_t<void, boost::_mfi::mf5<void, caffe::InternalThread, int, caffe::Caffe::Brew, int, int, bool>, boost::_bi::list6<boost::_bi::value<caffe::InternalThread*>, boost::_bi::value<int>, boost::_bi::value<caffe::Caffe::Brew>, boost::_bi::value<int>, boost::_bi::value<int>, boost::_bi::value<bool> > > >::run(this=0x000000010170a960) + 28 at thread.hpp:116
    frame #7: 0x000000010109e804 libboost_thread-mt.dylib`boost::(anonymous namespace)::thread_proxy(void*) + 164
    frame #8: 0x00007fff922e29b1 libsystem_pthread.dylib`_pthread_body + 131
    frame #9: 0x00007fff922e292e libsystem_pthread.dylib`_pthread_start + 168
    frame #10: 0x00007fff922e0385 libsystem_pthread.dylib`thread_start + 13


* thread #3: tid = 0xa29a6a, 0x0000000100387310 libcaffe.so.1.0.0-rc3`caffe::db::LMDB::Open(this=0x0000000102009eb0, source="examples/mnist/mnist_test_lmdb", mode=READ) + 64 at db_lmdb.cpp:12, stop reason = breakpoint 1.1
  * frame #0: 0x0000000100387310 libcaffe.so.1.0.0-rc3`caffe::db::LMDB::Open(this=0x0000000102009eb0, source="examples/mnist/mnist_test_lmdb", mode=READ) + 64 at db_lmdb.cpp:12
    frame #1: 0x000000010017d79b libcaffe.so.1.0.0-rc3`caffe::DataReader::Body::InternalThreadEntry(this=0x0000000101660900) + 203 at data_reader.cpp:75
    frame #2: 0x000000010019a3ee libcaffe.so.1.0.0-rc3`caffe::InternalThread::entry(this=0x0000000101660900, device=0, mode=CPU, rand_seed=310595927, solver_count=1, root_solver=true) + 94 at internal_thread.cpp:51
    frame #3: 0x000000010019c233 libcaffe.so.1.0.0-rc3`boost::_mfi::mf5<void, caffe::InternalThread, int, caffe::Caffe::Brew, int, int, bool>::operator(this=0x0000000101661060, p=0x0000000101660900, a1=0, a2=CPU, a3=310595927, a4=1, a5=true)(caffe::InternalThread*, int, caffe::Caffe::Brew, int, int, bool) const + 163 at mem_fn_template.hpp:619
    frame #4: 0x000000010019c161 libcaffe.so.1.0.0-rc3`void boost::_bi::list6<boost::_bi::value<caffe::InternalThread*>, boost::_bi::value<int>, boost::_bi::value<caffe::Caffe::Brew>, boost::_bi::value<int>, boost::_bi::value<int>, boost::_bi::value<bool> >::operator(this=0x0000000101661070, (null)=type<void> @ 0x0000700000186e48, f=0x0000000101661060, a=0x0000700000186e70, (null)=0)<boost::_mfi::mf5<void, caffe::InternalThread, int, caffe::Caffe::Brew, int, int, bool>, boost::_bi::list0>(boost::_bi::type<void>, boost::_mfi::mf5<void, caffe::InternalThread, int, caffe::Caffe::Brew, int, int, bool>&, boost::_bi::list0&, int) + 241 at bind.hpp:602
    frame #5: 0x000000010019c06a libcaffe.so.1.0.0-rc3`boost::_bi::bind_t<void, boost::_mfi::mf5<void, caffe::InternalThread, int, caffe::Caffe::Brew, int, int, bool>, boost::_bi::list6<boost::_bi::value<caffe::InternalThread*>, boost::_bi::value<int>, boost::_bi::value<caffe::Caffe::Brew>, boost::_bi::value<int>, boost::_bi::value<int>, boost::_bi::value<bool> > >::operator(this=0x0000000101661060)() + 58 at bind_template.hpp:20
    frame #6: 0x000000010019b6ac libcaffe.so.1.0.0-rc3`boost::detail::thread_data<boost::_bi::bind_t<void, boost::_mfi::mf5<void, caffe::InternalThread, int, caffe::Caffe::Brew, int, int, bool>, boost::_bi::list6<boost::_bi::value<caffe::InternalThread*>, boost::_bi::value<int>, boost::_bi::value<caffe::Caffe::Brew>, boost::_bi::value<int>, boost::_bi::value<int>, boost::_bi::value<bool> > > >::run(this=0x0000000101660e60) + 28 at thread.hpp:116
    frame #7: 0x000000010109e804 libboost_thread-mt.dylib`boost::(anonymous namespace)::thread_proxy(void*) + 164
    frame #8: 0x00007fff922e29b1 libsystem_pthread.dylib`_pthread_body + 131
    frame #9: 0x00007fff922e292e libsystem_pthread.dylib`_pthread_start + 168
    frame #10: 0x00007fff922e0385 libsystem_pthread.dylib`thread_start + 13

这两个线程的source不同,也就是每一个source会有一个单独的读线程,读取的数据放入到data_reader的new_queue_pairs_中,这是一个缓冲队列,多线程安全的。

那什么时候读这个队列呢?


读队列会在data_layer中进行,使用另外的一个线程,

设置断点,data_layer.cpp:58

则* thread #5: tid = 0xa3aae2, 0x00000001001f85a1 libcaffe.so.1.0.0-rc3`caffe::DataLayer<float>::load_batch(this=0x000000010300bc00, batch=0x000000010300c078) + 49 at data_layer.cpp:58, stop reason = breakpoint 2.1
  * frame #0: 0x00000001001f85a1 libcaffe.so.1.0.0-rc3`caffe::DataLayer<float>::load_batch(this=0x000000010300bc00, batch=0x000000010300c078) + 49 at data_layer.cpp:58
    frame #1: 0x00000001001d8715 libcaffe.so.1.0.0-rc3`caffe::BasePrefetchingDataLayer<float>::InternalThreadEntry(this=0x000000010300bc00) + 325 at base_data_layer.cpp:87
    frame #2: 0x000000010019a3ee libcaffe.so.1.0.0-rc3`caffe::InternalThread::entry(this=0x000000010300bc00, device=0, mode=CPU, rand_seed=-1096880597, solver_count=1, root_solver=true) + 94 at internal_thread.cpp:51
    frame #3: 0x000000010019c233 libcaffe.so.1.0.0-rc3`boost::_mfi::mf5<void, caffe::InternalThread, int, caffe::Caffe::Brew, int, int, bool>::operator(this=0x0000000102015670, p=0x000000010300bc00, a1=0, a2=CPU, a3=-1096880597, a4=1, a5=true)(caffe::InternalThread*, int, caffe::Caffe::Brew, int, int, bool) const + 163 at mem_fn_template.hpp:619
    frame #4: 0x000000010019c161 libcaffe.so.1.0.0-rc3`void boost::_bi::list6<boost::_bi::value<caffe::InternalThread*>, boost::_bi::value<int>, boost::_bi::value<caffe::Caffe::Brew>, boost::_bi::value<int>, boost::_bi::value<int>, boost::_bi::value<bool> >::operator(this=0x0000000102015680, (null)=type<void> @ 0x0000700000209e48, f=0x0000000102015670, a=0x0000700000209e70, (null)=0)<boost::_mfi::mf5<void, caffe::InternalThread, int, caffe::Caffe::Brew, int, int, bool>, boost::_bi::list0>(boost::_bi::type<void>, boost::_mfi::mf5<void, caffe::InternalThread, int, caffe::Caffe::Brew, int, int, bool>&, boost::_bi::list0&, int) + 241 at bind.hpp:602
    frame #5: 0x000000010019c06a libcaffe.so.1.0.0-rc3`boost::_bi::bind_t<void, boost::_mfi::mf5<void, caffe::InternalThread, int, caffe::Caffe::Brew, int, int, bool>, boost::_bi::list6<boost::_bi::value<caffe::InternalThread*>, boost::_bi::value<int>, boost::_bi::value<caffe::Caffe::Brew>, boost::_bi::value<int>, boost::_bi::value<int>, boost::_bi::value<bool> > >::operator(this=0x0000000102015670)() + 58 at bind_template.hpp:20
    frame #6: 0x000000010019b6ac libcaffe.so.1.0.0-rc3`boost::detail::thread_data<boost::_bi::bind_t<void, boost::_mfi::mf5<void, caffe::InternalThread, int, caffe::Caffe::Brew, int, int, bool>, boost::_bi::list6<boost::_bi::value<caffe::InternalThread*>, boost::_bi::value<int>, boost::_bi::value<caffe::Caffe::Brew>, boost::_bi::value<int>, boost::_bi::value<int>, boost::_bi::value<bool> > > >::run(this=0x0000000102015470) + 28 at thread.hpp:116
    frame #7: 0x000000010109e804 libboost_thread-mt.dylib`boost::(anonymous namespace)::thread_proxy(void*) + 164
    frame #8: 0x00007fff922e29b1 libsystem_pthread.dylib`_pthread_body + 131
    frame #9: 0x00007fff922e292e libsystem_pthread.dylib`_pthread_start + 168
    frame #10: 0x00007fff922e0385 libsystem_pthread.dylib`thread_start + 13


Forward_cpu会将的数据从prefetch_full_中copy到top中,则data layer的数据往上进行了传递

调用堆栈如下:

* thread #1: tid = 0xa2a208, 0x00000001001d8237 libcaffe.so.1.0.0-rc3`caffe::BasePrefetchingDataLayer<float>::Forward_cpu(this=0x000000010300bc00, bottom=0x000000010200b520, top=0x000000010200ab60) + 39 at base_data_layer.cpp:109, queue = 'com.apple.main-thread', stop reason = breakpoint 3.1
  * frame #0: 0x00000001001d8237 libcaffe.so.1.0.0-rc3`caffe::BasePrefetchingDataLayer<float>::Forward_cpu(this=0x000000010300bc00, bottom=0x000000010200b520, top=0x000000010200ab60) + 39 at base_data_layer.cpp:109
    frame #1: 0x000000010019ee77 libcaffe.so.1.0.0-rc3`caffe::Layer<float>::Forward(this=0x000000010300bc00, bottom=0x000000010200b520, top=0x000000010200ab60) + 199 at layer.hpp:459
    frame #2: 0x00000001002f1d9c libcaffe.so.1.0.0-rc3`caffe::Net<float>::ForwardFromTo(this=0x00000001020080d0, start=0, end=5) + 636 at net.cpp:550
    frame #3: 0x00000001002f1ac2 libcaffe.so.1.0.0-rc3`caffe::Net<float>::Forward(this=0x00000001020080d0, loss=0x00007fff5fbfdf78) + 82 at net.cpp:570
    frame #4: 0x00000001003381be libcaffe.so.1.0.0-rc3`caffe::Solver<float>::Test(this=0x0000000102002060, test_net_id=0) + 2286 at solver.cpp:363
    frame #5: 0x0000000100336bec libcaffe.so.1.0.0-rc3`caffe::Solver<float>::TestAll(this=0x0000000102002060) + 124 at solver.cpp:330
    frame #6: 0x00000001003354f2 libcaffe.so.1.0.0-rc3`caffe::Solver<float>::Step(this=0x0000000102002060, iters=10000) + 674 at solver.cpp:207
    frame #7: 0x0000000100334a31 libcaffe.so.1.0.0-rc3`caffe::Solver<float>::Solve(this=0x0000000102002060, resume_file=0x0000000000000000) + 881 at solver.cpp:293
    frame #8: 0x0000000100004df8 caffe.bin`train() + 6840 at caffe.cpp:252
    frame #9: 0x0000000100009038 caffe.bin`main(argc=2, argv=0x00007fff5fbffb08) + 600 at caffe.cpp:443
    frame #10: 0x00007fff8d0585ad libdyld.dylib`start + 1


在最简单的模型中,模型描述如下:

name: "LeNet"
layer {
  name: "mnist"
  type: "Data"
  top: "data"
  top: "label"
  include {
    phase: TRAIN
  }
  transform_param {
    scale: 0.00390625
  }
  data_param {
    source: "examples/mnist/mnist_train_lmdb"
    batch_size: 64
    backend: LMDB
  }
}
layer {
  name: "mnist"
  type: "Data"
  top: "data"
  top: "label"
  include {
    phase: TEST
  }
  transform_param {
    scale: 0.00390625
  }
  data_param {
    source: "examples/mnist/mnist_test_lmdb"
    batch_size: 100
    backend: LMDB
  }
}
layer {
  name: "ip"
  type: "InnerProduct"
  bottom: "data"
  top: "ip"
  param {
    lr_mult: 1
  }
  param {
    lr_mult: 2
  }
  inner_product_param {
    num_output: 10
    weight_filler {
      type: "xavier"
    }
    bias_filler {
      type: "constant"
    }
  }
}
layer {
  name: "accuracy"
  type: "Accuracy"
  bottom: "ip"
  bottom: "label"
  top: "accuracy"
  include {
    phase: TEST
  }
}
layer {
  name: "loss"
  type: "SoftmaxWithLoss"
  bottom: "ip"
  bottom: "label"
  top: "loss"
}

其中只有data ip和softmaxwithloss三个层次,不同层之间通过名字bottom top的方式关联到一起,bottom和top可以有多个,也就形成了网状结构。

data中,batch_size指定了一次计算的数据的大小。

在ip中,num_output标示模型输出的个数,这个地方为10,表示的是输出维度为10,这是和mnist中label的数量为10对应的。

在网络完成初始化之后,开始进行训练,训练的第一步是前向计算,会从网络的第0层开始调用forword_cpu,逐层将数据从底层向上层传递,直到计算出loss。

在上面的例子中,就是void SoftmaxWithLossLayer<Dtype>::Forward_cpu 

函数栈如下:

* thread #1: tid = 0xdba216, 0x00000001002abc43 libcaffe.so.1.0.0-rc3`caffe::SoftmaxLayer<float>::Forward_cpu(this=0x0000000102304080, bottom=0x0000000101717fd8, top=0x0000000101717ff0) + 1043 at softmax_layer.cpp:55, queue = 'com.apple.main-thread', stop reason = breakpoint 14.1
  * frame #0: 0x00000001002abc43 libcaffe.so.1.0.0-rc3`caffe::SoftmaxLayer<float>::Forward_cpu(this=0x0000000102304080, bottom=0x0000000101717fd8, top=0x0000000101717ff0) + 1043 at softmax_layer.cpp:55
    frame #1: 0x000000010019ee77 libcaffe.so.1.0.0-rc3`caffe::Layer<float>::Forward(this=0x0000000102304080, bottom=0x0000000101717fd8, top=0x0000000101717ff0) + 199 at layer.hpp:459
    frame #2: 0x00000001002ae1c5 libcaffe.so.1.0.0-rc3`caffe::SoftmaxWithLossLayer<float>::Forward_cpu(this=0x0000000101717cb0, bottom=0x00000001017009d0, top=0x0000000101615070) + 117 at softmax_loss_layer.cpp:92
    frame #3: 0x000000010019ee77 libcaffe.so.1.0.0-rc3`caffe::Layer<float>::Forward(this=0x0000000101717cb0, bottom=0x00000001017009d0, top=0x0000000101615070) + 199 at layer.hpp:459
    frame #4: 0x00000001002f1d9c libcaffe.so.1.0.0-rc3`caffe::Net<float>::ForwardFromTo(this=0x0000000101625a50, start=0, end=2) + 636 at net.cpp:550
    frame #5: 0x00000001002f1ac2 libcaffe.so.1.0.0-rc3`caffe::Net<float>::Forward(this=0x0000000101625a50, loss=0x00007fff5fbfe584) + 82 at net.cpp:570
    frame #6: 0x00000001002f3d3d libcaffe.so.1.0.0-rc3`caffe::Net<float>::ForwardBackward(this=0x0000000101625a50) + 29 at net.hpp:88
    frame #7: 0x00000001003356eb libcaffe.so.1.0.0-rc3`caffe::Solver<float>::Step(this=0x00000001017003f0, iters=10000) + 1179 at solver.cpp:222
    frame #8: 0x0000000100334a31 libcaffe.so.1.0.0-rc3`caffe::Solver<float>::Solve(this=0x00000001017003f0, resume_file=0x0000000000000000) + 881 at solver.cpp:293
    frame #9: 0x0000000100004df8 caffe.bin`train() + 6840 at caffe.cpp:252
    frame #10: 0x0000000100009038 caffe.bin`main(argc=2, argv=0x00007fff5fbffb08) + 600 at caffe.cpp:443
    frame #11: 0x00007fff8d0585ad libdyld.dylib`start + 1


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 安装caffe-ssd-gpu在ubuntu18.04的步骤如下: 1. 安装CUDA:从Nvidia官网下载合适的CUDA安装包,按照官方文档的指引进行安装。 2. 安装依赖:运行以下命令安装所需依赖库: ``` sudo apt-get install libprotobuf-dev libleveldb-dev libsnappy-dev \ libopencv-dev libhdf5-serial-dev protobuf-compiler \ libgflags-dev libgoogle-glog-dev liblmdb-dev libboost-all-dev ``` 3. 下载caffe-ssd-gpu源码并编译:从Github上下载caffe-ssd-gpu的源码,按照官方文档指引进行编译。编译时需要指定编译选项为GPU模式。 4. 运行测试:安装完成后,运行测试脚本,确保安装配置成功。 以上为简要步骤,具体操作请参考对应文档和官方指引。 ### 回答2: Ubuntu18.04是目前比较常见的Linux操作系统之一,而CAFFE-SSD-GPU是深度学习的一个工具。下面是安装caffe-ssd-gpu的步骤: 1. 安装CUDA和cuDNN 首先,您需要安装CUDA和cuDNN,这是运行深度学习框架所需的必备组件。下载安装CUDA和cuDNN之前,您需要查看您的图形卡的型号,以便选择正确的CUDA版本和cuDNN版本。 在下载和安装CUDA和cuDNN之前,您需要在NVIDIA的开发者网站上注册自己,并下载适用于您机器的CUDA和cuDNN版本。此外,您还需要在命令行界面中设置以下环境变量: export PATH=/usr/local/cuda-8.0/bin:$PATH export LD_LIBRARY_PATH=/usr/local/cuda-8.0/lib64:$LD_LIBRARY_PATH 2. 安装依赖项 在安装caffe之前,需要安装一些依赖项。您可以使用以下命令将这些依赖项安装到您的Ubuntu系统上: sudo apt-get update sudo apt-get install -y libprotobuf-dev libleveldb-dev libsnappy-dev libopencv-dev libboost-all-dev libhdf5-serial-dev protobuf-compiler gfortran libjpeg62 libfreeimage-dev libatlas-base-dev git python-dev python-pip libgoogle-glog-dev libbz2-dev libxml2-dev libxslt-dev libffi-dev libssl-dev libgflags-dev liblmdb-dev python-yaml python-numpy python-scipy 3. 下载和安装CAFFE 现在,您需要在您的系统上下载和安装CAFFE。从github上获取caffesource代码并进行安装: git clone https://github.com/weiliu89/caffe.git cd caffe git checkout ssd 4. 编译和安装CAFFE 使用以下命令编译和安装caffe: cp Makefile.config.example Makefile.config make all -j $(($(nproc) + 1)) make pycaffe 执行该命令后,您需要等待一段时间才能完成CAFFE的编译。如果出现任何编译错误,请检查您的CUDA和cuDNN版本是否正确,并重新安装依赖项。 5. 使用CAFFE-SSD-GPU 现在,您已经成功地在Ubuntu18.04操作系统上安装并编译了CAFFE-SSD-GPU,您可以开始使用该工具来执行深度学习任务了。 总结 安装CAFFE-SSD-GPU需要充分理解linux的命令行操作。需要先确认CUDA和cuDNN已经安装,并正确设置环境变量。然后需要下载和安装CAFFE, 并最后编译和安装CAFFE。在安装过程中如果存在问题,可以查看错误日志,重新检查步骤。如果对命令行操作不熟悉,则先学习linux基础操作。 ### 回答3: caffe-ssd-gpu是一种基于caffe框架的用于实现目标检测的神经网络模型,在Ubuntu18.04系统中安装caffe-ssd-gpu需要进行以下步骤: 1. 安装CUDA CUDA是NVIDIA公司推出的用于高性能计算的并行计算平台和编程模型,是使用GPU进行深度学习任务所必需的。在Ubuntu18.04上安装CUDA需要首先确认自己的显卡型号,并选择合适的CUDA版本进行安装。可以在NVIDIA官网上下载相应的CUDA安装包,也可以通过命令行方式进行安装。在安装过程中注意要按照提示完成相应的配置和设置。 2. 安装cuDNN cuDNN是用于深度神经网络的GPU加速库,也是必需的组件之一。在安装过程中同样需要确认CUDA的版本和自己的显卡型号,并下载相应的cuDNN安装包进行安装。 3. 安装依赖包 在安装caffe-ssd-gpu前需要先安装几个依赖包,包括protobuf、opencv、boost等。可以通过命令行方式进行安装,例如: ``` sudo apt-get install libprotobuf-dev libleveldb-dev libsnappy-dev libopencv-dev libboost-all-dev libhdf5-serial-dev libgflags-dev libgoogle-glog-dev liblmdb-dev ``` 4. 下载caffe-ssd-gpu源码 可以在GitHub上找到caffe-ssd-gpu的源码,下载后解压到自己想要的目录下。 5. 编译和安装caffe-ssd-gpu 进入caffe-ssd-gpu源码目录下,执行以下命令: ``` cd caffe-ssd-gpu mkdir build cd build cmake .. make all -j8 make install ``` 其中,make all -j8表示使用8个线程进行编译,提高编译速度。make install表示安装编译好的caffe-ssd-gpu库文件和可执行文件。 6. 测试安装是否成功 可以尝试运行caffe-ssd-gpu自带的测试程序,检查安装是否成功。在源码目录下执行以下命令: ``` ./build/tools/caffe time --model=models/VGGNet/VOC0712/SSD_300x300_ft/deploy.prototxt --gpu=0 ``` 这条命令会测试caffe-ssd-gpu在GPU上执行推断的速度,如果没有问题,则说明安装成功。 需要注意的是,在安装过程中可能会遇到各种问题,例如依赖包的版本不兼容、CUDA和cuDNN的配置出错等等。这时候需要耐心调试错误,逐个解决问题,才能确保caffe-ssd-gpu能够正常运行。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值