示例#1
0
 def __init__(
         self,
         n_units,
         sig_level=2,
         train_time_lapse=False,
         initial_time_lapse=0.1,
         output_signatures=False,  #whether the output includes the signatures
         use_signatures=True,  #whether each new state can depend on the signature
         kernel_initializer='glorot_uniform',
         recurrent_initializer='he_normal',  #could be good to use 'orthogonal' if not use_signatures
         activation='tanh',  #not applied to signature elements
         **kwargs):
     self.sig_level = sig_level
     self.sigsize = iisignature.siglength(2, sig_level)
     self.n_units = n_units  #like output_dim
     self.units = n_units * (self.sigsize +
                             1) if output_signatures else n_units
     self.train_time_lapse = train_time_lapse
     self.initial_time_lapse = initial_time_lapse
     self.output_signatures = output_signatures
     self.use_signatures = use_signatures
     self.kernel_initializer = initializers.get(kernel_initializer)
     self.recurrent_initializer = initializers.get(recurrent_initializer)
     self.activation = activations.get(activation)
     super(RecurrentSig, self).__init__(**kwargs)
示例#2
0
    def __init__(self, ef_num_hlayers, ef_num_hu, ef_num_filters, pslevel,
                 num_slices, dropout):
        '''
        for each diagram, we have different slices
        Across different functions, we have the same parameters for #h0slices, #h0siglevel, #h1slices, #h1siglevel


        '''
        super(dgmslice_ps2, self).__init__()

        self.filters = ef_num_filters
        self.pslevel = pslevel  #list [pslevel for h0, pslevel for h1]
        self.slices = num_slices  #list [#slices for h0, #slices for pslevel for h1]

        #self.siglength = [iisignature.siglength(num_slices+1, m) for m in pslevel]
        self.siglength = [
            iisignature.siglength(num_slices[i], pslevel[i]) for i in range(2)
        ]  #
        self.eigfs = nn.ModuleList()
        self.projections0 = nn.ModuleList()
        self.projections1 = nn.ModuleList()
        self.final_vec_length = self.filters * sum(self.siglength)

        for i in range(self.filters):
            self.eigfs.append(eigf(ef_num_hlayers, ef_num_hu))

        for i in range(self.filters):
            self.projections0.append(nn.Conv1d(1, self.slices[0], 2, 2))

        for i in range(self.filters):
            self.projections1.append(nn.Conv1d(1, self.slices[1], 2, 2))

        self.final_layer = nn.Sequential(nn.Dropout(dropout),
                                         nn.Linear(self.final_vec_length, 1),
                                         nn.BatchNorm1d(1))
示例#3
0
    def testcombining(self):
        dim = 2
        level = 2
        siglength = iisignature.siglength(dim,level)
        pathLength = 20
        halfPathLength=10
        numberToDo=4
        path = numpy.random.uniform(size=(numberToDo,pathLength,dim))
        sig = iisignature.sig(path,level)
        sig1 = iisignature.sig(path[:,:halfPathLength],level)
        sig2 = iisignature.sig(path[:,(halfPathLength-1):],level)
        combined = iisignature.sigcombine(sig1,sig2,dim,level)
        self.assertLess(diff(sig,combined),0.0001)

        extra = numpy.random.uniform(size=(siglength,))
        bumpedsig1 = 1.001 * sig1
        bumpedsig2 = 1.001 * sig2
        base = numpy.sum(iisignature.sigcombine(sig1,sig2,dim,level))
        bump1 = numpy.sum(iisignature.sigcombine(bumpedsig1,sig2,dim,level))
        bump2 = numpy.sum(iisignature.sigcombine(sig1,bumpedsig2,dim,level))
        derivsOfSum = numpy.ones((numberToDo,siglength))
        calculated = iisignature.sigcombinebackprop(derivsOfSum,sig1,sig2,dim,level)
        self.assertEqual(len(calculated), 2)
        diff1 = (bump1 - base) - numpy.sum(calculated[0] * (bumpedsig1 - sig1))
        diff2 = (bump2 - base) - numpy.sum(calculated[1] * (bumpedsig2 - sig2))
        #print ("\n",bump1,bump2,base,diff1,diff2)
        self.assertLess(numpy.abs(diff1),0.000001)
        self.assertLess(numpy.abs(diff2),0.00001)
示例#4
0
 def testFewPoints(self):
     # check sanity of paths with less than 3 points
     path1=[[4.3,0.8]]
     path2=numpy.array([[1,2],[2,4]])
     m=4
     d=2
     s=iisignature.prepare(d,m,"cosx")
     s_a=iisignature.prepare(d,2,"cosx")
     length=iisignature.siglength(d,m)
     loglength=iisignature.logsiglength(d,m)
     loglength_a=iisignature.logsiglength(d,2)
     blankLogSig=numpy.zeros(loglength)
     blankLogSig_a=numpy.zeros(loglength_a)
     blankSig=numpy.zeros(length)
     self.assertLess(diff(iisignature.sig(path1,m),blankSig),0.000000001)
     self.assertTrue(numpy.array_equal(iisignature.sig(path1,m,2),numpy.zeros([0,length])))
     self.assertLess(diff(iisignature.logsig(path1,s,"C"),blankLogSig),0.000000001)
     self.assertLess(diff(iisignature.logsig(path1,s,"O"),blankLogSig),0.000000001)
     self.assertLess(diff(iisignature.logsig(path1,s,"S"),blankLogSig),0.000000001)
     self.assertLess(diff(iisignature.logsig(path1,s,"X"),blankSig),0.000000001)
     self.assertLess(diff(iisignature.logsig(path1,s_a,"A"),blankLogSig_a),0.000000001)
     blankLogSig[:d]=path2[1]-path2[0]
     blankLogSig_a[:d]=path2[1]-path2[0]
     blankSig[:d]=path2[1]-path2[0]
     self.assertLess(diff(iisignature.logsig(path2,s,"C"),blankLogSig),0.000001)
     self.assertLess(diff(iisignature.logsig(path2,s,"O"),blankLogSig),0.000001)
     self.assertLess(diff(iisignature.logsig(path2,s,"S"),blankLogSig),0.000001)
     self.assertLess(diff(iisignature.logsig(path2,s,"X"),blankSig),0.000001)
     self.assertLess(diff(iisignature.logsig(path2,s_a,"A"),blankLogSig_a),0.000001)
