本文细述上文引出的RAECost和SoftmaxCost两个类。

SoftmaxCost

我们已经知道,SoftmaxCost类在给定features和label的情况下(超参数给定),衡量给定权重($hidden\times catSize$)的误差值$cost$,并指出当前的权重梯度。看代码。

@Override
public double valueAt(double[] x)
{
if( !requiresEvaluation(x) )
return value;
int numDataItems = Features.columns; int[] requiredRows = ArraysHelper.makeArray(0, CatSize-2);
ClassifierTheta Theta = new ClassifierTheta(x,FeatureLength,CatSize);
DoubleMatrix Prediction = getPredictions (Theta, Features); double MeanTerm = 1.0 / (double) numDataItems;
double Cost = getLoss (Prediction, Labels).sum() * MeanTerm;
double RegularisationTerm = 0.5 * Lambda * DoubleMatrixFunctions.SquaredNorm(Theta.W); DoubleMatrix Diff = Prediction.sub(Labels).muli(MeanTerm);
DoubleMatrix Delta = Features.mmul(Diff.transpose()); DoubleMatrix gradW = Delta.getColumns(requiredRows);
DoubleMatrix gradb = ((Diff.rowSums()).getRows(requiredRows)); //Regularizing. Bias does not have one.
gradW = gradW.addi(Theta.W.mul(Lambda)); Gradient = new ClassifierTheta(gradW,gradb);
value = Cost + RegularisationTerm;
gradient = Gradient.Theta;
return value;
} public DoubleMatrix getPredictions (ClassifierTheta Theta, DoubleMatrix Features)
    {
        int numDataItems = Features.columns;
        DoubleMatrix Input = ((Theta.W.transpose()).mmul(Features)).addColumnVector(Theta.b);
        Input = DoubleMatrix.concatVertically(Input, DoubleMatrix.zeros(1,numDataItems));
        return Activation.valueAt(Input);
    }

是个典型的2层神经网络,没有隐层,首先根据features预测labels,预测结果用softmax归一化,然后根据误差反向传播算出权重梯度。

此处增加200字。

这个典型的2层神经网络,label为一列向量,目标label置1,其余为0;转换函数为softmax函数,输出为每个label的概率。

计算cost的函数为getLoss,假设目标label的预测输出为$p^*$,则每个样本的cost也即误差函数为:

$$cost=E(p^*)=-\log(p^*)$$

根据前述的神经网络后向传播算法,我们得到($j$为目标label时,否则为0):

$$\frac{\partial E}{\partial w_{ij}}=\frac{\partial E}{\partial p_j}\frac{\partial h_j}{\partial net_j}x_i=-\frac{1}{p_j}p_j(1-p_j)x_i=-(1-p_j)x_i=-(label_j-p_j)feature_i$$

因此我们便理解了下面代码的含义:

DoubleMatrix Delta = Features.mmul(Diff.transpose());

RAECost

先看实现代码:

@Override
public double valueAt(double[] x)
{
if(!requiresEvaluation(x))
return value; Theta Theta1 = new Theta(x,hiddenSize,visibleSize,dictionaryLength);
FineTunableTheta Theta2 = new FineTunableTheta(x,hiddenSize,visibleSize,catSize,dictionaryLength);
Theta2.setWe( Theta2.We.add(WeOrig) ); final RAEClassificationCost classificationCost = new RAEClassificationCost(
catSize, AlphaCat, Beta, dictionaryLength, hiddenSize, Lambda, f, Theta2);
final RAEFeatureCost featureCost = new RAEFeatureCost(
AlphaCat, Beta, dictionaryLength, hiddenSize, Lambda, f, WeOrig, Theta1); Parallel.For(DataCell,
new Parallel.Operation<LabeledDatum<Integer,Integer>>() {
public void perform(int index, LabeledDatum<Integer,Integer> Data)
{
try {
LabeledRAETree Tree = featureCost.Compute(Data);
classificationCost.Compute(Data, Tree);
} catch (Exception e) {
System.err.println(e.getMessage());
}
}
}); double costRAE = featureCost.getCost();
double[] gradRAE = featureCost.getGradient().clone(); double costSUP = classificationCost.getCost();
gradient = classificationCost.getGradient(); value = costRAE + costSUP;
for(int i=0; i<gradRAE.length; i++)
gradient[i] += gradRAE[i]; System.gc(); System.gc();
System.gc(); System.gc();
System.gc(); System.gc();
System.gc(); System.gc(); return value;
}

cost由两部分组成,featureCost和classificationCost。程序遍历每个样本,用featureCost.Compute(Data)生成一个递归树,同时累加cost和gradient,然后用classificationCost.Compute(Data, Tree)根据生成的树计算并累加cost和gradient。因此关键类为RAEFeatureCost和RAEClassificationCost。

RAEFeatureCost类在Compute函数中调用RAEPropagation的ForwardPropagate函数生成一棵树,然后调用BackPropagate计算梯度并累加。具体的算法过程,下一章分解。

