介紹一種更加靈活的方法,用MemoryData層輸入數據,能夠直接用opencv接口讀入咱們的圖片再添加的網絡中。
第一個問題:仍然是工程創建問題,提示卷積層或其餘層沒有註冊,解決方法與上一篇博客同樣。可查看:http://blog.csdn.net/sunshine_in_moon/article/details/50125255
第二個問題:網絡配置文件的改寫,由於使用MemoryData層。數組
layers{
name: "data"
type: MEMORY_DATA //MemoryData層類型,還有須要注意,MEMORY_DATA別多此一舉加上引號,不然會報錯!
top: "data"
top: "label" //最好寫上,雖而後面沒有用到
transform_param{
mirror: false
crop_size:224
mean_value:129.1863//三個通道的均值
mean_value:104.7624
mean_value:93.5940
}
memory_data_param{//如下四個參數與ImageData稍有不一樣,請注意
batch_size:1
channels:3
height:224
width:224
}
}
第三個問題:代碼,這段代碼寫的有點亂,請見諒!網絡
template <typename Dtype>
caffe::Net<Dtype>* Net_Init_Load(
std::string param_file, std::string pretrained_param_file, caffe::Phase phase)
{
CheckFile(param_file);//CheckFile 是一個子函數我沒有貼上,能夠直接刪掉這兩行
CheckFile(pretrained_param_file);
caffe::Net<Dtype>* net(new caffe::Net<Dtype>(param_file, phase));
net->CopyTrainedLayersFrom(pretrained_param_file);
return net;
}
#define NetF float //宏定義 不少人包括我本身剛開始看到NetF也很困惑,原來就是float
int main()
{
/* boost::shared_ptr< Net<float> > feature_net; feature_net = Init_net(); cv::Mat src1; src1 = cv::imread("test.jpg"); //cv::imshow("img", src1); //cv::waitKey(0); //cv::destroyAllWindows(); //cv::Mat rszimage; //// The mean file image size is 256x256, need to resize the input image to 256x256 //cv::resize(src1, rszimage, cv::Size(244, 244)); std::vector<cv::Mat> patches; patches.push_back(src1); // image is a cv::Mat, as I'm using #1416 std::vector<int> labels; labels.push_back(0); boost::shared_ptr< MemoryDataLayer<float> >memory_data_layer; memory_data_layer = boost::static_pointer_cast<MemoryDataLayer<float>>(feature_net->layer_by_name("data")); /* caffe::Datum data; caffe::ReadFileToDatum("test.jpg", &data); caffe::MemoryDataLayer<float> *m_layer_ = (caffe::MemoryDataLayer<float> *)feature_net->layers()[0].get(); */
/* memory_data_layer->AddMatVector(patches,labels); feature_net->ForwardPrefilled(); float data1; data1 = Read_Feature_data(feature_net, "fc8"); cout << data1 << endl; */
/*從這裏開始*/
cv::Mat src1;
src1 = cv::imread("test.jpg");
//cv::Mat rszimages;
//cv::resize(src1, rszimages, cv::Size(224, 224));
std::vector<cv::Mat> dv = { src1 };//****輸入的圖片,注意格式,即便只有一張圖片也要使用向量格式
std::vector<int> label = { 0 };//**輸入圖片的標籤(可隨便寫),也要注意是向量,這是由AddMatVector函數決定的
//caffe::Datum data;
//caffe::ReadFileToDatum("test.jpg", &data);
caffe::Net<NetF>* _net = Net_Init_Load<NetF>("FACE_deploy.prototxt",
"FACE.caffemodel", caffe::TEST);
caffe::MemoryDataLayer<NetF> *m_layer_ = (caffe::MemoryDataLayer<NetF> *)_net->layers()[0].get();//**定義個內存數據層指針
m_layer_->AddMatVector(dv, label);//***這兩行很重要,是使用MemoryData層必須的,這是把圖片和標籤,添加到
//**MemoryData層
/*float loss = 0.0; std::vector<caffe::Blob<float>*> results = _net->ForwardPrefilled(&loss);*/
int end_ind = _net->layers().size();
std::vector<caffe::Blob<NetF>*> input_vec;
clock_t start = clock();
_net->Forward(input_vec);
clock_t end = clock();
double totaltime;
totaltime = (double)(end - start) / CLOCKS_PER_SEC;
cout << "\n此程序的運行時間爲" << totaltime << "秒!" << endl;
boost::shared_ptr<caffe::Blob<NetF>> fc8 = _net->blob_by_name("fc8");
const NetF* pstart = fc8->cpu_data();// ***這裏是重點!重點!重點!,在這裏耽誤了很長時間。注意這裏是個指針
//**也就是fc8->cpu_data()返回的通常是多維數據(能夠當作是個數組),cout<<* pstart<<endl;這樣只是打印出一個
//***數?固然是一個數了,*pstart只表明數組的第一個數,所以想得到全部的數據必須用循環!
std::cout << "It is right !!\n";
//std::cout << m_layer_->width() << std::endl;
//std::cout << pstart << endl;
//std::cout << fc8->cpu_data() << endl;
std::vector<double> V1;
for (int i = 0; i < 2622; i++)//**必須用循環打印
{
std::cout << *pstart << endl;
V1.push_back(*pstart);
pstart++;
}
//std::cout << *pstart << endl;
//std::cout << *(pstart++) << endl;
cout << "\n此程序的運行時間爲" << totaltime << "秒!" << endl;
return 0;
}
重點內容已經在註釋上標明(前面加了**),但願這些對你有幫助!
寫的比較匆忙,之後若有新的體會,會及時更新!函數