2016-04-10 14 views
14

Ich bin neu in Python, und ich lerne TensorFlow. In einem Lernprogramm mit dem NotMNIST-Dataset geben sie Beispielcode, um die Beschriftungsmatrix in ein Ein-von-N-codiertes Array umzuwandeln.Verständnis == An ein NumPy-Array

Das Ziel ist es, eine Anordnung zu übernehmen, bestehend aus Etikett ganzen Zahlen 0 ... 9, und gibt eine Matrix, wobei jede ganze Zahl in einen wie diese ein-von-n codierten Arrays transformiert wurde:

0 -> [1, 0, 0, 0, 0, 0, 0, 0, 0, 0] 
1 -> [0, 1, 0, 0, 0, 0, 0, 0, 0, 0] 
2 -> [0, 0, 1, 0, 0, 0, 0, 0, 0, 0] 
... 

Der Code, den sie geben, ist:

# Map 0 to [1.0, 0.0, 0.0 ...], 1 to [0.0, 1.0, 0.0 ...] 
labels = (np.arange(num_labels) == labels[:,None]).astype(np.float32) 

Allerdings verstehe ich nicht, wie dieser Code das überhaupt macht. Es sieht so aus, als ob es nur ein Array von Ganzzahlen im Bereich von 0 bis 9 erzeugt und vergleicht dieses dann mit der Etikettenmatrix und wandelt das Ergebnis in einen Gleitkommawert um. Wie ergibt sich ein == Operator in einer one-of-n codierten Matrix?

Antwort

22

Hier gibt es ein paar Dinge: numpys Vektor-Ops, Hinzufügen einer Singleton-Achse und Broadcasting.

Zunächst sollten Sie in der Lage zu sehen, wie die == macht die Magie.

Nehmen wir an, wir beginnen mit einem einfachen Label-Array. == verhält sich vektorisiert, was bedeutet, dass wir das gesamte Array mit einem Skalar vergleichen können und ein Array erhalten, das aus den Werten jedes elementweisen Vergleichs besteht. Zum Beispiel:

>>> labels = np.array([1,2,0,0,2]) 
>>> labels == 0 
array([False, False, True, True, False], dtype=bool) 
>>> (labels == 0).astype(np.float32) 
array([ 0., 0., 1., 1., 0.], dtype=float32) 

Zuerst bekommen wir einen boolean-Array, und dann zwingen wir Schwimmern: False == 0 in Python, und True == 1. Wir enden also mit einem Array, das 0 ist, labels ist nicht gleich 0 und 1 wo es ist.

>>> (labels == 2).astype(np.float32) 
array([ 0., 1., 0., 0., 1.], dtype=float32) 

In der Tat, wir Schleife über alle möglichen Etikett konnte und dieses Array erzeugen:

Aber es gibt nichts Besonderes zu 0 zu vergleichen, könnten wir auf 1 oder 2 oder 3 stattdessen für ähnliche Ergebnisse vergleichen. Wir könnten eine listcomp verwenden:

>>> np.array([(labels == i).astype(np.float32) for i in np.arange(3)]) 
array([[ 0., 0., 1., 1., 0.], 
     [ 1., 0., 0., 0., 0.], 
     [ 0., 1., 0., 0., 1.]], dtype=float32) 

aber das dauert nicht wirklich nutzen numpy. Was wir tun möchten, ist jede mögliche Etikett mit jedem Element verglichen haben, IOW

>>> np.arange(3) 
array([0, 1, 2]) 

mit

>>> labels 
array([1, 2, 0, 0, 2]) 

zu vergleichen Und hier ist, wo die Magie von numpy Rundfunk kommt in. Im Moment labels a 1-dimensionales Objekt der Form (5,). Wenn wir es zu einem zweidimensionalen Objekt der Form (5,1) machen, wird die Operation über die letzte Achse "übertragen" und wir erhalten eine Ausgabe der Form (5,3) mit den Ergebnissen des Vergleichs jedes Eintrags in der Bereich mit jedem Element der Etiketten.

Zuerst können wir eine „extra“ Achse labels mit None (oder np.newaxis) hinzufügen, seine Form zu verändern:

>>> labels[:,None] 
array([[1], 
     [2], 
     [0], 
     [0], 
     [2]]) 
>>> labels[:,None].shape 
(5, 1) 

Und dann können wir den Vergleich machen (dies ist die Transponierung der Anordnung ist, wir waren schaue früher, aber das ist nicht wirklich wichtig).

Broadcasting in numpy ist sehr mächtig, und es lohnt sich, es zu lesen.

+0

Eine sehr detaillierte und schöne Erklärung. Die meisten Leute, die den Udacity Deep Learning-Kurs besuchen, müssen auf diese Antwort gestoßen sein. – AgentX

0

Kurz gesagt, == angewendet auf ein numpy Array bedeutet elementweises = = auf das Array anwenden. Das Ergebnis ist ein Array von Booleschen Werten. Hier ein Beispiel:

>>> b = np.array([1,0,0,1,1,0]) 
>>> b == 1 
array([ True, False, False, True, True, False], dtype=bool) 

sagen zu zählen, wie viele 1s gibt es in b, müssen Sie nicht das Array werfen müssen, um schwimmen, dh die .astype(np.float32) gespeichert werden können, weil in Python boolean ist eine Unterklasse von int und in Python 3 haben Sie True == 1 False == 0. Hier ist also, wie man zählt, wie viele Einsen in b:

>>> np.sum((b == 1)) 
3 

Oder:

>>> np.count_nonzero(b == 1) 
3