-
Notifications
You must be signed in to change notification settings - Fork 1
/
SlowSpatialConvolution.lua
102 lines (68 loc) · 3.02 KB
/
SlowSpatialConvolution.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
require 'slowspatialconvolution'
local SlowSpatialConvolution, parent = torch.class('nn.SlowSpatialConvolution', 'nn.Module')
function SlowSpatialConvolution:__init(nInputPlane, nOutputPlane, kW, kH)
parent.__init(self)
self.nInputPlane = nInputPlane
self.nOutputPlane = nOutputPlane
self.kW = kW
self.kH = kH
self.weight = torch.Tensor(nOutputPlane, nInputPlane, kH, kW)
self.bias = torch.Tensor(nOutputPlane)
self.gradWeight = torch.Tensor(nOutputPlane, nInputPlane, kH, kW)
self.gradBias = torch.Tensor(nOutputPlane)
end
function SlowSpatialConvolution:updateOutput(input)
local wOutputImage = input:size(3)-self.kW+1
local hOutputImage = input:size(2)-self.kH+1
self.output = torch.Tensor(self.nOutputPlane, hOutputImage, wOutputImage)
unfoldedInput = slowspatialconvolution.im2col(input,self.kH,self.kW)
self.output = torch.mm(
self.weight:view(self.nOutputPlane,self.nInputPlane*self.kW*self.kH)
,unfoldedInput
):view(self.nOutputPlane,hOutputImage, wOutputImage)
for c2 = 1, self.nOutputPlane do
self.output[c2]:add(self.bias[c2])
end
return self.output
end
function SlowSpatialConvolution:updateGradInput(input,gradOutput)
self.gradInput = torch.Tensor(input:size()):zero()
weightRotated = slowspatialconvolution.rotate(self.weight)
fgradOutput = slowspatialconvolution.frame(gradOutput,self.kH-1,self.kW-1)
for c1star = 1, self.nInputPlane do
for c2 = 1, self.nOutputPlane do
self.gradInput[c1star]:add(torch.mm(
weightRotated[c2][c1star]:view(1,self.kW*self.kH)
,slowspatialconvolution.im2col(
fgradOutput[c2]:view(1,fgradOutput:size(2),fgradOutput:size(3))
,self.kH
,self.kW)
):view(input:size(2),input:size(3)))
end
end
--print(gradOutput)
return self.gradInput
end
function SlowSpatialConvolution:accGradParameters(input,gradOutput, scale)
scale = scale or 1
local gradBias = torch.Tensor(self.gradBias:size()):zero()
local gradWeight = torch.Tensor(self.gradWeight:size()):zero()
ones = torch.Tensor(gradOutput:size(2),gradOutput:size(3)):fill(1)
for i = 1, self.nOutputPlane do
gradBias[i] = gradBias[i] + gradOutput[i]:dot(ones)
end
for c1star = 1, self.nInputPlane do
for c2star = 1, self.nOutputPlane do
gradWeight[c2star][c1star]:add(torch.mm(
gradOutput[c2star]:view(1,gradOutput:size(2)*gradOutput:size(3))
,slowspatialconvolution.im2col(
input[c1star]:view(1,input:size(2),input:size(3))
,gradOutput:size(2)
,gradOutput:size(3))
):view(self.kH,self.kW))
end
end
self.gradBias:add(scale * gradBias)
self.gradWeight:add(scale * gradWeight)
--print(gradOutput)
end