用神经网络找到多项式的最大根


11

挑战

找到最小的前馈神经网络,以便在给定具有整数项的任何3维输入向量,网络输出最大前馈神经网络(即,“最正”)的根多项式,其误差严格小于。(a,b,c)[10,10]x3+ax2+bx+c0.1

可接纳性

我之前的神经网络高尔夫挑战赛中,可接纳性的概念似乎有些局限,因此对于这一挑战,我们使用了更为宽松的前馈神经网络定义:

神经元是一个函数,其由向量所指定的权重,一个偏压激活函数的方式如下:ν:RnRwRn bR f:RR

ν(x):=f(wx+b),xRn.

具有输入节点 的前馈神经网络是,可以根据序列个神经元,其中每个从并输出标量。鉴于一些指定的一组的输出节点,则所述神经网络的输出是向量。{1,,n}(x1,,xn)Rn(νk)k=n+1Nνk:Rk1R(x1,,xk1)xkS{1,,N}(xk)kS

由于可以针对任何给定任务调整激活功能,因此我们需要限制激活功能的类别,以使这一挑战变得有趣。允许以下激活功能:

  • 身份。 f(t)=t

  • ReLU。 f(t)=max(t,0)

  • SoftPlus。 f(t)=ln(et+1)

  • 乙状结肠。 f(t)=etet+1

  • 正弦曲线。 f(t)=sint

总体而言,可允许的神经网络由输入节点,神经元序列和输出节点指定,而每个神经元由权重,偏差和激活函数(由上表列出)指定。例如,以下神经网络是可以接受的,尽管它不能满足此挑战的性能目标:

  • 输入节点: {1,2}

  • 神经元: forνk(x1,,xk1):=xk2+xk1k{3,,10}

  • 输出节点: {5,9,10}

该网络由8个神经元组成,每个神经元具有零偏倚和身份激活。换句话说,该网络计算由和生成的广义斐波纳契数列,然后以该顺序输出该数列的第5,第9和第10个数。x1x2

计分

给定的实数与十进制扩展,让是最小的非负整数为其中,并且让是最小的非负整数为其中是整数。然后我们说是精密的。xp(x)p10p|x|<1q(x)q10qxp(x)+q(x)x

例如,的精度为,而的精度为。x=1.0014x=00

您的分数是神经网络中权重和偏差的精度之和。

(例如,上面的示例得分为16。)

验证

虽然可以用三次公式来表示根,但是最大的根也许最容易通过数值手段获得。继@ XNOR的建议下,我计算出的最大根整数的每一次选择,并且结果可以在这里找到。此文本文件的每一行都是形式。例如,第一行报告的最大根大约为。a,b,c[10,10]a,b,c,rootx310x210x1010.99247140445449

编辑:如果多项式具有多个根,我发布的原始文件将出错。当前版本应该没有此类错误。


3
输入多项式没有实际根时会发生什么,例如何时a=0和二次有两个复数根?
xnor19

我认为最干净的解决方案是说输入将为a非零或什至仅为1。此外,我建议放入一些测试用例,将根设为高精度,以便我们可以检查输入值是否在0.1以内。为所有可能的输入提供输出也可能是一件好事,可能在链接中,因为帖子很多。
xnor19

1
我喜欢新的受理规则。看起来新的正弦函数非常有用。我有一个粗略的证明,即该形式的函数x -> a * sin(b * softplus(x) + c)可以x使用极大且精确的频率将整数形式的任意有限数量的数据点过度拟合为任意精度。
xnor19年

1
不确定它的用途(对于未来的挑战):在数论中,我们使用高度函数来测量数的复杂度。例如,(降低的)分数的天真高度由(并且有很多概括)。也许这可以用作替代措施。p/qh=logmax{|p|,|q|}
瑕疵的

1
@ DustinG.Mixon我不确定您是否知道,但是我们确实有一个沙盒,用于发布草稿并讨论问题的细节以及聊天
瑕疵的

Answers:


6

14,674,000,667 5,436,050 5,403,448 10,385 5,994 4,447
3,806总精度

对于基线,我研究了以下方法:选择,以便如果我们对多项式进行采样M,δ,ϵ>0p(x)=x3+ax2+bx+c

S:={M,M+δ,M+2δ,,M},

则满足的最大采样点必须存在,并且必须位于的最大根的内。可以证明,对于我们的多项式集合,可以取,和。sSp(s)<ϵ0.1pM=11δ=0.1ϵ=104

