【MatConvNet代码解析】 一些理解
1.DagNN对象的executionOrder属性
该属性是hidden属性,所以外部是访问不到的。只有dagnn.DagNN类和dagnn.Layer类可以访问到。
该属性的设置是在DagNN类的rebuild方法中实现的,在该方法的53行左右调用了一个getOrder函数去实现。而rebuild方法又被dagNN类的addLayer方法调用
所以我们如果想从外部设置该属性,一种情况是我们给网络加一层就会自动设置该属性,还有一种情况可以手动调用dagNN类的rebuild方法
2019.4.29
2.DagNN的属性layers不是一个类,它只是一个结构体数组,layers这个结构体中有一个field叫做block,这个block中间才会放dagnn.layer类。
同理,一个Layer类是没有inputs,outputs这些属性的。一个标准的Layer类没有public的properties。而dagnn.DagNN的layers属性中才有inputs,outputs这些filed的。
这样我们一般调用DagNN类的addLayer方法就是给DagNN类的layers属性(是一个结构体数组)再添加一个结构体(添加这个结构体数组的最后),并且会在这个结构体的block field中添加相应的Layer类作为其value。
2019.4.30
3. logistic loss在vl_nnloss.m中的实现
252行左右的实现如下:
case 'logistic' %t = log(1 + exp(-c.*X)) ; a = -c.*x ; b = max(0, a) ; t = b + log(exp(-b) + exp(a-b)) ;%这样写和t=log(1+exp(-c.*X))是一样的
这个实现没有问题的,如下:
1.b=a,即分类错误,此时
t=a+log(1+exp(-a))=a+log(exp(-a).*(exp(a)+1))=a+log(exp(-a))+log(exp(a)+1)=a-a+log(1+exp(a))=log(1+exp(a))=log(1+exp(-c.*X))
2.b=0,即分类正确(分类正确的话a就是负值,而且越负越好,最好无穷大)
t=0+log(1+exp(a))
但是不知道作者这样实现的目的,为什么不直接按照公式实现?
2019.5.1
4. 关于vl_nnconv的一些理解
addpath(genpath('/home/qian/nutCloud/codes/libraries/ml/matconvnet-1.0-beta25_linux/')); vl_setupnn; x1=rand(22,22,3,8); f1=rand(6,6,3,16); y1=vl_nnconv(x1,f1,[]);%17*17*16*8 x2=rand(22,22,3*8); f2=rand(6,6,3,16); y2=vl_nnconv(x2,f2,[]);%17*17*16 x3=rand(22,22,3,1); f3=rand(6,6,3,16); y3=vl_nnconv(x3,f3,[]);%17*17*16 x4=rand(22,22,6,1); f4=rand(6,6,3,16); y4=vl_nnconv(x4,f4,[]);%17*17*16 x5=rand(22,22,6,8); f5=rand(6,6,3,16); y5=vl_nnconv(x5,f5,[]);%17*17*16×8 x6=rand(22,22,3,8); f6=rand(6,6,6,16); y6=vl_nnconv(x6,f6,[]);%error:The FILTERS depth does not divide the DATA depth.
(1)首先注意1和2的情况,x的大小其实都是一样的,但是对于x的不同处理,输出是不一样的,其中1 的处理是我们一般意义上的batch,2的处理是group
(2)上面的例子中2,4,5都是group。6不会被成功执行,由此可知,x的第三维必须被filter的第三维整除。
2019.6.8