在不知道算法原理的情况下,如何阅读理解算法的matlab程序
很多的时候,对于一个好的算法,我们没有它相关的第一手材料,如其相关的论文、期刊文章、会议报告、专门课程、专门的讲座、个人博客、百度文献、*、谷歌搜索内容等等。没有这些材料,对算法原理的理解无疑犹如水中捞月,比登天还难。但是,我们只有算法的matlab程序。这时,如何只通过算法的matlab程序去理解算法的原理变为很重要了。这种情景就像你刚进一家公司,上一届的负责人把项目的程序扔给你后就拍屁股走人,没有给你任何项目的相关材料,叫你一个人去研究项目的程序,在程序里自己领悟。那怎样从matlab程序中哪些抽象的常量、变量、函数等去理解其中算法的原理呢?
单从算法的五个特性来看,这就相当从算法的输入与输出找出算法原理(本质是处理数据的过程)。
下面我将我通过一个例子来讲解“如何只通过算法的matlab程序去理解算法的原理”。
我们主要从几方面去把握:
(1)把算法当成一个简单的数据处理系统,即只有三大块:输入、输出、处理过程。
(2)输出量的定位反追踪,即根据输出量的表达式去寻找算法处理数据的步骤。
(3)思维的迁移,程序中各量的含义,三个层次:数学意义、物理意义、实际当中具体的例子
例子程序的代码如下:
% Version 1.000 % % Code provided by Ruslan Salakhutdinov and Geoff Hinton % % Permission is granted for anyone to copy, use, modify, or distribute this % program and accompanying programs and documents for any purpose, provided % this copyright notice is retained and prominently displayed, along with % a note saying that the original programs are available from our % web page. % The programs and documents are distributed without any warranty, express or % implied. As the programs were written for research purposes only, they have % not been tested to the degree that would be advisable in any important % application. All use of these programs is entirely at the user‘s own risk. function [f, df] = CG_MNIST(VV,Dim,XX); l1 = Dim(1); l2 = Dim(2); l3 = Dim(3); l4= Dim(4); l5= Dim(5); l6= Dim(6); l7= Dim(7); l8= Dim(8); l9= Dim(9); N = size(XX,1); % Do decomversion. w1 = reshape(VV(1:(l1+1)*l2),l1+1,l2); xxx = (l1+1)*l2; w2 = reshape(VV(xxx+1:xxx+(l2+1)*l3),l2+1,l3); xxx = xxx+(l2+1)*l3; w3 = reshape(VV(xxx+1:xxx+(l3+1)*l4),l3+1,l4); xxx = xxx+(l3+1)*l4; w4 = reshape(VV(xxx+1:xxx+(l4+1)*l5),l4+1,l5); xxx = xxx+(l4+1)*l5; w5 = reshape(VV(xxx+1:xxx+(l5+1)*l6),l5+1,l6); xxx = xxx+(l5+1)*l6; w6 = reshape(VV(xxx+1:xxx+(l6+1)*l7),l6+1,l7); xxx = xxx+(l6+1)*l7; w7 = reshape(VV(xxx+1:xxx+(l7+1)*l8),l7+1,l8); xxx = xxx+(l7+1)*l8; w8 = reshape(VV(xxx+1:xxx+(l8+1)*l9),l8+1,l9); XX = [XX ones(N,1)]; w1probs = 1./(1 + exp(-XX*w1)); w1probs = [w1probs ones(N,1)]; w2probs = 1./(1 + exp(-w1probs*w2)); w2probs = [w2probs ones(N,1)]; w3probs = 1./(1 + exp(-w2probs*w3)); w3probs = [w3probs ones(N,1)]; w4probs = w3probs*w4; w4probs = [w4probs ones(N,1)]; w5probs = 1./(1 + exp(-w4probs*w5)); w5probs = [w5probs ones(N,1)]; w6probs = 1./(1 + exp(-w5probs*w6)); w6probs = [w6probs ones(N,1)]; w7probs = 1./(1 + exp(-w6probs*w7)); w7probs = [w7probs ones(N,1)]; XXout = 1./(1 + exp(-w7probs*w8)); f = -1/N*sum(sum( XX(:,1:end-1).*log(XXout) + (1-XX(:,1:end-1)).*log(1-XXout))); IO = 1/N*(XXout-XX(:,1:end-1)); Ix8=IO; dw8 = w7probs‘*Ix8; Ix7 = (Ix8*w8‘).*w7probs.*(1-w7probs); Ix7 = Ix7(:,1:end-1); dw7 = w6probs‘*Ix7; Ix6 = (Ix7*w7‘).*w6probs.*(1-w6probs); Ix6 = Ix6(:,1:end-1); dw6 = w5probs‘*Ix6; Ix5 = (Ix6*w6‘).*w5probs.*(1-w5probs); Ix5 = Ix5(:,1:end-1); dw5 = w4probs‘*Ix5; Ix4 = (Ix5*w5‘); Ix4 = Ix4(:,1:end-1); dw4 = w3probs‘*Ix4; Ix3 = (Ix4*w4‘).*w3probs.*(1-w3probs); Ix3 = Ix3(:,1:end-1); dw3 = w2probs‘*Ix3; Ix2 = (Ix3*w3‘).*w2probs.*(1-w2probs); Ix2 = Ix2(:,1:end-1); dw2 = w1probs‘*Ix2; Ix1 = (Ix2*w2‘).*w1probs.*(1-w1probs); Ix1 = Ix1(:,1:end-1); dw1 = XX‘*Ix1; df = [dw1(:)‘ dw2(:)‘ dw3(:)‘ dw4(:)‘ dw5(:)‘ dw6(:)‘ dw7(:)‘ dw8(:)‘ ]‘;
一、算法三大块
输入:在matlab函数定义的时候,我们可以看到有那几个输入量
输出:在matlab函数定义的时候,我们可以看到有那几个输出量
处理过程:这一块,我们主要看整个程序的阶段性注释。好的程序可读性都很强。我们通过程序块的注释了解程序处理大体的步骤。
二、确定已知量和未知量
要从函数的定义、程序的注释、变量的定义当中去确定那个量是已知的,那个是未知的。这个环节很重要。它可以帮你理清程序是如何求解的。因为在数学中,我们都是用已知量来求解未知量的,而且未知量一定有其求解的过程。
三、输出量的定位反追踪
输出量的定位:(1)确定各个输出量最后一次被赋值的位置
反追踪:(1)由输出量的最后一次被赋值的位置开始,由下往上追踪输出量的变化,画出输出量由下而上变化的流线图
(2)有用下而上的变化流线图写出由上至下的变化流线图,即是程序求解输出量的过程
四、思维的迁移
至此,我们已经知道了变量的整个求解过程。那么,接下来,我们要弄清在输出量、输出量表达式中的变量和求解输出量过程中所涉及的变量的最抽象层数学含义、处于次层的物理意义、最具体的最形象的代表事例。这个环节对算法的理解是非常重要的,也是最实际的。在此阶段,我们不但掌握了算法的原理,还可以把算法应用到相关的领域。
..............