Capturing Beauty - Hybrides inkrementelles Lernen für das Wischen von Zunderprofilen mit KI-Unterstützung: Eine Implementierung in Keras.

Einführung

„Schönheit liegt im Auge des Betrachters“ - eine gut zitierte Zeile über die Standards menschlicher Schönheit. Aber was ist Schönheit? Können wir die oberflächliche Attraktivität eines Individuums definieren oder quantifizieren? Noch wichtiger ist, sollten wir etwas so Sensibles und Subjektives für eine Black Box abstrahieren? Während einige universelle Attribute wie Symmetrie als kulturübergreifend als schön identifiziert wurden, bleibt die Tatsache bestehen, dass die Beurteilung der Attraktivität eines Individuums eine subjektive Angelegenheit bleibt, die stark von der Umgebung abhängt, in der sich die Person befindet.

Tinder ist die weltweit beliebteste Dating-Anwendung, mit über 4,1 Millionen zahlenden Benutzern allein und über 20 Milliarden Übereinstimmungen, die 2018 täglich durchgeführt wurden. Die Beliebtheit kann auf seine Einfachheit zurückgeführt werden: Ein Benutzer wird präsentiert, wenn Profile aus einer Reihe von Fotos und Fotos bestehen einige Textinformationen. Basierend auf diesen Informationen wischt ein Benutzer nach rechts oder links, je nachdem, ob er das Profil attraktiv findet. Wenn zwei Benutzer direkt aufeinander streichen, wird eine Übereinstimmung hergestellt und die beiden Benutzer können dann miteinander chatten. Das Wischen wird stark von oberflächlichen Faktoren beeinflusst, wodurch tiefere Verbindungen bis in die Zukunft vermieden werden.

Es gibt automatische Wischskripte für Dating-Apps wie Tinder, solange die App existiert, obwohl die Anwendung die Verwendung ihrer APIs stark eingeschränkt hat. Diese Skripte basieren auf dem Ansatz von Quantität über Qualität, vorausgesetzt, dass bei genügend richtigen Wischbewegungen eine Übereinstimmung statistisch wahrscheinlicher ist. Untersuchungen haben gezeigt, dass Männer beim richtigen Wischen deutlich weniger selektiv sind als Frauen. Solche Ansätze werden jedoch durch Tinders eigenen internen Schutz behindert - den ELO-Score.

Das nach seinem Erfinder Arpad Elo benannte ELO-Bewertungssystem ist eine Berechnungsmethode zur Beurteilung der relativen Fähigkeiten von Spielern innerhalb eines Nullsummenspiels. Während des Ursprungs im Schach hat sich die Verwendung des Systems anderen Wettkampfsportarten zugewandt und ist auf professioneller Ebene für Ranglisten besonders nützlich. Im Kontext von Tinder können Benutzer durch eine Kombination bestimmter gewichteter Statistiken, wie z. B. Übereinstimmungs- und Rechtswischraten, gegeneinander eingestuft werden. Diese Ranglisten wirken sich dann darauf aus, wie, wie oft ein Profil von anderen Benutzern gesehen wird. Obwohl die vollständige Formel der Öffentlichkeit nicht zur Verfügung steht, haben Beobachtungen unter Benutzern gezeigt, dass ein Wischrecht durchweg dazu führt, dass der Benutzer bestraft wird und sein Profil an den unteren Rand des Stapels verschoben wird, wodurch es weniger wahrscheinlich wird, dass andere Benutzer auf ihr Profil stoßen .

Um dies zu überwinden, haben bestehende Autoswiping-Anwendungen statische oder variable Wahrscheinlichkeiten verwendet, um in regelmäßigen oder zufälligen Intervallen Linkswischungen einzuführen. Dies ist jedoch immer noch eine unzureichende Lösung, da sich gezeigt hat, dass der ELO-Wert des Zielprofils, auf den man direkt wischt, auch einen Einfluss auf den Wert des Wischers hat - zum Beispiel, wenn man direkt auf eine Person mit niedrigerem Rang wischt Dies wirkt sich nachteilig auf Ihre eigene ELO-Punktzahl aus.