jrae源码解析(二)的更多相关文章

  1. Mybatis源码解析(二) —— 加载 Configuration

    Mybatis源码解析(二) -- 加载 Configuration    正如上文所看到的 Configuration 对象保存了所有Mybatis的配置信息,也就是说mybatis-config. ...

  2. RxJava2源码解析(二)

    title: RxJava2源码解析(二) categories: 源码解析 tags: 源码解析 rxJava2 前言 本篇主要解析RxJava的线程切换的原理实现 subscribeOn 首先, ...

  3. Sentinel源码解析二(Slot总览)

    写在前面 本文继续来分析Sentinel的源码,上篇文章对Sentinel的调用过程做了深入分析,主要涉及到了两个概念:插槽链和Node节点.那么接下来我们就根据插槽链的调用关系来依次分析每个插槽(s ...

  4. iOS即时通讯之CocoaAsyncSocket源码解析二

    原文 前言 本文承接上文:iOS即时通讯之CocoaAsyncSocket源码解析一 上文我们提到了GCDAsyncSocket的初始化,以及最终connect之前的准备工作,包括一些错误检查:本机地 ...

  5. jQuery 源码解析二:jQuery.fn.extend=jQuery.extend 方法探究

    终于动笔开始 jQuery 源码解析第二篇,写文章还真是有难度,要把自已懂的表述清楚,要让别人听懂真的不是一见易事. 在 jQuery 源码解析一:jQuery 类库整体架构设计解析 一文,大致描述了 ...

  6. Common.Logging源码解析二

    Common.Logging源码解析一分析了LogManager主入口的整个逻辑,其中第二步生成日志实例工厂类接口分析的很模糊,本随笔将会详细讲解整个日志实例工厂类接口的生成过程! (1).关于如何生 ...

  7. erlang下lists模块sort(排序)方法源码解析(二)

    上接erlang下lists模块sort(排序)方法源码解析(一),到目前为止,list列表已经被分割成N个列表,而且每个列表的元素是有序的(从大到小) 下面我们重点来看看mergel和rmergel ...

  8. element-ui 源码解析 二

    Carousel 走马灯源码解析 1. 基本原理:页面切换 页面切换使用的是 transform 2D 转换和 transition 过渡 可以看出是采用内联样式来实现的 举个栗子 <div : ...

  9. ArrayList源码解析(二)

    欢迎转载,转载烦请注明出处,谢谢. https://www.cnblogs.com/sx-wuyj/p/11177257.html 自己学习ArrayList源码的一些心得记录. 继续上一篇,Arra ...

  10. React的Component,PureComponent源码解析(二)

    1.什么是Component,PureComponent? 都是class方式定义的基类,两者没有什么大的区别,只是PureComponent内部使用shouldComponentUpdate(nex ...

随机推荐

  1. J2EE和EJB有什么关系?

    其实j2EE就是java的企业版,与javaSE(标准版)有是有区别的,所以运行环境会有差异(简单点可以说,这是两组不同的接口),我们一般所熟悉的tomcat仅仅只实现了j2ee的一小部分规范,它只是 ...

  2. Ubuntu 中使用 谷歌日历

    简介 对于经常使用待办类软件的人来说,谷歌日历是个不错的选择.但每次,都要登录网页去查看,对于我这样的懒人来说似乎麻烦了些. 所以在网上找了个叫做 Calendar Indicator 的软件. 效果 ...

  3. BZOJ1636: [Usaco2007 Jan]Balanced Lineup

    1636: [Usaco2007 Jan]Balanced Lineup Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 476  Solved: 345[ ...

  4. Eclipse ARM IDE 开发环境

    一.Eclipse Eclipse的本身只是一个框架平台,但是众多插件的支持,使得Eclipse拥有较好的灵活性. 二.CDT CDT是Eclipse用于扩展Eclipse支持C/C++开发的插件. ...

  5. 动态规划(方案还原):SGU 104 Little shop of flowers

    花店橱窗布置问题 时间限制:3000 ms 问题描述(Problem)    假设你想以最美观的方式布置花店的橱窗,你有F束花,每束花的品种都不一样,同时,你至少有同样数量的花瓶,被按顺序摆成一行.花 ...

  6. 【动态规划】【最短路】Codeforces 710E Generate a String

    题目链接: http://codeforces.com/problemset/problem/710/E 题目大意: 问写N个字符的最小花费,写一个字符或者删除一个字符花费A,将当前的字符数量翻倍花费 ...

  7. 【有源汇上下界最大流】ZOJ 3229 Shoot the Bullet

    题目链接: http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3229 题目大意: n天给m个女孩拍照(1<=n<= ...

  8. One day

    1.c的格式化输入输出:  printf()和scanf()函数可以较好实现格式化输入输出,例子如下:  printf("%3d",3); //结果为__3 (_为空格)  pri ...

  9. linux下安装python linux下一些常用的命令

    注意 ubuntukylin-14.04.2-desktop-amd64 自带python2.7.6 这个说的比较详细 http://wenku.baidu.com/link?url=gaeFcQrc ...

  10. bzoj1251 序列终结者(Splay Tree+懒惰标记)

    Description 网上有许多题,就是给定一个序列,要你支持几种操作:A.B.C.D.一看另一道题,又是一个序列 要支持几种操作:D.C.B.A.尤其是我们这里的某人,出模拟试题,居然还出了一道这 ...