[PYTHON] Erstellen Sie AND / OR / NAND / XOR-Schaltkreise mit FPGA, die für Deep Learning mit Polyphony erforderlich sein können

Lesen Sie Deep Learning von Grund auf neu

Das Buch Deep Learning von Grund auf neu ist wunderbar. Lernen mit Python Wie der Untertitel von Deep Learning zeigt, geht es in diesem Buch darum, Ihr Verständnis zu vertiefen, indem Sie eine Deep Learning-App (? Algorithmus?) Von Grund auf mit Python erstellen.

Dieses Buch macht zuerst AND, OR, NAND, XOR. Ich fühle mich überwältigt, aber lassen Sie uns diese mit Polyphony kompilieren und in Hardware umwandeln.

Die Quelle stammt von der folgenden URL auf github. https://github.com/ryos36/polyphony-tutorial/

Wenn Sie es einfach ausprobieren möchten, installieren Sie Polyphony und iverilog, klonen Sie die obige URL und führen Sie jede Quelle mit simu.py aus.

> pip3 install polyphony
<Installieren Sie iverilog ordnungsgemäß>
> git clone https://github.com/ryos36/polyphony-tutorial/
> cd polyphony-tutorial/DeepLearning
> ../bin/simu.py and.py 

Die Umgebungskonstruktion mit Pyvenv ist hier zusammengefasst. http://qiita.com/ryos36/items/7e7fce9078a79f782380

Von Perceptron in Kapitel 2

Lassen Sie uns das UND-Gatter erstellen, das im Beispiel in 2.3.1 gezeigt wird.

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()

Die Parameter im Buch sind 0,5, 0,5, 0,7, ändern Sie sie jedoch für Polyphonie in ganzzahlige Werte von 5, 5 und 7. (Wenn Sie jetzt darüber nachdenken, wäre vielleicht 2,2,3 besser gewesen)

Das Ergebnis ist wie folgt.

[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

Wie erwartet. Die Zahl links vom Doppelpunkt mysteriöser Informationen, die ohne Erlaubnis ausgegeben werden, ist die Zeit (Anzahl der Uhren). Es ist eine grobe Richtlinie für die Leistung.

Verwenden Sie eine Python-Liste

Verwenden wir nun die Python-Liste.

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()

Polyphonie hat keine Listenmultiplikation oder -summe, daher definieren wir eine Funktion.

[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

Durch die Verwendung von Listen wurde die Abstraktion hinzugefügt, aber sie wurde langsamer, da ich eine for-Anweisung für die Operation verwendet habe. Sie können or.py und nand.py auf die gleiche Weise erstellen. Es ist eine kleine traurige Quelle, dass es kopiert wird.

Versuchen Sie, XOR zu machen

Erstellen und führen Sie basierend darauf XOR aus.

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()

Es ist ein Höhepunkt des Kopier- und Einfügeprogramms, aber es funktioniert. Es ist wichtig, sich zu bewegen. Das Ergebnis scheint wie folgt korrekt zu sein.

[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

Verwenden Sie Python-Klassen

Verwenden Sie Klassen, um das Kopieren zu vermeiden. Die Aussichten haben sich erheblich verbessert.

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()

Ich habe aufgehört, Listen zu verwenden, daher ist die Ausführungszeit schneller.

[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: Taple-Version und

Wenn Sie Polyphony auf 0.3.0 setzen (normalerweise wird bei pip3 install 0.2.2 im Moment 2017.3.27 installiert), funktioniert auch die Taple-Version.

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()

Ich habe XOR gemacht

Ich konnte XOR machen, aber ist es natürlich, dass FPGA das überhaupt kann? Der Weg zum Deep Learning-Meister ist noch weit entfernt

Recommended Posts

Erstellen Sie AND / OR / NAND / XOR-Schaltkreise mit FPGA, die für Deep Learning mit Polyphony erforderlich sein können
Übersicht und nützliche Funktionen von Scikit-Learn, die auch für Deep Learning verwendet werden können
Erstellen Sie mit Docker eine Umgebung für "Deep Learning von Grund auf neu"
Versuchen Sie Deep Learning mit FPGA
Realisieren Sie mit Docker und Vagrant die Umgebungskonstruktion für "Deep Learning von Grund auf neu"
Selen: Warten Sie mit UND / ODER auf das Element
Eine Sammlung von Ressourcen, die zum Erstellen und Erweitern von Punktedateien hilfreich sein können