示例#5
0
    def __init__(self,
                 input_size,
                 n_units,
                 sig_level=2,
                 train_time_lapse=True,
                 initial_time_lapse=0.1,
                 output_signatures=False,
                 use_signatures=True):
        super(RecurrentSig, self).__init__()
        self.sig_level = sig_level
        self.sigsize = iisignature.siglength(2, sig_level)
        self.n_units = n_units
        self.units = n_units * (self.sigsize +
                                1) if output_signatures else n_units
        self.train_time_lapse = train_time_lapse
        #self.initial_time_lapse = initial_time_lapse
        self.output_signatures = output_signatures
        self.use_signatures = use_signatures

        saved_data_length = self.n_units * (1 + self.sigsize
                                            if self.use_signatures else 1)
        self.W = nn.Linear(input_size, self.n_units)
        self.U = nn.Linear(saved_data_length, self.n_units)
        if self.train_time_lapse:
            self.log_timelapse = nn.parameter.Parameter(
                torch.FloatTensor([math.log(initial_time_lapse)]))
        else:
            self.time_lapse = Variable(torch.FloatTensor([initial_time_lapse]))
示例#6
0
    def get_penalization(self, n, k, Kpen):
        """Returns the penalization function used in the estimator of the truncation order, that is,
        pen_n(k)=Kpen*sqrt((d^(k+1)-1)/(d-1))/n^rho.

        Parameters
        ----------
        n: int
            Number of samples.

        k: int
            Truncation order of the signature.

        Kpen: float, default=1
            Constant in front of the penalization, it has to be strictly positive.

        Returns
        -------
        pen_n(k):float
            The penalization pen_n(k)
        """
        if k == 0:
            size_sig = 1
        else:
            size_sig = isig.siglength(self.d, k) + 1

        return Kpen * n**(-self.rho) * math.sqrt(size_sig)
示例#7
0
def get_sigX(X, k):
    """Returns a matrix containing signatures truncated at k of n samples
	given in the input tensor X.

	Parameters
	----------
	X: array, shape (n, npoints, d)
		A 3-dimensional array, containing the coordinates in R^d of n
		piecewise linear paths, each composed of n_points.

	k: int
		Truncation order of the signature

	Returns
	-------
	sigX: array, shape (n,p)
		A matrix containing in each row the signature truncated at k of a sample.
	"""
    if k == 0:
        return np.full((np.shape(X)[0], 1), 1)
    else:
        d = X.shape[2]
        sigX = np.zeros((np.shape(X)[0], isig.siglength(d, k) + 1))
        sigX[:, 0] = 1
        for i in range(np.shape(X)[0]):
            sigX[i, 1:] = isig.sig(X[i, :, :], k)
        return sigX
示例#8
0
 def testFewPoints(self):
     # check sanity of paths with less than 3 points
     path1=[[4.3,0.8]]
     path2=numpy.array([[1,2],[2,4]])
     m=4
     d=2
     s=iisignature.prepare(d,m,"cosx")
     s_a=iisignature.prepare(d,2,"cosx")
     length=iisignature.siglength(d,m)
     loglength=iisignature.logsiglength(d,m)
     loglength_a=iisignature.logsiglength(d,2)
     blankLogSig=numpy.zeros(loglength)
     blankLogSig_a=numpy.zeros(loglength_a)
     blankSig=numpy.zeros(length)
     self.assertLess(diff(iisignature.sig(path1,m),blankSig),0.000000001)
     self.assertTrue(numpy.array_equal(iisignature.sig(path1,m,2),numpy.zeros([0,length])))
     self.assertLess(diff(iisignature.logsig(path1,s,"C"),blankLogSig),0.000000001)
     self.assertLess(diff(iisignature.logsig(path1,s,"O"),blankLogSig),0.000000001)
     self.assertLess(diff(iisignature.logsig(path1,s,"S"),blankLogSig),0.000000001)
     self.assertLess(diff(iisignature.logsig(path1,s,"X"),blankSig),0.000000001)
     self.assertLess(diff(iisignature.logsig(path1,s_a,"A"),blankLogSig_a),0.000000001)
     blankLogSig[:d]=path2[1]-path2[0]
     blankLogSig_a[:d]=path2[1]-path2[0]
     blankSig[:d]=path2[1]-path2[0]
     self.assertLess(diff(iisignature.logsig(path2,s,"C"),blankLogSig),0.000001)
     self.assertLess(diff(iisignature.logsig(path2,s,"O"),blankLogSig),0.000001)
     self.assertLess(diff(iisignature.logsig(path2,s,"S"),blankLogSig),0.000001)
     self.assertLess(diff(iisignature.logsig(path2,s,"X"),blankSig),0.000001)
     self.assertLess(diff(iisignature.logsig(path2,s_a,"A"),blankLogSig_a),0.000001)
示例#9
0
    def consistency(self, coropa, dim, level):
        #numpy.random.seed(21)
        s = iisignature.prepare(dim,level,"coshx" if coropa else "cosx")
        myinfo = {"level":level, "dimension":dim,
                  "methods": ("COSAX" if level <= 2 else "COSX"),
                  "basis":("Standard Hall" if coropa else "Lyndon")}
        self.assertEqual(iisignature.info(s),myinfo)
        path = numpy.random.uniform(size=(10,dim))
        basis = iisignature.basis(s)
        logsig = iisignature.logsig(path,s)
        sig = iisignature.sig(path,level)

        #check lengths
        self.assertEqual(len(basis),iisignature.logsiglength(dim,level))
        self.assertEqual((len(basis),),logsig.shape)
        self.assertEqual(sig.shape,(iisignature.siglength(dim,level),))

        #calculate a signature from logsig
        expanded_logsig = [numpy.zeros(dim ** m) for m in range(1,level + 1)]
        for coeff, expression in zip(logsig,basis):
            values, depth = valueOfBracket(expression,dim)
            expanded_logsig[depth - 1]+=values * coeff
        calculated_sig = numpy.concatenate(exponentiateTensor(expanded_logsig))
        self.assertLess(diff(sig,calculated_sig),0.00001)

        #calculate a log signature from sig
        fullLogSig = numpy.concatenate(logTensor(splitConcatenatedTensor(sig,dim,level)))
        fullLogSigLib = iisignature.logsig(path,s,"x")
        diff1 = numpy.max(numpy.abs(fullLogSigLib - fullLogSig))
        #print
        #(numpy.vstack([fullLogSig,fullLogSigLib,numpy.abs(fullLogSigLib-fullLogSig)]).transpose())
        self.assertLess(diff1,0.00001)

        basisMatrix = []
        zeros = [numpy.zeros(dim ** m) for m in range(1,level + 1)]
        for expression in basis:
            values, depth = valueOfBracket(expression, dim)
            temp = zeros[depth - 1]
            zeros[depth - 1] = values
            basisMatrix.append(numpy.concatenate(zeros))
            zeros[depth - 1] = temp
        calculatedLogSig = lstsq(numpy.transpose(basisMatrix),fullLogSig)[0]
        diff2 = numpy.max(numpy.abs(logsig - calculatedLogSig))
        self.assertLess(diff2,0.00001)

        #check consistency of methods
        slowLogSig = iisignature.logsig(path,s,"o")
        diffs = numpy.max(numpy.abs(slowLogSig - calculatedLogSig))
        self.assertLess(diffs,0.00001)

        sigLogSig = iisignature.logsig(path,s,"s")
        diffs = numpy.max(numpy.abs(sigLogSig - calculatedLogSig))
        self.assertLess(diffs,0.00001)

        if level < 3:
            areaLogSig = iisignature.logsig(path,s,"a")
            diffs = numpy.max(numpy.abs(areaLogSig - calculatedLogSig))
            self.assertLess(diffs,0.00001)
