2017-12-19 4 views
0

Ich arbeite an der Udacity Deep Learning-Klasse und ich arbeite an der ersten Aufgabe, Problem 5, wo Sie versuchen, die Anzahl der Duplikate in, sagen wir, Ihre Testgruppe zu zählen und Trainingssatz. (Oder Validierung und Training, etc.)Udacity Deep Learning: Aufgabe 1, Teil 5

Ich habe die Antworten anderer Leute angeschaut, aber ich bin nicht mit ihnen aus verschiedenen Gründen zufrieden. Zum Beispiel habe ich jemandes Hash-basierte Lösung ausprobiert. Aber ich fühlte, dass die zurückgegebenen Ergebnisse nicht korrekt sein würden.

Also die Hauptidee ist, dass Sie eine Reihe von Bildern haben, die als Arrays formatiert sind. I.e. Sie versuchen, zwei dreidimensionale Arrays auf Index 0 zu vergleichen. Ein Array ist das Trainings-Dataset, das aus 200000 Zeilen besteht, wobei jede Zeile ein 2D-Array enthält, bei dem es sich um die Werte für das Bild handelt. Der andere ist der Testsatz mit 10000 Zeilen, wobei jede Zeile ein 2-D-Array eines Bildes enthält. Das Ziel besteht darin, alle Zeilen in der Testmenge zu finden, die eine Zeile im Trainingssatz (für jetzt ist eine genaue Übereinstimmung in Ordnung) übereinstimmen. Da jede "Zeile" selbst ein Bild ist (welches ein 2-d-Array ist), muss ich in der Lage sein, einen Vergleich beider Sätze als einen elementweisen Vergleich jeder Zeile zu machen, um diese Arbeit schnell zu machen.

arbeitete ich meine eigene ziemlich einfache Lösung wie diese auf:

# Find duplicates 
# Loop through validation/test set and find ones that are identical matrices to something in the training data 
def find_duplicates(compare_set, compare_labels, training_set, training_labels): 
    dup_count = 0 
    duplicates = [] 
    for i in range(len(compare_set)): 
     if i > 100: continue 
     if i % 100 == 0: 
      print("i: ", i) 
     for j in range(len(training_set)): 
      if compare_labels[i] == training_labels[j]: 
       if np.array_equal(compare_set[i], training_set[j]): 
        duplicates.append((i,j)) 
        dup_count += 1 
    return dup_count, duplicates 

#print(len(valid_dataset)) 
print(len(train_dataset)) 
valid_dup_count, duplicates = find_duplicates(valid_dataset, valid_labels, train_dataset, train_labels) 
print(valid_dup_count) 
print(duplicates) 
#test_dups = find_duplicates(test_dataset, train_dataset) 
#print(test_dups) 

Der Grund ist es „weiterhin“ nur nach 100 da ist, dass allein eine sehr lange Zeit in Anspruch nimmt. Wenn ich versuchen würde, alle 10.000 Zeilen des Validierungssatzes mit dem Trainingssatz zu vergleichen, würde es ewig dauern.

Ich mag meine Lösung im Prinzip, weil es mir erlaubt, nicht nur die Duplikate zu zählen, sondern eine Liste der Übereinstimmungen zu erhalten. (Etwas fehlt bei jeder anderen Lösung, die ich mir angesehen habe.) Dadurch kann ich manuell testen, ob ich die richtige Lösung gefunden habe.

Was ich wirklich brauche, ist eine viel schnellere Lösung (d. H. In Numpy eingebaut), Matrizen dieser Matrizen zu vergleichen. Ich habe mit 'Isin' und 'Wo' gespielt, aber ich habe nicht herausgefunden, wie ich diese verwenden kann, um die Ergebnisse zu erzielen, nach denen ich suche. Kann mir jemand in die richtige Richtung für eine schnellere Lösung zeigen?

+0

Nicht sicher auf die Zeiten hier, aber vorausgesetzt, Ihre 'compare_set' und' trainings_set' sind von Form '(n_images, img_h, img_w)', dann anstelle einer doppelten 'for' Schleife, können Sie einfach über' für img in compare_set' und 'np.where (np.all (training_set == img, axis = (1, 2))' gibt dir die Indizes aller Übereinstimmungen in 'trainings_set'. –

Antwort

1

Sie sollten in der Lage sein, ein einzelnes Bild von compare_set in allen Bildern in training_set mit einer einzelnen Codezeile unter Verwendung np.all() zu vergleichen. Sie können mehrere Achsen als Tupel im axis-Argument bereitstellen, um die Array-Gleichheit über Zeilen und Spalten zu überprüfen, wobei jedes Bild durchlaufen wird. Dann kann np.where() Ihnen die Indizes geben, die Sie wünschen.

Zum Beispiel:

n_train = 50 
n_validation = 10 
h, w = 28, 28 

training_set = np.random.rand(n_train, h, w) 
validation_set = np.random.rand(n_validation, h, w) 

