From db06c97789bb759a8017a793a7dd629481a87cb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=20van=20Merri=C3=ABnboer?= Date: Fri, 27 May 2016 16:26:55 -0400 Subject: [PATCH 1/2] Fix zero gradient for subtensor assignment. The variable that is being assigned has its gradient correctly calculated (g[k]) but later on when the gradient of the variable being assigned to is calculated g[k] is set to 0. This gives the correct gradient for the variable being assigned to, but because it shares the same storage it actually overrides the earlier gradient incorrectly to zero. This fixes that. --- src/gradfuns.lua | 7 ++++++- test/test.lua | 5 +++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/gradfuns.lua b/src/gradfuns.lua index 80fade1..24306e7 100644 --- a/src/gradfuns.lua +++ b/src/gradfuns.lua @@ -152,7 +152,12 @@ functions.set = { return nil end, function(g, ans, x, k, v) - return g[k] + local gk = getValue(g[k]) + if type(gk) == 'number' then + return gk + else + return torch.clone(gk) + end end, } diff --git a/test/test.lua b/test/test.lua index 9bdaad3..5adc28f 100644 --- a/test/test.lua +++ b/test/test.lua @@ -1687,6 +1687,11 @@ local tests = { return torch.sum(xc) end tester:assert(gradcheck(f4,{x=torch.randn(10,10),y=torch.randn(3)}), "Incorrect gradient") + local f5 = function(params) + params.x[2] = params.y*2.0 + return torch.sum(params.x) + end + tester:assert(gradcheck(f5,{x=torch.randn(10,10),y=torch.randn(10)}), "Incorrect gradient") end, ScalarSigmoid = function() From 1fa109ab53cbed20e986f6514d72caf1adc30a15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=20van=20Merri=C3=ABnboer?= Date: Wed, 13 Jul 2016 13:08:48 -0400 Subject: [PATCH 2/2] Add overwriting test, fix indexing test --- src/gradcheck.lua | 13 ++++++++++++- test/test.lua | 5 +++-- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/gradcheck.lua b/src/gradcheck.lua index 4e31780..7dc8cf5 100644 --- a/src/gradcheck.lua +++ b/src/gradcheck.lua @@ -1,5 +1,6 @@ -- Autograd local autograd = require 'autograd' +local util = require 'autograd.util' -- Perturbation (finite diffs): local perturbation = 1e-6 @@ -12,20 +13,30 @@ local function jacobianFromAutograd(func, inputs, key) -- Autograd: local df = autograd(func) local grads = df(table.unpack(inputs)) - local gradsVerify = df(table.unpack(inputs)) -- Find grad: local g = autograd.util.nestedGet(grads, key) + local g_clone + if torch.isTensor(g) then + g_clone = g:clone() + end + + -- Get the grad again + local gradsVerify = df(table.unpack(inputs)) local gVerify = autograd.util.nestedGet(gradsVerify, key) local err + local overwrite_err = 0 if torch.isTensor(g) then err = (g - gVerify):abs():max() + overwrite_err = (g - g_clone):abs():max() else err = torch.abs(g - gVerify) end if err ~= 0 then error("autograd gradient not deterministic") + elseif overwrite_err ~= 0 then + error("autograd gradient overwritten when called twice") end -- Return grads: diff --git a/test/test.lua b/test/test.lua index 5adc28f..8c8e8eb 100644 --- a/test/test.lua +++ b/test/test.lua @@ -1688,8 +1688,9 @@ local tests = { end tester:assert(gradcheck(f4,{x=torch.randn(10,10),y=torch.randn(3)}), "Incorrect gradient") local f5 = function(params) - params.x[2] = params.y*2.0 - return torch.sum(params.x) + local xc = torch.clone(params.x) + xc[2] = params.y * 2.0 + return torch.sum(xc) end tester:assert(gradcheck(f5,{x=torch.randn(10,10),y=torch.randn(10)}), "Incorrect gradient") end,