源码
template < typename Dtype>
void Net< Dtype> :: AppendTop ( const NetParameter& param, const int layer_id,
const int top_id, set< string> * available_blobs,
map< string, int > * blob_name_to_idx) {
shared_ptr< LayerParameter> layer_param (
new LayerParameter ( param. layer ( layer_id) ) ) ;
const string& blob_name = ( layer_param- > top_size ( ) > top_id) ?
layer_param- > top ( top_id) : "(automatic)" ;
if ( blob_name_to_idx && layer_param- > bottom_size ( ) > top_id &&
blob_name == layer_param- > bottom ( top_id) ) {
LOG_IF ( INFO, Caffe:: root_solver ( ) )
<< layer_param- > name ( ) << " -> " << blob_name << " (in-place)" ;
top_vecs_[ layer_id] . push_back ( blobs_[ ( * blob_name_to_idx) [ blob_name] ] . get ( ) ) ;
top_id_vecs_[ layer_id] . push_back ( ( * blob_name_to_idx) [ blob_name] ) ;
} else if ( blob_name_to_idx &&
blob_name_to_idx- > find ( blob_name) != blob_name_to_idx- > end ( ) ) {
LOG ( FATAL) << "Top blob '" << blob_name
<< "' produced by multiple sources." ;
} else {
if ( Caffe:: root_solver ( ) ) {
LOG ( INFO) << layer_param- > name ( ) << " -> " << blob_name;
}
shared_ptr< Blob< Dtype> > blob_pointer ( new Blob< Dtype> ( ) ) ;
const int blob_id = blobs_. size ( ) ;
blobs_. push_back ( blob_pointer) ;
blob_names_. push_back ( blob_name) ;
blob_need_backward_. push_back ( false ) ;
if ( blob_name_to_idx) { ( * blob_name_to_idx) [ blob_name] = blob_id; }
top_id_vecs_[ layer_id] . push_back ( blob_id) ;
top_vecs_[ layer_id] . push_back ( blob_pointer. get ( ) ) ;
}
if ( available_blobs) { available_blobs- > insert ( blob_name) ; }
}
template < typename Dtype>
int Net< Dtype> :: AppendBottom ( const NetParameter& param, const int layer_id,
const int bottom_id, set< string> * available_blobs,
map< string, int > * blob_name_to_idx) {
const LayerParameter& layer_param = param. layer ( layer_id) ;
const string& blob_name = layer_param. bottom ( bottom_id) ;
if ( available_blobs- > find ( blob_name) == available_blobs- > end ( ) ) {
LOG ( FATAL) << "Unknown bottom blob '" << blob_name << "' (layer '"
<< layer_param. name ( ) << "', bottom index " << bottom_id << ")" ;
}
const int blob_id = ( * blob_name_to_idx) [ blob_name] ;
LOG_IF ( INFO, Caffe:: root_solver ( ) )
<< layer_names_[ layer_id] << " <- " << blob_name;
bottom_vecs_[ layer_id] . push_back ( blobs_[ blob_id] . get ( ) ) ;
bottom_id_vecs_[ layer_id] . push_back ( blob_id) ;
available_blobs- > erase ( blob_name) ;
bool need_backward = blob_need_backward_[ blob_id] ;
if ( layer_param. propagate_down_size ( ) > 0 ) {
need_backward = layer_param. propagate_down ( bottom_id) ;
}
bottom_need_backward_[ layer_id] . push_back ( need_backward) ;
return blob_id;
}
功能分析
假定网络结构如下:
name:datan
type:Data
top:data
top:label
name:ipn
type:InnerProduct
top:ip
bottom:data
name:relun
type:ReLU
top:ip
bottom:ip
name:lossn
type:SoftmaxWithLoss
top:loss
bottom:ip
bottom:label
过程分析
datan层
blobs_ blob_names blob_need_backward blob_pointer0 data false blob_pointer1 label false
top_id_vecs_[0] top_vecs_[0] bottom_vecs_[0] bottom_id_vecs_[0] bottom_need_backward_[1] 0 blob_pointer0 1 blob_pointer1
ipn层
blos_id blobs_ blob_names blob_need_backward 0 blob_pointer0 data false 1 blob_pointer1 label false 2 blob_pointer2 ip false
top_id_vecs_[1] top_vecs_[1] bottom_vecs_[1] bottom_id_vecs_[1] bottom_need_backward_[1] 2 blob_pointer2 0 blob_pointer0 propagate_down
relu层
blos_id blobs_ blob_names blob_need_backward 0 blob_pointer0 data false 1 blob_pointer1 label false 2 blob_pointer2 ip false
top_id_vecs_[2] top_vecs_[2] bottom_vecs_[2] bottom_id_vecs_[2] bottom_need_backward_[2] 2 blob_pointer2 2 blob_pointer2 propagate_down
loss层
blos_id blobs_ blob_names blob_need_backward 0 blob_pointer0 data false 1 blob_pointer1 label false 2 blob_pointer2 ip false 3 blob_pointer3 loss false
top_id_vecs_[2] top_vecs_[2] bottom_vecs_[2] bottom_id_vecs_[2] bottom_need_backward_[2] 3 blob_pointer3 2 blob_pointer2 propagate_down 1 blob_pointer1 propagate_down
功能总结
__blob<0>连接
__blob<2>连接
__blob<2>连接
__blob<1>连接
name:datan
type:Data
top:data
top:label
name:ipn
type:InnerProduct
top:ip
bottom:data
name:relun
type:ReLU
top:ip
bottom:ip
name:lossn
type:SoftmaxWithLoss
top:loss
bottom:ip
bottom:label
blob<3>