Makine Öğrenimi Golf: Çarpma


68

Bu topluma farklı bir tür golf mücadelesi önermek istiyorum:

(Yapay) Yapay Sinir Ağları , verilen (genellikle bilinmeyen) herhangi bir işlevi yerine getirmek üzere tasarlanıp eğitilebilecek çok popüler bir makine öğrenme modelidir. Sıklıkla konuşma tanıma, bazı görüntü sınıflandırmaları, özerk sürüş sistemlerinde çeşitli görevler gibi algoritmik olarak nasıl çözeceğimizi bilmediğimiz oldukça karmaşık problemleri çözmek için kullanılırlar ... Sinir ağları için bir primer olarak, bu mükemmel düşünün Wikipedia makalesi .

Bu, bir dizi makine öğrenmesi golf mücadelesi olmayı umduğum ilk şey olduğundan, işleri mümkün olduğunca basit tutmak isterim:

Senin seçimin, tasarımın dil ve çerçeve içinde ve verilen bir sinir ağı eğitmek (x1,x2) kendi ürününü hesaplar x1x2 tüm tamsayılar için x1,x2 arasındaki (ve dahil) 10 ve 10 .

Performans hedefi

Kalifiye olmak için modeliniz bu kayıtların hiçbirindeki doğru sonuçtan 0.5 fazla sapma gösteremez .

kurallar

Senin modelin

  • 'geleneksel' bir sinir ağı olması gerekir (bir düğümün değeri önceki bir katmandaki bazı düğümlerin ağırlıklı bir doğrusal birleşimi ve ardından bir etkinleştirme işlevi olarak hesaplanır),
  • yalnızca aşağıdaki standart etkinleştirme işlevlerini kullanabilir:
    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
  • atmalıdır (x1,x2) ya bir tupel / vektör / liste olarak / ... tamsayılar ya da sadece girdi olarak yüzen,
  • cevabı bir tamsayı, değişken (veya bu cevabı içeren uygun bir kap, örneğin bir vektör veya liste) olarak döndürün.

Cevabınız, modelinizin eğitimli ağırlıkları dahil olmak üzere, sonuçlarınızı kontrol etmek için gerekli tüm kodu içermeli (veya buna bağlanmalıdır).

puanlama

En az ağırlığa sahip sinir ağı (ön ağırlık ağırlıkları dahil) kazanır.

Keyfini çıkarın!


9
Siteye Hoşgeldiniz! Bence bu zorluk sinir ağının daha sağlam bir tanımından çok iyi bir kazanç sağlayabilir. Burada birkaç şey var 1) NN'lerin bilgisini anlamayan bir dilde söylemeniz çok iyi olurdu 2) Görevinizdeki bir dış kaynağa bağlamak yerine aktivasyon işlevlerini gerçekten listelemelisiniz ( dış bağlantılar değişebilir veya kaybolabilir).
Buğday Sihirbazı

4
Ağırlıkları tekrar kullanabilir miyiz / evrişimli katmanlar kullanabilir miyiz? (Bu zorluğa bir şey eklemediği ve sadece asıl hedefin dikkatini dağıttığı için bonusu kaldırmanızı tavsiye ederim.) Ağırlıklar gerçek mi yoksa karmaşık mı olabilir?
kusur

4
Sizin ifade tabakadan 3 düğümler yaptığını basitçe katman 2 düğüme sahip bir ağırlık maliyet getirir katmanda 1. girdileri kullanamaz ima f(x) = xonun girişini yönlendirmek için?
Grimy,

4
Soru, ana siteye gönderilmeden önce, bu sütunları düzeltmek için açıkça oluşturulan Sandbox'a sağ sütunda bir bağlantı bulunmalıdır. Ve ağ felsefesi, bir soruyu kapatmanın, düzeltmenin ve tekrar açtıktan sonra, sorunun düzeltilmesinden sonra hiçbir anlam ifade etmeyecek veya soruya yapılabilecek değişiklikleri sıkıca kısıtlayacak bir cevaplar almaktan daha iyidir. .
Peter Taylor,

7
Bir şey değil. Bu tür sorunlar yıllarca başkalarının aynı tür hataları yaptığını görme tecrübesiyle tespit edilir. Bazı belirsizlikler kum havuzunu geçiyor, ancak daha fazlası orada kalıyor. Ve bu kesinlikle yakalanmış olacaktı, çünkü ilk yorumumda belirtildiği gibi, iki ay önce sinirsel net bir soru ile tamamen aynı problemlerimiz vardı .
Peter Taylor,

Yanıtlar:


37

21 13 11 9 ağırlıklar

Bu, bir boyutlu gerçek durumda polinom kimliğine indirgeyen bilinear formların kutuplaşma kimliğine dayanmaktadır :

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

Dolayısıyla y1sadece [x+y, x-y]doğrusal bir dönüşüm kullanarak y3hesaplanır ve y1bir sonraki adım için bir ön işleme adımı olarak mutlak değerdir : O zaman "zor" kısım aşağıda açıklayacağım kareleri hesaplar ve ondan sonra sadece bir fark ve ölçeklemeyi hesaplar. yine doğrusal bir işlemdir.

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

Çevrimiçi deneyin!


Sanırım TIO bağlantısının altındaki kontrol kodunuz bir uygulamayı özlüyor abs. Ama yine de her şey yolunda.
Christian Sievers