示例#10
0
    def consistency(self, coropa, dim, level):
        #numpy.random.seed(21)
        s = iisignature.prepare(dim,level,"coshx" if coropa else "cosx")
        myinfo = {"level":level, "dimension":dim,
                  "methods": ("COSAX" if level <= 2 else "COSX"),
                  "basis":("Standard Hall" if coropa else "Lyndon")}
        self.assertEqual(iisignature.info(s),myinfo)
        path = numpy.random.uniform(size=(10,dim))
        basis = iisignature.basis(s)
        logsig = iisignature.logsig(path,s)
        sig = iisignature.sig(path,level)

        #check lengths
        self.assertEqual(len(basis),iisignature.logsiglength(dim,level))
        self.assertEqual((len(basis),),logsig.shape)
        self.assertEqual(sig.shape,(iisignature.siglength(dim,level),))

        #calculate a signature from logsig
        expanded_logsig = [numpy.zeros(dim ** m) for m in range(1,level + 1)]
        for coeff, expression in zip(logsig,basis):
            values, depth = valueOfBracket(expression,dim)
            expanded_logsig[depth - 1]+=values * coeff
        calculated_sig = numpy.concatenate(exponentiateTensor(expanded_logsig))
        self.assertLess(diff(sig,calculated_sig),0.00001)

        #calculate a log signature from sig
        fullLogSig = numpy.concatenate(logTensor(splitConcatenatedTensor(sig,dim,level)))
        fullLogSigLib = iisignature.logsig(path,s,"x")
        diff1 = numpy.max(numpy.abs(fullLogSigLib - fullLogSig))
        #print
        #(numpy.vstack([fullLogSig,fullLogSigLib,numpy.abs(fullLogSigLib-fullLogSig)]).transpose())
        self.assertLess(diff1,0.00001)

        basisMatrix = []
        zeros = [numpy.zeros(dim ** m) for m in range(1,level + 1)]
        for expression in basis:
            values, depth = valueOfBracket(expression, dim)
            temp = zeros[depth - 1]
            zeros[depth - 1] = values
            basisMatrix.append(numpy.concatenate(zeros))
            zeros[depth - 1] = temp
        calculatedLogSig = lstsq(numpy.transpose(basisMatrix),fullLogSig)[0]
        diff2 = numpy.max(numpy.abs(logsig - calculatedLogSig))
        self.assertLess(diff2,0.00001)

        #check consistency of methods
        slowLogSig = iisignature.logsig(path,s,"o")
        diffs = numpy.max(numpy.abs(slowLogSig - calculatedLogSig))
        self.assertLess(diffs,0.00001)

        sigLogSig = iisignature.logsig(path,s,"s")
        diffs = numpy.max(numpy.abs(sigLogSig - calculatedLogSig))
        self.assertLess(diffs,0.00001)

        if level < 3:
            areaLogSig = iisignature.logsig(path,s,"a")
            diffs = numpy.max(numpy.abs(areaLogSig - calculatedLogSig))
            self.assertLess(diffs,0.00001)
 def infer_shape(self,node,shapes):
     #d=shapes[0][-1]
     s,method=_prepared_obeject_store[node.inputs[1].get_value()]
     m=iisignature.info(s)["level"]
     d=iisignature.info(s)["dimension"]
     if "x" in method or "X" in method:
         length=iisignature.siglength(d,m)
     else:
         length=iisignature.logsiglength(d,m)
     return [shapes[0][:-2]+(length,)]
    def get_sig_dimension(self):
        """ Returns the dimension of the signature vector truncated at
		self.order and with the embedding chosen by self.path

		Returns
		-------
		siglength: int
			The dimension of the signature vector.
		"""
        return (isig.siglength(self.get_embedding_dimension(), self.order))
def delayedBM_limit(BM_1d, depth, time):
    """Returns limiting rough path in p-var top for the delayed BM problem (with iisignature and BnB)"""
    N = len(BM_1d)
    X_inf = np.zeros((N, iisignature.siglength(2, depth)))
    for k, t in enumerate(time):
        X_inf[k, 0] = BM_1d[k]
        X_inf[k, 1] = BM_1d[k]
        X_inf[k, 2] = 0.
        X_inf[k, 3] = t / 2.
        X_inf[k, 4] = -t / 2.
        X_inf[k, 5] = 0.
    return X_inf
示例#14
0
    def testSig(self):
        #test that sigjacobian and sigbackprop compatible with sig
        numpy.random.seed(291)
        d = 3
        m = 5
        pathLength = 10
        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 * numpy.random.uniform(size=(pathLength,d))
        base_sig = iisignature.sig(path,m)

        target = fdDeriv(lambda x:iisignature.sig(x,m),path,increment,2, nosum=True)
        
        gradient = iisignature.sigjacobian(path,m)
        calculated = numpy.tensordot(increment,gradient)

        diffs = numpy.max(numpy.abs(calculated - target))
        niceOnes = numpy.abs(calculated) > 1.e-4
        niceOnes2 = numpy.abs(calculated) < numpy.abs(base_sig)
        diffs1 = numpy.max(numpy.abs((calculated[niceOnes2] - target[niceOnes2]) / base_sig[niceOnes2]))
        diffs2 = numpy.max(numpy.abs(calculated[1 - niceOnes2] - target[1 - niceOnes2]))
        ratioDiffs = numpy.max(numpy.abs(calculated[niceOnes] / target[niceOnes] - 1))

        #numpy.set_printoptions(suppress=True,linewidth=os.popen('stty size',
        #'r').read().split()[1] #LINUX
        #numpy.set_printoptions(suppress=True,linewidth=150)
        #print ("")
        #print (path)
        #print
        #(numpy.vstack([range(len(base_sig)),base_sig,calculated,target,(calculated-target)/base_sig,calculated/target-1]).transpose())
        #print (diffs, ratioDiffs, diffs1, diffs2)
        #print(numpy.argmax(numpy.abs(calculated[niceOnes]/target[niceOnes]-1)),numpy.argmax(numpy.abs((calculated-target)/base_sig)))

        self.assertLess(diffs,0.00001)
        self.assertLess(ratioDiffs,0.01)
        self.assertLess(diffs1,0.001) 
        self.assertLess(diffs2,0.00001) 

        #compatibility between sigbackprop and sigjacobian is strong
        dFdSig = numpy.random.uniform(size=(iisignature.siglength(d,m),))
        backProp = iisignature.sigbackprop(dFdSig,path,m)
        manualCalcBackProp = numpy.dot(gradient,dFdSig)
        backDiffs = numpy.max(numpy.abs(backProp - manualCalcBackProp))
        if 0: # to investigate the compile logic problem I used this and
              # (d,m,pathLength)=(1,2,2)
            print("")
            print(dFdSig)
            print(path)
            print(backProp)
            print(manualCalcBackProp)
        self.assertLess(backDiffs,0.000001)