为了设计实现此逻辑的神经网络,我们从对上的多项式采样的神经元层开始。对于每个,我们采取SsS

x1,s=s2a+sb+1c+s3.

接下来,我们确定其中哪个小于。事实证明,对于,仅当,才认为。因此,我们可以使用relu激活来准确识别我们的样本:ϵ=104sSp(s)<104p(s)0

relu(104t)relu(t)104={1if t00if t104.

我们用几层神经元来实现这一点:

x2,s=relu(1x1,s+104),x3,s=relu(1x1,s),x4,s=104x2,s104x3,s.

此时,当时,我们有,否则。回想一下,我们寻求最大的为其。为此,我们将标记为(为方便起见),并且对于每个,我们迭代定义x4,s=1p(s)<104x4,s=0sx4,s=1x4,Mx5,Mk1

x5,Mkδ=1x4,Mkδ+2x5,M(k1)δ=j=0k2kjx4,Mjδ.

由于这一转变,每是一个非负整数,而是唯一的为其。现在,我们可以通过relu激活的另一个应用程序来识别:x5,sssx5,s=1s

relu(t2)2relu(t1)+t={1if t=10if tZ0{1}.

明确地说,我们通过

x6,s=relu(1x5,s2),x7,s=relu(1x5,s1),x8,s=1x6,s2x7,s+1x5s.

然后,如果否则。我们将它们线性组合以产生输出节点:x8,s=1s=sx8,s=0

x9=sSsx8,s=s.

对于得分,每一层具有不同精度级别的神经元:(1),(2),(3),(4), (5),(6),(7),(8),(9)。此外,除两层外,所有层都有神经元;第5层具有神经元,第9层具有神经元。6+3+1+9=191+4=515+5=101+1=21+1=21+1=21+1+1=33|S||S|=221|S|11

编辑:改进:(1)我们可以使用有限差分更有效地对多项式进行采样。(2)我们可以通过使用S型激活来绕过第2到第4层。(3)通过更仔细地应用relu激活,可以避免第5层中的溢出问题(并且可以合并后续的层)。(4)将最终总和是更便宜的通过部分求和

接下来是MATLAB代码。要明确的prec是,一个函数(在此处找到)可计算权重或偏差向量的精度。

function sstar = findsstar2(a,b,c)

relu = @(x) x .* (x>0);

totprec = 0;

% x1 samples the polynomial on -11:0.1:11
x1=[];
for s = -11:0.1:11
    if length(x1) < 5
        w1 = [s^2 s 1];
        b1 = s^3;
        x1(end+1,:) = w1 * [a; b; c] + b1;
        totprec = totprec + prec(w1) + prec(b1);
    else
        w1 = [-1 4 -6 4];
        x1(end+1,:) = w1 * x1(end-3:end,:);
        totprec = totprec + prec(w1);
    end
end

% x4 indicates whether the polynomial is nonpositive
w4 = -6e5;
b4 = 60;
x4=[];
for ii=1:length(x1)
    x4(end+1) = sigmf(w4 * x1(ii) + b4, [1,0]);
    totprec = totprec + prec(w4) + prec(b4);
end

% x6 indicates which entries are less than or equal to sstar
x5 = zeros(size(x1));
x6 = zeros(size(x1));
x5(end) = 0;
x6(end) = 0;
for ii = 1:length(x5)-1
    w5 = [-1 -1];
    b5 = 1;
    x5(end-ii) = relu(w5 * [x4(end-ii); x6(end-ii+1)] + b5);
    totprec = totprec + prec(w5) + prec(b5);
    w6 = -1;
    b6 = 1;
    x6(end-ii) = w6 * x5(end-ii) + b6;
    totprec = totprec + prec(w6) + prec(b6);
end

% a linear combination produces sstar
w7 = 0.1*ones(1,length(x1));
w7(1) = -11;
sstar = w7 * x6;

%disp(totprec) % uncomment to display score

end

2

53,268 29,596 29,306总精度

与@ A.Rex的私人通信导致了该解决方案,在该解决方案中,我们构建了一个用于记忆答案的神经网络。核心思想是,有限集上的每个函数可以分解f:SRS

f(x)=sSf(s){1if x=s0else}.

这样,可以通过首先将输入转换为输入的指标函数,然后使用所需的输出作为权重进行线性组合,来构造的神经网络实现。此外,relu激活使这种转换成为可能:f

relu(t1)2relu(t)+relu(t+1)={1if t=00if tZ{0}.

接下来是该方法的MATLAB实现。为了清楚起见,roots.txt是根文件发布上述(发现这里),并且prec是一个功能(发现这里,计算权重或偏差的向量的总精度)。

编辑1:与原始版本相比有两个改进:(1)我将一些神经元从for循环中分解出来。(2)通过首先合并来自同一水平集的术语,最终实现了“ Lebesgue积分 ”。这样,我为每个级别设置只为输出的高精度值支付一次。同样,通过有理根定理将输出四舍五入到最接近的五分之一也是安全的。

编辑2:其他较小的改进:(1)我从for循环中分解出了更多的神经元。(2)我不会费心计算最终总和中的项,对于该总和而言,其输出已经为零。

function r = approxroot(a,b,c)

relu = @(x)x .* (x>0);

totalprec=0;

% x4 indicates which entry of (-10:10) is a
w1 = ones(21,1);   b1 = -(-10:10)'-1;    x1 = relu(w1 * a + b1);
w2 = ones(21,1);   b2 = -(-10:10)';      x2 = relu(w2 * a + b2);
w3 = ones(21,1);   b3 = -(-10:10)'+1;    x3 = relu(w3 * a + b3);
w4p1 = ones(21,1); w4p2 = -2*ones(21,1); w4p3 = ones(21,1);
x4 = w4p1 .* x1 + w4p2 .* x2 + w4p3 .* x3;
totalprec = totalprec + prec(w1) + prec(w2) + prec(w3) + prec(b1) + prec(b2) + prec(b3) + prec(w4p1) + prec(w4p2) + prec(w4p3);

% x8 indicates which entry of (-10:10) is b
w5 = ones(21,1);   b5 = -(-10:10)'-1;    x5 = relu(w5 * b + b5);
w6 = ones(21,1);   b6 = -(-10:10)';      x6 = relu(w6 * b + b6);
w7 = ones(21,1);   b7 = -(-10:10)'+1;    x7 = relu(w7 * b + b7);
w8p1 = ones(21,1); w8p2 = -2*ones(21,1); w8p3 = ones(21,1);
x8 = w8p1 .* x5 + w8p2 .* x6 + w8p3 .* x7;
totalprec = totalprec + prec(w5) + prec(w6) + prec(w7) + prec(b5) + prec(b6) + prec(b7) + prec(w8p1) + prec(w8p2) + prec(w8p3);

% x12 indicates which entry of (-10:10) is c
w9 = ones(21,1);    b9 = -(-10:10)'-1;     x9 = relu(w9 * c + b9);
w10 = ones(21,1);   b10 = -(-10:10)';      x10 = relu(w10 * c + b10);
w11 = ones(21,1);   b11 = -(-10:10)'+1;    x11 = relu(w11 * c + b11);
w12p1 = ones(21,1); w12p2 = -2*ones(21,1); w12p3 = ones(21,1);
x12 = w12p1 .* x9 + w12p2 .* x10 + w12p3 .* x11;
totalprec = totalprec + prec(w9) + prec(w10) + prec(w11) + prec(b9) + prec(b10) + prec(b11) + prec(w12p1) + prec(w12p2) + prec(w12p3);

% x15 indicates which row of the roots file is relevant
x15=[];
for aa=-10:10
    w13 = 1;
    b13 = -2;
    x13 = w13 * x4(aa+11) + b13;
    totalprec = totalprec + prec(w13) + prec(b13);
    for bb=-10:10
        w14p1 = 1;
        w14p2 = 1;
        x14 = w14p1 * x13 + w14p2 * x8(bb+11);
        totalprec = totalprec + prec(w14p1) + prec(w14p2);
        for cc=-10:10
            w15p1 = 1;
            w15p2 = 1;
            x15(end+1,1) = relu(w15p1 * x14 + w15p2 * x12(cc+11));
            totalprec = totalprec + prec(w15p1) + prec(w15p2);
        end
    end
end

% r is the desired root, rounded to the nearest fifth
A = importdata('roots.txt');
outputs = 0.2 * round(5 * A(:,4)');
uniqueoutputs = unique(outputs);
x16 = [];
for rr = uniqueoutputs
    if rr == 0
        x16(end+1,:) = 0;
    else
        lvlset = find(outputs == rr);
        w16 = ones(1,length(lvlset));
        x16(end+1,:) = w16 * x15(lvlset);
        totalprec = totalprec + prec(w16);
    end
end
w17 = uniqueoutputs;
r = w17 * x16;
totalprec = totalprec + prec(w17);

%disp(totalprec) % uncomment to display score

end
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.