Esempio n. 1
0
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){
	boost::shared_ptr<LayerParameter> layer_param(
		layer_id >= 0 ? new LayerParameter(param.layer(layer_id)) : NULL);
	//	use (layer_id//top_id) or (-1//top_id) to get a blob name
	const string& blob_name = layer_param ?
		(top_id<layer_param->top_size() ? layer_param->top(top_id) : "(automatic)") : param.input(top_id);
	//	in-place case (e.g:
	//	I0721 10:38 : 16.722070  4692 net.cpp : 84] relu1 <-conv1
	//	I0721 10:38 : 16.722082  4692 net.cpp : 98] relu1->conv1(in-place)
	//	check a blob whether at the same postion in both bottom and top
	if (blob_name_to_idx && layer_param && top_id < layer_param->bottom_size()
		&& blob_name == layer_param->bottom(top_id)){
		LOG_IF(INFO, Dragon::get_root_solver())
			<< layer_param->name() << "[Layer-Produce]->" << blob_name << " [Blob-Name] (in-place)";
		//	add into this layer's top blob using blob_name
		top_vecs[layer_id].push_back(blobs[(*blob_name_to_idx)[blob_name]].get());
		//	log the id
		top_id_vecs[layer_id].push_back((*blob_name_to_idx)[blob_name]);
	}
	else if (blob_name_to_idx && (*blob_name_to_idx).count(blob_name) ){
		LOG(FATAL) << "Top blob:" << blob_name << " propogate from multiple sources.";
	}
	// normal top blob stuffing
	else{
		//	debug info
		if (Dragon::get_root_solver()){
			if (layer_param) LOG(INFO) << layer_param->name() << "[Layer-Produce] ->" << blob_name << " [Blob-Name]";
			//	special case and only used when viewing a Net's structure
			//	because they need not specify data source and can not train or test
			//	virtual data input blobs do not belong to any layers
			//	see more in insert_splits.cpp/void InsertSplits()
			else LOG(INFO) << "Input " << top_id << "[Blob-Code] -> " << blob_name << "[Blob - Name]";
		}
		//	allocate a null blob at first
		boost::shared_ptr<Blob<Dtype>> ptr_blob(new Blob<Dtype>());
		//	store global blob infos
		const int blob_id = blobs.size();
		blobs.push_back(ptr_blob);
		blobs_name.push_back(blob_name);
		blobs_need_backward.push_back(false);
		//	encode index number for a name
		//	which also represent this top blob is binded from a bottom
		//	check it before can know whether a top blob has multiple sources(Forbidden)
		if (blob_name_to_idx) (*blob_name_to_idx)[blob_name] = blob_id;
		//	reshape for virtual input blobs solely
		//	becaude they do not exist into a DataLayer(provide reshape/transfrom service)
		if (layer_id == -1){
			ptr_blob->reshape(param.input_shape(top_id));
			//	store solely for virtual input blobs
			net_input_blobs.push_back(ptr_blob.get());
			net_input_blob_indices.push_back(blob_id);
		}
		else{
			top_vecs[layer_id].push_back(ptr_blob.get());
			top_id_vecs[layer_id].push_back(blob_id);
		}
	}
	//	a set used for listing all exsiting top blobs
	if (available_blobs) available_blobs->insert(blob_name);
}