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

SoftmaxCost

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
@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;
    }<br><br>public DoubleMatrix
getPredictions (ClassifierTheta Theta, DoubleMatrix Features)<br>    {<br>        
int numDataItems
= Features.columns;<br>        DoubleMatrix Input = ((Theta.W.transpose()).mmul(Features)).addColumnVector(Theta.b);<br>        Input = DoubleMatrix.concatVertically(Input, DoubleMatrix.zeros(
1,numDataItems));<br>  
     
return Activation.valueAt(Input);
<br>    }

是个典型的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):

∂E∂wij=∂E∂pj∂hj∂netjxi=−1pjpj(1−pj)xi=−(1−pj)xi=−(labelj−pj)featurei

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

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

RAECost

先看实现代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
@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. Spring源代码解析

    Spring源代码解析(一):IOC容器:http://www.iteye.com/topic/86339 Spring源代码解析(二):IoC容器在Web容器中的启动:http://www.itey ...

  2. Spring源代码解析(收藏)

    Spring源代码解析(收藏)   Spring源代码解析(一):IOC容器:http://www.iteye.com/topic/86339 Spring源代码解析(二):IoC容器在Web容器中的 ...

  3. C#使用zxing,zbar,thoughtworkQRcode解析二维码,附源代码

    最近做项目需要解析二维码图片,找了一大圈,发现没有人去整理下开源的几个库案例,花了点时间 做了zxing,zbar和thoughtworkqrcode解析二维码案例,希望大家有帮助. zxing是谷歌 ...

  4. NIO框架之MINA源代码解析(二):mina核心引擎

    NIO框架之MINA源代码解析(一):背景 MINA的底层还是利用了jdk提供了nio功能,mina仅仅是对nio进行封装.包含MINA用的线程池都是jdk直接提供的. MINA的server端主要有 ...

  5. SDWebImage源代码解析(二)

    上一篇:SDWebImage源代码解析(一) 2.缓存 为了降低网络流量的消耗.我们都希望下载下来的图片缓存到本地.下次再去获取同一张图片时.能够直接从本地获取,而不再从远程server获取.这样做的 ...

  6. redis之字符串命令源代码解析(二)

    形象化设计模式实战             HELLO!架构                     redis命令源代码解析 在redis之字符串命令源代码解析(一)中讲了get的简单实现,并没有对 ...

  7. asp.net C#生成和解析二维码代码

    类库文件我们在文件最后面下载 [ThoughtWorks.QRCode.dll 就是类库] 使用时需要增加: using ThoughtWorks.QRCode.Codec;using Thought ...

  8. Fixflow引擎解析(二)(模型) - BPMN2.0读写

    Fixflow引擎解析(四)(模型) - 通过EMF扩展BPMN2.0元素 Fixflow引擎解析(三)(模型) - 创建EMF模型来读写XML文件 Fixflow引擎解析(二)(模型) - BPMN ...

  9. Arrays.sort源代码解析

    Java Arrays.sort源代码解析 Java Arrays中提供了对所有类型的排序.其中主要分为Primitive(8种基本类型)和Object两大类. 基本类型:采用调优的快速排序: 对象类 ...

随机推荐

  1. c#中virtual, abstract和override的区别和用法

    virtual是把一个方法声明为虚方法,使派生类可重写此方法,一般建立的方法是不能够重写的,譬如类A中有个方法protected void method(){ 原代码....;}类B继承自类A,类B能 ...

  2. The working copy at 'xxx' is too old 错误解决

    使用svn update更新时候提示: svn: E155036: The working copy at 'xxx' is too old (format 29) to work with clie ...

  3. 运行edX Devstack

    前一篇文章,我们安装完成了edX Devstack,本文将介绍edX Devstack的常用命令 6.1. 连接到 Devstack Virtual Machine 为了连接到Devstack vir ...

  4. C内存管理

    一般而言,分配给进程的内存有四个概念上不同的区域,分别为:代码段.数据段.堆和栈,其中数据段又可以细分为初始化为非零的数据和初始化为零的数据.如下图所示: 1.栈区(stack)— 由编译器自动分配释 ...

  5. .NET事件的指导原则

    C#允许编写所需的各种类型的事件.但是,为了与.NET Framwork的组件相兼容,开发人员必须遵循微软为此建立的一系列指导原则.这些指导原则的核心是,事件处理程序必须拥有两个参数.第一个参数是一个 ...

  6. leetcode面试准备: Maximal Rectangle

    leetcode面试准备: Maximal Rectangle 1 题目 Given a 2D binary matrix filled with 0's and 1's, find the larg ...

  7. YIi 权限管理和基于角色的访问控制

    验证和授权(Authentication and Authorization) 定义身份类 (Defining Identity Class) 登录和注销(Login and Logout) 访问控制 ...

  8. OpenCV学习笔记:如何扫描图像、利用查找表和计时

    目的 我们将探索以下问题的答案: 如何遍历图像中的每一个像素? OpenCV的矩阵值是如何存储的? 如何测试我们所实现算法的性能? 查找表是什么?为什么要用它? 测试用例 这里我们测试的,是一种简单的 ...

  9. 物联网操作系统HelloX V1.77(beta)版本发布

    物联网操作系统HelloX V1.77发布 经过近半年的努力,物联网操作系统HelloX V1.77版本正式完成,源代码已上载到github(github.com/hellox-project/Hel ...

  10. MyEclipse常用操作技巧

    1.源码和帮助文档的的关连 下面以关联struts2-core-2.3.14.2.jar源代码为例: 如下为示意图 2.拷贝项目的时候,要注意 将项目的web-root fold改成更新后的名字项目名 ...