示例#15
0
    def testSig(self):
        #test that sigjacobian and sigbackprop compatible with sig
        numpy.random.seed(291)
        d = 3
        m = 5
        pathLength = 10
        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 * numpy.random.uniform(size=(pathLength,d))
        base_sig = iisignature.sig(path,m)

        target = fdDeriv(lambda x:iisignature.sig(x,m),path,increment,2, nosum=True)
        
        gradient = iisignature.sigjacobian(path,m)
        calculated = numpy.tensordot(increment,gradient)

        diffs = numpy.max(numpy.abs(calculated - target))
        niceOnes = numpy.abs(calculated) > 1.e-4
        niceOnes2 = numpy.abs(calculated) < numpy.abs(base_sig)
        diffs1 = numpy.max(numpy.abs((calculated[niceOnes2] - target[niceOnes2]) / base_sig[niceOnes2]))
        diffs2 = numpy.max(numpy.abs(calculated[1 - niceOnes2] - target[1 - niceOnes2]))
        ratioDiffs = numpy.max(numpy.abs(calculated[niceOnes] / target[niceOnes] - 1))

        #numpy.set_printoptions(suppress=True,linewidth=os.popen('stty size',
        #'r').read().split()[1] #LINUX
        #numpy.set_printoptions(suppress=True,linewidth=150)
        #print ("")
        #print (path)
        #print
        #(numpy.vstack([range(len(base_sig)),base_sig,calculated,target,(calculated-target)/base_sig,calculated/target-1]).transpose())
        #print (diffs, ratioDiffs, diffs1, diffs2)
        #print(numpy.argmax(numpy.abs(calculated[niceOnes]/target[niceOnes]-1)),numpy.argmax(numpy.abs((calculated-target)/base_sig)))

        self.assertLess(diffs,0.00001)
        self.assertLess(ratioDiffs,0.01)
        self.assertLess(diffs1,0.001) 
        self.assertLess(diffs2,0.00001) 

        #compatibility between sigbackprop and sigjacobian is strong
        dFdSig = numpy.random.uniform(size=(iisignature.siglength(d,m),))
        backProp = iisignature.sigbackprop(dFdSig,path,m)
        manualCalcBackProp = numpy.dot(gradient,dFdSig)
        backDiffs = numpy.max(numpy.abs(backProp - manualCalcBackProp))
        if 0: # to investigate the compile logic problem I used this and
              # (d,m,pathLength)=(1,2,2)
            print("")
            print(dFdSig)
            print(path)
            print(backProp)
            print(manualCalcBackProp)
        self.assertLess(backDiffs,0.000001)
    def __init__(self, trend, init_money=10000, window_size=20):  #这里把df改为trend

        self.n_actions = 3  # 动作数量
        self.n_features = window_size + iisignature.siglength(2, 3)  # 特征数量
        #self.trend = df['close'].values # 收盘数据
        #self.df = df #数据的DataFrame
        self.trend = trend  # 收盘数据
        self.init_money = init_money  # 初始化资金
        self.n_lagged_time_steps = 20  #用于计算signature的p-lag value 200

        self.window_size = window_size  #滑动窗口大小
        self.half_window = window_size // 2
        #self.signature = np.empty(shape=[len(self.trend),iisignature.siglength(2,3)])
        self.signature = self.signature_normalisation(self.trend)
示例#17
0
    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 delayed_roughBM(BM, BM_del, delay, depth, time):
    if delay == 0:
        return delayedBM_limit(BM, depth, time)
    BM = np.concatenate((BM, np.array(delay * [BM[-1]])), 0)
    N = len(BM)
    roughBM = np.zeros((N, iisignature.siglength(2, depth)))
    DeltaBM = np.append(0., np.diff(BM, 0))
    for k in range(N):
        roughBM[k, 0] = BM[k]
        roughBM[k, 1] = BM_del[k]
        roughBM[k, 2] = 0.
        levy_area = (BM_del[:k] * DeltaBM[:k]).sum() - 0.5 * BM[k] * BM_del[k]
        roughBM[k, 3] = levy_area
        roughBM[k, 4] = -levy_area
        roughBM[k, 5] = 0.
    return roughBM
示例#19
0
    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)
示例#20
0
    def testjoining(self):
        numberToDo = 1
        dim = 2
        level = 2
        siglength = iisignature.siglength(dim,level)
        for fixedPoint, inputDim, fixed in [(float('nan'),dim,False),(0.1,dim - 1,True)]:
            pathLength = 10
            def makePath():
                p = numpy.random.uniform(size=(pathLength,dim))
                if fixed:
                    p[:,-1] = fixedPoint * numpy.arange(pathLength)
                return p
            paths = [makePath() for i in range(numberToDo)]
            sig = numpy.vstack([iisignature.sig(path,level) for path in paths])

            joinee = numpy.zeros((numberToDo,siglength))
            for i in range(1,pathLength):
                displacements = [path[i:(i + 1),:] - path[(i - 1):i,:] for path in paths]
                displacement = numpy.vstack(displacements)
                if fixed:
                    displacement = displacement[:,:-1]
                joinee = iisignature.sigjoin(joinee,displacement,level,fixedPoint)
            self.assertLess(diff(sig,joinee),0.0001,"fullSig matches sig" + (" with fixed Dim" if fixed else ""))

            extra = numpy.random.uniform(size=(numberToDo,inputDim))
            bumpedExtra = 1.001 * extra
            bumpedJoinee = 1.001 * joinee
            base = numpy.sum(iisignature.sigjoin(joinee,extra,level,fixedPoint))
            bump1 = numpy.sum(iisignature.sigjoin(bumpedJoinee,extra,level,fixedPoint))
            bump2 = numpy.sum(iisignature.sigjoin(joinee,bumpedExtra,level,fixedPoint))
            derivsOfSum = numpy.ones((numberToDo,siglength))
            calculated = iisignature.sigjoinbackprop(derivsOfSum,joinee,extra,
                                                     level,fixedPoint)
            self.assertEqual(len(calculated),3 if fixed else 2)
            diff1 = (bump1 - base) - numpy.sum(calculated[0] * (bumpedJoinee - joinee))
            diff2 = (bump2 - base) - numpy.sum(calculated[1] * (bumpedExtra - extra))
            #print ("\n",bump1,bump2,base,diff1,diff2)
            self.assertLess(numpy.abs(diff1),0.000001,"diff1 as expected " + (" with fixed Dim" if fixed else ""))
            self.assertLess(numpy.abs(diff2),0.00001,"diff2 as expected " + (" with fixed Dim" if fixed else ""))
            if fixed:
                bumpedFixedPoint = fixedPoint * 1.01
                bump3 = numpy.sum(iisignature.sigjoin(joinee,extra, level, bumpedFixedPoint))
                diff3 = (bump3-base - numpy.sum(calculated[2] * (bumpedFixedPoint-fixedPoint)))
                #print("\n",bump3,base, fixedPoint, bumpedFixedPoint, calculated[2])
                self.assertLess(numpy.abs(diff3),0.00001, "diff3")
