[PYTHON] Créez des circuits AND / OR / NAND / XOR avec FPGA qui peuvent être nécessaires pour le Deep Learning avec Polyphony

Lire l'apprentissage profond à partir de zéro

Le livre Deep Learning from scratch est merveilleux. Apprendre avec Python Comme le montre le sous-titre de Deep Running, ce livre vise à approfondir votre compréhension en créant une application Deep Learning (? Algorithme?) À partir de zéro avec Python.

Ce livre fait d'abord AND, OR, NAND, XOR. J'ai l'impression d'être dépassé, mais compilons-les avec Polyphony et transformons-les en matériel.

La source est tirée de l'URL suivante sur github. https://github.com/ryos36/polyphony-tutorial/

Si vous voulez l'essayer facilement, installez polyphony et iverilog, clonez l'URL ci-dessus et exécutez chaque source avec simu.py.

> pip3 install polyphony
<Installez correctement iverilog>
> git clone https://github.com/ryos36/polyphony-tutorial/
> cd polyphony-tutorial/DeepLearning
> ../bin/simu.py and.py 

La construction de l'environnement à l'aide de pyvenv est résumée ici. http://qiita.com/ryos36/items/7e7fce9078a79f782380

De Perceptron au chapitre 2

Créons la porte ET montrée dans l'exemple en 2.3.1.

and.py


from polyphony import testbench

def AND(x1, x2):
    w1, w2, theta = 5, 5, 7
    tmp = x1*w1 + x2*w2
    if tmp <= theta:
        return 0
    elif tmp > theta:
        return 1

@testbench
def test():
    print(AND(0, 0))
    print(AND(1, 0))
    print(AND(0, 1))
    print(AND(1, 1))

test()

Les paramètres sont 0,5, 0,5, 0,7 dans le livre, mais modifiez-les en valeurs entières de 5, 5 et 7 pour la polyphonie. (Si vous y réfléchissez maintenant, peut-être que 2,2,3 auraient été mieux)

Le résultat est le suivant.

[test-0.2.2] Persimmon:polyphony-tutorial> cd DeepLearning/
[test-0.2.2] Persimmon:DeepLearning> ../bin/simu.py and.py
    0:AND_0_in_x1=   x, AND_0_in_x2=   x, AND_0_out_0=   x
  110:AND_0_in_x1=   0, AND_0_in_x2=   0, AND_0_out_0=   x
  160:AND_0_in_x1=   0, AND_0_in_x2=   0, AND_0_out_0=   0
0
  180:AND_0_in_x1=   1, AND_0_in_x2=   0, AND_0_out_0=   0
0
  250:AND_0_in_x1=   0, AND_0_in_x2=   1, AND_0_out_0=   0
0
  320:AND_0_in_x1=   1, AND_0_in_x2=   1, AND_0_out_0=   0
  370:AND_0_in_x1=   1, AND_0_in_x2=   1, AND_0_out_0=   1
1

Comme prévu. Le nombre à gauche du signe deux-points des informations mystérieuses qui sont sorties sans autorisation est l'heure (nombre d'horloges). C'est un guide approximatif pour les performances.

Utiliser une liste Python

Utilisons maintenant la liste Python.

and2.py


from polyphony import testbench

def list_mul(lst_r, lst_a, lst_b):
    for i in range(len(lst_r)):
        lst_r[i] = lst_a[i] * lst_b[i]

def sum(lst):
    tmp = 0
    for i in range(len(lst)):
        tmp = tmp + lst[i]

    return tmp

def AND(x1, x2):
    lst_r = [0, 0]
    lst_a = [x1, x2]
    lst_b = [5, 5]
    b = -7

    list_mul(lst_r, lst_a, lst_b)
    tmp = sum(lst_r) + b

    if tmp <= 0:
        return 0
    else:
        return 1

@testbench
def test():
    print(AND(0, 0))
    print(AND(1, 0))
    print(AND(0, 1))
    print(AND(1, 1))

test()

La polyphonie n'a pas de multiplication de liste ni de somme, nous définissons donc une fonction.