# create some duplicates 
training_set[5] = training_set[10] 
validation_set[2] = training_set[10] 
validation_set[8] = training_set[10] 

duplicates = [] 
for i, img in enumerate(validation_set): 
    training_dups = np.where(np.all(training_set == img, axis=(1, 2)))[0] 
    for j in training_dups: 
     duplicates.append((i, j)) 

print(duplicates) 
[(2, 5), (2, 10), (8, 5), (8, 10)] 

Viele numpy Funktionen, np.all() enthalten, können Sie die Achsen festlegen, für den Betrieb auf. Zum Beispiel, sagen wir mal hatte man die beiden Arrays

>>> A = np.array([[1, 2], [3, 4]]) 
>>> B = np.array([[1, 2], [5, 6]]) 
>>> A 
array([[1, 2], 
     [3, 4]]) 
>>> B 
array([[1, 2], 
     [5, 6]]) 

Nun A und B die gleiche erste Reihe haben, aber eine andere zweite Reihe. Wenn wir Gleichheit prüfen sie

>>> A == B 
array([[ True, True], 
     [False, False]], dtype=bool) 

Wir bekommen ein Array die gleiche Form wie A und B. Aber was, wenn ich die Indizes der Zeilen haben möchte, die gleich sind?Nun, in diesem Fall, was wir tun können, ist sagen, nur True, wenn alle die Werte in der Zeile (d. H. Der Wert in jeder Spalte) sind True '. So können wir np.all() nach der Prüfung der Gleichheit verwenden und es die Achse entsprechend den Spalten zur Verfügung stellen.

>>> np.all(A == B, axis=1) 
array([ True, False], dtype=bool) 

Also das Ergebnis lässt uns wissen, dass die erste Zeile in beiden Arrays gleich ist, und die zweite Reihe ist nicht alle gleich sind. Wir können dann bekommen Sie die Zeilenindizes mit np.where()

>>> np.where(np.all(A == B, axis=1)) 
(array([0]),) 

So sehen wir hier die Zeile 0, das heißt A[0] und B[0] gleich sind.


Jetzt in der Lösung, die ich vorgeschlagen habe, haben Sie ein 3D-Array anstelle dieser 2D-Arrays. Es ist uns egal, ob eine einzelne Zeile gleich ist, wir kümmern uns, wenn alle die Zeilen und Spalten sind gleich. Also, wie oben beschrieben, erstellen wir zwei zufällige 5x5-Bilder. Ich werde eines jener Bilder greifen und unter der Anordnung von zwei Bildern auf Gleichheit überprüfen:

>>> imgs = np.random.rand(2, 5, 5) 
>>> img = imgs[1] 
>>> imgs == img 
array([[[False, False, False, False, False], 
     [False, False, False, False, False], 
     [False, False, False, False, False], 
     [False, False, False, False, False], 
     [False, False, False, False, False]], 

     [[ True, True, True, True, True], 
     [ True, True, True, True, True], 
     [ True, True, True, True, True], 
     [ True, True, True, True, True], 
     [ True, True, True, True, True]]], dtype=bool) 

Das ist also offensichtlich, dass die zweite ist richtig, aber ich will alle jene True Werte auf einen reduzieren True Wert; Ich möchte nur den Index, der Bildern entspricht, wobei jeder Wert gleich ist.

Wenn wir axis=1 verwenden

>>> np.all(imgs == img, axis=1) 
array([[False, False, False, False, False], 
     [ True, True, True, True, True]], dtype=bool) 

Dann erhalten wir True für jede Reihe, wenn alle Spalten in jeder Zeile äquivalent sind. Und das wollen wir noch weiter reduzieren, indem wir die Gleichheit auch in allen Zeilen überprüfen. So können wir dieses Ergebnis nehmen, füttern es in np.all() und überprüfen entlang der Reihen des resultierenden Array:

>>> np.all(np.all(imgs == img, axis=1), axis=1) 
array([False, True], dtype=bool) 

Und das gibt uns einen boolean von welcher Bild innerhalb imgs gleich img, und wir können einfach das bekommen Ergebnis mit np.where(). Aber Sie müssen nicht wirklich np.all() zweimal so anrufen; stattdessen können Sie es mehrere Achsen in einem Tupel bieten nur entlang zu reduzieren sowohl die Zeilen und Spalten in einem Schritt:

>>> np.all(imgs == img, axis=(1, 2)) 
array([False, True], dtype=bool) 

Und das ist, was die Lösung oben tut. Hoffe das klärt es auf!

+0

Schön, ich werde es ausprobieren und lass es dich wissen! –

+0

Okay, es funktioniert wie ein Charme. Zumindest für kleine Zahlen. Ich muss es auf die ganze Sache loslassen, um zu sehen, ob es beschleunigt genug, um die Lösung zu sein, die ich brauche. Vielen Dank viel! –

+0

Ja, es ist jetzt viel schneller! Hey, können Sie erklären, wie Achse mit einem Tupel hier funktioniert? Ich verstehe nicht ganz das Konzept, das Sie hier verwendet. –