机器学习高尔夫:乘法


68

我想向这个社区提出另一种高尔夫挑战:

(人工)神经网络是非常流行的机器学习模型,可以对其进行设计和训练以近似任何给定的(通常是未知的)功能。它们通常用于解决高度复杂的问题,这些问题我们不知道如何通过算法解决,例如语音识别,某些类型的图像分类,自动驾驶系统中的各种任务……对于神经网络的入门书籍,请考虑一下这方面的出色知识维基百科文章

由于这是我希望成为一系列机器学习高尔夫球挑战中的第一项,所以我想让事情尽可能简单:

在您选择的语言和框架中,设计和训练一个神经网络,对于给定)的和之间(包括该整数)的所有整数,计算出它们的乘积。(x1,x2)x1x2x1,x21010

绩效目标

为了符合条件,您的模型与任何这些条目的正确结果之间的偏差不得超过。0.5

规则

您的模特

  • 必须是“传统”神经网络(节点的值是前一层中某些节点的加权线性组合,再加上激活函数来计算),
  • 只能使用以下标准激活功能:
    1. linear(x)=x
    2. softmax(x)i=exijexj
    3. seluα,β(x)={βx, if x>0αβ(ex1), otherwise
    4. softplus(x)=ln(ex+1)
    5. leaky-reluα(x)={x, if x<0αx, otherwise
    6. tanh(x)
    7. sigmoid(x)=exex+1
    8. hard-sigmoid(x)={0, if x<2.51, if x>2.50.2x+0.5, otherwise
    9. ex
  • 必须以作为整数的tupel / vector / list / ...或浮点数作为其唯一输入,(x1,x2)
  • 以整数,浮点数(或包含此答案的合适容器,例如向量或列表)形式返回答案。

您的答案必须包括(或链接到)检查结果所需的所有代码-包括模型的训练好的权重。

计分

权重(包括偏向权重)最少的神经网络获胜。

请享用!


9
欢迎光临本站!我认为,通过对神经网络进行更可靠的定义,这一挑战可能会受益匪浅。这里有几件事情:1)用一种尚不代表NN知识的语言来陈述它非常好2)您确实应该在帖子中列出激活功能,而不是链接到外部源(外部链接可能会更改或消失)。
小麦巫师

4
我们可以重用权重/使用卷积层吗?(我建议删除奖金,因为它不会给挑战增加任何东西,只会分散主要目标的注意力。)权重应该是真实的还是复杂的?
flawr

4
您的措辞暗示第3层的节点不能使用第1层的输入。让第2层的节点简单f(x) = x地转发其输入是否会产生负担?
肮脏的

4
右栏中应有一个指向沙盒的链接,该沙盒是专门为解决此类问题而创建的,甚至可以将问题发布到主站点之前。网络哲学是,关闭问题,解决问题并重新打开它比获得一堆答案要好得多,这些答案要么在问题解决后就没有意义,要么会严格限制可以对问题进行的更改。
彼得·泰勒

7
一点也不。多年查看其他人犯同样类型的错误的经验可以发现这类问题。一些歧义性越过了沙盒,但还有更多歧义被捕获。这肯定会被抓住,因为正如我在第一条评论中指出的那样,两个月前我们在神经网络问题上遇到完全相同的问题
彼得·泰勒

Answers:


37

21 13 11 9重量

这是基于双线性形式极化恒等式,在一维实数情况下,其简化为多项式恒等式:

xy=(x+y)2(xy)24

因此,y1[x+y, x-y]使用线性变换进行计算,并且y3将其y1作为下一个预处理步骤的绝对值:然后,“困难”部分将计算平方,这将在下面进行解释,然后再计算差值和缩放比例,再次是线性运算。

为了计算平方,我使用指数级数,它对于左右的所有整数应该都是准确的。该系列的形式为s{0,1,2,,20}0.5

approx_square(x)=i=02wiexp(0.0001ix)

我刚刚针对权重W2()进行了优化。这个整体近似还仅包括两个线性变换,它们之间夹有指数激活。这种方法导致最大偏差约为。=(wi)i0.02

function p = net(x)
% 9 weights
one = 1; 
mone =-1;
zero = 0;
fourth = 0.25;
W1 = [1e-4, 2e-4];
W2  = [-199400468.100687;99700353.6313757];
b2 = 99700114.4299316;
leaky_relu = @(a,x)max(a*x,x); 


% Linear
y0 = [one, one; one, mone] * x;

% Linear + ReLU
y1 = mone * y0;
y2 = [leaky_relu(zero, y0), leaky_relu(zero, y1)];

% Linear
y3 = y2 * [one; one];

% Linear + exp
y4 = exp(y3 * W1); 

% Linear + Bias
y5 =  y4 * W2 + b2;

% Linear
y6 = [one, mone]*y5;
p = y6 * fourth;

end

在线尝试!


我认为您在TIO链接页脚中的检查代码错过了的应用abs。但是无论如何一切都很好。
Christian Sievers

@ChristianSievers谢谢,我更新了TIO链接!
flawr

我不是神经网络专家,出于好奇,体重计数是如何进行的?y0需要4,y1需要2,y3需要2,y4需要1,y5需要1和y6需要2。那是12?
玛格丽特·布鲁姆

3
@MargaretBloom是的,这确实有点不寻常,但是OP在评论中表示,即使我们多次使用相同的权重,我们也可以重用权重,并且只需要计算一次即可。因此,我正在使用的所有权重均在函数的第一部分中定义。
flawr

31

7重

eps = 1e-6
c = 1 / (2 * eps * eps)

def f(A, B):
	e_s = exp(eps * A + eps * B)  # 2 weights, exp activation
	e_d = exp(eps * A - eps * B)  # 2 weights, exp activation
	return c * e_s + (-c) * e_d + (-1 / eps) * B  # 3 weights, linear activation

在线尝试!

ϵex1+x+x22

ABeϵA+ϵBeϵAϵB2ϵ2Bϵ

ϵepsc


1
不确定将其视为“传统神经网络”(规则1),但是很明显它可以重新格式化为一个,因此我认为没有问题。不错的解决方案!
Stefan Mesken

1
您可以定义C = -B(1个权重),然后定义([e_s, e_d] = conv([A,B,C], [eps, eps])2个权重)以节省一个权重:)(顺便说一句:非常聪明的方法!)
更加虚假的

