您的位置:首页 > 理论基础 > 计算机网络

Torch7入门续集(四)----利用Table layers构建灵活的网络

2017-03-17 09:57 609 查看

总说

先附加几个有用的。

replace(function)

这个可以是将function应用到net中每一层上。比如,我们可以将model中的
nn.Dropout
替换成
nn.Identity()
,显然传入的参数
module
随便写成什么变量,都指某一层。

model:replace(function(module)
if torch.typename(module) == 'nn.Dropout' then
return nn.Identity()
else
return module
end
end)


apply(function)

这个和上面的类似,也是对每一层进行操作。

local function weights_init(m)
local name = torch.type(m)
if name:find('Convolution') then
m.weight:normal(0.0, 0.02)
m.bias:fill(0)
elseif name:find('BatchNormalization') then
if m.weight then m.weight:normal(1.0, 0.02) end
if m.bias then m.bias:fill(0) end
end
end

-- define net
...
net:apply(weights_init)  --这样就把net的每一层自定义初始化参数了


remove和insert

有时候我们想直接移除某一层,或是中间添加一层。

model = nn.Sequential()
model:add(nn.Linear(10, 20))
model:add(nn.Linear(20, 20))
model:add(nn.Linear(20, 30))

-- 直接写移除的层的index即可
model:remove(2)
> model
nn.Sequential {
[input -> (1) -> (2) -> output]
(1): nn.Linear(10 -> 20)
(2): nn.Linear(20 -> 30)
}


对于insert,

model = nn.Sequential()
model:add(nn.Linear(10, 20))
model:add(nn.Linear(20, 30))
-- 希望插入的Linear(20,20)在model中的第二层
model:insert(nn.Linear(20, 20), 2)
> model
nn.Sequential {
[input -> (1) -> (2) -> (3) -> output]
(1): nn.Linear(10 -> 20)
(2): nn.Linear(20 -> 20)      -- The inserted layer
(3): nn.Linear(20 -> 30)
}


training()和evaluate()

对于Dropout和BN之类的层,训练和测试的操作不一样。

这时候可以用

model:training()
或是
model:evaluate()
进行。

apply
函数类似上面的
replace
函数。

下面是training()的实现方式。

model:apply(function(module)
module.train = true
end)


convolution

一般来说用的最多的还是SpatialConvolution和反卷积SpatialFullConvolution. 当然你可能会加点
SpatialBatchNormalization
之类的。

我们也可以用convolution的方式来单独padding。分为
0 padding
,’反射 padding’以及和
复制 padding
.

module = nn.SpatialZeroPadding(padLeft, padRight, padTop, padBottom)


module = nn.SpatialReflectionPadding(padLeft, padRight, padTop, padBottom)


module = nn.SpatialReplicationPadding(padLeft, padRight, padTop, padBottom)


对于这3种中的任意一种,我们可以直接通过pad的值为负数,从而实现裁剪的功能。

比如

module = nn.SpatialZeroPadding(-1,0,-1,0)
就是左边和上面分别裁去一个像素。

Table Layers

正因为由table layers才能使得Torch能够构建非常灵活强大的网络。

ConcatTable与ParrelTable

对于ConcatTable就是,将一个输入喂入每一个成员里,每个成员接收到的内容都是一样的。相当于复制了n份。

+-----------+
+----> {member1, |
+-------+    |    |           |
| input +----+---->  member2, |
+-------+    |    |           |
or        +---->  member3} |
{input}          +-----------+


mlp = nn.ConcatTable()
-- 可以看到下面的nn.Linear都是接受5个维度的输入,因为
-- 两个member都接受相同的一个输入。
mlp:add(nn.Linear(5, 2))
mlp:add(nn.Linear(5, 3))

pred = mlp:forward(torch.randn(5))
for i, k in ipairs(pred) do print(i, k) end
-- 可以看到
1
-0.4073
0.0110
[torch.Tensor of dimension 2]

2
0.0027
-0.0598
-0.1189
[torch.Tensor of dimension 3]