Die optimale Lösung für dieses Problem würde daher darin bestehen, einen Wischalgorithmus an die Vorlieben eines Benutzers anzupassen. Indem wir Informationen darüber sammeln, auf welche Profile ein Benutzer nach links und rechts wischt, können wir einen Klassifikator erstellen, der nur nach rechts über Profile wischen kann, die der Benutzer als ästhetisch ansprechend erachtet. Ein Problem bei diesem Ansatz ist der Mangel an Daten zu Beginn des Trainingsprozesses, da Informationen zu den Einstellungen eines Benutzers nur erstellt werden, wenn er einen Wisch ausführt. Um dies zu beheben, können wir inkrementelles Lernen verwenden - einen Trainingsansatz, bei dem das Modell kontinuierlich mit einzelnen Datenpunkten trainiert wird, die im Laufe der Zeit gesammelt wurden. Ein solcher Ansatz würde nicht nur ermöglichen, dass ein sich kontinuierlich verbessernder Klassifikator zur sofortigen Verwendung verfügbar ist, sondern auch mögliche Änderungen der Präferenz im Laufe der Zeit berücksichtigen.

Beachten Sie, dass die Implementierung eines Autoswipers oder das Abkratzen von Daten von Tinder, solange eine Tinder-API vorhanden ist, gegen die Nutzungsbedingungen verstößt. Stattdessen verwenden wir stattdessen eine simulierte inkrementelle Lernumgebung: Wir verwenden für jede unserer beiden Klassen eine reduzierte Gesamtdatensatzgröße von 500 Bildern, die Gesichter mit wünschenswerten und unerwünschten Eigenschaften darstellen.

Wir werden zwei hypothetische Szenarien untersuchen:

  • Ein Benutzer, der ausschließlich auf asiatische weibliche Gesichter steht.
  • Ein Benutzer, der ausschließlich asiatischen weiblichen Gesichtern gegenüber einer bestimmten Attraktivitätsschwelle gegenüber parteiisch ist.
Beispielbilder aus dem SCUT-FBP-Datensatz.

Um dies zu beheben, werden wir den SCUT-FBP-Datensatz verwenden, der vom Human Computer Intelligent Interaction Lab an der South China University of Technology gesammelt wurde und aus 500 weiblichen asiatischen Gesichtern besteht, die von drei Forschern auf einer Skala von 1 bis 5 für „Attraktivität“ eingestuft wurden . Für diese Klasse verwenden wir einen Datensatz mit 477 Bildern, die aus dem Flicker Faces-Datensatz von NVIDIA stammen und von asiatischen weiblichen Beispielen befreit wurden.

Implementierung

In einer realen inkrementellen Lernsituation passen wir unser Modell an einzelne Datenpunkte an, speichern unseren Fortschritt und setzen das Training fort, sobald ein neuer Datenpunkt erfasst wurde. Wir werden uns jedoch mit einer Simulation abfinden, indem wir unsere Stapelgröße auf ein oder zwei Bilder beschränken. Im Wesentlichen bedeutet dies, dass das Netzwerk mit jeweils nur wenigen Bildern trainiert wird (ohne Just-in-Time-Keras-Datenerweiterungseffekte).

Unser Code wurde in Google Colaboratory mit Keras und Tensorflow implementiert. Der vollständige Code befindet sich wie gewohnt im GradientCrescent Repository.

Zu Beginn importieren wir unsere Datensätze in unser Notizbuch.

! pip install vis! pip install -I scipy == 1.2. *
! mkdir Daten
aus numpy.random importieren seed #seed (6) # 1 aus tensorflow import set_random_seed #set_random_seed (5) # 2
#
importiere numpy als np # lineare Algebra importiere Pandas als pd # Datenverarbeitung, CSV-Datei-E / A (zB pd.read_csv)
# Eingabedatendateien sind im Verzeichnis „../input/“ verfügbar. # Wenn Sie dies beispielsweise ausführen (indem Sie auf Ausführen klicken oder Umschalt + Eingabetaste drücken), werden die Dateien im Eingabeverzeichnis aufgelistet
os importieren
#TRAINING SETS ###########################################
#Download des FFHQ-Datensatzes minus asiatischer Frauen
! gdown https://drive.google.com/uc?id=1neeeqFXWcdgTognHrPlndnjqPUxBBL1i #Downlaod SCUT-FBP Asian Dataset
! gdown https://drive.google.com/uc?id=1IUqrFv9Fal5S3bujWfEx0hIlquecDVFn #Download Ratings CSV - dies wird für das Beauty-Ranking verwendet (3)
! gdown https://drive.google.com/uc?id=1LBP5MnfB-IY2hSjkt_qsaoqEJv3OS6kD
# Alle Ordner entpacken
! unzip asian_tinder.zip -d data! unzip real_tinder.zip -d data