示例#21
0
    def testjoining(self):
        numberToDo = 1
        dim = 2
        level = 2
        siglength = iisignature.siglength(dim,level)
        for fixedPoint, inputDim, fixed in [(float('nan'),dim,False),(0.1,dim - 1,True)]:
            pathLength = 10
            def makePath():
                p = numpy.random.uniform(size=(pathLength,dim))
                if fixed:
                    p[:,-1] = fixedPoint * numpy.arange(pathLength)
                return p
            paths = [makePath() for i in range(numberToDo)]
            sig = numpy.vstack([iisignature.sig(path,level) for path in paths])

            joinee = numpy.zeros((numberToDo,siglength))
            for i in range(1,pathLength):
                displacements = [path[i:(i + 1),:] - path[(i - 1):i,:] for path in paths]
                displacement = numpy.vstack(displacements)
                if fixed:
                    displacement = displacement[:,:-1]
                joinee = iisignature.sigjoin(joinee,displacement,level,fixedPoint)
            self.assertLess(diff(sig,joinee),0.0001,"fullSig matches sig" + (" with fixed Dim" if fixed else ""))

            extra = numpy.random.uniform(size=(numberToDo,inputDim))
            bumpedExtra = 1.001 * extra
            bumpedJoinee = 1.001 * joinee
            base = numpy.sum(iisignature.sigjoin(joinee,extra,level,fixedPoint))
            bump1 = numpy.sum(iisignature.sigjoin(bumpedJoinee,extra,level,fixedPoint))
            bump2 = numpy.sum(iisignature.sigjoin(joinee,bumpedExtra,level,fixedPoint))
            derivsOfSum = numpy.ones((numberToDo,siglength))
            calculated = iisignature.sigjoinbackprop(derivsOfSum,joinee,extra,
                                                     level,fixedPoint)
            self.assertEqual(len(calculated),3 if fixed else 2)
            diff1 = (bump1 - base) - numpy.sum(calculated[0] * (bumpedJoinee - joinee))
            diff2 = (bump2 - base) - numpy.sum(calculated[1] * (bumpedExtra - extra))
            #print ("\n",bump1,bump2,base,diff1,diff2)
            self.assertLess(numpy.abs(diff1),0.000001,"diff1 as expected " + (" with fixed Dim" if fixed else ""))
            self.assertLess(numpy.abs(diff2),0.00001,"diff2 as expected " + (" with fixed Dim" if fixed else ""))
            if fixed:
                bumpedFixedPoint = fixedPoint * 1.01
                bump3 = numpy.sum(iisignature.sigjoin(joinee,extra, level, bumpedFixedPoint))
                diff3 = (bump3-base - numpy.sum(calculated[2] * (bumpedFixedPoint-fixedPoint)))
                #print("\n",bump3,base, fixedPoint, bumpedFixedPoint, calculated[2])
                self.assertLess(numpy.abs(diff3),0.00001, "diff3")
示例#22
0
 def __init__(
         self,
         n_hidden,
         sig_dimension,
         sig_level=2,
         kernel_initializer='glorot_uniform',
         #inner_init='he_normal',#could be good to use 'orthogonal' - not used
         activation='tanh',  #not applied to signature elements
         **kwargs):
     self.n_hidden = n_hidden
     self.units = n_hidden
     self.sig_dimension = sig_dimension
     self.sig_level = sig_level
     self.sigsize = iisignature.siglength(sig_dimension, sig_level)
     self.kernel_initializer = initializers.get(kernel_initializer)
     self.activation = activations.get(activation)
     self.states = [None, None]
     super(LSTMSig, self).__init__(**kwargs)
	def get_Y_sig(self, X, mast, noise_std=100, plot=False):
		"""Compute the target values Y as scalar products of the truncated signatures of rows of X with a certain
		parameter beta plus a gaussian noise. Y follows therefore the signature linear model.

		Parameters
		----------
		X: array, shape (n, self.npoints, self.d)
			Array of paths. It is a 3-dimensional array, containing the coordinates in R^d of n piecewise linear paths,
			each composed of npoints.

		mast: int
			True value of the truncation order of the signature.

		noise_std: float, default=100
			Amount of noise of Y, Y is equal to the scalar product of the signature of X against beta plus a uniform
			noise on [-noise_std,noise_std].

		plot: boolean, default=False
			If True, output two plots: one plot with the signature coefficients of one sample and the regression vector
			beta, one scatter plot with Y against Y+noise to check the calibration of the noise variance.

		Returns
		-------
		Y: array, shape (n)
			Target values
		"""
		n = X.shape[0]

		if mast == 0:
			size_sig = 1
		else:
			size_sig = isig.siglength(self.d, mast) + 1
		beta = np.random.random(size=size_sig) / 1000
		noise = 2 * noise_std * np.random.random(size=n) - noise_std

		SigX = get_sigX(X, mast)
		beta_repeated = np.repeat(beta.reshape(1, size_sig), n, axis=0)
		Y = np.sum(beta_repeated * SigX, axis=1)

		if plot:
			plt.scatter(Y, Y + noise)
			plt.title("Y against Y+noise")
			plt.show()
		return Y + noise
示例#24
0
    def __init__(self, ef_num_hlayers, ef_num_hu, ef_num_filters, pslevel,
                 num_slices, dropout):

        super(dgmslice_ps, self).__init__()

        self.filters = ef_num_filters
        self.pslevel = pslevel
        self.siglength = [
            iisignature.siglength(num_slices + 1, m) for m in pslevel
        ]
        self.eigfs = nn.ModuleList()
        self.final_vec_length = self.filters * sum(self.siglength)
        self.slices = num_slices
        for i in range(self.filters):
            self.eigfs.append(eigf(ef_num_hlayers, ef_num_hu))

        self.projections = nn.Conv1d(1, self.slices, 2, 2)
        self.final_layer = nn.Sequential(nn.Dropout(dropout),
                                         nn.Linear(self.final_vec_length, 1),
                                         nn.BatchNorm1d(1))