对应的是ParallelTable,它是输入是几份,就要有几个成员,是按顺序一一对应的!而ConcatTable是输入是一份,但是成员是n个,输入是”复制成n份“,然后给每个成员一份的。

+----------+         +-----------+
| {input1, +---------> {member1, |
|          |         |           |
|  input2, +--------->  member2, |
|          |         |           |
|  input3} +--------->  member3} |
+----------+         +-----------+


mlp = nn.ParallelTable()
-- 可以看到,ParallelTable中,每个input是独立的。
-- 每个memberi接受对应的输入inputi
mlp:add(nn.Linear(10, 2))
mlp:add(nn.Linear(5, 3))

x = torch.randn(10)
y = torch.rand(5)

-- parallelTable后面添加了2个member,因此输入也是2个。用table的形式输入{x,y}
pred = mlp:forward{x, y}
for i, k in pairs(pred) do print(i, k) end

1
0.0331
0.7003
[torch.Tensor of dimension 2]

2
0.0677
-0.1657
-0.7383
[torch.Tensor of dimension 3]


JoinTable

这个主要是将多个输出联合起来,那自然就要指定联合的维度。

module = JoinTable(dimension, nInputDims)


第一个参数是在第几个维度上联合,第二个参数表示每个输入的维度大小

值得注意的是,联合起来的table必须在除了第dimension的维度之外,其他维度必须相同!这个,显然的。否则就乱套了。

x = torch.randn(5, 1)
y = torch.randn(5, 1)
z = torch.randn(2, 1)

print(nn.JoinTable(1):forward{x, y})
print(nn.JoinTable(2):forward{x, y})
print(nn.JoinTable(1):forward{x, z})

1.3965
0.5146
-1.5244
-0.9540
0.4256
0.1575
0.4491
0.6580
0.1784
-1.7362
[torch.DoubleTensor of dimension 10x1]

1.3965  0.1575
0.5146  0.4491
-1.5244  0.6580
-0.9540  0.1784
0.4256 -1.7362
[torch.DoubleTensor of dimension 5x2]

-- x,z 在第一个维度上联合,其余维度是相同的。
1.3965
0.5146
-1.5244
-0.9540
0.4256
-1.2660
1.0869
[torch.Tensor of dimension 7x1]


常用的应该就是这3个,当然还有其他很多。

table和tensor之间相互转换的除了JoinTable。还有
SplitTable
等。

每个输入的相似性度量

CosineDistance

这个属于module之间相互计算测量值的一种层。

mlp = nn.CosineDistance()
x = torch.Tensor({{1,2,3},{1,2,-3}})
y = torch.Tensor({{4,5,6},{-4,5,6}})
print(mlp:forward({x,y}))

-- {1 2 3}与{4 5 6}
-- {1 2 -3}与{-4 5 6}
0.9746
-0.3655
[torch.DoubleTensor of size 2]


这个和Simple Layers的Cosine的用法还是有很大区别的。

类似的还有
PairewiseDistance
DotProduct
.

每个输入进行element-wise 操作

就是加减乘除以及最大最小,6种运算。

比如CAddTable,…, CDivTable(),以及CMaxTable和CMinTable。

-- 显然两个操作的输入的维度要相同。
m = nn.CDivTable()
a = torch.randn(4,5):mul(4):floor()
b = torch.Tensor(a:size()):fill(2)

th> a
1  2 -6  0  1
5  0 -2  8 -8
-1 -1  4  9  7
-7 -5 -4  0  5
[torch.DoubleTensor of size 4x5]

>th m:forward({a,b})
0.5000  1.0000 -3.0000  0.0000  0.5000
2.5000  0.0000 -1.0000  4.0000 -4.0000
-0.5000 -0.5000  2.0000  4.5000  3.5000
-3.5000 -2.5000 -2.0000  0.0000  2.5000
[torch.DoubleTensor of size 4x5]


CriterionTable

mlp = nn.CriterionTable(nn.MSECriterion())
x = torch.randn(5)
y = torch.randn(5)
print(mlp:forward{x, x})
print(mlp:forward{x, y})

0
1.9028918413199
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: