struts2源码解析(共2篇)
SoftmaxCost
我们已经知道,SoftmaxCost类在给定features和label的情况下(超参数给定),衡量给定权重(hidden×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):
∂E∂wij=∂E∂pj∂hj∂netjxi=−1pjpj(1−pj)xi=−(1−pj)xi=−(labelj−pj)featurei
因此我们便理解了下面代码的含义:
1
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>() {
public void perform(int index, LabeledDatum 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
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。
1 Linux内核系统
当前计算机技术已经广泛的应用在生活和工作中,从计算机系统本身进行分析,其中的操作系统是对计算机系统中的硬件、软件等进行组织管理的系统,为计算机系统的使用者提供相应的计算机服务,以及访问接口[1]。操作系统是计算机系统的最基础的软件系统,也是计算机系统的支持系统,作为计算机的操作系统Linux系统和核心为Linux内核。
Linux内核是计算机从磁盘加载到计算机内存中的一个程序,其在计算机系统运行的过程中,处于运行的状态,而且其运行直到计算机系统关闭。Linux内核中的大部分都是在C语言的基础上完成的,但是也有部分是使用汇编软件编写的。Linux内核在Linux系统中有非常大的作用,地位也非常高,在整个Linux系统中,包括了4个子系统,分别为用户进程、系统调用接口、Linux内核以及硬件,Linux内核占主导地位。在计算机系统运行的过程中,Linux系统的应用,帮助计算机系统的运行解决安全性问题以及运行效率的问题,Linux内核在Linux系统中,是硬件与用户之间交流、沟通的关键性部分[2]。
随着信息技术的发展,在大型软件代码分析的过程中,静态代码分析需要对各个组成模块、文件、函数之间的关系进行分析,传统的分析只是从代码层分析各个函数、变量之间的关系,对于Linux内核源码而言,编译选项为软件提供了配置的可能性,但是针对Linux内核源码这种大型的软件系统或者过于庞大的系统而言,进行静态代码分析,缺少自上而下的分析线索。
针对Linux系统进行分析,编译选项与源文件之间的关系分析,采用传统的静态代码分析,也存在一定不足的地方,为了有效地分析Linux内核源码编译选项、文件、函数之间的依赖关系,需要通过功能描述和物理源文件之间存在的关系,再有效地分析这些函数、变量之间的关系。为了将这些问题解决,需要在Linux内核源码的基础上,产生一种编译选项到文件、函数关系分析的方法,这种方法也就是在Linux内核源码的基础上增加Makefile生成文件和Kconfig配置文件的分析。
2 依赖关系
在Linux内核源码中存在着一些的依赖关系,这些关系从数学的角度进行分析如下:
假设在Linux内核源码存在一个关系模式为R (U),其中U{A1,A2,A3,……,An)则是这个关系的全集,X、Y则是U的子集,令t以及u为关系模式R的任意两个组成元素,如果出现t和u在X的投影中出现t[X]=u[X],则可以得出t[]Y=u[Y]。也就是t[X]=u[X]≥t[]Y=u[Y],此时则说明X决定Y,或者是Y受到X的牵制,又或者Y依赖X,为此将其记作X→Y。
在计算机系统的操作(Linux系统)系统中Linux内核源码中,不是所有的源代码与编译选项存在关系,针对Linux系统功能进行分析,Linux内核源码中的与编译选项有关的源代码大多是具有可定制性功能的代码[3]。其结构如图1所示。
从图1可以知道,Linux内核源码中存在的依赖关系,可以分为3种层次。第一层次是以配置文件(Kconfig)定义的编译选项以及编译菜单;第二层是每一个编译选项相对应的文件;第三层是最地层文件相对应的函数。在这3个层次中,每一次都存在一定的依赖关系,例如函数关系,代入上面的关系式,也就是R (U),其中U{A1,A2,A3,……,An}为函数的全集,X、Y则是U中任意两个子集,如果在函数调用的过程中,令t以及u为关系模式R的任意两个组成元素,在一定的条件下t可以满足t[X]=u[X],并得出t[]Y=u[Y],则说明在这个函数之间,在t环境下,存在依赖的关系。将这个关系应用在Linux内核源码中,可以解释为在一定的条件下,函数X可以用于函数Y的调用。在Linux内核源码的编译选项、文件函数之间的关系分析中,也存在这样的依赖关系。
在Linux内核源码编译选项中,每一层存在的依赖关系并不是这一层中存在的所有子集的关系,这种依赖关系是相对应的。在Linux内核源码编译选项中存在的依赖关系,内部依赖是文件之间的相互引用,而且这种引用表现为Linux内核源码中大量跨文件函数的调用。通过对Linux内核源码的编译选项、文件、函数之间的依赖关系进行分析,Linux内核源码内部存在复杂的关系,这种关系可以称之为上层与下层之间的依赖关系。Linux内核源码中编译选项、编译菜单之间的关系,由配置文件、生成文件进行定义[4]。
3 配置文件、生成文件的编译选项依赖关系
在Linux内核源码中Makefile生成文件针对编译选项与文件之间的依赖关系进行定义和描述,Makefile生成文件对编译选项与文件之间的依赖关系进行的定义和描述,其实是Linux内核源码与编译选项依赖关系的细化。在Linux内核源码中Makefile生成文件组织如图2所示。
为了更好地认识Linux内核源码与编译选项、文件、函数之间存在的依赖关系,对编译选项之间的依赖关系、编译选项与文件之间的依赖关系、文件与文件之间的依赖关系等进行分析[5]。
在编译选项之间存在的依赖关系主要为编译选项名字、类型、选项与菜单之间的关系。在Linux内核源码中Kconfig配置文件的形式如图3所示。
其中在Linux内核源码中Kconfig配置文件的语言对于现编译选项类型的解释说明为:
从以上Linux内核源码中配置文件的语言说明进行分析,可以知道编译选项中编译类型中的关键词为bool、tristate、string、hex、int。而“def-bool”、“def-tristate”为default与bool、trisate的缩写。
在Linux内核源码中编译选项与菜单之间的依赖关系如图4所示。
在实际工作中Linux内核源码配置文件编译的以Linux内核源码/Kconfig为起点进行工作,其他编译选项之间的依赖关系的分析也是以上方法进行。Linux内核源码中编译选项、文件、函数之间的依赖关系分析,是为了方便计算机系统的操作系统以及其他系统的运行可以有保障,在运行中出现故障,可以查找故障发生处等。
随着计算机技术等信息技术的发展,计算机技术运行系统、操作系统等的性能和结构会进一步地深度优化,准确地掌握这些操作系统中编译选项内部存在的依赖关系,可以提高计算机系统操作系统的工作效率等。
4 结语
Linux系统是计算机系统的基础支持软件系统,在Linux系统中内核源码是核心,而Linux内核源码从源码到使用,需要经历配置、编译、安装3个环节。在Linux内核源码的编译选项中,关系复杂,存在一定的依赖关系,针对基于Linux内核源码的编译选项、文件、函数之间的依赖关系进行了解释分析,通过分析,证明Linux系统在计算机系统中的地位,以及重要性,在信息技术不断进步的过程中,Linux系统、计算机系统等会得到进一步的优化改善,将运行效率提升。
摘要:对Linux内核源码的编译选项、文件、函数之间依赖关系以及相关的内容进行分析研究。
关键词:Linux内核源码,编译选项,函数,依赖关系
参考文献
[1]李鹏飞.Linux内核编译机制分析以及优化研究[D].西安电子科技大学,2014.
[2]朱宇.基于嵌入式Linux操作系统的实时性研究[D].长安大学,2012.
[3]江梦涛,潘朋飞,宋杨,荆琦.Linux内核中编译选项、文件以及函数之间依赖关系的解析方法[J].计算机科学,2014,(S1):445—450+454.
[4]李超.基于Xen的Linux内核源码调试器设计[D].上海交通大学,2013.