caffe中的矩阵操作函数

转载自:https://blog.csdn.net/seven_first/article/details/47378697#15-caffecpuasum-函数

目录

主要函数

math_function 定义了caffe 中用到的一些矩阵操作和数值计算的一些函数,这里以float类型为例做简单的分析

1. caffe_cpu_gemm 函数:

template<>
void caffe_cpu_gemm<float>(const CBLAS_TRANSPOSE TransA,
    const CBLAS_TRANSPOSE TransB, const int M, const int N, const int K,
    const float alpha, const float* A, const float* B, const float beta,
    float* C) {
  int lda = (TransA == CblasNoTrans) ? K : M;
  int ldb = (TransB == CblasNoTrans) ? N : K;
  cblas_sgemm(CblasRowMajor, TransA, TransB, M, N, K, alpha, A, lda, B,
      ldb, beta, C, N);
}
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

功能: C=alpha*A*B+beta*C
A,B,C 是输入矩阵(一维数组格式)
CblasRowMajor :数据是行主序的(二维数据也是用一维数组储存的)
TransA, TransB:是否要对A和B做转置操作(CblasTrans CblasNoTrans)
M: A、C 的行数
N: B、C 的列数
K: A 的列数, B 的行数
lda : A的列数(不做转置)行数(做转置)
ldb: B的列数(不做转置)行数(做转置)

2. caffe_cpu_gemv 函数:

template <>
void caffe_cpu_gemv<float>(const CBLAS_TRANSPOSE TransA, const int M,
    const int N, const float alpha, const float* A, const float* x,
    const float beta, float* y) {
  cblas_sgemv(CblasRowMajor, TransA, M, N, alpha, A, N, x, 1, beta, y, 1);
}
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

功能: y=alpha*A*x+beta*y
其中X和Y是向量,A 是矩阵
M:A 的行数
N:A 的列数
cblas_sgemv 中的 参数1 表示对X和Y的每个元素都进行操作

3.caffe_axpy 函数:

template <>
void caffe_axpy<float>(const int N, const float alpha, const float* X,
    float* Y) { cblas_saxpy(N, alpha, X, 1, Y, 1); }
  
  
  • 1
  • 2
  • 3

功能: Y=alpha*X+Y
N:为X和Y中element的个数

4.caffe_set 函数:

template <typename Dtype>
void caffe_set(const int N, const Dtype alpha, Dtype* Y) {
  if (alpha == 0) {
    memset(Y, 0, sizeof(Dtype) * N);  // NOLINT(caffe/alt_fn)
    return;
  }
  for (int i = 0; i < N; ++i) {
    Y[i] = alpha; 
  }
}
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

功能:用常数 alpha 对 Y 进行初始化
函数 void *memset(void *buffer, char c, unsigned count) 一般为新申请的内存做初始化,功能是将buffer所指向内存中的每个字节的内容全部设置为c指定的ASCII值, count为块的大小

5.caffe_add_scalar 函数:

template <>
void caffe_add_scalar(const int N, const float alpha, float* Y) {
  for (int i = 0; i < N; ++i) {
    Y[i] += alpha;
  }
}
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

功能: 给 Y 的每个 element 加上常数 alpha

6.caffe_copy 函数:

template <typename Dtype>
void caffe_copy(const int N, const Dtype* X, Dtype* Y) {
  if (X != Y) {
    if (Caffe::mode() == Caffe::GPU) {
#ifndef CPU_ONLY
      // NOLINT_NEXT_LINE(caffe/alt_fn)
      CUDA_CHECK(cudaMemcpy(Y, X, sizeof(Dtype) * N, cudaMemcpyDefault));
#else
      NO_GPU;
#endif
    } else {
      memcpy(Y, X, sizeof(Dtype) * N);  // NOLINT(caffe/alt_fn)
    }
  }
}
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

函数 void *memcpy(void *dest, void *src, unsigned int count) 把src所指向的内存区域 copy到dest所指向的内存区域, count为块的大小

7.caffe_scal 函数:

template <>
void caffe_scal<float>(const int N, const float alpha, float *X) {
  cblas_sscal(N, alpha, X, 1);
}

  
  
  • 1
  • 2
  • 3
  • 4
  • 5

功能:X = alpha*X
N: X中element的个数

8.caffeine_cup_axpby 函数:

template <>
void caffe_cpu_axpby<float>(const int N, const float alpha, const float* X,
                            const float beta, float* Y) {
  cblas_saxpby(N, alpha, X, 1, beta, Y, 1);
}
  
  
  • 1
  • 2
  • 3
  • 4
  • 5

功能:Y= alpha*X+beta*Y

9.caffe_add、 caffe_sub、 caffe_mul、 caffe_div 函数:

template <>
void caffe_add<float>(const int n, const float* a, const float* b,
    float* y) {
  vsAdd(n, a, b, y);
}
template <>
void caffe_sub<float>(const int n, const float* a, const float* b,
    float* y) {
  vsSub(n, a, b, y);
}

template <>
void caffe_mul<float>(const int n, const float* a, const float* b,
    float* y) {
  vsMul(n, a, b, y);
}

template <>
void caffe_div<float>(const int n, const float* a, const float* b,
    float* y) {
  vsDiv(n, a, b, y);
}


  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

功能:这四个函数分别实现element-wise的加减乘除(y[i] = a[i] + - * \ b[i])

10.caffe_powx、 caffe_sqr、 caffe_exp、 caffe_abs 函数:

template <>
void caffe_powx<float>(const int n, const float* a, const float b,
    float* y) {
  vsPowx(n, a, b, y);
}

template <>
void caffe_sqr<float>(const int n, const float* a, float* y) {
  vsSqr(n, a, y);
}