Sie werden feststellen, dass wir zusammen mit unseren Datensätzen auch eine CSV-Tabelle herunterladen. Dies ist das Attraktivitätsranking der SCUT-FBP-Forscher, an dem wir für einen späteren Teil der Studie festhalten werden. Sie werden auch die nächste Codezelle bemerken - diese Sortierung durch den SCUT-FBP enthält nur Beispiele, die über einer Attraktivitätsbewertung von 3 liegen. Dies wird nur aktiviert, wenn das zweite Szenario betrachtet wird. Lassen Sie es also so, wie es ist .

print (os.listdir ("/ content /"))
#Der folgende Code dient zum Ändern des Datensatzes gemäß den Rankings des Asian Female Face-Datensatzes. Standardmäßig deaktiviert, aktivieren Sie diese Option, wenn Sie den Beauty-Ranking-Teil des Tutorials "" replizieren möchten.
base_dir_A = '/ content / data / asian /' base_dir_B = '/ content / data / real /' base_dir_Beauty = '/ content / data / beauty /'
os.mkdir (base_dir_Beauty)
Pandas als PD importieren Shutil importieren
Ranking = pd.read_csv ("tinder_labels.csv") #print (Ranking)
#Iterieren Sie alle Beschriftungen innerhalb des df für i, j in ranking.iterrows (): #print (int (j ["Image"])) filenumber = int (j ["Image"]) filename = "SCUT-" FBP - ”+ str (Dateinummer) +”. Jpg ”
#Iterrate über alle Bilder und verschiebe sie zur Schönheit. Ruhe bewegen sich zu real.
 # Setzen Sie dann eine neue A-Klasse als Beauty-Ordner. # Definieren Sie Quelle und Ziel, kopieren Sie sie über src = base_dir_A + Dateiname dst = base_dir_Beauty + Dateiname shutil.copy (src, dst) (src) #Wenn wir dies für alle Dateien im Datenrahmen tun, verschieben Sie die Reste in Verzeichnis B.
für Dateiname in os.listdir (base_dir_A): leftsrc = base_dir_A + Dateiname leftdst = base_dir_B + Dateiname # rename () Funktion # benennt alle Dateien um shutil.copy (leftsrc, leftdst) os.remove (leftsrc) #Sanity check print ( os.listdir (base_dir_A))
# Denken Sie danach daran, die Klassenverzeichnisse entsprechend festzulegen. # /Content/data/asian/SCUT-FBP-11.jpg
os.rmdir (base_dir_A) "" "

Als nächstes definieren wir unsere Vorverarbeitungsfunktionen und ImageDataGenerators. Die gesamte Vorverarbeitung stammt ursprünglich von Keras. Sie werden feststellen, dass wir hier zwei Sätze davon erstellt haben, wobei ein Trainings- und Validierungspaar eine Stapelgröße von 1 und ein anderes eine Stapelgröße von 5 abdeckt. Wir werden diese beiden Sätze verwenden, um ein Hybridtraining zu implementieren Methodik.

