forked from jcjohnson/torch-rnn
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathHistory.lua
73 lines (60 loc) · 1.66 KB
/
History.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
require 'torch'
require 'nn'
local layer, parent = torch.class('nn.History', 'nn.Module')
function layer:__init(history_depth)
parent.__init(self)
self.history_depth = history_depth
self.gradInput = torch.Tensor()
self.prevInputs = torch.Tensor()
end
function layer:updateOutput(input)
local N, T, ID = input:size(1), input:size(2), input:size(3)
local HD = self.history_depth
local output, prev = self.output, self.prevInputs
if prev:nElement() == 0 then
prev:resize(N, HD, ID):zero()
else
assert(self.prevInputs:size(1) == N, 'batch size changed')
end
output:resize(N, T, ID*(HD+1))
prev:resize(N, HD, ID)
for i = 0, HD do
if i < T then
output[{{}, {1+i, T}, {i*ID+1, (i+1)*ID}}]:copy(input[{{}, {1, T-i}}])
end
if i > 0 then
local e = 0
if T < i then e = i - T end
output[{{}, {1, i-e}, {i*ID+1, (i+1)*ID}}]:copy(prev[{{}, {-i, HD-e}}])
end
end
if HD > 0 then
if HD <= T then
prev:copy(input[{{}, {-HD, T}}])
else
for i = 1, HD-T do
prev[{{}, {i,i}}]:copy(prev[{{}, {i+1, i+1}}])
end
prev[{{}, {-T, -1}}]:copy(input)
end
end
return output
end
function layer:updateGradInput(input, gradOutput)
local N, T, ID = input:size(1), input:size(2), input:size(3)
local HD = self.history_depth
local gradInput = self.gradInput
gradInput:resizeAs(input)
gradInput:copy(gradOutput[{{}, {}, {1, ID}}])
for i = 1, HD do
if i < T then
gradInput[{{}, {1, T-i}}]:add(gradOutput[{{}, {1+i, T}, {i*ID+1, (i+1)*ID}}])
end
end
return gradOutput
end
function layer:clearState()
self.gradInput:set()
self.prevInputs:set()
self.output:set()
end