示例#25
0
def ComputeMultiLevelSig1dBM(BM_paths, number_of_segment, depth_of_tensors, T):
    """
    Compute the signature of all samples
    """
    s = iisignature.prepare(2, depth_of_tensors)
    no_of_samples = np.shape(BM_paths)[0]
    MultiLevelSigs = np.zeros([no_of_samples, iisignature.siglength(
        2, depth_of_tensors) * number_of_segment - 1], dtype=float)
    print('start computing the sigs of degree %d:' % depth_of_tensors)
    for j in tqdm(range(0, no_of_samples, 1), total=no_of_samples):
        BM = TimeJointPath(BM_paths[j, :], T)
        result2 = ComputeMultiLevelSig(
            BM, number_of_segment, depth_of_tensors, s, sig='True')
        MultiLevelSigs[j] = result2['MultiLevelLogSig']
    if number_of_segment > 1:
        n_input = int(np.shape(MultiLevelSigs)[1] / number_of_segment)
        X_sig = MultiLevelSigs.reshape(
            (np.shape(MultiLevelSigs)[0], number_of_segment, n_input))
    else:
        X_sig = MultiLevelSigs
    return X_sig
 def __init__(self, n_units,
              sig_level=2,
              train_time_lapse =False,
              initial_time_lapse=0.1,
              output_signatures = False,#whether the output includes the signatures
              use_signatures = True, #whether each new state can depend on the signature
              kernel_initializer='glorot_uniform',
              recurrent_initializer='he_normal',#could be good to use 'orthogonal' if not use_signatures
              activation='tanh',#not applied to signature elements
              **kwargs):
     self.sig_level = sig_level
     self.sigsize = iisignature.siglength(2,sig_level)
     self.n_units = n_units #like output_dim
     self.units = n_units*(self.sigsize+1) if output_signatures else n_units
     self.train_time_lapse = train_time_lapse
     self.initial_time_lapse = initial_time_lapse
     self.output_signatures = output_signatures
     self.use_signatures = use_signatures
     self.kernel_initializer = initializers.get(kernel_initializer)
     self.recurrent_initializer = initializers.get(recurrent_initializer)
     self.activation = activations.get(activation)
     super(RecurrentSig, self).__init__(**kwargs)
示例#27
0
    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))
示例#28
0
    def dotest(self,type):
        m = 8
        nPaths = 95
        nAngles = 348
        numpy.random.seed(775)
        s = iisignature.rotinv2dprepare(m,type)
        coeffs = iisignature.rotinv2dcoeffs(s)
        angles = numpy.random.uniform(0,math.pi * 2,size=nAngles + 1)
        angles[0] = 0
        rotationMatrices = [numpy.array([[math.cos(i),math.sin(i)],[-math.sin(i),math.cos(i)]]) for i in angles]
        paths = [numpy.random.uniform(-1,1,size=(32,2)) for i in range(nPaths)]
        samePathRotInvs = [iisignature.rotinv2d(numpy.dot(paths[0],mtx),s) for mtx in rotationMatrices]

        #check the length matches
        (length,) = samePathRotInvs[0].shape
        self.assertEqual(length,sum(i.shape[0] for i in coeffs))
        self.assertEqual(length,iisignature.rotinv2dlength(s))
        if type == "a":
            self.assertEqual(length,sumCentralBinomialCoefficient(m // 2))

        self.assertLess(length,nAngles)#sanity check on the test itself

        #check that the invariants are invariant
        if 0:
            print("\n",numpy.column_stack(samePathRotInvs[0:7]))
        for i in range(nAngles):
            if 0 and diff(samePathRotInvs[0],samePathRotInvs[1 + i]) > 0.01:
                print(i)
                print(samePathRotInvs[0] - samePathRotInvs[1 + i])
                print(diff(samePathRotInvs[0],samePathRotInvs[1 + i]))
            self.assertLess(diff(samePathRotInvs[0],samePathRotInvs[1 + i]),0.01)

        #check that the invariants match the coefficients
        if 1:
            sigLevel=iisignature.sig(paths[0],m)[iisignature.siglength(2,m-1):]
            lowerRotinvs = 0 if 2==m else iisignature.rotinv2dlength(iisignature.rotinv2dprepare(m-2,type))
            #print("\n",numpy.dot(coeffs[-1],sigLevel),"\n",samePathRotInvs[0][lowerRotinvs:])
            #print(numpy.dot(coeffs[-1],sigLevel)-samePathRotInvs[0][lowerRotinvs:])
            self.assertTrue(numpy.allclose(numpy.dot(coeffs[-1],sigLevel),samePathRotInvs[0][lowerRotinvs:],atol=0.000001))

        #check that we are not missing invariants
        if type == "a":
            #print("\nrotinvlength=",length,"
            #siglength=",iisignature.siglength(2,m))
            sigOffsets = []
            for path in paths:
                samePathSigs = [iisignature.sig(numpy.dot(path,mtx),m) for mtx in rotationMatrices[1:70]]
                samePathSigsOffsets = [i - samePathSigs[0] for i in samePathSigs[1:]]
                sigOffsets.extend(samePathSigsOffsets)
            #print(numpy.linalg.svd(numpy.row_stack(sigOffsets))[1])
            def split(a, dim, level):
                start = 0
                out = []
                for m in range(1,level + 1):
                    levelLength = dim ** m
                    out.append(a[:,start:(start + levelLength)])
                    start = start + levelLength
                assert(start == a.shape[1])
                return out
            allOffsets = numpy.row_stack(sigOffsets)
            #print (allOffsets.shape)
            splits = split(allOffsets,2,m)
            #print()
            rank_tolerance = 0.01 # this is hackish
            #print
                                             #([numpy.linalg.matrix_rank(i.astype("float64"),rank_tolerance)
                                                                              #for
                                                                              #i in splits])
                                                                              #print ([i.shape for i in splits])
                                                                              #print(numpy.linalg.svd(splits[-1])[1])

            #sanity check on the test
            self.assertLess(splits[-1].shape[1],splits[0].shape[0])
            totalUnspannedDimensions = sum(i.shape[1] - numpy.linalg.matrix_rank(i,rank_tolerance) for i in splits)
            self.assertEqual(totalUnspannedDimensions,length)

        if 0: #This doesn't work - the rank of the whole thing is less than
        #sigLength-totalUnspannedDimensions, which suggests that there are
        #inter-level dependencies,
        #even though the shuffle product dependencies aren't linear. 
        #I don't know why this is.
            sigLength = iisignature.siglength(2,m)
            numNonInvariant = numpy.linalg.matrix_rank(numpy.row_stack(sigOffsets))

            predictedNumberInvariant = sigLength - numNonInvariant
            print(sigLength,length,numNonInvariant)
            self.assertLess(sigLength,nAngles)
            self.assertEqual(predictedNumberInvariant,length)
def sigdim(d,m):
    return 1 + iisignature.siglength(d,m)
示例#30
0
 def perform(self,node,inp,out):
     #do I really need to create an array here?
     out[0][0]=np.array(iisignature.siglength(inp[0],inp[1]),dtype="int32")
示例#31
0
fixed = 0.1

numpy.random.seed(51)
start = numpy.random.uniform(size=(pathlength, dim)).astype("float32")

#2: DEFINE THEANO STUFF

path = theano.shared(start, "path")
if not numpy.isnan(fixed):
    fixedT = theano.shared(fixed, "fixedT")
    path = theano.tensor.horizontal_stack(
        path[:, :-1], fixedT * T.shape_padright(T.arange(pathlength)))
cost1 = theano.tensor.mean(theano.tensor.sqr(Sig(path, level)))
grad1 = theano.grad(cost1, path)

signature = numpy.zeros((1, iisignature.siglength(dim,
                                                  level))).astype("float32")
for i in six.moves.xrange(1, pathlength):
    if not numpy.isnan(fixed):
        displacement = path[i:(i + 1), :-1] - path[(i - 1):i, :-1]
        signature = SigJoin(signature, displacement, level, fixedT)
    else:
        displacement = path[i:(i + 1), :] - path[(i - 1):i, :]
        signature = SigJoin(signature, displacement, level)

cost2 = theano.tensor.mean(theano.tensor.sqr(signature))
grad2 = theano.grad(cost2, path)

#theano.printing.pydotprint(grad2,outfile="a.png")

ff = theano.function([], [grad1, grad2])
#theano.printing.pydotprint(ff,outfile="b.png")
def setup(obj):
    obj.path = torch.rand(obj.size, dtype=torch.float).numpy()
    shape = obj.size[-3], iisignature.siglength(obj.size[-1], obj.depth)
    obj.grad = torch.rand(shape).numpy()
示例#33
0
#This program just continually runs some of the important functionality in
#iisignature on small data, so that you can check that memory usage
#does not grow. Even a tiny memory leak becomes very visible e.g. in htop.

#add the parent directory, so we find our iisignature build if it was built --inplace
sys.path.append(os.path.dirname(os.path.abspath(os.path.dirname(__file__))))
import iisignature

length = 20
dim=3
level=2
npaths=3
paths_ = np.random.uniform(size=(npaths,length,dim))
scale_ = np.random.uniform(size=(npaths,dim))
initialsigs_ = np.random.uniform(size=(npaths,iisignature.siglength(dim,level)))
p=iisignature.prepare(dim,level,"cosx")
while 0:
    iisignature.sig(paths[0],level)
for i in range(10**10):
    #copy major parts of the input data, in case we are leaking references to it
    paths=paths_[:]
    increment=scale=scale_[:]
    initialsigs=initialsigs_[:]
    iisignature.sigjoin(initialsigs,scale,level)
    iisignature.sigscale(initialsigs,scale,level)
    iisignature.sigjoinbackprop(initialsigs,initialsigs,scale,level)
    iisignature.sigscalebackprop(initialsigs,initialsigs,scale,level)
    iisignature.sig(paths[0,:,:],level)
    iisignature.sigbackprop(initialsigs[0,:],paths[0,:,:],level)
    #iisignature.sigjacobian(paths[0,:,:],level)
示例#34
0
    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))