[test-0.2.2] Persimmon:DeepLearning> ../bin/simu.py and2.py
    0:AND_0_in_x1=   x, AND_0_in_x2=   x, AND_0_out_0=   x
  110:AND_0_in_x1=   0, AND_0_in_x2=   0, AND_0_out_0=   x
  550:AND_0_in_x1=   0, AND_0_in_x2=   0, AND_0_out_0=   0
0
  570:AND_0_in_x1=   1, AND_0_in_x2=   0, AND_0_out_0=   0
0
 1030:AND_0_in_x1=   0, AND_0_in_x2=   1, AND_0_out_0=   0
0
 1490:AND_0_in_x1=   1, AND_0_in_x2=   1, AND_0_out_0=   0
 1930:AND_0_in_x1=   1, AND_0_in_x2=   1, AND_0_out_0=   1
1

L'utilisation de listes a ajouté une abstraction, mais cela a ralenti car j'ai utilisé une instruction for pour l'opération. Vous pouvez créer or.py et nand.py de la même manière. C'est une source un peu triste qu'il soit copié.

Essayez de faire XOR

Sur cette base, créez et exécutez XOR.

xor.py


from polyphony import testbench

def list_mul(lst_r, lst_a, lst_b):
    for i in range(len(lst_r)):
        lst_r[i] = lst_a[i] * lst_b[i]

def sum(lst):
    tmp = 0
    for i in range(len(lst)):
        tmp = tmp + lst[i]

    return tmp

def AND(x1, x2):
    lst_r = [0, 0]
    lst_a = [x1, x2]
    lst_b = [5, 5]
    b = -7

    list_mul(lst_r, lst_a, lst_b)
    tmp = sum(lst_r) + b

    if tmp <= 0:
        return 0
    else:
        return 1

def OR(x1, x2):
    lst_r = [0, 0]
    lst_a = [x1, x2]
    lst_b = [5, 5]
    b = -2

    list_mul(lst_r, lst_a, lst_b)
    tmp = sum(lst_r) + b

    if tmp <= 0:
        return 0
    else:
        return 1

def NAND(x1, x2):
    lst_r = [0, 0]
    lst_a = [x1, x2]
    lst_b = [-5, -5]
    b = 7

    list_mul(lst_r, lst_a, lst_b)
    tmp = sum(lst_r) + b

    if tmp <= 0:
        return 0
    else:
        return 1

def XOR(x1, x2):
    s1 = NAND(x1, x2)
    s2 = OR(x1, x2)
    y = AND(s1, s2)
    return y

@testbench
def test():
    print(XOR(0, 0))
    print(XOR(1, 0))
    print(XOR(0, 1))
    print(XOR(1, 1))

test()

C'est l'aboutissement du programme de copier-coller, mais cela fonctionne. Il est important de bouger. Le résultat semble être correct comme suit.

[test-0.2.2] Persimmon:DeepLearning> ../bin/simu.py xor.py
    0:XOR_0_in_x1=   x, XOR_0_in_x2=   x, XOR_0_out_0=   x
  110:XOR_0_in_x1=   0, XOR_0_in_x2=   0, XOR_0_out_0=   x
 1440:XOR_0_in_x1=   0, XOR_0_in_x2=   0, XOR_0_out_0=   0
0
 1450:XOR_0_in_x1=   1, XOR_0_in_x2=   0, XOR_0_out_0=   0
 2780:XOR_0_in_x1=   1, XOR_0_in_x2=   0, XOR_0_out_0=   1
1
 2790:XOR_0_in_x1=   0, XOR_0_in_x2=   1, XOR_0_out_0=   1
1
 4130:XOR_0_in_x1=   1, XOR_0_in_x2=   1, XOR_0_out_0=   1
 5460:XOR_0_in_x1=   1, XOR_0_in_x2=   1, XOR_0_out_0=   0
0

Utiliser les classes Python

Utilisez des classes pour éviter la copie. Les perspectives se sont considérablement améliorées.

c_xor.py


from polyphony import testbench