aus tensorflow.keras importieren Backend als K aus tensorflow.keras.models importieren Modell, load_model aus tensorflow.keras.layers importieren Flatten, Dense, Dropout aus tensorflow.keras.applications.inception_resnet_v2 importieren InceptionResNetV2, preprocess_input aus tensorflow.keras.optimizers , RMSprop von tensorflow.keras.preprocessing.image importieren ImageDataGenerator von tensorflow.keras.callbacks importieren ModelCheckpoint importieren numpy als np von tensorflow.keras.layers importieren Dense, GlobalAveragePooling2D von tensorflow.keras.applications.inception_v3 importieren InceptionV3 importieren Tensor
DATASET_PATH = '/ content / data'
IMAGE_SIZE = (299, 299) NUM_CLASSES = 2 BATCH_SIZE = 1 # Stapelgröße eins zur Simulation des Online-Lernens
NUM_EPOCHS = 150 LEARNING_RATE = 5e-4 # Langsame Lernrate beim Transfertraining5e-5. 2E-4 versucht, DROP_OUT = .5
#Train datagen hier ist ein Präprozessor train_datagen = ImageDataGenerator (preprocessing_function = preprocess_input, rotationsbereich = 50, featurewise_center = True, featurewise_std_normalization = True, width_shift_range = 0.2, height_shift_range = 0.2, height_shange_range = , horizontal_flip = True, vertikale_flip = True, validation_split = 0,3, fill_mode = 'Konstante')
# test_datagen = ImageDataGenerator (Vorverarbeitungsfunktion = Vorverarbeitungseingabe, # fill_mode = 'Konstante')
train_batches_5 = train_datagen.flow_from_directory (DATASET_PATH, target_size = IMAGE_SIZE, shuffle = True, batch_size = 5, subset = "training", class_mode = 'binary')
valid_batches_5 = train_datagen.flow_from_directory (DATASET_PATH, target_size = IMAGE_SIZE, shuffle = True, batch_size = 3, subset = "validation", class_mode = 'binary')
train_batches_1 = train_datagen.flow_from_directory (DATASET_PATH, target_size = IMAGE_SIZE, shuffle = True, batch_size = 1, subset = "training", class_mode = 'binary')
valid_batches_1 = train_datagen.flow_from_directory (DATASET_PATH, target_size = IMAGE_SIZE, shuffle = True, batch_size = 1, subset = "validation", class_mode = 'binary')

Als nächstes definieren wir unser InceptionV3-Modell. Wir haben dasselbe Modell bereits verwendet - ein einfaches Vanillemodell mit ImageNet-Gewichten und einem benutzerdefinierten Top-End für die binäre Klassifizierung. Die Verwendung eines vorab geschulten Benchmark-Modells verkürzt die Schulungszeit und ermöglicht eine schnelle Implementierung und Ideenvalidierung.

Lassen Sie uns zunächst untersuchen, wie sich unser InceptionV3-Modell mit einem rein inkrementellen lernbasierten Ansatz verhält, mit einer Stapelgröße von eins für 150 Epochen und einer Lernrate von 2E-4. Wir können dies mit dem Befehl .fit () tun:

Ergebnis = model.fit_generator (train_batches_1, schritte_per_epoch = 100, validierungsdaten = valid_batches_1, validierungsschritte = 50, epochen = 150,)

Das Training sollte weniger als eine Stunde dauern. Sobald wir fertig sind, können wir unsere Ergebnisse mit der Matplotlib-Bibliothek überprüfen:

def plot_acc_loss (Ergebnis, Epochen): acc = result.history ['acc'] loss = result.history ['loss'] val_acc = result.history ['val_acc'] val_loss = result.history ['val_loss'] plt. figure (figsize = (15, 5)) plt.subplot (121) plt.plot (Bereich (Epochen), acc [: 150], label = 'Train_acc') plt.plot (Bereich (Epochen), val_acc [: 150 ], label = 'Test_acc') plt.title ('Genauigkeit über' + str (Epochen) + 'Epochen', Größe = 15) plt.legend () plt.grid (True) plt.subplot (122) plt.plot (Bereich (Epochen), Verlust [: 150], label = 'Train_loss') plt.plot (Bereich (Epochen), val_loss [: 150], label = 'Test_loss') plt.title ('Verlust über' + str ( Epochen) + 'Epochen', Größe = 15) plt.legend () plt.grid (True) plt.show () plot_acc_loss (Ergebnis, 50)
Genauigkeit und Verlustleistung unseres Modells nach Schulung und Feinabstimmung mit einem rein inkrementellen Lernansatz (Chargengröße = 1).

Das ist ziemlich schrecklich. Unsere Validierungsgenauigkeit beträgt ca. 50%. Der Versuch, dieses Modell mit einer niedrigeren Lernrate von 2E-5 zu optimieren, hilft auch nicht.

Ist kein gutes Zeichen für reines inkrementelles Lernen. Aufgrund der geringen Größe jeder Charge verfügen wir einfach nicht über genügend Daten, damit der Gradientenabstieg zu den optimalen Parametern konvergieren kann, was zu einer anhaltend schlechten Leistung führt. Beachten Sie, wie die Genauigkeits- und Verlustwerte stark schwanken, eine bekannte Schwäche des inkrementellen Lernens. Da die Anzahl der Bilder pro Stapel in einer Epoche sehr begrenzt ist, wird der relative Beitrag jedes einzelnen Bildes erheblich vergrößert, was zu den beobachteten großen Schwankungen führt.

