(原)torch的apply函数

转载请注明出处:

http://www.cnblogs.com/darkknightzh/p/6221633.html

torch中的apply函数通过可以不断遍历model的各个模块。实际上其使用的是深度优先算法。

其具体代码如下所示(代码见torch/install/share/lua/5.1/nn/Module.lua):

-- Run a callback (called with the module as an argument) in preorder over this
-- module and its children.
--
function Module:apply(callback)
    callback(self)

    if self.modules then
        for _, module in ipairs(self.modules) do
            module:apply(callback)
        end
    end
end

可见,apply递归调用自身,直到不存在模块为止(这样说不太合理)。

如下所示的测试代码:

require "dpnn"

function createModel()
   local net = nn.Sequential()

   net:add(nn.SpatialConvolutionMM(3, 64, 7, 7, 2, 2, 3, 3))
   net:add(nn.SpatialBatchNormalization(64))
   net:add(nn.ReLU())
   net:add(nn.SpatialMaxPooling(3, 3, 2, 2, 1, 1))

   net:add(nn.Inception{
     inputSize = 192,
     kernelSize = {3, 5},
     kernelStride = {1, 1},
     outputSize = {128, 32},
     reduceSize = {96, 16, 32, 64},
     pool = nn.SpatialMaxPooling(3, 3, 1, 1, 1, 1),
     batchNorm = true
   })

   net:add(nn.Inception{
     inputSize = 256,
     kernelSize = {3, 5},
     kernelStride = {1, 1},
     outputSize = {128, 64},
     reduceSize = {96, 32, 64, 64},
     pool = nn.SpatialLPPooling(256, 2, 3, 3, 1, 1),
     batchNorm = false
   })

   net:add(nn.SpatialAveragePooling(7, 7))
   net:add(nn.View(320))
   net:add(nn.Linear(320, 128))
   net:add(nn.Normalize(2))

   return net
end

torch.setdefaulttensortype(‘torch.FloatTensor‘)

local model = createModel()

--print(model)
tt = 0
model:apply(function(module)
    tt = tt + 1
    print(tt, module)
end)

其输出结果为:

