Windows10 下安装caffe
本文主要包含如下内容:
参考博客,可以参考博客和本篇博客进行Windows10下配置安装caffe。
Caffe安装及编译教程
本篇博客将会教会你在Windows下配置Caffe,请细心仔细阅读。说白了,Windows下配置这些东西就是一个坑。
在安装之前,需要安装相应的cuda和cuDNN。其中,cuda版本为cuda_8.0.61_win10
,双击安装即可;cuDNN版本为cudnn-7.5-windows10-x64-v5.0-ga
,下载并将其解压至D:\
CUDA下载地址 cuDNN下载地址
同样的,需要从github上下载相应的windows-caffe,并将其解压至D:\
。
windows-caffe下载地址
随后,开始配置caffe:
进入D:\caffe-master\windows
,复制文件CommonSettings.props.example
并将其改名为CommonSettings.props
,双击进入工程caffe(这里注意:需要安装了VS,才可以打开并编译)。有时候libcaffe没有加载成功(主要原因在于看看propos里面的cuda版本是7.5,而你装的是8.0,ctrl+F搜索7.5,找到到改为8.0.并重启caffe.sln即可)
- 注意:如果libcaffe和testall存在问题,请参考如下解决办法:
由于vs2013的安装路径中缺少 CUDA 8.0.props ,文件引用CUDA 8.0的路径是 C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V120\BuildCustomizations ,其实 CUDA 8.0.props 安装路径是 C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v9.0\extras\visual_studio_integration\MSBuildExtensions ,只要拷贝到 C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V120\BuildCustomizations 就行了,那么libcaffe和testall就都没问题了!
在打开caffe工程后,打开右侧文件列表中的文件CommenSetting.probs
,在文件中搜索cudapath
,该栏存放从cudnn
解压出来的文件夹cuda
的目录路径。由于我们从cudnn
解压出来的文件夹cuda
的目录路径是D:\
,因此,输入D:\
即可。
如果需要配置pycaffe,即caffe的python接口,则请进行一下操作:打开右侧文件列表中的文件CommenSetting.probs
,编译支持python接口<PythonSupport>ture</PythonSupport>
,同时修改python的路径,指定到Anaconda中。
随后,我们参考博客,将roi_pooling_layer.hpp,cu,cpp加入到libcaffe文件配置中。
参考博客
接下来,选择编译类型为release,x64
,关闭 Treat Warnings As Errors (即设置为No) ,如果不设置的话在编译boost库的时候会由于文字编码的警告而报错。下面两张图帮你进行设置。
然后开始漫长的编译过程,编译结束后会在D:\
下生成文件夹NugetPackages
,我们也可以在拷贝别人的文件NugetPackages
到指定目录D:\
后进行编译。
在编译好libcaffe
后,需要继续编译其他任务:下面两张图帮你进行设置并进行相关编译。
至此,caffe工程已经编译完成,可以正常训练测试网络。
编译错误:
error MSB4062:未能从程序集D:\NugetPackages\OpenCV.2.4.10\build\native\private\
coapp.NuGetNativeMSBuildTasks.dll加载任务“NuGetPackageOverlay”
该问题解决办法,只需要升级opencv即可,参考博客解决问题
Windows使用Caffe的工程
在特定的工程中,我们需要运用caffe软件包,即集成caffe代码生成对应的可执行文件。如果你需要这样做,请参考下面流程。
首先,用VS新建一个工程,将编译模式改为Release ×64模式,随后进入DEBUG->Properties:
根据上图,我们设置相关参数,从而可以导入caffe相关库文件,对应的参数设置为:
D:\cuda\include;
C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v7.5\include;
D:\NugetPackages\protobuf-v120.2.6.1\build\native\include;
D:\NugetPackages\OpenCV.2.4.10\build\native\include;
D:\NugetPackages\OpenBLAS.0.2.14.1\lib\native\include;
D:\NugetPackages\lmdb-v120-clean.0.9.14.0\lib\native\include;
D:\NugetPackages\LevelDB-vc120.1.2.0.0\build\native\include;
D:\NugetPackages\hdf5-v120-complete.1.8.15.2\lib\native\include;
D:\NugetPackages\glog.0.3.3.0\build\native\include;
D:\NugetPackages\gflags.2.1.2.1\build\native\include;
D:\NugetPackages\boost.1.59.0.0\lib\native\include;
D:\caffe-master\include;$(IncludePath)
D:\cuda\lib\x64;C:\Program Files\NVIDIA GPU ComputingToolkit\CUDA\v7.5\lib\x64;
D:\NugetPackages\protobuf-v120.2.6.1\build\native\lib\x64\v120\Release;
D:\NugetPackages\OpenCV.2.4.10\build\native\lib\x64\v120\Release;
D:\NugetPackages\OpenBLAS.0.2.14.1\lib\native\lib\x64;
D:\NugetPackages\lmdb-v120-clean.0.9.14.0\lib\native\lib\x64;
D:\NugetPackages\LevelDB-vc120.1.2.0.0\build\native\lib\x64\v120\Release;
D:\NugetPackages\hdf5-v120-complete.1.8.15.2\lib\native\lib\x64;
D:\NugetPackages\glog.0.3.3.0\build\native\lib\x64\v120\Release\dynamic;
D:\NugetPackages\gflags.2.1.2.1\build\native\x64\v120\dynamic\Lib;
D:\NugetPackages\boost_thread-vc120.1.59.0.0\lib\native\address-model-64\lib;
D:\NugetPackages\boost_system-vc120.1.59.0.0\lib\native\address-model-64\lib;
D:\NugetPackages\boost_filesystem-vc120.1.59.0.0\lib\native\address-model-64\lib;
D:\NugetPackages\boost_date_time-vc120.1.59.0.0\lib\native\address-model-64\lib;
D:\NugetPackages\boost_chrono-vc120.1.59.0.0\lib\native\address-model-64\lib;
D:\caffe-master\Build\x64\Release;$(LibraryPath)
根据上图,我们设置相关参数,从而可以导入caffe相关库文件,对应的参数设置为:
opencv_core2410.lib;opencv_highgui2410.lib;opencv_imgproc2410.lib;
opencv_contrib2410.lib;caffe.lib;libcaffe.lib;gflags.lib;libglog.lib;
libopenblas.dll.a;libprotobuf.lib;leveldb.lib;lmdb.lib;hdf5.lib;hdf5_hl.lib;
libboost_date_time-vc120-mt-1_59.lib;libboost_filesystem-vc120-mt-1_59.lib;
cublas.lib;curand.lib;cudart.lib;%(AdditionalDependencies)
如果你想要单独运行可执行文件跑caffe代码,还需要配置环境包;即在工程目录下.\x64\Release\中的添加相应环境包,所需的环境包截图如下,可以在上一步编译好的caffe工程中找到。
接下来,我们还需要编译head.h文件,引用这个文件可以帮助你正常调用caffe源码。
#include <caffe/common.hpp>
#include <caffe/layer.hpp>
#include <caffe/layer_factory.hpp>
#include <caffe/layers/input_layer.hpp>
#include <caffe/layers/inner_product_layer.hpp>
#include <caffe/layers/dropout_layer.hpp>
#include <caffe/layers/conv_layer.hpp>
#include <caffe/layers/relu_layer.hpp>
#include <caffe/layers/pooling_layer.hpp>
#include <caffe/layers/lrn_layer.hpp>
#include <caffe/layers/softmax_layer.hpp>
#include<caffe/layers/batch_norm_layer.hpp>
#include<caffe/layers/scale_layer.hpp>
#include<caffe/layers/bias_layer.hpp>
#include<caffe/layers/concat_layer.hpp>
#include<caffe/layers/accuracy_layer.hpp>
#include<caffe/layers/sigmoid_layer.hpp>
namespace caffe
{
extern INSTANTIATE_CLASS(InputLayer);
extern INSTANTIATE_CLASS(InnerProductLayer);
extern INSTANTIATE_CLASS(DropoutLayer);
extern INSTANTIATE_CLASS(ConvolutionLayer);
REGISTER_LAYER_CLASS(Convolution);
extern INSTANTIATE_CLASS(ReLULayer);
REGISTER_LAYER_CLASS(ReLU);
extern INSTANTIATE_CLASS(PoolingLayer);
REGISTER_LAYER_CLASS(Pooling);
extern INSTANTIATE_CLASS(LRNLayer);
REGISTER_LAYER_CLASS(LRN);
extern INSTANTIATE_CLASS(SoftmaxLayer);
REGISTER_LAYER_CLASS(Softmax);
//REGISTER_LAYER_CLASS(Data);
extern INSTANTIATE_CLASS(BatchNormLayer);
REGISTER_LAYER_CLASS(BatchNorm);
extern INSTANTIATE_CLASS(ScaleLayer);
REGISTER_LAYER_CLASS(Scale);
extern INSTANTIATE_CLASS(BiasLayer);
REGISTER_LAYER_CLASS(Bias);
extern INSTANTIATE_CLASS(ConcatLayer);
REGISTER_LAYER_CLASS(Concat);
extern INSTANTIATE_CLASS(AccuracyLayer);
REGISTER_LAYER_CLASS(Accuracy);
extern INSTANTIATE_CLASS(SigmoidLayer);
REGISTER_LAYER_CLASS(Sigmoid);
}
下面代码使我们运用caffe写的测试代码,最后生成了可执行文件,双击即可运行输出对应的分类结果。你可以参考我们的代码,修改为自己所用:
#include <caffe/caffe.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/contrib/contrib.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include "boost/algorithm/string.hpp"
#include <boost/math/special_functions/next.hpp>
#include <boost/random.hpp>
#include <boost/progress.hpp>
#include <algorithm>
#include <iosfwd>
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include "head.h"
using namespace caffe;
using namespace cv;
using namespace std;
using namespace boost;
int main(int argc, char** argv){
// 定义输出文件,模型配置文件,模型文件,均值文件以及测试图像
std::ofstream out_one("./质量评估结果/质量评估结果.txt");
string model_file = "./net/deploy_val.prototxt";
string trained_file = "./caffemodel/_iter_100000.caffemodel";
string mean_file = "./mean_file/imagenet_mean.binaryproto";
string dir_path = "./质量评估图片/";
// 定义变量
boost::shared_ptr<Net<float> > net_; // 保存模型
cv::Size input_geometry_; // 模型输入图像的尺寸
int num_channels_; // 图像的通道数
cv::Mat mean_; // 根据均值文件计算得到的均值文件
Caffe::set_mode(Caffe::CPU); // 使用GPU
net_.reset(new Net<float>(model_file, caffe::TEST)); // 加载配置文件
net_->CopyTrainedLayersFromBinaryProto(trained_file); // 加载训练好的模型修改模型参数
Blob<float>* input_layer = net_->input_blobs()[0]; // 定义输入层变量
num_channels_ = input_layer->channels(); // 得到输入层的通道数
input_geometry_ = cv::Size(input_layer->width(), input_layer->height()); // 得到输入层图像的大小
// 处理均值文件,得到均值图像
BlobProto blob_proto;
ReadProtoFromBinaryFileOrDie(mean_file.c_str(), &blob_proto);
/* Convert from BlobProto to Blob<float> */
Blob<float> mean_blob;
mean_blob.FromProto(blob_proto);
/* The format of the mean file is planar 32-bit float BGR or grayscale. */
std::vector<cv::Mat> channels;
float* data = mean_blob.mutable_cpu_data();
for (int i = 0; i < num_channels_; ++i) {
/* Extract an individual channel. */
cv::Mat channel(mean_blob.height(), mean_blob.width(), CV_32FC1, data);
channels.push_back(channel);
data += mean_blob.height() * mean_blob.width();
}
/* Merge the separate channels into a single image. */
cv::Mat mean;
cv::merge(channels, mean);
/* Compute the global mean pixel value and create a mean image
* filled with this value. */
cv::Scalar channel_mean = cv::mean(mean);
mean_ = cv::Mat(input_geometry_, mean.type(), channel_mean); //得到均值图像
cv::Mat img, sample, sample_resized, sample_float, sample_normalized;
Blob<float>* output_layer;
const float* prob;
int num = 0;
std::vector<string> filename_sub_;
std::vector<std::vector<int> > first_res_;
std::vector<std::vector<int> > second_res_;
std::vector<int> res_;
cv::Directory dir;
vector<string> fileNames = dir.GetListFiles(dir_path, "*", false);
for (int i = 0; i < fileNames.size(); i++)
{
string img_file = dir_path + fileNames[i];
//string img_file = fileNames[i];
string img_file_names = fileNames[i];
//std::cout << fileNames[i] << std::endl << img_file << std::endl;
std::cout << "Prediction for " << fileNames[i] << " ----------" << std::endl;
out_one << "Prediction for " << fileNames[i] << ": ";
// reshape模型的输入尺寸
input_layer->Reshape(1, num_channels_,
input_geometry_.height, input_geometry_.width);
net_->Reshape(); // 调整模型的大小
std::vector<cv::Mat> input_channels;
int width = input_layer->width();
int height = input_layer->height();
float* input_data = input_layer->mutable_cpu_data();
for (int i = 0; i < input_layer->channels(); ++i) {
cv::Mat channel(height, width, CV_32FC1, input_data);
input_channels.push_back(channel);
input_data += width * height;
}
// 改变图像的通道数,resize图像的大小
//img_file = "D:/Project_Nanrui/C++/folder_test/picture/1.jpg";
img = imread(img_file);
//cv::imshow("img", img);
if (img.channels() == 3 && num_channels_ == 1)
cv::cvtColor(img, sample, cv::COLOR_BGR2GRAY);
else if (img.channels() == 4 && num_channels_ == 1)
cv::cvtColor(img, sample, cv::COLOR_BGRA2GRAY);
else if (img.channels() == 4 && num_channels_ == 3)
cv::cvtColor(img, sample, cv::COLOR_BGRA2BGR);
else if (img.channels() == 1 && num_channels_ == 3)
cv::cvtColor(img, sample, cv::COLOR_GRAY2BGR);
else
sample = img;
// change img size
if (sample.size() != input_geometry_)
cv::resize(sample, sample_resized, input_geometry_);
else
sample_resized = sample;
// change ing to float
if (num_channels_ == 3)
sample_resized.convertTo(sample_float, CV_32FC3);
else
sample_resized.convertTo(sample_float, CV_32FC1);
// img normalize
cv::subtract(sample_float, mean_, sample_normalized);
// 将图像通过input_channels变量传递给模型
cv::split(sample_normalized, input_channels);
net_->Forward(); // 调整模型进行预测
output_layer = net_->output_blobs()[0];
prob = output_layer->cpu_data();
std::cout << "图像质量评估结果: ";
std::cout << prob[0] << " ";
out_one << "\t图像质量评估结果为: ";
out_one << prob[0] << "\n";
std::cout << std::endl;
}
out_one.close();
return 1;
}