(我忘了加上exp
瑕疵的

4
通过重复使用权重,您甚至可以降低很多-不必多次计算相同的权重。
flawr

2
@flawr这是一个很好的技巧,但是我认为注释中的卷积和重用权重使得这成为了很大的挑战,我将保持原样。
xnor

22

33 31重量

# Activation functions
sub hard { $_[0] < -2.5 ? 0 : $_[0] > 2.5 ? 1 : 0.2 * $_[0] + 0.5 }
sub linear { $_[0] }

# Layer 0
sub inputA() { $a }
sub inputB() { $b }

# Layer 1
sub a15() { hard(5*inputA) }

# Layer 2
sub a8()  { hard(-5*inputA + 75*a15 - 37.5) }

# Layer 3
sub aa()  { linear(-5*inputA + 75*a15 - 40*a8) }

# Layer 4
sub a4()  { hard(aa - 17.5) }

# Layer 5
sub a2()  { hard(aa - 20*a4 - 7.5) }

# Layer 6
sub a1()  { linear(0.2*aa - 4*a4 - 2*a2) }

# Layer 7
sub b15() { hard(0.25*inputB - 5*a15) }
sub b8()  { hard(0.25*inputB - 5*a8) }
sub b4()  { hard(0.25*inputB - 5*a4) }
sub b2()  { hard(0.25*inputB - 5*a2) }
sub b1()  { hard(0.25*inputB - 5*a1) }

# Layer 8
sub output() { linear(-300*b15 + 160*b8 + 80*b4 + 40*b2 + 20*b1 - 10*inputA) }

# Test
for $a (-10..10) {
        for $b (-10..10) {
                die if abs($a * $b - output) >= 0.5;
        }
}

print "All OK";

在线尝试!

这会在(sorta)二进制文件中进行长时间乘法,因此返回准确的结果。应该可以利用0.5错误窗口来进行更多操作,但是我不确定如何操作。

第1层到第6层将第一个输入分解为5个“位”。出于打高尔夫球的原因,我们不使用实际的二进制文件。最高有效的“位”的权重为-15而不是16,并且当输入为0时,所有“位”均为0.5(由于保留了ID,因此仍然可以正常工作inputA = -15*a15 + 8*a8 + 4*a4 + 2*a2 + 1*a1)。


1
我确实希望有人提出一种经过硬编码,ANN简化的乘法算法。但是我不认为这是第一反应。做得好!(我也很想看看您是否能够使用MNIST数据集或其他更具弹性的ML问题来实现这样的功能:)
Stefan Mesken

14

43个重量

到目前为止,发布的两个解决方案非常聪明,但是它们的方法可能不适用于机器学习中更传统的任务(例如OCR)。因此,我想为此任务提交一个“通用”(绝妙的技巧)解决方案,以期激励其他人对此进行改进,并被机器学习领域所吸引:

我的模型是一个非常简单的神经网络,具有在TensorFlow 2.0中构建的2个隐藏层(但其他任何框架也可以使用):

model = tf.keras.models.Sequential([
tf.keras.layers.Dense(6, activation='tanh', input_shape=(2,)),
tf.keras.layers.Dense(3, activation='tanh'),
tf.keras.layers.Dense(1, activation='linear')
])

如您所见,除了输出层(由于该任务的性质,具有线性激活功能。

有43个权重:

  • (2+1)6=18
  • (6+1)3=21
  • (3+1)1=4

1010

接下来,我对其进行了微调-针对任何整数乘法任务优化了最大偏差。不幸的是,我的笔记并没有显示出我最终做过的微调,但这是非常小的。在这441个训练样本上的100个纪元附近,批量为441个。

这些是我最终得到的权重:

[<tf.Variable 'dense/kernel:0' shape=(2, 6) dtype=float32, numpy=
 array([[ 0.10697944,  0.05394982,  0.05479664, -0.04538541,  0.05369904,
         -0.0728976 ],
        [ 0.10571832,  0.05576797, -0.04670485, -0.04466859, -0.05855528,
         -0.07390639]], dtype=float32)>,
 <tf.Variable 'dense/bias:0' shape=(6,) dtype=float32, numpy=
 array([-3.4242163, -0.8875816, -1.7694025, -1.9409281,  1.7825342,
         1.1364107], dtype=float32)>,
 <tf.Variable 'dense_1/kernel:0' shape=(6, 3) dtype=float32, numpy=
 array([[-3.0665843 ,  0.64912266,  3.7107112 ],
        [ 0.4914808 ,  2.1569328 ,  0.65417236],
        [ 3.461693  ,  1.2072319 , -4.181983  ],
        [-2.8746269 , -4.9959164 ,  4.505049  ],
        [-2.920127  , -0.0665407 ,  4.1409926 ],
        [ 1.3777553 , -3.3750365 , -0.10507642]], dtype=float32)>,
 <tf.Variable 'dense_1/bias:0' shape=(3,) dtype=float32, numpy=array([-1.376577  ,  2.8885336 ,  0.19852689], dtype=float32)>,
 <tf.Variable 'dense_2/kernel:0' shape=(3, 1) dtype=float32, numpy=
 array([[-78.7569  ],
        [-23.602606],
        [ 84.29587 ]], dtype=float32)>,
 <tf.Variable 'dense_2/bias:0' shape=(1,) dtype=float32, numpy=array([8.521169], dtype=float32)>]

0.44350433910=90.443504

我的模型可以在这里找到,您也可以在线尝试!在Google Colab环境中。


6

2个砝码

ϵ>0

xyeϵx+ϵy+eϵxϵyeϵxϵyeϵx+ϵy4ϵ2.

ϵ=0.01

{±ϵ,±(4ϵ2)1}{±ϵ,(4ϵ3)1}±(4ϵ2)1=±ϵ(4ϵ3)1。正如我在上面的评论中提到的那样,每个具有机器精度权重的神经网络都可以打成一个只有两个不同权重的神经网络。我应用了此过程来编写以下MATLAB代码:

function z=approxmultgolfed(x,y)

w1 = 0.1;   % first weight
w2 = -w1;   % second weight

k  = 250000;
v1 = w1*ones(k,1);
v2 = w2*ones(k,1);

L1 = w1*eye(2);
L2 = [ w1 w1; w2 w2; w1 w2; w2 w1 ];
L3 = [ v1 v1 v2 v2 ];
L4 = v1';

z = L4 * L3 * exp( L2 * L1 * [ x; y ] );

{±0.1}

如何仅用1磅就能摆脱困境(!)

{±0.1}0.10.1

0.1x=wwx,

w100.110.5

{±10k}10k

(也许我们应该修改如何在未来的神经网络高尔夫挑战赛中对重用权重进行评分。)

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.