1	nn.Sequential {
  [input -> (1) -> (2) -> (3) -> (4) -> (5) -> (6) -> (7) -> (8) -> (9) -> (10) -> output]
  (1): nn.SpatialConvolutionMM(3 -> 64, 7x7, 2,2, 3,3)
  (2): nn.SpatialBatchNormalization
  (3): nn.ReLU
  (4): nn.SpatialMaxPooling(3x3, 2,2, 1,1)
  (5): nn.Inception @ nn.DepthConcat {
    input
      |`-> (1): nn.Sequential {
      |      [input -> (1) -> (2) -> (3) -> (4) -> (5) -> (6) -> output]
      |      (1): nn.SpatialConvolution(192 -> 96, 1x1)
      |      (2): nn.SpatialBatchNormalization
      |      (3): nn.ReLU
      |      (4): nn.SpatialConvolution(96 -> 128, 3x3, 1,1, 1,1)
      |      (5): nn.SpatialBatchNormalization
      |      (6): nn.ReLU
      |    }
      |`-> (2): nn.Sequential {
      |      [input -> (1) -> (2) -> (3) -> (4) -> (5) -> (6) -> output]
      |      (1): nn.SpatialConvolution(192 -> 16, 1x1)
      |      (2): nn.SpatialBatchNormalization
      |      (3): nn.ReLU
      |      (4): nn.SpatialConvolution(16 -> 32, 5x5, 1,1, 2,2)
      |      (5): nn.SpatialBatchNormalization
      |      (6): nn.ReLU
      |    }
      |`-> (3): nn.Sequential {
      |      [input -> (1) -> (2) -> (3) -> (4) -> output]
      |      (1): nn.SpatialMaxPooling(3x3, 1,1, 1,1)
      |      (2): nn.SpatialConvolution(192 -> 32, 1x1)
      |      (3): nn.SpatialBatchNormalization
      |      (4): nn.ReLU
      |    }
      |`-> (4): nn.Sequential {
             [input -> (1) -> (2) -> (3) -> output]
             (1): nn.SpatialConvolution(192 -> 64, 1x1)
             (2): nn.SpatialBatchNormalization
             (3): nn.ReLU
           }
       ... -> output
  }
  (6): nn.Inception @ nn.DepthConcat {
    input
      |`-> (1): nn.Sequential {
      |      [input -> (1) -> (2) -> (3) -> (4) -> output]
      |      (1): nn.SpatialConvolution(256 -> 96, 1x1)
      |      (2): nn.ReLU
      |      (3): nn.SpatialConvolution(96 -> 128, 3x3, 1,1, 1,1)
      |      (4): nn.ReLU
      |    }
      |`-> (2): nn.Sequential {
      |      [input -> (1) -> (2) -> (3) -> (4) -> output]
      |      (1): nn.SpatialConvolution(256 -> 32, 1x1)
      |      (2): nn.ReLU
      |      (3): nn.SpatialConvolution(32 -> 64, 5x5, 1,1, 2,2)
      |      (4): nn.ReLU
      |    }
      |`-> (3): nn.Sequential {
      |      [input -> (1) -> (2) -> (3) -> output]
      |      (1): nn.Sequential {
      |        [input -> (1) -> (2) -> (3) -> (4) -> output]
      |        (1): nn.Square
      |        (2): nn.SpatialAveragePooling(3x3, 1,1)
      |        (3): nn.MulConstant
      |        (4): nn.Sqrt
      |      }
      |      (2): nn.SpatialConvolution(256 -> 64, 1x1)
      |      (3): nn.ReLU
      |    }
      |`-> (4): nn.Sequential {
             [input -> (1) -> (2) -> output]
             (1): nn.SpatialConvolution(256 -> 64, 1x1)
             (2): nn.ReLU
           }
       ... -> output
  }
  (7): nn.SpatialAveragePooling(7x7, 1,1)
  (8): nn.View(320)
  (9): nn.Linear(320 -> 128)
  (10): nn.Normalize(2)
}
2	nn.SpatialConvolutionMM(3 -> 64, 7x7, 2,2, 3,3)
3	nn.SpatialBatchNormalization
4	nn.ReLU
5	nn.SpatialMaxPooling(3x3, 2,2, 1,1)
6	nn.Inception @ nn.DepthConcat {
  input
    |`-> (1): nn.Sequential {
    |      [input -> (1) -> (2) -> (3) -> (4) -> (5) -> (6) -> output]
    |      (1): nn.SpatialConvolution(192 -> 96, 1x1)
    |      (2): nn.SpatialBatchNormalization
    |      (3): nn.ReLU
    |      (4): nn.SpatialConvolution(96 -> 128, 3x3, 1,1, 1,1)
    |      (5): nn.SpatialBatchNormalization
    |      (6): nn.ReLU
    |    }
    |`-> (2): nn.Sequential {
    |      [input -> (1) -> (2) -> (3) -> (4) -> (5) -> (6) -> output]
    |      (1): nn.SpatialConvolution(192 -> 16, 1x1)
    |      (2): nn.SpatialBatchNormalization
    |      (3): nn.ReLU
    |      (4): nn.SpatialConvolution(16 -> 32, 5x5, 1,1, 2,2)
    |      (5): nn.SpatialBatchNormalization
    |      (6): nn.ReLU
    |    }
    |`-> (3): nn.Sequential {
    |      [input -> (1) -> (2) -> (3) -> (4) -> output]
    |      (1): nn.SpatialMaxPooling(3x3, 1,1, 1,1)
    |      (2): nn.SpatialConvolution(192 -> 32, 1x1)
    |      (3): nn.SpatialBatchNormalization
    |      (4): nn.ReLU
    |    }
    |`-> (4): nn.Sequential {
           [input -> (1) -> (2) -> (3) -> output]
           (1): nn.SpatialConvolution(192 -> 64, 1x1)
           (2): nn.SpatialBatchNormalization
           (3): nn.ReLU
         }
     ... -> output
}
7	nn.DepthConcat {
  input
    |`-> (1): nn.Sequential {
    |      [input -> (1) -> (2) -> (3) -> (4) -> (5) -> (6) -> output]
    |      (1): nn.SpatialConvolution(192 -> 96, 1x1)
    |      (2): nn.SpatialBatchNormalization
    |      (3): nn.ReLU
    |      (4): nn.SpatialConvolution(96 -> 128, 3x3, 1,1, 1,1)
    |      (5): nn.SpatialBatchNormalization
    |      (6): nn.ReLU
    |    }
    |`-> (2): nn.Sequential {
    |      [input -> (1) -> (2) -> (3) -> (4) -> (5) -> (6) -> output]
    |      (1): nn.SpatialConvolution(192 -> 16, 1x1)
    |      (2): nn.SpatialBatchNormalization
    |      (3): nn.ReLU
    |      (4): nn.SpatialConvolution(16 -> 32, 5x5, 1,1, 2,2)
    |      (5): nn.SpatialBatchNormalization
    |      (6): nn.ReLU
    |    }
    |`-> (3): nn.Sequential {
    |      [input -> (1) -> (2) -> (3) -> (4) -> output]
    |      (1): nn.SpatialMaxPooling(3x3, 1,1, 1,1)
    |      (2): nn.SpatialConvolution(192 -> 32, 1x1)
    |      (3): nn.SpatialBatchNormalization
    |      (4): nn.ReLU
    |    }
    |`-> (4): nn.Sequential {
           [input -> (1) -> (2) -> (3) -> output]
           (1): nn.SpatialConvolution(192 -> 64, 1x1)
           (2): nn.SpatialBatchNormalization
           (3): nn.ReLU
         }
     ... -> output
}
8	nn.Sequential {
  [input -> (1) -> (2) -> (3) -> (4) -> (5) -> (6) -> output]
  (1): nn.SpatialConvolution(192 -> 96, 1x1)
  (2): nn.SpatialBatchNormalization
  (3): nn.ReLU
  (4): nn.SpatialConvolution(96 -> 128, 3x3, 1,1, 1,1)
  (5): nn.SpatialBatchNormalization
  (6): nn.ReLU
}
9	nn.SpatialConvolution(192 -> 96, 1x1)
10	nn.SpatialBatchNormalization
11	nn.ReLU
12	nn.SpatialConvolution(96 -> 128, 3x3, 1,1, 1,1)
13	nn.SpatialBatchNormalization
14	nn.ReLU
15	nn.Sequential {
  [input -> (1) -> (2) -> (3) -> (4) -> (5) -> (6) -> output]
  (1): nn.SpatialConvolution(192 -> 16, 1x1)
  (2): nn.SpatialBatchNormalization
  (3): nn.ReLU
  (4): nn.SpatialConvolution(16 -> 32, 5x5, 1,1, 2,2)
  (5): nn.SpatialBatchNormalization
  (6): nn.ReLU
}
16	nn.SpatialConvolution(192 -> 16, 1x1)
17	nn.SpatialBatchNormalization
18	nn.ReLU
19	nn.SpatialConvolution(16 -> 32, 5x5, 1,1, 2,2)
20	nn.SpatialBatchNormalization
21	nn.ReLU
22	nn.Sequential {
  [input -> (1) -> (2) -> (3) -> (4) -> output]
  (1): nn.SpatialMaxPooling(3x3, 1,1, 1,1)
  (2): nn.SpatialConvolution(192 -> 32, 1x1)
  (3): nn.SpatialBatchNormalization
  (4): nn.ReLU
}
23	nn.SpatialMaxPooling(3x3, 1,1, 1,1)
24	nn.SpatialConvolution(192 -> 32, 1x1)
25	nn.SpatialBatchNormalization
26	nn.ReLU
27	nn.Sequential {
  [input -> (1) -> (2) -> (3) -> output]
  (1): nn.SpatialConvolution(192 -> 64, 1x1)
  (2): nn.SpatialBatchNormalization
  (3): nn.ReLU
}
28	nn.SpatialConvolution(192 -> 64, 1x1)
29	nn.SpatialBatchNormalization
30	nn.ReLU
31	nn.Inception @ nn.DepthConcat {
  input
    |`-> (1): nn.Sequential {
    |      [input -> (1) -> (2) -> (3) -> (4) -> output]
    |      (1): nn.SpatialConvolution(256 -> 96, 1x1)
    |      (2): nn.ReLU
    |      (3): nn.SpatialConvolution(96 -> 128, 3x3, 1,1, 1,1)
    |      (4): nn.ReLU
    |    }
    |`-> (2): nn.Sequential {
    |      [input -> (1) -> (2) -> (3) -> (4) -> output]
    |      (1): nn.SpatialConvolution(256 -> 32, 1x1)
    |      (2): nn.ReLU
    |      (3): nn.SpatialConvolution(32 -> 64, 5x5, 1,1, 2,2)
    |      (4): nn.ReLU
    |    }
    |`-> (3): nn.Sequential {
    |      [input -> (1) -> (2) -> (3) -> output]
    |      (1): nn.Sequential {
    |        [input -> (1) -> (2) -> (3) -> (4) -> output]
    |        (1): nn.Square
    |        (2): nn.SpatialAveragePooling(3x3, 1,1)
    |        (3): nn.MulConstant
    |        (4): nn.Sqrt
    |      }
    |      (2): nn.SpatialConvolution(256 -> 64, 1x1)
    |      (3): nn.ReLU
    |    }
    |`-> (4): nn.Sequential {
           [input -> (1) -> (2) -> output]
           (1): nn.SpatialConvolution(256 -> 64, 1x1)
           (2): nn.ReLU
         }
     ... -> output
}
32	nn.DepthConcat {
  input
    |`-> (1): nn.Sequential {
    |      [input -> (1) -> (2) -> (3) -> (4) -> output]
    |      (1): nn.SpatialConvolution(256 -> 96, 1x1)
    |      (2): nn.ReLU
    |      (3): nn.SpatialConvolution(96 -> 128, 3x3, 1,1, 1,1)
    |      (4): nn.ReLU
    |    }
    |`-> (2): nn.Sequential {
    |      [input -> (1) -> (2) -> (3) -> (4) -> output]
    |      (1): nn.SpatialConvolution(256 -> 32, 1x1)
    |      (2): nn.ReLU
    |      (3): nn.SpatialConvolution(32 -> 64, 5x5, 1,1, 2,2)
    |      (4): nn.ReLU
    |    }
    |`-> (3): nn.Sequential {
    |      [input -> (1) -> (2) -> (3) -> output]
    |      (1): nn.Sequential {
    |        [input -> (1) -> (2) -> (3) -> (4) -> output]
    |        (1): nn.Square
    |        (2): nn.SpatialAveragePooling(3x3, 1,1)
    |        (3): nn.MulConstant
    |        (4): nn.Sqrt
    |      }
    |      (2): nn.SpatialConvolution(256 -> 64, 1x1)
    |      (3): nn.ReLU
    |    }
    |`-> (4): nn.Sequential {
           [input -> (1) -> (2) -> output]
           (1): nn.SpatialConvolution(256 -> 64, 1x1)
           (2): nn.ReLU
         }
     ... -> output
}
33	nn.Sequential {
  [input -> (1) -> (2) -> (3) -> (4) -> output]
  (1): nn.SpatialConvolution(256 -> 96, 1x1)
  (2): nn.ReLU
  (3): nn.SpatialConvolution(96 -> 128, 3x3, 1,1, 1,1)
  (4): nn.ReLU
}
34	nn.SpatialConvolution(256 -> 96, 1x1)
35	nn.ReLU
36	nn.SpatialConvolution(96 -> 128, 3x3, 1,1, 1,1)
37	nn.ReLU
38	nn.Sequential {
  [input -> (1) -> (2) -> (3) -> (4) -> output]
  (1): nn.SpatialConvolution(256 -> 32, 1x1)
  (2): nn.ReLU
  (3): nn.SpatialConvolution(32 -> 64, 5x5, 1,1, 2,2)
  (4): nn.ReLU
}
39	nn.SpatialConvolution(256 -> 32, 1x1)
40	nn.ReLU
41	nn.SpatialConvolution(32 -> 64, 5x5, 1,1, 2,2)
42	nn.ReLU
43	nn.Sequential {
  [input -> (1) -> (2) -> (3) -> output]
  (1): nn.Sequential {
    [input -> (1) -> (2) -> (3) -> (4) -> output]
    (1): nn.Square
    (2): nn.SpatialAveragePooling(3x3, 1,1)
    (3): nn.MulConstant
    (4): nn.Sqrt
  }
  (2): nn.SpatialConvolution(256 -> 64, 1x1)
  (3): nn.ReLU
}
44	nn.Sequential {
  [input -> (1) -> (2) -> (3) -> (4) -> output]
  (1): nn.Square
  (2): nn.SpatialAveragePooling(3x3, 1,1)
  (3): nn.MulConstant
  (4): nn.Sqrt
}
45	nn.Square
46	nn.SpatialAveragePooling(3x3, 1,1)
47	nn.MulConstant
48	nn.Sqrt
49	nn.SpatialConvolution(256 -> 64, 1x1)
50	nn.ReLU
51	nn.Sequential {
  [input -> (1) -> (2) -> output]
  (1): nn.SpatialConvolution(256 -> 64, 1x1)
  (2): nn.ReLU
}
52	nn.SpatialConvolution(256 -> 64, 1x1)
53	nn.ReLU
54	nn.SpatialAveragePooling(7x7, 1,1)
55	nn.View(320)
56	nn.Linear(320 -> 128)
57	nn.Normalize(2)