class BitOp:
    def __init__(self, w0, w1, b):
        self.w0 = w0
        self.w1 = w1
        self.b = b

    def eval(self, x0, x1):
        tmp0 = self.w0 * x0
        tmp1 = self.w1 * x1
        tmp = tmp0 + tmp1 + self.b
        if tmp <= 0:
            return 0
        else:
            return 1

def AND(x1, x2):
    op = BitOp(5, 5, -7)
    return op.eval(x1, x2)

def OR(x1, x2):
    op = BitOp(5, 5, -2)
    return op.eval(x1, x2)

def NAND(x1, x2):
    op = BitOp(-5, -5, 7)
    return op.eval(x1, x2)

def XOR(x1, x2):
    AND = BitOp(5, 5, -7)
    OR = BitOp(5, 5, -2)
    NAND = BitOp(-5, -5, 7)
    s1 = NAND.eval(x1, x2)
    s2 = OR.eval(x1, x2)
    y = AND.eval(s1, s2)
    return y

@testbench
def test():
    print(XOR(0, 0))
    print(XOR(1, 0))
    print(XOR(0, 1))
    print(XOR(1, 1))

test()

J'ai arrêté d'utiliser des listes, donc le temps d'exécution est plus rapide.

[test-0.2.2] Persimmon:DeepLearning> ls
and.py  and2.py  c_xor.py  nand.py  or.py  t_and.py  xor.py
[test-0.2.2] Persimmon:DeepLearning> ../bin/simu.py c_xor.py
    0:XOR_0_in_x1=   x, XOR_0_in_x2=   x, XOR_0_out_0=   x
  110:XOR_0_in_x1=   0, XOR_0_in_x2=   0, XOR_0_out_0=   x
  280:XOR_0_in_x1=   0, XOR_0_in_x2=   0, XOR_0_out_0=   0
0
  290:XOR_0_in_x1=   1, XOR_0_in_x2=   0, XOR_0_out_0=   0
  460:XOR_0_in_x1=   1, XOR_0_in_x2=   0, XOR_0_out_0=   1
1
  470:XOR_0_in_x1=   0, XOR_0_in_x2=   1, XOR_0_out_0=   1
1
  650:XOR_0_in_x1=   1, XOR_0_in_x2=   1, XOR_0_out_0=   1
  820:XOR_0_in_x1=   1, XOR_0_in_x2=   1, XOR_0_out_0=   0
0

Bonus: version Taple et

Si vous définissez Polyphony sur 0.3.0 (normalement l'installation de pip3 installera 0.2.2 au moment 2017.3.27), la version taple fonctionnera également.

t_and.py


from polyphony import testbench

def t_mul2(t_a, t_b):
    a0, a1 = t_a
    b0, b1 = t_b
    return (a0 * b0, a1 * b0)

def t_sum2(t_a):
    a0, a1 = t_a
    return a0 + a1

def AND(x1, x2):
    para = (5, 5)
    b = -7

    t_r = t_mul2((x1, x2), para)
    tmp = t_sum2(t_r) + b

    if tmp <= 0:
        return 0
    else:
        return 1

@testbench
def test():
    print(AND(0, 0))
    print(AND(1, 0))
    print(AND(0, 1))
    print(AND(1, 1))

test()

J'ai fait XOR

J'ai pu faire XOR, mais est-il naturel que FPGA puisse le faire en premier lieu? La route pour devenir un maître du Deep Learning est encore loin

Recommended Posts

Créez des circuits AND / OR / NAND / XOR avec FPGA qui peuvent être nécessaires pour le Deep Learning avec Polyphony
Présentation et fonctionnalités utiles de scikit-learn qui peuvent également être utilisées pour l'apprentissage en profondeur
Créez un environnement pour "Deep Learning from scratch" avec Docker
Essayez le Deep Learning avec FPGA
Réaliser la construction d'environnement pour "Deep Learning from scratch" avec docker et Vagrant
sélénium: attendre l'élément avec ET / OU
Une collection de ressources qui peuvent être utiles pour créer et développer des fichiers dotfiles