{"id":2588,"date":"2016-11-07T15:56:37","date_gmt":"2016-11-07T20:56:37","guid":{"rendered":"http:\/\/bioinfo.iric.ca\/?p=2588"},"modified":"2017-04-29T16:53:00","modified_gmt":"2017-04-29T20:53:00","slug":"reseau-siamois-avec-mariana-1-0","status":"publish","type":"post","link":"https:\/\/bioinfo.iric.ca\/fr\/reseau-siamois-avec-mariana-1-0\/","title":{"rendered":"R\u00e9seau de neurones \u00ab\u00a0Siamois\u00a0\u00bb avec Mariana 1.0"},"content":{"rendered":"<p><em>Mariana fut introduit pr\u00e9c\u00e9demment sur ce blog en mai\u00a0par\u00a0Genevi\u00e8ve dans son article <a href=\"https:\/\/bioinfo.iric.ca\/fr\/apprentissage-automatique-en-sciences-de-la-vie\/\">Apprentissage automatique en sciences de la vie<\/a>.<\/em><\/p>\n<p>Pr\u00e9sentement \u00e0 la version 1.0rc3 sur <a href=\"https:\/\/github.com\/tariqdaouda\/Mariana\">github<\/a>, le lancement de la version 1.0 stable de Mariana approche maintenant \u00e0 grands pas.\u00a0Cette nouvelle version repr\u00e9sente un remaniement de code important et ajoute\u00a0plusieurs nouvelles fonctionnalit\u00e9s (une liste compl\u00e8te des changements incorpor\u00e9s dans la version 1.0 est disponible <a href=\"https:\/\/github.com\/tariqdaouda\/Mariana\/blob\/master\/CHANGELOG.rst\">ici<\/a>). Je profite de cette occasion pour pr\u00e9senter une petite capsule sur l&rsquo;extension des fonctionnalit\u00e9s de Mariana 1.0.<\/p>\n<h3>Impl\u00e9mentation d&rsquo;un r\u00e9seau \u00ab\u00a0Siamois\u00a0\u00bb<\/h3>\n<p>La documentation de Mariana couvre un grand nombre de r\u00e9seaux; tous d\u00e9j\u00e0 impl\u00e9ment\u00e9s et facilement utilisables dans Mariana. Mais qu&rsquo;en est-il des cas non couverts par Mariana? Si l&rsquo;on veut utiliser Mariana mais que le r\u00e9seau dont nous avons besoin n&rsquo;est pas disponible?<\/p>\n<p>Heureusement, \u00e9tendre la fonctionnalit\u00e9 de Mariana (i.e. ajouter des fonctions ou un nouveau type de r\u00e9seau) se fait g\u00e9n\u00e9ralement\u00a0sans trop d&rsquo;efforts. Prenons comme exemple\u00a0l&rsquo;impl\u00e9mentation d&rsquo;un\u00a0r\u00e9seau de type \u00ab\u00a0Siamois\u00a0\u00bb inspir\u00e9 par le r\u00e9seau d\u00e9crit dans\u00a0<em>Signature Verification using a \u00ab\u00a0Siamese\u00a0\u00bb Time Delay Neural Network<\/em>\u00a0[1].<\/p>\n<p><a href=\"https:\/\/bioinfo.iric.ca\/wpbioinfo\/wp-content\/uploads\/2016\/11\/main-qimg-1a64e6b37db230538c7b82d7abbf34f6.png\"><img decoding=\"async\" class=\"aligncenter wp-image-2608\" src=\"https:\/\/bioinfo.iric.ca\/wpbioinfo\/wp-content\/uploads\/2016\/11\/main-qimg-1a64e6b37db230538c7b82d7abbf34f6.png\" alt=\"main-qimg-1a64e6b37db230538c7b82d7abbf34f6\" width=\"442\" height=\"412\" srcset=\"https:\/\/bioinfo.iric.ca\/wpbioinfo\/wp-content\/uploads\/2016\/11\/main-qimg-1a64e6b37db230538c7b82d7abbf34f6-200x186.png 200w, https:\/\/bioinfo.iric.ca\/wpbioinfo\/wp-content\/uploads\/2016\/11\/main-qimg-1a64e6b37db230538c7b82d7abbf34f6-300x280.png 300w, https:\/\/bioinfo.iric.ca\/wpbioinfo\/wp-content\/uploads\/2016\/11\/main-qimg-1a64e6b37db230538c7b82d7abbf34f6-400x373.png 400w, https:\/\/bioinfo.iric.ca\/wpbioinfo\/wp-content\/uploads\/2016\/11\/main-qimg-1a64e6b37db230538c7b82d7abbf34f6-600x559.png 600w, https:\/\/bioinfo.iric.ca\/wpbioinfo\/wp-content\/uploads\/2016\/11\/main-qimg-1a64e6b37db230538c7b82d7abbf34f6-768x716.png 768w, https:\/\/bioinfo.iric.ca\/wpbioinfo\/wp-content\/uploads\/2016\/11\/main-qimg-1a64e6b37db230538c7b82d7abbf34f6-800x745.png 800w, https:\/\/bioinfo.iric.ca\/wpbioinfo\/wp-content\/uploads\/2016\/11\/main-qimg-1a64e6b37db230538c7b82d7abbf34f6.png 850w\" sizes=\"(max-width: 442px) 100vw, 442px\" \/><\/a><\/p>\n<p>Dans cette exemple, le r\u00e9seau \u00ab\u00a0Siamois\u00a0\u00bb essaie de d\u00e9tecter de fausses signatures. Il re\u00e7oit ainsi en entr\u00e9e des paires de signatures v\u00e9ritables et de contrefa\u00e7ons. Ce r\u00e9seau \u00ab\u00a0Siamois\u00a0\u00bb est en fait compos\u00e9 de deux r\u00e9seaux de type <em>feed-forward<\/em> dont les\u00a0poids sont li\u00e9s. La similarit\u00e9 cosinus des sorties des deux r\u00e9seaux est utilis\u00e9e comme mesure de distance.<\/p>\n<p style=\"text-align: center;\">$ \\text{Similarit\u00e9 cosinus} = \\cos(\\theta) = {\\mathbf{A} \\cdot \\mathbf{B} \\over \\|\\mathbf{A}\\| \\|\\mathbf{B}\\|} = \\frac{ \\sum\\limits_{i=1}^{n}{A_i \u00a0B_i} }{ \\sqrt{\\sum\\limits_{i=1}^{n}{A_i^2}} \u00a0\\sqrt{\\sum\\limits_{i=1}^{n}{B_i^2}} }$<\/p>\n<p>Afin d&rsquo;impl\u00e9menter ce type de r\u00e9seau dans Mariana, nous devons cr\u00e9er\u00a0une nouvelle couche de sortie. Deux\u00a0modifications sont \u00e0 faire \u00e0 notre\u00a0nouvelle couche : 1) g\u00e9rer\u00a0les connections entre les couches des deux r\u00e9seaux et 2) d\u00e9finir\u00a0le calcul de notre mesure de distance, la similarit\u00e9 cosinus.<\/p>\n<p>Commen\u00e7ons par d\u00e9finir notre\u00a0nouvelle couche de sortie. Cette couche, nomm\u00e9e\u00a0<em>Siamese<\/em>, abstrait la classe de base pour les couches de sortie de Mariana, <em>Output_ABC<\/em>.<\/p>\n<pre><code class=\"python\">import theano.tensor as tt\r\nfrom Mariana.layers import Output_ABC\r\nclass Siamese(Output_ABC):\r\n    def __init__(self, **kwargs):\r\n        Output_ABC.__init__(self, size=1, **kwargs)\r\n        self.targets = tt.ivector(name=\"targets_\" + self.name)\r\n        self.inpLayers = []\r\n<\/code><\/pre>\n<p>Une telle couche doit aussi impl\u00e9menter quelques restrictions dans ses connections. Ici, la fonction\u00a0<code>_femaleConnect<\/code> s&rsquo;assure qu&rsquo;il y ait un maximum de 2 connections en entr\u00e9e et s&rsquo;occupe que ces deux couches aient la m\u00eame taille de sortie.<\/p>\n<pre><code class=\"python\">    def _femaleConnect(self, layer):\r\n        if self.nbInputs is None:\r\n            self.nbInputs = layer.nbOutputs\r\n        elif self.nbInputs != layer.nbOutputs:\r\n            raise ValueError(\"All inputs to layer %s must have the same size, \\\r\ngot: %s previous: %s\" % (self.name, layer.nbOutputs, self.nbInputs))\r\n\r\n        if len(self.inpLayers) &gt; 2:\r\n            raise ValueError(\"%s cannot have more than 2 input layers.\" % (self.name))\r\n        self.inpLayers.append(layer)\r\n<\/code><\/pre>\n<p>La manipulation de la sortie de la couche est d\u00e9crite dans la fonction <code>_setOutputs<\/code>\u00a0et impl\u00e9mente le calcul de la similarit\u00e9 cosinus.<\/p>\n<pre><code class=\"python\">    def _setOutputs(self):\r\n        \"\"\"Defines self.outputs and self.testOutputs\"\"\"\r\n\r\n        if len(self.inpLayers) != 2:\r\n            raise ValueError(\"%s must have exactly 2 input layers.\" % (self.name))\r\n\r\n        num = tt.sum(self.inpLayers[0].outputs * self.inpLayers[1].outputs, axis=1)\r\n        d0 = tt.sqrt(tt.sum(self.inpLayers[0].outputs**2, axis=1))\r\n        d1 = tt.sqrt(tt.sum(self.inpLayers[1].outputs**2, axis=1))\r\n\r\n        num_test = tt.sum(self.inpLayers[0].testOutputs * self.inpLayers[1].testOutputs, axis=1)\r\n        d0_test = tt.sqrt(tt.sum(self.inpLayers[0].testOutputs**2, axis=1))\r\n        d1_test = tt.sqrt(tt.sum(self.inpLayers[1].testOutputs**2, axis=1))\r\n\r\n        self.outputs = num \/ (d0 * d1)\r\n        self.testOutputs = num_test \/ (d0_test * d1_test)\r\n<\/code><\/pre>\n<p>Et voil\u00e0! Maintenant que nous avons notre couche <em>Siamese<\/em> sous la main, passons \u00e0 la construction de\u00a0notre r\u00e9seau.<\/p>\n<p>Tout comme pour les versions ant\u00e9rieures de Mariana, sp\u00e9cifier la structure et les connections d&rsquo;un r\u00e9seau demeure\u00a0un jeu d&rsquo;enfant. Une fois instanci\u00e9es, les composantes du r\u00e9seau peuvent \u00eatres reli\u00e9es entre elles gr\u00e2ce \u00e0\u00a0l&rsquo;op\u00e9rateur <code>&gt;<\/code>. Ce d\u00e9tail permet la cr\u00e9ation rapide d&rsquo;une panoplie de diff\u00e9rentes structures telles que bifurcations, fusions et boucles (bien qu&rsquo;une impl\u00e9mentation compl\u00e8te de r\u00e9seaux r\u00e9currents ne soit pas encore disponible).<\/p>\n<p>Notre r\u00e9seau sera entra\u00een\u00e9 par descente de gradient avec un taux d&rsquo;apprentissage de 0.01. L&rsquo;erreur quadratique moyenne sera utilis\u00e9e comme fonction de co\u00fbt.<\/p>\n<pre><code class=\"python\">ls = MS.GradientDescent(lr=0.01)\r\ncost = MC.MeanSquaredError()\r\n<\/code><\/pre>\n<p>Les couches du r\u00e9seau doivent maintenant \u00eatre instanci\u00e9es. Deux branches, A et B, avec une couche d&rsquo;entr\u00e9es (_i) et deux couches cach\u00e9es (_h1, _h2), sont introduites et utilisent de la rectification lin\u00e9aire (MA.ReLU) comme fonction d&rsquo;activation et un peu de r\u00e9gularisation L2 (MR.L2). La taille des couches est pass\u00e9e comme premier param\u00e8tre. Enfin, notre couche de sortie <em>Siamese<\/em> est instanci\u00e9e et le tout est li\u00e9\u00a0gr\u00e2ce \u00e0 l&rsquo;op\u00e9rateur <code>&gt;<\/code>.<\/p>\n<pre><code class=\"python\">import Mariana.activations as MA\r\nimport Mariana.layers as ML\r\nimport Mariana.costs as MC\r\nimport Mariana.regularizations as MR\r\nimport Mariana.scenari as MS\r\n\r\nA_i = ML.Input(28 * 28, name='inpA')\r\nA_h1 = ML.Hidden(28 * 28, activation=MA.ReLU(), regularizations=[MR.L2(0.01)], name='A_h1')\r\nA_h2 = ML.Hidden(50, activation=MA.ReLU(), regularizations=[MR.L2(0.01)], name='A_h2')\r\n\r\nB_i = ML.Input(28 * 28, name='inpB')\r\nB_h1 = ML.Hidden(28 * 28, activation=MA.ReLU(), regularizations=[MR.L2(0.01)], name='B_h1')\r\nB_h2 = ML.Hidden(50, activation=MA.ReLU(), regularizations=[MR.L2(0.01)], name='B_h2')\r\n\r\no = Siamese(learningScenario=ls, name='Siamese', costObject=cost)\r\n\r\nnetwork = A_i &gt; A_h1 &gt; A_h2 &gt; o\r\nnetwork = B_i &gt; B_h1 &gt; B_h2 &gt; o\r\n<\/code><\/pre>\n<p>Il ne nous reste maintenant qu&rsquo;\u00e0 lier les poids des deux branches de notre r\u00e9seau. Il nous faut premi\u00e8rement instancier le r\u00e9seau afin que les poids subissent les m\u00eames initialisations.<\/p>\n<pre><code class=\"python\">network.init()\r\nA_h1.W = B_h1.W\r\nA_h2.W = B_h2.W\r\n<\/code><\/pre>\n<p>La fonction <code>saveHTML<\/code> nous offre\u00a0un aper\u00e7u de la structure finale du r\u00e9seau:<\/p>\n<p><a href=\"https:\/\/bioinfo.iric.ca\/wpbioinfo\/wp-content\/uploads\/2016\/11\/siamese_mariana.png\"><img decoding=\"async\" class=\"aligncenter size-medium wp-image-2670\" src=\"https:\/\/bioinfo.iric.ca\/wpbioinfo\/wp-content\/uploads\/2016\/11\/siamese_mariana-300x285.png\" alt=\"siamese_mariana\" width=\"300\" height=\"285\" srcset=\"https:\/\/bioinfo.iric.ca\/wpbioinfo\/wp-content\/uploads\/2016\/11\/siamese_mariana-200x190.png 200w, https:\/\/bioinfo.iric.ca\/wpbioinfo\/wp-content\/uploads\/2016\/11\/siamese_mariana-300x285.png 300w, https:\/\/bioinfo.iric.ca\/wpbioinfo\/wp-content\/uploads\/2016\/11\/siamese_mariana-400x380.png 400w, https:\/\/bioinfo.iric.ca\/wpbioinfo\/wp-content\/uploads\/2016\/11\/siamese_mariana.png 462w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p>La version 1.0 stable de Mariana est attendue dans les prochains mois. Surveillez le compte github pour les plus r\u00e9centes mises \u00e0 jour!<\/p>\n<p><em>J&rsquo;aimerais souligner la contribution de\u00a0<a href=\"https:\/\/github.com\/tariqdaouda\">Tariq Daouda<\/a>, auteur de Mariana,\u00a0\u00e0 la r\u00e9daction de cet article.<\/em><\/p>\n<h3><\/h3>\n<h3>R\u00e9f\u00e9rences<\/h3>\n<p style=\"padding-left: 30px;\">[1] Bromley, Jane, et al. \u00ab\u00a0Signature verification using a \u201cSiamese\u201d time delay neural network.\u00a0\u00bb <i>International Journal of Pattern Recognition and Artificial Intelligence<\/i> 7.04 (1993): 669-688.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Mariana fut introduit pr\u00e9c\u00e9demment sur ce blog en mai\u00a0par\u00a0Genevi\u00e8ve dans son article Apprentissage automatique en sciences de la vie. Pr\u00e9sentement \u00e0 la version 1.0rc3 sur github, le lancement de la version 1.0 stable de Mariana approche maintenant \u00e0 grands pas.\u00a0Cette nouvelle version repr\u00e9sente un remaniement de code important et ajoute\u00a0plusieurs nouvelles fonctionnalit\u00e9s (une liste compl\u00e8te des changements incorpor\u00e9s dans la version 1.0 est disponible ici). Je profite de cette occasion pour pr\u00e9senter une petite capsule sur l&rsquo;extension des fonctionnalit\u00e9s de <a href=\"https:\/\/bioinfo.iric.ca\/fr\/reseau-siamois-avec-mariana-1-0\/\"> [&#8230;]<\/a><\/p>\n","protected":false},"author":7,"featured_media":2608,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[85,26],"tags":[129,133,106],"class_list":["post-2588","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-apprentissage-automatique","category-langage-python","tag-analyse-de-donnees","tag-informatique","tag-mariana"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"https:\/\/bioinfo.iric.ca\/wpbioinfo\/wp-content\/uploads\/2016\/11\/main-qimg-1a64e6b37db230538c7b82d7abbf34f6.png","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/bioinfo.iric.ca\/fr\/wp-json\/wp\/v2\/posts\/2588","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/bioinfo.iric.ca\/fr\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/bioinfo.iric.ca\/fr\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/bioinfo.iric.ca\/fr\/wp-json\/wp\/v2\/users\/7"}],"replies":[{"embeddable":true,"href":"https:\/\/bioinfo.iric.ca\/fr\/wp-json\/wp\/v2\/comments?post=2588"}],"version-history":[{"count":57,"href":"https:\/\/bioinfo.iric.ca\/fr\/wp-json\/wp\/v2\/posts\/2588\/revisions"}],"predecessor-version":[{"id":2814,"href":"https:\/\/bioinfo.iric.ca\/fr\/wp-json\/wp\/v2\/posts\/2588\/revisions\/2814"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/bioinfo.iric.ca\/fr\/wp-json\/wp\/v2\/media\/2608"}],"wp:attachment":[{"href":"https:\/\/bioinfo.iric.ca\/fr\/wp-json\/wp\/v2\/media?parent=2588"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/bioinfo.iric.ca\/fr\/wp-json\/wp\/v2\/categories?post=2588"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/bioinfo.iric.ca\/fr\/wp-json\/wp\/v2\/tags?post=2588"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}