由上述结果可以看出,使用apply后,第1次输出整个模型,此处为最顶层的。

第2-5次输出:

2       nn.SpatialConvolutionMM(3 -> 64, 7x7, 2,2, 3,3)

3       nn.SpatialBatchNormalization

4       nn.ReLU

5       nn.SpatialMaxPooling(3x3, 2,2, 1,1)

为Inception之前的几个层。

第6次为nn.Inception @ nn.DepthConcat,第7次为nn.DepthConcat。此处是第一个Inceptioin层。

第8次为Inception的第一个nn.Sequential,第9-14次为该层的具体层。此时已经到了第一个最底层。

第15次为Inception的第二个nn.Sequential,第16-21次为该层的具体层。此时已经到了第二个最底层。

第22次为Inception的第三个nn.Sequential,第23-26次为该层的具体层。此时已经到了第三个最底层。

第27次为Inception的第四个nn.Sequential,第28-30次为该层的具体层。此时已经到了第四个最底层。

至此,第一个Inception层通过深度优先的方式遍历完毕。

第31次为nn.Inception @ nn.DepthConcat,第32次为nn.DepthConcat。此处是第二个Inceptioin层(注意,为了区分第一个Inception和第二个Inception层,这两个层具体结构不完全一样)。

第33次为Inception的第一个nn.Sequential,第34-37次为该层的具体层。此时已经到了第一个最底层。

