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}")
我在跑自己的数据和训练代码的时候,遇到了2个问题:
1,为了方便调试,我修改了一下symbolic_formula函数为:
20240626调试symbolic_formula
然后运行我自己根据需求写的一个训练代码,用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](https://github.com/KindXiaoming/pykan/assets/65295258/f95822cc-a4d9-4913-b780-1a45bf63dd5a)
但是有个问题,我的x_5当中,有很多数据是负数,而上述kan给出的公式当中,x_5有根号:
7.73sqrt(0.08x_5 + 1)
也就是这个计算会出现虚数,而我的数据都没有虚数。。。。
这就不对了。。。。。’
不知道kan这个为啥回归推理关系式,出现了这种情况。。。。
大佬来研究研究doge