总说
先看一段代码,一般来说传入VGG的数据要先经过预处理,无非是先将BGR变成RGB,然后减去整个训练集的平均RGB值。写的最精简的可能是下面这样写。
function preprocess(img)
local mean_pixel = torch.FloatTensor({
103.939, 116.779, 123.68}):type(img:type())
local perm = torch.LongTensor{
3, 2, 1}
img = img:index(1, perm):mul(255.0)
mean_pixel = mean_pixel:view(3, 1, 1):expandAs(img)
img:add(-1, mean_pixel)
return img
end
然而。。请看下面的这种写法:
function getPreprocessConv()
local mean_pixel = torch.Tensor({
103.939, 116.779, 123.68})
local conv = nn.SpatialConvolution(3,3, 1,1)
conv.weight:zero()
conv.weight[{
1,3}] = 255
conv.weight[{
2,2}] = 255
conv.weight[{
3,1}] = 255
conv.bias = -mean_pixel
conv.gradBias = nil
conv.gradWeight = nil
conv.parameters = function() --[[nop]] end
conv.accGradParameters = function() --[[nop]] end
return conv
end
没错,直接用内置的卷积层进行操作!这启发我们一件事情:很多常见操作,我们都可以用内置的已有的各种层进行!而不是自己单独写,这就相当于nn层式编码!。。自创的词,大概知道就行。
Simple Layers就是一些常见的层操作,利用这些函数可以便捷的在某层后面加入各种操作层,这些操作层可以直接进行反向传播。
Simple Layers主要分为4个部分:
带参的Module—-> 基本Tensor变换——->数学Tensor运算——>其他Module
前面两篇写的就是Tensor和Math的,而在这里第二三正是利用这些简单层来替代Tensor变换和Math操作。
Parameterized Modules
- Linear
- Bilinear
- Dropout
- Abs
- Add
- CAdd
- Mul
- CMul
- Euclidean
- WeightedEuclidean
- Cosine
从名字就可以大概看出这些层的作用,比如Linear就是全连接层。Bilinear就是进行双线性插值。
Dropout
module= nn.Dropout(p)
训练前向:使得输入每个值按照p的概率丢弃,即使得该位置的值为0。同时输出大小的值被放大1/(1-p)
,主要是用来进行正规化的。
训练反向:被前向丢弃的位置仍旧为0,gradOutput
和input
都被放大1/(1-p)
倍。