示例#35
0
def iisignature_sig(x, d):
    if len(x) <= 1:
        return np.zeros(iisignature.siglength(x.shape[1], d))
    else:
        return iisignature.sig(x, d)
示例#36
0
import os, sys
#os.environ["KERAS_BACKEND"]="tensorflow"
#os.environ["THEANO_FLAGS"]="mode=DebugMode,device=cpu,optimizer_excluding=local_shape_to_shape_i"
import numpy as np, keras
import keras.models, keras.layers.recurrent, keras.layers.core
import keras.backend as K
sys.path.append(os.path.dirname(os.path.abspath(os.path.dirname(__file__))))
if K.backend() == "theano":
    from iisignature_theano import Sig
if K.backend() == "tensorflow":
    from iisignature_tensorflow import Sig
import iisignature

sig_level = 2
siglen = iisignature.siglength(2, sig_level)
nSamples = 21
xDim = 55

X = np.zeros((nSamples, xDim), dtype="float32")
Y = np.ones((nSamples, ), dtype="float32")

m = keras.models.Sequential()

m.add(keras.layers.core.Dense(106, input_shape=(xDim, )))
m.add(keras.layers.core.Reshape((53, 2)))
m.add(keras.layers.core.Lambda(lambda x: Sig(x, 2), output_shape=(siglen, )))
m.add(keras.layers.core.Reshape((siglen, 1)))
m.add(keras.layers.pooling.AveragePooling1D(siglen))
m.add(keras.layers.core.Flatten())
m.compile(loss='mse', optimizer="sgd")
示例#37
0
import os, sys
#os.environ["KERAS_BACKEND"]="tensorflow"
#os.environ["THEANO_FLAGS"]="mode=DebugMode,device=cpu,optimizer_excluding=local_shape_to_shape_i"
import numpy as np, keras
import keras.models, keras.layers.recurrent, keras.layers.core
import keras.backend as K
sys.path.append(os.path.dirname(os.path.abspath(os.path.dirname(__file__))))
if K.backend() == "theano":
    from iisignature_theano import Sig
if K.backend() == "tensorflow":
    from iisignature_tensorflow import Sig
import iisignature

sig_level=2
siglen = iisignature.siglength(2,sig_level)
nSamples=21
xDim=55

X=np.zeros((nSamples,xDim),dtype="float32")
Y=np.ones((nSamples,),dtype="float32")

m=keras.models.Sequential()

m.add(keras.layers.core.Dense(106, input_shape=(xDim,)))
m.add(keras.layers.core.Reshape((53,2)))
m.add(keras.layers.core.Lambda(lambda x:Sig(x,2),output_shape=(siglen,)))
m.add(keras.layers.core.Reshape((siglen,1)))
m.add(keras.layers.pooling.AveragePooling1D(siglen))
m.add(keras.layers.core.Flatten())
m.compile(loss='mse',optimizer="sgd")
示例#38
0
#This program just continually runs some of the important functionality in
#iisignature on small data, so that you can check that memory usage
#does not grow. Even a tiny memory leak becomes very visible e.g. in htop.

#add the parent directory, so we find our iisignature build if it was built --inplace
sys.path.append(os.path.dirname(os.path.abspath(os.path.dirname(__file__))))
import iisignature

length = 20
dim = 3
level = 2
npaths = 3
paths_ = np.random.uniform(size=(npaths, length, dim))
scale_ = np.random.uniform(size=(npaths, dim))
initialsigs_ = np.random.uniform(size=(npaths,
                                       iisignature.siglength(dim, level)))
p = iisignature.prepare(dim, level, "cosx")
while 0:
    iisignature.sig(paths[0], level)
