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
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.
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é.
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
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
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 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