Wie überwinden wir dieses Problem?

Nehmen wir an, wir beginnen nicht sofort nach dem Empfang der Daten mit dem Training, sondern warten, bis eine bestimmte Mindestgröße des Datensatzes erreicht ist. Wir könnten das Modell dann traditionell für einige Epochen mit einer größeren Charge trainieren und erst dann inkrementelles Lernen ermöglichen. Wenn alle Daten von einer gemeinsam genutzten Domäne stammen, würde dieser Ansatz eine schnellere Konvergenz des Gradientenabfalls zu den richtigen Parametern ermöglichen, wobei inkrementelles Lernen eine geringere Rolle spielt, ähnlich wie bei der Feinabstimmung.

Simulieren wir das also. Nehmen wir an, der Benutzer wischt über einige Tage, wischt über 50 Profile und erzielt eine ungefähr gleiche Datenverteilung, die unseren Kriterien entspricht. Wir könnten dann eine Stapelgröße von 5 Bildern (train_batches_5) verwenden, um unser Modell für 6 Epochen mit einer höheren Lernrate von 5E-4 zu trainieren, wobei 20 Bilder zur Validierung bei einer Stapelgröße von 3 (valid_batches_5) übrig bleiben. Wir wechseln dann zu unserem inkrementellen Modell, trainieren mit einer Stapelgröße von 1 und einer Lernrate von 2E-5 und optimieren unser Modell im Wesentlichen mit frischen Daten. Werfen wir einen Blick auf die Ergebnisse:

Genauigkeit und Verlustleistung unseres Modells nach Schulung und Feinabstimmung mit einem hybriden inkrementellen Lernansatz (Chargengröße = 5 & 1).

Mit einer Validierungsgenauigkeit von ungefähr 90% haben wir einen kompetenten Klassifikator für unsere Anwendung erstellt. Die anfänglich höhere Lernrate hat Fortschritte in Richtung des richtigen Optimums gemacht, sodass die kleinere Rate schneller zu diesem konvergieren kann. Wir beobachten jedoch einige Überanpassungen nach 60 Epochen, weshalb ein frühzeitiges Anhalten gerechtfertigt sein kann.

Nachdem wir unser erstes Szenario behandelt haben, was wäre, wenn unser Benutzer selektiver wäre und lieber nur Benutzer über eine Attraktivitätsschwelle streicht? Lassen Sie uns unseren Vorverarbeitungscode aktivieren, der dazu führen sollte, dass 119 Beispiele in das neue Verzeichnis „Beauty“ übertragen werden und der Rest in die Hilfsklasse verschoben wird. Anschließend trainieren wir unser Modell mit der gleichen Hybridmethode wie zuvor, behalten jedoch die Feinabstimmung auf 50 Epochen bei, um eine Überanpassung zu vermeiden:

Genauigkeit und Verlustleistung unseres Modells nach Schulung und Feinabstimmung mit einem hybriden inkrementellen Lernansatz (Stapelgröße = 5 & 1), wobei unausgeglichene Datenklassen auf hochattraktive weibliche asiatische Gesichter abzielen.

Sie werden feststellen, dass unsere Validierungsgenauigkeit hier relativ schnell konvergiert und der Verlust mit der Zeit scheinbar zunimmt. Dies deutet darauf hin, dass das Modell nicht wirklich lernt, was auf eine Überlappung der Datendomäne zurückzuführen ist. Die kleinen Unterschiede zwischen dem, was als „schön“ und einem durchschnittlicheren Gesichtsbeispiel angesehen wird, sind zu klein, um mit diesem Modell unterschieden zu werden. Vielleicht ist das das Beste. Wir möchten nicht, dass KI die Magie der Verbindung mit den Menschen, die wir schön finden, aufhebt, oder?

Schönheit liegt wirklich im Auge des Betrachters.

Wir hoffen, Ihnen hat dieser Artikel auf GradientCrescent gefallen. Um über unsere Artikel auf dem Laufenden zu bleiben, sollten Sie die Veröffentlichung abonnieren. Als nächstes entfernen wir uns endlich von den neuronalen Faltungsnetzen und diskutieren das Lernen der Verstärkung.