第38次为Inception的第二个nn.Sequential,第39-42次为该层的具体层。此时已经到了第二个最底层。

第43次为Inception的第三个nn.Sequential。

第44次为第三个nn.Sequential的第一个小module(也是一个nn.Sequential)。第45-48依次遍历此nn.Sequential。到了最底层后遍历完毕。

第49-50为第三个nn.Sequential的最后两层。

第51次为Inception的第四个nn.Sequential,第52-53次为该层的具体层。此时已经到了第四个最底层。

至此,第二个Inception层通过深度优先的方式遍历完毕。

第54-57为最后的两个层。

由上面可以看出,apply采用的是深度优先的方式进行遍历。

时间: 2024-10-11 21:55:05

(原)torch的apply函数的相关文章

R语言中apply函数

前言 刚开始接触R语言时,会听到各种的R语言使用技巧,其中最重要的一条就是不要用循环,效率特别低,要用向量计算代替循环计算. 那么,这是为什么呢?原因在于R的循环操作for和while,都是基于R语言本身来实现的,而向量操作是基于底层的C语言函数实现的,从性能上来看,就会有比较明显的差距了.那么如何使用C的函数来实现向量计算呢,就是要用到apply的家族函数,包括apply, sapply, tapply, mapply, lapply, rapply, vapply, eapply等. 目录