for i in range(10**10):
    #copy major parts of the input data, in case we are leaking references to it
    paths = paths_[:]
    increment = scale = scale_[:]
    initialsigs = initialsigs_[:]
    iisignature.sigjoin(initialsigs, scale, level)
    iisignature.sigscale(initialsigs, scale, level)
    iisignature.sigjoinbackprop(initialsigs, initialsigs, scale, level)
    iisignature.sigscalebackprop(initialsigs, initialsigs, scale, level)
    iisignature.sig(paths[0, :, :], level)
    iisignature.sigbackprop(initialsigs[0, :], paths[0, :, :], level)
    #iisignature.sigjacobian(paths[0,:,:],level)
示例#39
0
 def perform(self,node,inp,out):
     #do I really need to create an array here?
     out[0][0]=numpy.array(iisignature.siglength(inp[0],inp[1]),dtype="int32")
示例#40
0
def sigdim(d, m):
    return 1 + iisignature.siglength(d, m)
示例#41
0
    def dotest(self,type):
        m = 8
        nPaths = 95
        nAngles = 348
        numpy.random.seed(775)
        s = iisignature.rotinv2dprepare(m,type)
        coeffs = iisignature.rotinv2dcoeffs(s)
        angles = numpy.random.uniform(0,math.pi * 2,size=nAngles + 1)
        angles[0] = 0
        rotationMatrices = [numpy.array([[math.cos(i),math.sin(i)],[-math.sin(i),math.cos(i)]]) for i in angles]
        paths = [numpy.random.uniform(-1,1,size=(32,2)) for i in range(nPaths)]
        samePathRotInvs = [iisignature.rotinv2d(numpy.dot(paths[0],mtx),s) for mtx in rotationMatrices]

        #check the length matches
        (length,) = samePathRotInvs[0].shape
        self.assertEqual(length,sum(i.shape[0] for i in coeffs))
        self.assertEqual(length,iisignature.rotinv2dlength(s))
        if type == "a":
            self.assertEqual(length,sumCentralBinomialCoefficient(m // 2))

        self.assertLess(length,nAngles)#sanity check on the test itself

        #check that the invariants are invariant
        if 0:
            print("\n",numpy.column_stack(samePathRotInvs[0:7]))
        for i in range(nAngles):
            if 0 and diff(samePathRotInvs[0],samePathRotInvs[1 + i]) > 0.01:
                print(i)
                print(samePathRotInvs[0] - samePathRotInvs[1 + i])
                print(diff(samePathRotInvs[0],samePathRotInvs[1 + i]))
            self.assertLess(diff(samePathRotInvs[0],samePathRotInvs[1 + i]),0.01)

        #check that the invariants match the coefficients
        if 1:
            sigLevel=iisignature.sig(paths[0],m)[iisignature.siglength(2,m-1):]
            lowerRotinvs = 0 if 2==m else iisignature.rotinv2dlength(iisignature.rotinv2dprepare(m-2,type))
            #print("\n",numpy.dot(coeffs[-1],sigLevel),"\n",samePathRotInvs[0][lowerRotinvs:])
            #print(numpy.dot(coeffs[-1],sigLevel)-samePathRotInvs[0][lowerRotinvs:])
            self.assertTrue(numpy.allclose(numpy.dot(coeffs[-1],sigLevel),samePathRotInvs[0][lowerRotinvs:],atol=0.000001))

        #check that we are not missing invariants
        if type == "a":
            #print("\nrotinvlength=",length,"
            #siglength=",iisignature.siglength(2,m))
            sigOffsets = []
            for path in paths:
                samePathSigs = [iisignature.sig(numpy.dot(path,mtx),m) for mtx in rotationMatrices[1:70]]
                samePathSigsOffsets = [i - samePathSigs[0] for i in samePathSigs[1:]]
                sigOffsets.extend(samePathSigsOffsets)
            #print(numpy.linalg.svd(numpy.row_stack(sigOffsets))[1])
            def split(a, dim, level):
                start = 0
                out = []
                for m in range(1,level + 1):
                    levelLength = dim ** m
                    out.append(a[:,start:(start + levelLength)])
                    start = start + levelLength
                assert(start == a.shape[1])
                return out
            allOffsets = numpy.row_stack(sigOffsets)
            #print (allOffsets.shape)
            splits = split(allOffsets,2,m)
            #print()
            rank_tolerance = 0.01 # this is hackish
            #print
                                             #([numpy.linalg.matrix_rank(i.astype("float64"),rank_tolerance)
                                                                              #for
                                                                              #i in splits])
                                                                              #print ([i.shape for i in splits])
                                                                              #print(numpy.linalg.svd(splits[-1])[1])

            #sanity check on the test
            self.assertLess(splits[-1].shape[1],splits[0].shape[0])
            totalUnspannedDimensions = sum(i.shape[1] - numpy.linalg.matrix_rank(i,rank_tolerance) for i in splits)
            self.assertEqual(totalUnspannedDimensions,length)

        if 0: #This doesn't work - the rank of the whole thing is less than
        #sigLength-totalUnspannedDimensions, which suggests that there are
        #inter-level dependencies,
        #even though the shuffle product dependencies aren't linear. 
        #I don't know why this is.
            sigLength = iisignature.siglength(2,m)
            numNonInvariant = numpy.linalg.matrix_rank(numpy.row_stack(sigOffsets))

            predictedNumberInvariant = sigLength - numNonInvariant
            print(sigLength,length,numNonInvariant)
            self.assertLess(sigLength,nAngles)
            self.assertEqual(predictedNumberInvariant,length)
示例#42
0
fixed = float("nan")
fixed = 0.1

numpy.random.seed(51)
start = numpy.random.uniform(size=(pathlength,dim)).astype("float32")

#2: DEFINE THEANO STUFF

path = theano.shared(start, "path")
if not numpy.isnan(fixed):
    fixedT = theano.shared(fixed, "fixedT")
    path=theano.tensor.horizontal_stack(path[:,:-1],fixedT*T.shape_padright(T.arange(pathlength)))
cost1 = theano.tensor.mean(theano.tensor.sqr(Sig(path,level)))
grad1 = theano.grad(cost1,path)

signature = numpy.zeros((1,iisignature.siglength(dim,level))).astype("float32")
for i in six.moves.xrange(1,pathlength):
    if not numpy.isnan(fixed):
        displacement = path[i:(i+1),:-1]-path[(i-1):i,:-1]
        signature = SigJoin(signature,displacement,level,fixedT)
    else:
        displacement = path[i:(i+1),:]-path[(i-1):i,:]
        signature = SigJoin(signature,displacement,level)

cost2 = theano.tensor.mean(theano.tensor.sqr(signature))
grad2 = theano.grad(cost2,path)

#theano.printing.pydotprint(grad2,outfile="a.png")

ff = theano.function([],[grad1,grad2])
#theano.printing.pydotprint(ff,outfile="b.png")