@ChristianSievers Teşekkürler, TIO bağlantısını güncellendi!
flawr

NN konusunda uzman değilim, meraktan, ağırlık sayımı nasıl? y0ihtiyaç 4, y1ihtiyaç 2, y3ihtiyaç 2, y4ihtiyaç 1, y5ihtiyaç 1 ve y6ihtiyaç 2.
Margaret Bloom,

3
@MargaretBloom Evet, bu gerçekten alışılmadık bir durum, ancak OP yorumlarda ağırlıkları tekrar kullanabileceğimizi ve aynı ağırlığı birden fazla kullansak bile, bir kez saymak zorunda kaldığını söyledi. Bu yüzden kullandığım tüm ağırlıklar, fonksiyonun ilk bölümünde tanımlanmıştır.
kusur

31

7 ağırlık

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

Çevrimiçi deneyin!

ϵex1+x+x22

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

ϵepsc


1
Bunun 'geleneksel sinir ağı' olarak kabul edildiğinden emin değilim (kural # 1), ancak bir tanesine yeniden biçimlendirilebileceği açık, bu yüzden bununla ilgili bir sorun görmüyorum. Güzel çözüm!
Stefan Mesken

1
Bir C = -Bkiloyu tanımlamak için (1 ağırlık) ve sonra [e_s, e_d] = conv([A,B,C], [eps, eps])(2 ağırlık) olabilir :) (BTW: Çok akıllıca bir yaklaşım!)
kusur

(Eklemeyi unuttum exp)
kusur

4
Ağırlıkları tekrar kullanarak çok daha düşük bile olabilirsiniz - aynı ağırlığı birden çok kez saymanız gerekmez.
flawr,

2
@flawr Bu güzel bir püf noktası, ancak bence evrimleşme ve yorumlardaki ağırlıkları tekrar kullanmanın ödenekleri, bu cevabı olduğu gibi tutacağımdan çok daha farklı bir meydan okuma yapıyor.
xnor

22

33 31 ağırlıklar

# 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";

Çevrimiçi deneyin!

Bu (sorta) ikilisinde uzun çarpım yapar ve böylece kesin sonuç verir. Bu daha golf oynamak için 0.5 hata penceresinden yararlanmak mümkün olmalı, ama nasıl emin değilim.

Katmanlar 1 ila 6, ilk girişi 5 "bit" ile ayrıştırır. Golf nedeniyle, gerçek ikili kullanmıyoruz. En önemli "bit", 16 yerine -15 ağırlığına sahiptir ve giriş 0 olduğunda, tüm "bitler" 0,5'tir (kimliğini koruduğu için hala düzgün çalışır inputA = -15*a15 + 8*a8 + 4*a4 + 2*a2 + 1*a1).


1
Birinin, kodlanmış, YSA Ified çarpım algoritması bulmasını bekledim. Ama ilk cevap olacağını düşünmedim. Aferin! (Ayrıca MNIST veri kümesiyle veya başka, daha esnek olan bir ML problemiyle bunun gibi bir şeyden çekip çekemeyeceğinizi görmeye istekliyim: D.)
Stefan Mesken

14

43 ağırlıklar

Şimdiye kadar yayınlanan iki çözüm çok akıllıydı, ancak yaklaşımları makine öğreniminde (OCR gibi) daha geleneksel görevler için çalışmayacak. Bu nedenle, bu göreve, diğer insanlara geliştirmeleri ve makine öğrenmesi dünyasında emilmeleri için ilham veren, 'genel' (akıllıca numaralar yok) bir çözüm sunmak istiyorum:

Modelim, TensorFlow 2.0'da yerleşik 2 gizli katmana sahip çok basit bir sinir ağıdır (ancak başka bir çerçeve de işe yarayabilir):

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')
])

Gördüğünüz gibi, tüm katmanlar yoğundur (kesinlikle en uygun olmayanı), etkinleştirme işlevi bu görevin doğası gereği, çıktı katmanı dışında, tanh'dir (aslında bu görev için uygun olabilir). doğrusal bir etkinleştirme işlevine sahiptir.

43 tane ağırlık var:

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

1010

Daha sonra, onları ince ayar yaptım - herhangi bir tamsayı çarpma işleminde maksimum sapma için en iyi duruma getirme. Maalesef, notlarım sonunda bitirdiğim kadar iyi bir ayar yapmıyor, ama çok küçüktü. 441 parti büyüklüğüne sahip 441 eğitim örneğinde 100 dönemin mahallesinde.

Bunlar sonlandırdığım ağırlıklar:

[<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

Modelim burada bulunabilir ve ayrıca çevrimiçi deneyebilirsiniz! Google Colab ortamında.


6

2 ağırlık

ϵ>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. Yukarıdaki bir yorumda bahsettiğim gibi, makine hassasiyetindeki ağırlıkları olan her sinir ağı sadece iki farklı ağırlığa sahip (devasa!) Bir sinir ağına golf edilebilir. Aşağıdaki MATLAB kodunu yazmak için bu prosedürü uyguladım:

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}

Sadece 1 kilo ile nasıl kurtulurum (!)

{±0.1}0.10.1

0.1x=wwx,

w100.110.5

{±10k}10k

(Gelecekteki sinirsel net golf mücadelelerinde tekrar kullanılan ağırlıkların nasıl puanlandığını değiştirmeliyiz.)

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.