caffe中的softmax layer

    在caffe中的lenet实现最后一层是softmax layer,输出分类的结果,下面就简单介绍一下softmax回归。

    1,首先,在caffe中,softmax layer输出的是原始的输入在每一个分类标签上的概率,例如在lenet网络中,输出的分类共有0-9的10中分类,那么softmax layer就会输出含有10个元素的向量,每一个元素表示输入在每一个分类上的概率。

    那么,用softmax的目的是让输入在正确的分来标签上的概率最大,这就是我们优化的目标函数,普通的优化函数只是比较输出和标签的差值,然后对差值进行优化,让其最小,就可以得出网络的参数值。但是在分类中,这种方法不太适用,因为输出的结果不是连续的,而是离散的,是无法对其求梯度的,所以要从概率的角度进行考虑。

    那么问题来了,从概率的角度进行优化是可行的,但是输入在每个标签上的概率应该怎么求呢,这是一个多元分布问题,而softmax就是解决多元分布问题的,在介绍具体的过程之前,我们先看softmax layer的输入代表的含义,在《deeping learning》的181页有这么一句话:we can think of a as a vector of scores whose elements a(i) as associated with each category i, with larger relative scores yielding exponentially larger probabilities. 就是说softmax layer的输入可以看作是输入在每个标签上的打分,分数越高,说明输入越有可能属于这个标签上,那么我们也可以利用这个分数求输入相对于每个标签的概率,分数越高,概率越大。

    2, softmax回归

    网上有很多关于softmax回归的帖子,我的理解是softmax本质的作用就是计算softmax layer的输入在每一个标签上的概率,caffe中softmax_layer的过程如下:

    (1)找出输入的最大值;

    (2)输入的每一个变量都减去最大值;

    (3)对(2)中结果求去指数函数;

    (4)对(3)中结果归一化,得出的结果就是输入在每一个标签上概率。

    caffe中代码是在softmax_layer.cpp Line 37

   

  for (int i = 0; i < outer_num_; ++i) { // use softmax to calculate the hypothesis function
    // initialize scale_data to the first plane
    caffe_copy(inner_num_, bottom_data + i * dim, scale_data);
    for (int j = 0; j < channels; j++) {
      for (int k = 0; k < inner_num_; k++) {
        scale_data[k] = std::max(scale_data[k],
            bottom_data[i * dim + j * inner_num_ + k]);
      }
    }
    // subtraction
    caffe_cpu_gemm<Dtype>(CblasNoTrans, CblasNoTrans, channels, inner_num_,
        1, -1., sum_multiplier_.cpu_data(), scale_data, 1., top_data);
    // exponentiation
    caffe_exp<Dtype>(dim, top_data, top_data);
    // sum after exp
    caffe_cpu_gemv<Dtype>(CblasTrans, channels, inner_num_, 1.,
        top_data, sum_multiplier_.cpu_data(), 0., scale_data);
    // division
    for (int j = 0; j < channels; j++) {
      caffe_div(inner_num_, top_data, scale_data, top_data);
      top_data += inner_num_;
    }
  }


    下面最重要的是求去代价函数,代价函数本质上就是输入在对应的正确的标签上的概率,我们优化的目标就是使这个概率最大,一般我们都是对概率取个log运算,然后,由于网络的训练是以batch为单位的,假如一个batch里有100个样本,我们就要对这100个样本的log(概率)进行求和,然后平均,最后我们就是利用这个代价函数求梯度,然后利用梯度更新权值。caffe中代码是在softmax_loss_layer.cpp中Line 100

   

for (int i = 0; i < outer_num_; ++i){ // sample by sample 
    for (int j = 0; j < inner_num_; j++) {
      const int label_value = static_cast<int>(label[i * inner_num_ + j]);
      if (has_ignore_label_ && label_value == ignore_label_) {
        continue;
      }
      DCHECK_GE(label_value, 0);
      DCHECK_LT(label_value, prob_.shape(softmax_axis_));
      loss -= log(std::max(prob_data[i * dim + label_value * inner_num_ + j],
                           Dtype(FLT_MIN)));  // cost function
      ++count;
    }
  }
  top[0]->mutable_cpu_data()[0] = loss / get_normalizer(normalization_, count);


    关于softmax的具体原理,参考下面两个博客:

   (1)http://ufldl.stanford.edu/wiki/index.php/Softmax%E5%9B%9E%E5%BD%92

   (2)http://blog.csdn.net/acdreamers/article/details/44663305

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值