NS前缀\OC中的注释\访问OC原文件、C原文件中的函数

///////////////////////////////////////// //////////////////////////////////////// NS前缀 NS来自于NeXTStep的一个软件 NeXT Software OC中不支持命名空间(namespace) NS是为了避免命名冲突而给的前缀 看到NS前缀就知道是Cocoa中的系统类的名称 "@"的使用方法 1.@""这个符号表示将C中的字符串转化为OC中的字符串对象 2.@符号 OC中的大

call()函数、apply()函数区别与意义

使用apply函数或call函数的意义: 在面对对象编程过程中,当A对象调用其他对象而非A对象方法是,该方法中所有的this引用都指向此方法所在的对象,而不是当前代码的上下文即A对象, 为了保持this的原来的指向(即A对象),则需要使用apply或call函数. apply()和call()的区别: apply和call,它们的作用都是将函数绑定到另外一个对象上去运行 原型分别是 Function.prototype.apply(thisArg,argArray); Function.prot

JavaScript中bind、call、apply函数用法详解

在给我们项目组的其他程序介绍 js 的时候,我准备了很多的内容,但看起来效果不大,果然光讲还是不行的,必须动手.前几天有人问我关于代码里 call() 函数的用法,我让他去看书,这里推荐用js 写服务器的程序猿看<javascript编程精粹> 这本书,crockford大神果然不是盖的.之后我在segmentfault上又看到了类似的问题,那边解答之后干脆这里记一笔. 首先,关于 js 定义类或对象的方法,请参看w3school 的这里的这里,写的非常详细和清晰,我不再赘言了. 为了介绍 b

