DAGNN:有向无环图神经网络

1.综述:

DagNN是用来代替SimpleNN的CNN wrapper。它是面向对象的,并且允许采用有向无环图构建神经网络。与SimpleNN相比,DagNN速度有点慢但是更加灵活。

一个DAG对象包括以下数据成员:

  • layers: 神经网络层

  • vars: 网络变量

  • params: 网络参数

  • meta: 额外的补充信息

同时,DAG还包括有一些临时的数据成员:

  • mode [normal] : 这个标志可以是“normal”或者“test”。在后面一种情况,某些模块转向测试模式,适合验证和评估;
  • accumulateParamDer [false] : 如果设置为“true”,那么网络参数的导数就会被累计,而不是在下次计算时重写;
  • conserveMemory [true] : 如果这个标记位设置为“true”,DagNN将会丢弃中间变量值,一旦在计算过程中不再需要它们;
  • device [cpu] : 这个标志的意思是,DagNN驻留在CPU内存中或者GPU内存中,使用 DagNN.move()可以在设备之间移动DagNN。

2. DAGNN相关函数

2.1 初始化为空

obj = DagNN() %初始化为空的DAGNN结构体

2.2  获取网络输入变量的名字

inputName = getInputs(obj) % 获取网络输入的名字

返回一个cell类型的输入组合。

2.3 获取网络输出变量的名字

outputName = getOutputs(obj); % 获取网络输出名称

2.4 获取网络层索引

index = getLayerIndex(obj, layerName); % 根据神经网络层的名字获取索引,用于网络评价;

obj.layers(index); % 用于网络评价

% 返回如下信息
% name = 'DCF'
% inputs = {'x', 'z'}
% outputs = {'response'}
% params = {}
% inputIndexsx = [7,14]
% outputIndexes = 15
% paramIndexes = []
% forwardTime = 0.6927
% backwardTime = 0.2452
% block = [1x1 dagnn.DCF]

2.5 获取网络变量的索引

index = getVarIndex(obj, varName); % 返回指定变量名的索引

obj.vars(index); % 对变量进行评价

% 返回如下信息
% name = 'conv1'
% value = []
% der = []
% fanin = 1
% fanout = 1
% precious = 0

2.6 获取参数的索引

index = getParamIndex(obj, paramName); % 指定参数名获取参数的索引号

obj.params(index);

% 返回如下信息:
% name = 'conv1f'
% value =  3x3x1x32 gpuArray
% der = 3x3x1x32 gpuArray
% fanout = 2
% trainMethod = 'gradient'
% learningRate = 0.01
% weightDecay = 0.0005

2.7 层、变量、参数拷贝

layer = getLayer(obj, layerName); %

var = getVar(obj, varName); %

param = getParam(obj, paramName); %
getLayerExecutionOrder(obj);

% 例如,孪生网络:
% 1    2 —— 3    4 —— 5     6 —— 13 —— 14 —— 15
% |    |    |    |    |     |
% 7 —— 8    9 —— 10   11 —— 12
% 

2.8 添加变量、参数、层

addVar(obj, varName);

addParam(obj, paramName);

addLayer(layerName, layer, input, output, params);

3. 评价DAGNN

eval(obj, inputs); % 指定输入值,评价DAGNN。
% 输入应该是cell矩阵,如 input = {'inputName', inputValue, ...},该语句的调用将导致网络的正向信息传递;并计算输出变量的值;

eval(obj, inputs, derOutputs); % 评价DAGNN前向和反向,执行误差反向传播算法。
% 和inputs很类似,的人Outputs也是cell矩阵,{‘outputName’, outputDerValue, ...};

4. 理解反向传播

4.1 损失函数权重分配层

通常,对应到损失函数,网络从表来那个的输入开始进行反向传播。在这种情况下,outputDerValue可以解释为输出的权重,通常设置为1.例如, {‘objective’, 1}。从‘objective’输出变量(权重为1)开始反向传播。

然而,很多情况下DAGNN会包括很多损失函数,在这种情况下,就需要设置不同的权重去平衡不同的目标,例如:{‘objective1’, w1, 'objective2', w2, ... }

4.2 影响evaluation的因素

  1. 评价模式可以是‘normal’ 或者 ‘test’; 在不同模式下,行为是不一样的。例如,在‘test’模式下,Dropout变成一个 Pass-through层; batch normalization使用固定的动量(通常极大提高了测试的性能);
  2. 在默认情况下,DAG会主动采用节省内存模式 conserve memory。对于GPU来说这是至关重要的,因为GPU的资源很稀缺。然而,这也意味着,在训练过程中,大多数的变量值和他们的导数都被丢弃了。 为了便于调试,这些中间变量有时对我们很重要, 在这种情况下,我们可以设置 obj.conserveMemory = false; 当然,我们也可以利用 obj.vars(v).precious = true 进行中间变量保存。

猜你喜欢

转载自blog.csdn.net/shenziheng1/article/details/81071622