J'aimerais proposer un autre type de défi de golf à cette communauté:
Les réseaux de neurones (artificiels) sont des modèles d’apprentissage automatique très populaires qui peuvent être conçus et formés pour se rapprocher d’une fonction donnée (généralement inconnue). Ils sont souvent utilisés pour résoudre des problèmes très complexes que nous ne savons pas résoudre par des algorithmes tels que la reconnaissance vocale, certains types de classifications d’images, diverses tâches de systèmes de conduite autonome, ... Pour une introduction aux réseaux de neurones, considérez cet excellent Article de Wikipedia .
Comme il s’agit du premier de ce que j’espère être une série de défis d’apprentissage automatique du golf, j’aimerais garder les choses aussi simples que possible:
Dans le langage et la structure de votre choix, concevez et formez un réseau de neurones qui, étant donné calcule son produit pour tous les entiers compris entre -10 et 10 .
Objectif de performance
Pour être éligible, votre modèle ne doit pas s'écarter de plus de du résultat correct sur l'une de ces entrées.
Règles
Votre modèle
- doit être un réseau neuronal «traditionnel» (la valeur d'un nœud est calculée comme une combinaison linéaire pondérée de certains des nœuds d'une couche précédente suivie d'une fonction d'activation),
- pouvez uniquement utiliser les fonctions d'activation standard suivantes:
- ,
- ,
- ,
- ,
- ,
- ,
- ,
- ,
- doit prendre soit en tant que tupel / vecteur / liste / ... d'entiers ou floats en tant que seule entrée,
- renvoie la réponse sous forme d’entier, float (ou un conteneur approprié, par exemple un vecteur ou une liste, contenant cette réponse).
Votre réponse doit inclure (ou créer un lien vers) tout le code nécessaire pour vérifier vos résultats, y compris les poids formés de votre modèle.
Notation
Le réseau de neurones avec le plus petit nombre de poids (y compris les poids de biais) l'emporte.
Prendre plaisir!
la source
f(x) = x
transférer son entrée?Réponses:
21 13 119 poidsCeci est basé sur l' identité de polarisation des formes bilinéaires qui, dans le cas réel unidimensionnel, se réduit à l'identité polynomiale:
Donc,
y1
calcule simplement en[x+y, x-y]
utilisant une transformation linéaire, ety3
est juste la valeur absolue dey1
comme une étape de prétraitement pour la suivante: Ensuite, la partie "difficile" consiste à calculer les carrés que je vais expliquer ci-dessous, puis à calculer une différence et une mise à l'échelle qui est encore une opération linéaire.Pour calculer les carrés, j’utilise une série exponentielle qui devrait être précise pour tous les entiers dans l’ordre de . Cette série est de la formes {0,1,2,…,20} 0.5
où je viens d'optimiser pour les poids=(wi)i
W2
( ). Toute cette approximation ne comprend encore que deux transformations linéaires avec une activation exponentielle prise en sandwich entre elles. Cette approche entraîne une déviation maximale d’environ .0.02
Essayez-le en ligne!
la source
abs
. Mais tout va bien quand même.y0
besoins 4,y1
besoins 2,y3
besoins 2,y4
besoins 1,y5
besoins 1 ety6
besoins 2. C'est 12?7 poids
Essayez-le en ligne!
Utilise l’égalité approximative suivante pour les petits fonction de l’agrandissement de Taylor :ϵ ex≈1+x+x22
Choisir assez petit nous place dans les limites d'erreur requises. Notez que et sont des poids constants dans le code.ϵ
eps
c
la source
C = -B
(1 poids) et ensuite[e_s, e_d] = conv([A,B,C], [eps, eps])
(2 poids) pour enregistrer un poids :) (BTW: approche très intelligente!)exp
)3331 poidsEssayez-le en ligne!
Cela fait une longue multiplication en (sorta) binary, et renvoie donc le résultat exact. Il devrait être possible de tirer parti de la fenêtre d’erreur 0.5 pour jouer au golf, mais je ne sais pas comment.
Les couches 1 à 6 décomposent la première entrée en 5 "bits". Pour des raisons de golf, nous n'utilisons pas de binaire réel. Le "bit" le plus significatif a un poids de -15 au lieu de 16, et lorsque l'entrée est égale à 0, tous les "bits" sont égaux à 0,5 (ce qui fonctionne toujours bien car il préserve l'identité
inputA = -15*a15 + 8*a8 + 4*a4 + 2*a2 + 1*a1
).la source
43 poids
Les deux solutions publiées jusqu'à présent ont été très intelligentes, mais leurs approches ne fonctionneront probablement pas pour des tâches plus traditionnelles d'apprentissage automatique (comme l'OCR). Par conséquent, j'aimerais soumettre une solution «générique» (sans astuce) à cette tâche qui, espérons-le, inspire d'autres personnes à l'améliorer et à se laisser entraîner dans le monde de l'apprentissage automatique:
Mon modèle est un réseau de neurones très simple avec 2 couches cachées intégré dans TensorFlow 2.0 (mais tout autre framework fonctionnerait également):
Comme vous pouvez le constater, toutes les couches sont denses (ce qui n’est certainement pas optimal), la fonction d’activation est tanh (ce qui pourrait en fait convenir pour cette tâche), à l’exception de la couche de sortie qui, en raison de la nature de cette tâche, a une fonction d'activation linéaire.
Il y a 43 poids:
Les poids ont été formés (avec un optimiseur adam) par une approche d’ajustement en couches: ils ont d’abord été ajustés afin de minimiser l’erreur quadratique moyenne non seulement lors de la multiplication d’entiers entre et mais également lors des entrées dans un voisinage donné autour de ces valeurs. . Il en résulte une bien meilleure convergence due à la nature de la descente de gradient. Et cela a représenté une formation d’une valeur de 400 époques sur 57 600 échantillons d’entraînement, en utilisant une taille de lot de 32.−10 10
Ensuite, je les ai affinés - optimisant l’écart maximal sur l’une des tâches de multiplication d’entiers. Malheureusement, mes notes ne montrent pas beaucoup d'ajustement que j'ai fini par faire, mais c'était très mineur. Au voisinage de 100 époques sur ces 441 échantillons d’entraînement, avec une taille de lot de 441.
Ce sont les poids que j'ai fini avec:
qui atteint à peine l'objectif de performance déclaré. La déviation maximale a finalement été de comme en témoigne .0.44350433 9⋅10=90.443504
Mon modèle se trouve ici et vous pouvez également l' essayer en ligne! dans un environnement Google Colab.
la source
2 poids
Les autres réponses m'ont inspiré pour approcher différemment l'identité de polarisation. Pour chaque petit , il est dit queϵ>0
Il suffit de prendre pour ce défi.ϵ=0.01
La mise en oeuvre évidente de cette approximation par un réseau neuronal prend des poids dans . Ces quatre poids peuvent être réduits à trois en factorisant . Comme je l'ai mentionné dans un commentaire ci-dessus, chaque réseau de neurones avec une pondération en précision de machine peut être transformé en un réseau (énorme!) De neurones avec seulement deux poids distincts. J'ai appliqué cette procédure pour écrire le code MATLAB suivant:{±ϵ,±(4ϵ2)−1} {±ϵ,(4ϵ3)−1} ±(4ϵ2)−1=±ϵ⋅(4ϵ3)−1
Au total, ce réseau de neurones comprend 1 250 010 poids, qui résident tous dans .{±0.1}
Comment sortir avec seulement 1 poids (!)
Il s’avère que vous pouvez simuler n’importe quel réseau de neurones dont le poids est à avec un réseau de neurones plus grand qui n’a qu’un seul poids, à savoir . En effet, la multiplication par peut être mise en œuvre comme{±0.1} −0.1 0.1
où est le vecteur de colonne de entrées, toutes égales à . Pour les réseaux de neurones dans lesquels la moitié des poids sont positifs, cette transformation produit un réseau de neurones fois plus grand.w 10 −0.1 10.5
La généralisation évidente de cette procédure transformera tout réseau de neurones avec des poids en en un réseau de neurones plus grand avec le poids unique . Combinée à la procédure décrite dans mon commentaire ci-dessus, elle considère donc que chaque réseau neuronal doté de poids de précision machine peut être transformé en un réseau neuronal à poids unique.{±10−k} −10−k
(Peut-être devrions-nous modifier la manière dont les poids réutilisés sont notés dans les futurs défis du golf neuronal.)
la source