Javascript中bind、call、apply函数用法

js 里函数调用有 4 种模式:方法调用.正常函数调用.构造器函数调用.apply/call 调用. 同时,无论哪种函数调用除了你声明时定义的形参外,还会自动添加 2 个形参,分别是 this 和arguments. arguments 不涉及到上述 3 个函数,所以这里只谈 this.this 的值,在上面 4 中调用模式下,分别会绑定不同的值.分别来说一说: 方法调用: 这个很好理解,函数是一个对象的属性,比如 var a = { v : 0, f : function(xx) { this

js中bind、call、apply函数的用法

最近一直在用 js 写游戏服务器,我也接触 js 时间不长,大学的时候用 js 做过一个 H3C 的 web 的项目,然后在腾讯实习的时候用 js 写过一些奇怪的程序,自己也用 js 写过几个的网站.但真正大规模的使用 js 这还是第一次.我也是初生牛犊不怕虎,这次服务器居然抛弃 C++ 和 lua 的正统搭配,而尝试用 nodejs 来写游戏服务器,折腾的自己要死要活的我也是醉了. 在给我们项目组的其他程序介绍 js 的时候,我准备了很多的内容,但看起来效果不大,果然光讲还是不行的,必须动手.

bind、call、apply函数的用法

js 里函数调用有 4 种模式:方法调用.正常函数调用.构造器函数调用.apply/call 调用.同时,无论哪种函数调用除了你声明时定义的形参外,还会自动添加 2 个形参,分别是 this 和arguments.arguments 不涉及到上述 3 个函数,所以这里只谈 this.this 的值,在上面 4 中调用模式下,分别会绑定不同的值.分别来说一说:方法调用:这个很好理解,函数是一个对象的属性,比如 var a = { v : 0, f : function(xx) { this.v =

Javascript中call函数和apply函数的使用

Javascript 中call函数和apply的使用: Javascript中的call函数和apply函数是对执行上下文进行切换,是将一个函数从当前执行的上下文切换到另一个对象中执行,例如: sourceObj.method.call(destObj,params1,params2) 是将sourceObj中的method函数放在destObj中执行 call函数还有另外一种重要的作用,在Javascript面向对象编程中实现多继承的作用,例如: function parentClass()

pandas中agg()函数和apply()函数的区别

如果对自定义top_n的调用采用agg函数的话,那么报出的错误将是 说明了一个问题,使用agg函数调用top_n的话,它在尝试对每一个分组使用top_n进行聚合,但是top_n的作用是排序,不是聚合,所以肯定会报错 所以在这种情况下,只能采用apply函数,而不能采用agg函数,agg函数内调用的函数只能对分组进行聚合使用. 新手入门,个人理解,如有错误,希望谅解