KindXiaoming / pykan

Kolmogorov Arnold Networks
MIT License
13.79k stars 1.23k forks source link

回归关系式除0的问题,以及回归出来的关系式存在根号下负值的问题 #289

Open Nzavcciuoier123 opened 2 weeks ago

Nzavcciuoier123 commented 2 weeks ago

我在跑自己的数据和训练代码的时候,遇到了2个问题:

1,为了方便调试,我修改了一下symbolic_formula函数为:

20240626调试symbolic_formula

def symbolic_formula(self, floating_digit=2, var=None, normalizer=None, simplify=False):
    '''
    obtain the symbolic formula

    Args:
    -----
        floating_digit : int
            the number of digits to display
        var : list of str
            the name of variables (if not provided, by default using ['x_1', 'x_2', ...])
        normalizer : [mean array (floats), varaince array (floats)]
            the normalization applied to inputs
        simplify : bool
            If True, simplify the equation at each step (usually quite slow), so set up False by default.

    Returns:
    --------
        symbolic formula : sympy function

    Example
    -------
    >>> model = KAN(width=[2,5,1], grid=5, k=3, noise_scale=0.1, seed=0, grid_eps=0.02)
    >>> f = lambda x: torch.exp(torch.sin(torch.pi*x[:,[0]]) + x[:,[1]]**2)
    >>> dataset = create_dataset(f, n_var=2)
    >>> model.train(dataset, opt='LBFGS', steps=50, lamb=0.01);
    >>> model = model.prune()
    >>> model(dataset['train_input'])
    >>> model.auto_symbolic(lib=['exp','sin','x^2'])
    >>> model.train(dataset, opt='LBFGS', steps=50, lamb=0.00, update_grid=False);
    >>> model.symbolic_formula()
    '''
    symbolic_acts = []
    x = []
    #original
    # def ex_round(ex1, floating_digit=floating_digit):
    #     ex2 = ex1
    #     for a in sympy.preorder_traversal(ex1):
    #         if isinstance(a, sympy.Float):
    #             ex2 = ex2.subs(a, round(a, floating_digit))
    #     return ex2
    #20240626调试
    def ex_round(ex1, floating_digit=2):
        ex2 = ex1
        for a in sympy.preorder_traversal(ex1):
            if isinstance(a, sympy.Float):
                try:
                    #round:将a进行floating_digit位的四舍五入
                    rounded_value = round(a, floating_digit)
                    #sympy.subs:将变量或者式子a替换成b
                    ex2 = ex2.subs(a, rounded_value)
                except ZeroDivisionError as e:
                    print("----------------")
                    print(
                        f"ZeroDivisionError: rounding value {a} to {floating_digit} digits resulted in error: {e}")
                    print("a:",a)
                    print("rounded_value:", rounded_value)
                    print("ex2.subs(a, rounded_value):", ex2)
                    print("----------------")
                    continue
                except Exception as e:
                    print(f"Exception during rounding: {e}")
                    continue
        return ex2

    # define variables
    if var == None:
        for ii in range(1, self.width[0] + 1):
            exec(f"x{ii} = sympy.Symbol('x_{ii}')")
            exec(f"x.append(x{ii})")
    else:
        x = [sympy.symbols(var_) for var_ in var]

    x0 = x

    if normalizer != None:
        mean = normalizer[0]
        std = normalizer[1]
        x = [(x[i] - mean[i]) / std[i] for i in range(len(x))]

    symbolic_acts.append(x)

    for l in range(len(self.width) - 1):
        y = []
        for j in range(self.width[l + 1]):
            yj = 0.
            for i in range(self.width[l]):
                a, b, c, d = self.symbolic_fun[l].affine[j, i]
                sympy_fun = self.symbolic_fun[l].funs_sympy[j][i]
                try:
                    yj += c * sympy_fun(a * x[i] + b) + d
                except ZeroDivisionError as e:
                    print(
                        f"ZeroDivisionError: layer={l}, input_neuron={i}, output_neuron={j}, a={a}, b={b}, c={c}, d={d}, sympy_fun={sympy_fun}")
                    return
                except Exception as e:
                    print(f"Exception: {e}")
                    return
            if simplify == True:
                y.append(sympy.simplify(yj + self.biases[l].weight.data[0, j]))
            else:
                y.append(yj + self.biases[l].weight.data[0, j])

        x = y
        symbolic_acts.append(x)

    self.symbolic_acts = [[ex_round(symbolic_acts[l][i]) for i in range(len(symbolic_acts[l]))] for l in
                          range(len(symbolic_acts))]

    out_dim = len(symbolic_acts[-1])
    return [ex_round(symbolic_acts[-1][i]) for i in range(len(symbolic_acts[-1]))], x0

