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
|
local MSELayer = nerv.class("nerv.MSELayer", "nerv.Layer")
function MSELayer:__init(id, global_conf, layer_conf)
nerv.Layer.__init(self, id, global_conf, layer_conf)
self:check_dim_len(2, -1)
end
function MSELayer:bind_params()
-- do nothing
end
function MSELayer:init(batch_size, chunk_size)
if self.dim_in[1] ~= self.dim_in[2] then
nerv.error("mismatching dimensions of previous network output and labels")
end
self.scale = 1.0 / self.dim_in[1]
self.total_mse = 0.0
self.total_frames = 0
self.mse = self.mat_type(batch_size, self.dim_in[1])
self.mse_sum = self.mat_type(batch_size, 1)
self.diff = {}
for t = 1, chunk_size do
self.diff[t] = self.mse:create()
end
end
function MSELayer:batch_resize(batch_size)
if self.mse:nrow() ~= batch_resize then
self.mse = self.mat_type(batch_size, self.dim_in[1])
self.mse_sum = self.mat_type(batch_size, 1)
for t = 1, chunk_size do
self.diff[t] = self.mse:create()
end
end
end
function MSELayer:update(bp_err, input, output)
-- no params, therefore do nothing
end
function MSELayer:propagate(input, output, t)
if t == nil then
t = 1
end
local mse = self.mse
local mse_sum = self.mse_sum
local diff = self.diff[t]
mse:add(input[1], input[2], 1.0, -1.0)
mse:set_values_by_mask(self.gconf.mask[t], 0)
diff:copy_from(mse)
mse:mul_elem(mse, mse)
mse_sum:add(mse_sum, mse:rowsum(), 0.0, self.scale * 0.5)
if output[1] ~= nil then
output[1]:copy_from(mse_sum)
end
self.total_mse = self.total_mse + mse_sum:colsum()[0][0]
self.total_frames = self.total_frames + self.gconf.mask[t]:colsum()[0][0]
end
-- NOTE: must call propagate before back_propagate
function MSELayer:back_propagate(bp_err, next_bp_err, input, output, t)
if t == nil then
t = 1
end
local nbe = next_bp_err[1]
local nbe2 = next_bp_err[2]
nbe:add(nbe, self.diff[t], 0.0, self.scale)
nbe2:add(nbe2, self.diff[t], 0.0, -self.scale)
if bp_err[1] ~= nil then
nbe:scale_rows_by_col(bp_err[1])
nbe2:scale_rows_by_col(bp_err[1])
end
end
function MSELayer:get_params()
return nerv.ParamRepo({}, self.loc_type)
end
|