def testLevel1(self): m = 1 d = 2 path = numpy.random.uniform(size=(10, d)) rightSig = path[-1, :] - path[0, :] s = iisignature.prepare(d, m, "cosx2") self.assertLess(diff(iisignature.sig(path, m), rightSig), 0.0000001) for type_ in ("C", "O", "S", "X", "A"): self.assertLess(diff(iisignature.logsig(path, s, type_), rightSig), 0.0000001, type_) self.assertLess(diff(rightSig, iisignature.logsigtosig(rightSig, s)), 0.000001) derivs = numpy.array([2.1, 3.2]) pathderivs = numpy.zeros_like(path) pathderivs[-1] = derivs pathderivs[0] = -derivs self.assertLess( diff(iisignature.logsigbackprop(derivs, path, s), pathderivs), 0.00001) self.assertLess( diff(iisignature.logsigbackprop(derivs, path, s, "X"), pathderivs), 0.00001) self.assertLess( diff(iisignature.sigbackprop(derivs, path, m), pathderivs), 0.00001)
def CLF_grad_Imp(g, path, deg_of_logsig, number_of_segment): """ The implementation of computing the derivatives of gradient from backpropagation. g: the flown gradient from backpropagation path: dimension (sample_size,n, d) number_of_segment: the number of segments deg_of_logsig: the degree of the log-signature """ nT = int(np.shape(path)[1]) dim_path = int(np.shape(path)[-1]) t_vec = np.linspace(1,nT,number_of_segment+1) t_vec = [int(round(x)) for x in t_vec] s = iisignature.prepare(dim_path, deg_of_logsig) MultiLevelBP = [] for k in range(int(np.shape(path)[0])): tmpMultiLevelBP = np.zeros([1,np.shape(path)[-1]]) for i in range(number_of_segment): temp_path = path[k][t_vec[i]-1:t_vec[i+1], :] tempBP = iisignature.logsigbackprop(g[k][i], temp_path , s, None) tmpMultiLevelBP[-1] += tempBP[0] tempBP = np.delete(tempBP, 0, axis=0) tmpMultiLevelBP = np.concatenate((tmpMultiLevelBP, tempBP), axis=0) MultiLevelBP.append(tmpMultiLevelBP) return np.float32(np.array(MultiLevelBP))
def testLevel1(self): m=1 d=2 path=numpy.random.uniform(size=(10,d)) rightSig = path[-1,:]-path[0,:] s=iisignature.prepare(d,m,"cosx") self.assertLess(diff(iisignature.sig(path,m),rightSig),0.0000001) for type_ in ("C","O","S","X","A"): self.assertLess(diff(iisignature.logsig(path,s,type_),rightSig),0.0000001,type_) derivs=numpy.array([2.1,3.2]) pathderivs=numpy.zeros_like(path) pathderivs[-1]=derivs pathderivs[0]=-derivs self.assertLess(diff(iisignature.logsigbackprop(derivs,path,s),pathderivs),0.00001) self.assertLess(diff(iisignature.logsigbackprop(derivs,path,s,"X"),pathderivs),0.00001) self.assertLess(diff(iisignature.sigbackprop(derivs,path,m),pathderivs),0.00001)
def backward(ctx, grad_output): (X, ) = ctx.saved_tensors s = ctx.s method = ctx.method g = grad_output.numpy() result = iisignature.logsigbackprop(g, X.detach().numpy(), s, method) return torch.FloatTensor(result), None, None
def logSig(self, type, m=5): numpy.random.seed(291) d=2 pathLength=10 s=iisignature.prepare(d,m,type) path = numpy.random.uniform(size=(pathLength,d)) path = numpy.cumsum(2 * (path - 0.5),0)#makes it more random-walk-ish, less like a scribble increment = 0.01*path increment = 0.1*numpy.random.uniform(size=(pathLength,d)) manualChange = fdDeriv(lambda x:iisignature.logsig(x,s,type),path,increment,4) dFdlogSig = numpy.ones(iisignature.siglength(d,m) if "X"==type else iisignature.logsiglength(d,m)) calculatedChange = numpy.sum(increment*iisignature.logsigbackprop(dFdlogSig,path,s,type)) #print(manualChange, calculatedChange) self.assertLess(numpy.abs(manualChange-calculatedChange),0.0001)
def logSig(self, type, m=5): numpy.random.seed(291) d=2 pathLength=10 s=iisignature.prepare(d,m,type) path = numpy.random.uniform(size=(pathLength,d)) path = numpy.cumsum(2 * (path - 0.5),0)#makes it more random-walk-ish, less like a scribble increment = 0.01*path increment = 0.1*numpy.random.uniform(size=(pathLength,d)) manualChange = fdDeriv(lambda x:iisignature.logsig(x,s,type),path,increment,4) dFdlogSig = numpy.ones(iisignature.siglength(d,m) if "X"==type else iisignature.logsiglength(d,m)) calculatedChange = numpy.sum(increment*iisignature.logsigbackprop(dFdlogSig,path,s,type)) #print(manualChange, calculatedChange) self.assertLess(numpy.abs(manualChange-calculatedChange),0.0001)
def test_logsigbackwards_can_augment_s(self): numpy.random.seed(291) d=2 m=7 pathLength=3 path = numpy.random.uniform(size=(pathLength,d)) increment = 0.1*numpy.random.uniform(size=(pathLength,d)) dFdlogSig = numpy.ones(iisignature.logsiglength(d,m)) for types in (("x","o","s"),("xh","oh","sh")): ss=[iisignature.prepare(d,m,t) for t in types] backs=[iisignature.logsigbackprop(dFdlogSig,path,s) for s in ss] self.assertTrue(numpy.allclose(backs[0],backs[2]),types[0]) self.assertTrue(numpy.allclose(backs[1],backs[2]),types[1]) fwds=[iisignature.logsig(path,s,"s") for s in ss] self.assertTrue(numpy.allclose(fwds[0],fwds[2]),types[0]) self.assertTrue(numpy.allclose(fwds[1],fwds[2]),types[1])
def test_logsigbackwards_can_augment_s(self): numpy.random.seed(291) d=2 m=7 pathLength=3 path = numpy.random.uniform(size=(pathLength,d)) increment = 0.1*numpy.random.uniform(size=(pathLength,d)) dFdlogSig = numpy.ones(iisignature.logsiglength(d,m)) for types in (("x","o","s"),("xh","oh","sh")): ss=[iisignature.prepare(d,m,t) for t in types] backs=[iisignature.logsigbackprop(dFdlogSig,path,s) for s in ss] self.assertTrue(numpy.allclose(backs[0],backs[2]),types[0]) self.assertTrue(numpy.allclose(backs[1],backs[2]),types[1]) fwds=[iisignature.logsig(path,s,"s") for s in ss] self.assertTrue(numpy.allclose(fwds[0],fwds[2]),types[0]) self.assertTrue(numpy.allclose(fwds[1],fwds[2]),types[1])
def backward(self, grad_output): (X, ) = self.saved_tensors g = grad_output.numpy() result = iisignature.logsigbackprop(g, X.numpy(), self.s, self.method) return torch.FloatTensor(result)
def backward(ctx, grad_output): X, = ctx.saved_tensors result = iisignature.logsigbackprop(grad_output.detach().numpy(), X.detach().numpy(), ctx.s) return torch.tensor(result).float(), None
def run(obj): return iisignature.logsigbackprop(obj.grad, obj.path, obj.prepare)
def __call__(self,g,x): return iisignature.logsigbackprop(g,x,self.s,self.method)
def perform(self,node,inputs_storage,out): grad_output=inputs_storage[0] x=inputs_storage[1] s,method=_prepared_obeject_store[inputs_storage[2]] out[0][0]=iisignature.logsigbackprop(grad_output,x,s,method)
def __call__(self, g, x): return iisignature.logsigbackprop(g, x, self.s, self.method)
def test_batch(self): numpy.random.seed(734) d=2 m=2 n=15 paths = [numpy.random.uniform(-1,1,size=(6,d)) for i in range(n)] pathArray15=stack(paths) pathArray1315=numpy.reshape(pathArray15,(1,3,1,5,6,d)) sigs = [iisignature.sig(i,m) for i in paths] sigArray=stack(sigs) sigArray15=iisignature.sig(pathArray15,m) sigArray1315=iisignature.sig(pathArray1315,m) siglength=iisignature.siglength(d,m) self.assertEqual(sigArray1315.shape,(1,3,1,5,siglength)) self.assertTrue(numpy.allclose(sigArray1315.reshape(n,siglength),sigs)) self.assertEqual(sigArray15.shape,(15,siglength)) self.assertTrue(numpy.allclose(sigArray15,sigs)) backsigs=[iisignature.sigbackprop(i,j,m) for i,j in zip(sigs,paths)] backsigArray = stack(backsigs) backsigs1315=iisignature.sigbackprop(sigArray1315,pathArray1315,m) self.assertEqual(backsigs1315.shape,(1,3,1,5,6,d)) self.assertTrue(numpy.allclose(backsigs1315.reshape(n,6,2),backsigArray)) data=[numpy.random.uniform(size=(d,)) for i in range(n)] dataArray1315=stack(data).reshape((1,3,1,5,d)) joined=[iisignature.sigjoin(i,j,m) for i,j in zip(sigs,data)] joined1315=iisignature.sigjoin(sigArray1315,dataArray1315,m) self.assertEqual(joined1315.shape,(1,3,1,5,siglength)) self.assertTrue(numpy.allclose(joined1315.reshape(n,-1),stack(joined))) backjoined=[iisignature.sigjoinbackprop(i,j,k,m) for i,j,k in zip(joined,sigs,data)] backjoinedArrays=[stack([i[j] for i in backjoined]) for j in range(2)] backjoined1315=iisignature.sigjoinbackprop(joined1315,sigArray1315,dataArray1315,m) self.assertEqual(backjoined1315[0].shape,sigArray1315.shape) self.assertEqual(backjoined1315[1].shape,dataArray1315.shape) self.assertTrue(numpy.allclose(backjoined1315[0].reshape(n,-1),backjoinedArrays[0])) self.assertTrue(numpy.allclose(backjoined1315[1].reshape(n,-1),backjoinedArrays[1])) scaled=[iisignature.sigscale(i,j,m) for i,j in zip(sigs,data)] scaled1315=iisignature.sigscale(sigArray1315,dataArray1315,m) self.assertEqual(scaled1315.shape,(1,3,1,5,siglength)) self.assertTrue(numpy.allclose(scaled1315.reshape(n,-1),stack(scaled))) backscaled=[iisignature.sigscalebackprop(i,j,k,m) for i,j,k in zip(scaled,sigs,data)] backscaledArrays=[stack([i[j] for i in backscaled]) for j in range(2)] backscaled1315=iisignature.sigscalebackprop(scaled1315,sigArray1315,dataArray1315,m) self.assertEqual(backscaled1315[0].shape,sigArray1315.shape) self.assertEqual(backscaled1315[1].shape,dataArray1315.shape) self.assertTrue(numpy.allclose(backscaled1315[0].reshape(n,-1),backscaledArrays[0])) self.assertTrue(numpy.allclose(backscaled1315[1].reshape(n,-1),backscaledArrays[1])) s_s=(iisignature.prepare(d,m,"cosax"),iisignature.prepare(d,m,"cosahx")) for type in ("c","o","s","x","a","ch","oh","sh","ah"): s=s_s[1 if "h" in type else 0] logsigs = [iisignature.logsig(i,s,type) for i in paths] logsigArray=stack(logsigs) logsigArray1315=iisignature.logsig(pathArray1315,s,type) self.assertEqual(logsigArray1315.shape,(1,3,1,5,logsigs[0].shape[0]),type) self.assertTrue(numpy.allclose(logsigArray1315.reshape(n,-1),logsigArray),type) if type in ("s","x","sh"): backlogs = stack(iisignature.logsigbackprop(i,j,s,type) for i,j in zip(logsigs,paths)) backlogs1315 = iisignature.logsigbackprop(logsigArray1315,pathArray1315,s,type) self.assertEqual(backlogs1315.shape,backsigs1315.shape) self.assertTrue(numpy.allclose(backlogs1315.reshape(n,6,d),backlogs),type) a=iisignature.rotinv2dprepare(m,"a") rots=stack([iisignature.rotinv2d(i,a) for i in paths]) rots1315=iisignature.rotinv2d(pathArray1315,a) self.assertEqual(rots1315.shape,(1,3,1,5,rots.shape[1])) self.assertTrue(numpy.allclose(rots1315.reshape(n,-1),rots))
def backward(self, grad_output): (X,) = self.saved_tensors g=grad_output.numpy() result = iisignature.logsigbackprop(g,X.numpy(),self.s,self.method) return torch.FloatTensor(result)
def test_batch(self): numpy.random.seed(734) d=2 m=2 n=15 paths = [numpy.random.uniform(-1,1,size=(6,d)) for i in range(n)] pathArray15=stack(paths) pathArray1315=numpy.reshape(pathArray15,(1,3,1,5,6,d)) sigs = [iisignature.sig(i,m) for i in paths] sigArray=stack(sigs) sigArray15=iisignature.sig(pathArray15,m) sigArray1315=iisignature.sig(pathArray1315,m) siglength=iisignature.siglength(d,m) self.assertEqual(sigArray1315.shape,(1,3,1,5,siglength)) self.assertTrue(numpy.allclose(sigArray1315.reshape(n,siglength),sigs)) self.assertEqual(sigArray15.shape,(15,siglength)) self.assertTrue(numpy.allclose(sigArray15,sigs)) backsigs=[iisignature.sigbackprop(i,j,m) for i,j in zip(sigs,paths)] backsigArray = stack(backsigs) backsigs1315=iisignature.sigbackprop(sigArray1315,pathArray1315,m) self.assertEqual(backsigs1315.shape,(1,3,1,5,6,d)) self.assertTrue(numpy.allclose(backsigs1315.reshape(n,6,2),backsigArray)) data=[numpy.random.uniform(size=(d,)) for i in range(n)] dataArray1315=stack(data).reshape((1,3,1,5,d)) joined=[iisignature.sigjoin(i,j,m) for i,j in zip(sigs,data)] joined1315=iisignature.sigjoin(sigArray1315,dataArray1315,m) self.assertEqual(joined1315.shape,(1,3,1,5,siglength)) self.assertTrue(numpy.allclose(joined1315.reshape(n,-1),stack(joined))) backjoined=[iisignature.sigjoinbackprop(i,j,k,m) for i,j,k in zip(joined,sigs,data)] backjoinedArrays=[stack([i[j] for i in backjoined]) for j in range(2)] backjoined1315=iisignature.sigjoinbackprop(joined1315,sigArray1315,dataArray1315,m) self.assertEqual(backjoined1315[0].shape,sigArray1315.shape) self.assertEqual(backjoined1315[1].shape,dataArray1315.shape) self.assertTrue(numpy.allclose(backjoined1315[0].reshape(n,-1),backjoinedArrays[0])) self.assertTrue(numpy.allclose(backjoined1315[1].reshape(n,-1),backjoinedArrays[1])) dataAsSigs=[iisignature.sig(numpy.row_stack([numpy.zeros((d,)),i]),m) for i in data] dataArray13151=dataArray1315[:,:,:,:,None,:] dataArray13151=numpy.repeat(dataArray13151,2,4)*[[0.0],[1.0]] dataArrayAsSigs1315=iisignature.sig(dataArray13151,m) combined1315=iisignature.sigcombine(sigArray1315,dataArrayAsSigs1315,d,m) self.assertEqual(joined1315.shape,combined1315.shape) self.assertTrue(numpy.allclose(joined1315,combined1315)) backcombined1315=iisignature.sigcombinebackprop(joined1315,sigArray1315,dataArrayAsSigs1315,d,m) backcombined=[iisignature.sigcombinebackprop(i,j,k,d,m) for i,j,k in zip(joined,sigs,dataAsSigs)] backcombinedArrays=[stack([i[j] for i in backcombined]) for j in range(2)] self.assertEqual(backcombined1315[0].shape,sigArray1315.shape) self.assertEqual(backcombined1315[1].shape,sigArray1315.shape) self.assertTrue(numpy.allclose(backjoined1315[0],backcombined1315[0])) self.assertTrue(numpy.allclose(backcombined1315[0].reshape(n,-1),backcombinedArrays[0])) self.assertTrue(numpy.allclose(backcombined1315[1].reshape(n,-1),backcombinedArrays[1])) scaled=[iisignature.sigscale(i,j,m) for i,j in zip(sigs,data)] scaled1315=iisignature.sigscale(sigArray1315,dataArray1315,m) self.assertEqual(scaled1315.shape,(1,3,1,5,siglength)) self.assertTrue(numpy.allclose(scaled1315.reshape(n,-1),stack(scaled))) backscaled=[iisignature.sigscalebackprop(i,j,k,m) for i,j,k in zip(scaled,sigs,data)] backscaledArrays=[stack([i[j] for i in backscaled]) for j in range(2)] backscaled1315=iisignature.sigscalebackprop(scaled1315,sigArray1315,dataArray1315,m) self.assertEqual(backscaled1315[0].shape,sigArray1315.shape) self.assertEqual(backscaled1315[1].shape,dataArray1315.shape) self.assertTrue(numpy.allclose(backscaled1315[0].reshape(n,-1),backscaledArrays[0])) self.assertTrue(numpy.allclose(backscaled1315[1].reshape(n,-1),backscaledArrays[1])) s_s=(iisignature.prepare(d,m,"cosax"),iisignature.prepare(d,m,"cosahx")) for type in ("c","o","s","x","a","ch","oh","sh","ah"): s=s_s[1 if "h" in type else 0] logsigs = [iisignature.logsig(i,s,type) for i in paths] logsigArray=stack(logsigs) logsigArray1315=iisignature.logsig(pathArray1315,s,type) self.assertEqual(logsigArray1315.shape,(1,3,1,5,logsigs[0].shape[0]),type) self.assertTrue(numpy.allclose(logsigArray1315.reshape(n,-1),logsigArray),type) if type in ("s","x","sh"): backlogs = stack(iisignature.logsigbackprop(i,j,s,type) for i,j in zip(logsigs,paths)) backlogs1315 = iisignature.logsigbackprop(logsigArray1315,pathArray1315,s,type) self.assertEqual(backlogs1315.shape,backsigs1315.shape) self.assertTrue(numpy.allclose(backlogs1315.reshape(n,6,d),backlogs),type) a=iisignature.rotinv2dprepare(m,"a") rots=stack([iisignature.rotinv2d(i,a) for i in paths]) rots1315=iisignature.rotinv2d(pathArray1315,a) self.assertEqual(rots1315.shape,(1,3,1,5,rots.shape[1])) self.assertTrue(numpy.allclose(rots1315.reshape(n,-1),rots))
def backward(ctx, grad): return torch.tensor(iisignature.logsigbackprop(grad.cpu(), ctx.path, ctx.prepare, 'x'), device=ctx.device, dtype=ctx.dtype), None