然后运行我自己根据需求写的一个训练代码,用kan模型回归12个因子数据,输出了除0的问题: model.symbolic_formula(): ZeroDivisionError: rounding value 0.0314825062202321 to 2 digits resulted in error: integer division or modulo by zero ZeroDivisionError: rounding value 0.0122997719047150 to 2 digits resulted in error: integer division or modulo by zero ZeroDivisionError: rounding value 0.00800001820320635 to 2 digits resulted in error: integer division or modulo by zero ZeroDivisionError: rounding value 0.0382286594952153 to 2 digits resulted in error: integer division or modulo by zero ZeroDivisionError: rounding value 0.00960726557240071 to 2 digits resulted in error: integer division or modulo by zero ZeroDivisionError: rounding value 0.00501973010930146 to 2 digits resulted in error: integer division or modulo by zero ZeroDivisionError: rounding value -0.0652459680717108 to 2 digits resulted in error: integer division or modulo by zero ZeroDivisionError: rounding value -0.0171770888741439 to 2 digits resulted in error: integer division or modulo by zero ZeroDivisionError: rounding value -0.0227702529010633 to 2 digits resulted in error: integer division or modulo by zero ZeroDivisionError: rounding value -0.0120942440459707 to 2 digits resulted in error: integer division or modulo by zero ZeroDivisionError: rounding value 0.0314825062202321 to 2 digits resulted in error: integer division or modulo by zero ZeroDivisionError: rounding value 0.0122997719047150 to 2 digits resulted in error: integer division or modulo by zero ZeroDivisionError: rounding value 0.00800001820320635 to 2 digits resulted in error: integer division or modulo by zero ZeroDivisionError: rounding value 0.0382286594952153 to 2 digits resulted in error: integer division or modulo by zero ZeroDivisionError: rounding value 0.00960726557240071 to 2 digits resulted in error: integer division or modulo by zero ZeroDivisionError: rounding value 0.00501973010930146 to 2 digits resulted in error: integer division or modulo by zero ZeroDivisionError: rounding value -0.0652459680717108 to 2 digits resulted in error: integer division or modulo by zero ZeroDivisionError: rounding value -0.0171770888741439 to 2 digits resulted in error: integer division or modulo by zero ZeroDivisionError: rounding value -0.0227702529010633 to 2 digits resulted in error: integer division or modulo by zero ZeroDivisionError: rounding value -0.0120942440459707 to 2 digits resulted in error: integer division or modulo by zero

输出的位置是在ex_round函数当中。 print( f"ZeroDivisionError: rounding value {a} to {floating_digit} digits resulted in error: {e}")

这个除0的问题咋解决啊啊啊

也就是报错提示有式子分母为0。。。。。。

2,这是kan回归推理出来,12个因子数据的关系式:

我调用的函数是: print(model.symbolic_formula())

输出的关系式是:

([32.46sin(-7.56tanh(11.17*(0.61 - x_1)2 + 36.78(0.63 - x_8)**3 - 7.73sqrt(0.08x_5 + 1) + 1.22sin(6.8x_11 + 10.0) - 3.52sin(10.0x_12 - 1.2) + 5.31tanh(1.8x_7 - 0.12) + 0.12Abs(8.35x_10 - 5.17) + 0.4Abs(8.77x_3 - 7.76) + 0.15Abs(9.0x_4 - 5.72) + 0.48Abs(3.94x_6 + 9.23) + 1.19Abs(9.48x_9 - 5.25) + 6.38 - 0.9/sqrt(x_2 - 0.72)) + 1.02tanh(-0.0227702529010633sin(3.6x_11 + 9.52) + 0.00800001820320635sin(10.0x_3 + 7.6) - 0.0120942440459707sin(10.0x_4 - 8.8) + 0.0314825062202321sin(0.4x_5 + 2.98) + 0.00960726557240071tanh(10.0x_1 - 4.6) + 0.012299771904715tanh(10.0x_10 - 2.2) + 6.72tanh(5.21x_12 - 4.4) + 0.0382286594952153tanh(2.73x_6 - 1.56) - 0.0171770888741439tanh(10.0x_9 - 5.07) + 0.01Abs(8.55x_2 - 7.54) + 0.00501973010930146asin(2.46x_8 - 1.46) - 3.92 - 0.0652459680717108exp(-6.0x_7)) + 10.96) + 33.59], [x_1, x_2, x_3, x_4, x_5, x_6, x_7, x_8, x_9, x_10, x_11, x_12])

png图片: QianJianTec1719404531316

但是有个问题,我的x_5当中,有很多数据是负数,而上述kan给出的公式当中,x_5有根号:

7.73sqrt(0.08x_5 + 1)

也就是这个计算会出现虚数,而我的数据都没有虚数。。。。

这就不对了。。。。。’

不知道kan这个为啥回归推理关系式,出现了这种情况。。。。

大佬来研究研究doge

Nzavcciuoier123 commented 2 weeks ago

QianJianTec171940453131333336

KindXiaoming commented 2 days ago

转成符号公式确实会有Singularity的问题,还在想咋解决。。