caffe中多个cpp共享一个变量 c++类中的静态变量
caffe中需要整个共享变量,就是从bias过来的tensor转图片,然后后面目标检测第一阶段查看定位效果,把目标框画在图上就需要一开始的图片。
实验1:这个可以在prototxt增加一个top通过网络给到后面的层,但是这样太麻烦。
实验2:
然后想想能不能通过类似与共享变量能完成,
首先实验的是在基类Layer添加一个变量,然后bias_layer压入图片,因为所有的层都是从Layer派生出来。
class BiasLayer : public Layer<Ftype, Btype>
这样添加的:
class Layer : public LayerBase {
public:
// std::vector<cv::Mat> v_img;
不好使,各种报错。
又实验了在blob定义变量,在bias用extern std::vectorcv::Mat v_img_0;声明。编译报错其他cpp提示重复定义,然后在blob.hpp这么写
static std::vectorcv::Mat v_img_0;
这样重复定义的错误解决可以正常编译通过,但是在其他cpp用这个变量v_img_0报错,明明已经在bias压入了但是好像在其他cpp里面访问是空的,没法解决。。
实验3:
在blob类中添加静态变量
class Blob {
public:
static std::vector<cv::Mat> v_img_0;
在bias_layer.cu里面代码如下:
主要是
Blob::v_img_0.clear();
Blob::v_img_0.push_back(image.clone());
#include <vector>
#include "caffe/filler.hpp"
#include "caffe/layers/bias_layer.hpp"
#include "caffe/util/math_functions.hpp"
#include "opencv2/opencv.hpp"
namespace caffe {
// extern std::vector<cv::Mat> v_img_0;
template <typename Dtype>
__global__ void BiasForward(const int n, const Dtype* in,
const Dtype* bias, const int bias_dim, const int inner_dim,
Dtype* out) {
CUDA_KERNEL_LOOP(index, n) {
const int bias_index = (index / inner_dim) % bias_dim;
out[index] = in[index] + bias[bias_index];
}
}
template <typename Ftype, typename Btype>
void BiasLayer<Ftype, Btype>::Forward_gpu(const vector<Blob*>& bottom,
const vector<Blob*>& top) {
const int count = top[0]->count();
const Ftype* bottom_data = bottom[0]->gpu_data<Ftype>();
const Ftype* bias_data =
((bottom.size() > 1) ? bottom[1] : this->blobs_[0].get())->template gpu_data<Ftype>();
Ftype* top_data = top[0]->mutable_gpu_data<Ftype>();
BiasForward // NOLINT_NEXT_LINE(whitespace/operators)
<<<CAFFE_GET_BLOCKS(count), CAFFE_CUDA_NUM_THREADS, 0, Caffe::thread_stream()>>>(
count, bottom_data, bias_data, bias_dim_, inner_dim_, top_data);
CUDA_CHECK(cudaStreamSynchronize(Caffe::thread_stream()));
int batchsize = bottom[0]->shape(0);
// this->v_img.clear();
Blob::v_img_0.clear();
for(int b =0;b<batchsize;b++)
{
const Ftype* top_cpu_data = top[0]->template cpu_data<Ftype>();
// Ftype* top_cpu_data = top[0]->mutable_cpu_data()<Ftype>();
int topheight= 192;
int topwidth= 768;
cv::Mat image=cv::Mat::zeros(topheight, topwidth, CV_8UC3);
for (int i=0; i<topheight; i++)
for(int j=0; j<topwidth; j++) {
const Ftype* top_cpu_data1 = top_cpu_data + b * 3 * topheight * topwidth;
int row = i;
int col = j;
uchar* ptr = image.data+(i*topwidth +j)*3;
ptr[0] = (uchar)((top_cpu_data1[(topheight*0+i)*topwidth+j])*1 + 128);
ptr[1] = (uchar)((top_cpu_data1[(topheight*1+i)*topwidth+j])*1 + 128);
ptr[2] = (uchar)((top_cpu_data1[(topheight*2+i)*topwidth+j])*1 + 128);
}
// this->v_img.push_back(image.clone());
Blob::v_img_0.push_back(image.clone());
// cvtColor(image, image, CV_BGR2RGB);
cv::imshow("imageslds", image);
cv::waitKey(0);
}
}
template <typename Ftype, typename Btype>
void BiasLayer<Ftype, Btype>::Backward_gpu(const vector<Blob*>& top,
const vector<bool>& propagate_down, const vector<Blob*>& bottom) {
if (propagate_down[0] && bottom[0] != top[0]) {
const Btype* top_diff = top[0]->gpu_diff<Btype>();
Btype* bottom_diff = bottom[0]->mutable_gpu_diff<Btype>();
caffe_copy(bottom[0]->count(), top_diff, bottom_diff);
}
// in-place, we don't need to do anything with the data diff
const bool bias_param = (bottom.size() == 1);
if ((!bias_param && propagate_down[1]) ||
(bias_param && this->param_propagate_down_[0])) {
const Btype* top_diff = top[0]->gpu_diff<Btype>();
Btype* bias_diff = (bias_param ? this->blobs_[0].get() : bottom[1])
->template mutable_gpu_diff<Btype>();
bool accum = bias_param;
for (int n = 0; n < outer_dim_; ++n) {
caffe_gpu_gemv(CblasNoTrans, bias_dim_, inner_dim_, Btype(1),
top_diff, bias_multiplier_.template gpu_data<Btype>(), Btype(accum), bias_diff);
top_diff += dim_;
accum = true;
}
}
}
INSTANTIATE_LAYER_GPU_FUNCS_FB(BiasLayer);
} // namespace caffe
这么整编译报错。
[ 2%] Linking CXX shared library ../../lib/libcaffe-nv-d.so
[100%] Built target caffe
[100%] Linking CXX executable caffe-d
../lib/libcaffe-nv-d.so.0.16.0:对‘caffe::Blob::v_img_0’未定义的引用
在blob.cpp添加初始化代码,就解决
std::vector<cv::Mat> Blob::v_img_0 = {};
在其他cpp就可以访问这变量
cv::Mat img = Blob::v_img_0[i];
解决!
c++类中的静态变量属于类,任何对象都可以访问且是共享的。
1、属于类,不属于对象,是类域中的全局变量
2、程序运行期间只有一个副本
3、不能在对象创建时初始化,即不能在类的构造函数初始化
4、被类、类对象、类的派生类对象共享
5、可以作为成员函数的可选参数,普通数据成员则不可以
6、数据成员类型可以声明为所属类的类型,普通数据成员只能声明为所属类类型的指针或引用