template <>
void caffe_exp<float>(const int n, const float* a, float* y) {
  vsExp(n, a, y);
}

template <>
void caffe_abs<float>(const int n, const float* a, float* y) {
    vsAbs(n, a, y);
}

  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

功能 : 同样是element-wise操作,分别是y[i] = a[i] ^ b, y[i] = a[i]^2,y[i] = exp(a[i] ),y[i] = |a[i] |

11.int caffe_rng_rand 函数:

unsigned int caffe_rng_rand() {
  return (*caffe_rng())();
}
  
  
  • 1
  • 2
  • 3

功能:返回一个随机数

12.caffe_nextafer 函数:

template <typename Dtype>
Dtype caffe_nextafter(const Dtype b) {
  return boost::math::nextafter<Dtype>(
      b, std::numeric_limits<Dtype>::max());
}
  
  
  • 1
  • 2
  • 3
  • 4
  • 5

功能 : 返回 b 最大方向上可以表示的最接近的数值。

13.caffe_cpu_strided_dot 函数:

template <>
double caffe_cpu_strided_dot<double>(const int n, const double* x,
    const int incx, const double* y, const int incy) {
  return cblas_ddot(n, x, incx, y, incy);
}
  
  
  • 1
  • 2
  • 3
  • 4
  • 5

功能: 返回 vector X 和 vector Y 的内积。
incx, incy : 步长,即每隔incx 或 incy 个element 进行操作。

14.caffe_cpu_hamming_distance 函数:

template <>
int caffe_cpu_hamming_distance<float>(const int n, const float* x,
                                  const float* y) {
  int dist = 0;
  for (int i = 0; i < n; ++i) {
    dist += __builtin_popcount(static_cast<uint32_t>(x[i]) ^
                               static_cast<uint32_t>(y[i]));
  }
  return dist;
}

  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

功能:返回 x 和 y 之间的海明距离。(两个等长字符串之间的海明距离是两个字符串对应位置的不同字符的个数。)

15. caffe_cpu_asum 函数:

template <>
float caffe_cpu_asum<float>(const int n, const float* x) {
  return cblas_sasum(n, x, 1);
}

  
  
  • 1
  • 2
  • 3
  • 4
  • 5

功能:计算 vector x 的所有element的绝对值之和。

16.caffe_cpu_scale 函数:

template <>
void caffe_cpu_scale<float>(const int n, const float alpha, const float *x,
                            float* y) {
  cblas_scopy(n, x, 1, y, 1);
  cblas_sscal(n, alpha, y, 1);
}
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

功能:y = alpha*x

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在使用Python层Caffe实现Bhattacharyya损失函数前,需要先了解Bhattacharyya距离和Bhattacharyya系数,它们是计算Bhattacharyya损失函数的基础。 Bhattacharyya距离是一种用于度量两个概率分布相似性的方法,其定义为: ![](https://cdn.jsdelivr.net/gh/1076827098/CDN/blog/nlp-chatbot/bhattacharyya_distance.png) 其,P(x)和Q(x)分别为两个概率分布函数,x为概率变量。 Bhattacharyya系数是Bhattacharyya距离的指数形式,其定义为: ![](https://cdn.jsdelivr.net/gh/1076827098/CDN/blog/nlp-chatbot/bhattacharyya_coefficient.png) 在了解了Bhattacharyya距离和Bhattacharyya系数后,我们可以开始实现Bhattacharyya损失函数。下面是一个使用Python层Caffe实现Bhattacharyya损失函数的示例代码: ```python import caffe import numpy as np class BhattacharyyaLossLayer(caffe.Layer): def setup(self, bottom, top): if len(bottom) != 2: raise Exception("Need two inputs to compute Bhattacharyya loss.") # 检查输入数据维度是否匹配 if bottom[0].count != bottom[1].count: raise Exception("Inputs must have the same dimension.") self.diff = np.zeros_like(bottom[0].data, dtype=np.float32) self.epsilon = 1e-6 # 避免除数为0 def reshape(self, bottom, top): top[0].reshape(1) def forward(self, bottom, top): # 计算Bhattacharyya系数 self.diff[...] = bottom[0].data - bottom[1].data self.distance = np.sum(np.sqrt(np.abs(self.diff))) + self.epsilon self.bc = np.exp(-self.distance) # 计算Bhattacharyya损失 self.loss = -np.log(self.bc + self.epsilon) top[0].data[...] = self.loss def backward(self, top, propagate_down, bottom): if propagate_down: bottom[0].diff[...] = -(1 / (self.bc + self.epsilon)) * np.sign(self.diff) * np.exp(-self.distance / 2) / np.sqrt(np.abs(self.diff)) bottom[1].diff[...] = (1 / (self.bc + self.epsilon)) * np.sign(self.diff) * np.exp(-self.distance / 2) / np.sqrt(np.abs(self.diff)) ``` 在上面的代码,我们定义了一个名为BhattacharyyaLossLayer的自定义层,实现了Bhattacharyya损失函数。在setup()函数,我们首先检查输入的数据维度是否匹配,然后初始化diff和epsilon变量。在reshape()函数,我们指定输出数据的维度。在forward()函数,我们计算了Bhattacharyya系数和Bhattacharyya损失,并将损失值保存到top[0]。在backward()函数,我们计算了梯度,并将梯度值保存到bottom[0]和bottom[1]。 需要注意的是,在计算梯度时,我们使用了符号函数和指数函数,这是由于Bhattacharyya距离的定义包含了绝对值,导致其不可导。因此,我们使用了符号函数来代替导数的符号,使用指数函数来代替导数的大小。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值