[PYTHON] Ich habe eine Twitter-App erstellt, die das Bild eines bestimmten Charakters auf der Twitter-Timeline durch Pytorch-Transfer-Lernen identifiziert und speichert

Einführung

Ich habe eine Anwendung erstellt, die die Bilder der empfohlenen Zeichen automatisch in Unterscheidungsordner klassifiziert.

Dieses Mal verwenden wir eine Bibliothek für maschinelles Lernen namens pytorch und eine API namens tweepy, die Informationen auf Twitter lernen kann.

Grund für die Erstellung

Es ist schwer, die gesamte Twitter-Timeline zu sehen, daher möchte ich nur das Bild des empfohlenen Charakters speichern Ich wollte etwas mit Tweeypy und maschinellem Lernen machen Das Transfer-Lern-Tutorial von Pytorch war wunderbar, deshalb wollte ich es nutzen. Ich wollte die Probleme erleben, die beim Erstellen einer App für maschinelles Lernen auftreten.

Was ich getan habe

--Pytorch Transfer Lernen

Modifikation des Lernprogramms für Pytorchtransfer

Ein trainiertes Modell wird im Voraus in Pytorch vorbereitet und ist einfach zu bedienen. Im Pytorch-Tutorial habe ich es verwendet und geändert, um es an die Aufgabe anzupassen, die auf der Methode des Transferlernens basiert. Bei dieser Aufgabe wird davon ausgegangen, dass es auf Twitter ein reales Bild und ein zweidimensionales Bild gibt und dass das zweidimensionale Bild eine Struktur aus einem Bild des Zielcharakters und einem Bild aufweist, das nicht zuerst die Animation und die Realität ist Ich habe ein Modell erstellt, um das Bild zu identifizieren, und dann ein Modell erstellt, um das zweidimensionale Bild erneut zu identifizieren.

Insbesondere bestand die erste Methode darin, die vollständig verbundene Schicht des trainierten res-net18 in eine verbundene Schicht mit einer für die Klasse geeigneten Größe zu ändern und dem Modell ein Bild der Aufgabe zu geben, sie neu zu trainieren.

Von Anfang an war die Unterscheidungsrate zwischen realen und nicht realen Bildern sehr hoch und lag über 95% oder mehr, aber die Unterscheidungsrate eines bestimmten Zeichens war nicht so hoch wie 70%, und wir haben versucht, sie durch verschiedene Methoden zu verbessern.

Algorithmus- und Modelländerungen

Einfacher Wechsel

Modellwechsel

Als erstes habe ich versucht, das Modell zu ändern. Es gibt einige trainierte Modelle in Pytorch, also habe ich versucht, Alex-Net unter ihnen zu verwenden. Die Genauigkeit verbesserte sich jedoch nicht durch einfaches Ändern, sodass ich zu resnet zurückkehrte.

Der Optimierungsalgorithmus wurde geändert

Am Anfang haben wir mit SGD als Optimierungsalgorithmus trainiert, aber wir haben dies geändert und beschlossen, Adam zu verwenden. Es war jedoch überhaupt nicht genau und Adam hörte, dass Hyperparameter wichtig waren, und entschied sich daher für optuma, eine Hyperparametersuchbibliothek.

optuna oputuna ist eine Bibliothek, die numerische Werte aus der Verteilung für die Hyperparameter liefert, die Sie optimieren möchten. Das spezifische Verfahren besteht darin, zuerst die Zielfunktion zu definieren, die den numerischen Wert und den hohen Para enthält, den Sie optimieren möchten.

Zielfunktion


def objective(trial):

    lr =trial.suggest_loguniform('lr', 1e-6, 1e-4)
    beta1 =trial.suggest_uniform('beta1', 0.8, 0.95)
    beta2 =trial.suggest_uniform('beta2', 0.9, 0.99)
    eps =trial.suggest_loguniform('eps', 1e-9,1e-7)
    gamma = trial.suggest_loguniform('gamma',0.05,0.2)

    model_ft = models.resnet18(pretrained=True)
    num_ftrs = model_ft.fc.in_features
    model_ft.fc = nn.Linear(num_ftrs, 2)
    model_ft = model_ft.to(device)

    criterion = nn.CrossEntropyLoss()

    optimizer_ft = optim.Adam(model_ft.parameters(), lr=lr, betas=(beta1, beta2), eps=eps, weight_decay=0, amsgrad=False)

    exp_lr_scheduler = lr_scheduler.StepLR(optimizer_ft, step_size=7, gamma=gamma)
    model_ft,best_loss,best_acc = train_model(model_ft, criterion, optimizer_ft, exp_lr_scheduler)
    return 1 - best_acc

Die Einschränkung hierbei ist, dass Sie die Zahl, die Sie optimieren möchten, als Minimierungsproblem definieren müssen, wenn Sie sie zurückgeben. Dieses Mal möchte ich die Genauigkeit maximieren, also subtrahiere ich die Genauigkeit von 1 und gebe den Wert zurück. Es scheint, dass es verschiedene andere Funktionen gibt, aber diesmal habe ich leicht gelernt.

study


study = optuna.create_study()
study.optimize(objective, n_trials=2)

Erstellen Sie nach dem Definieren der Zielfunktion ein Studienobjekt, übergeben Sie die Zielfunktion und die Anzahl der Versuche, und die Hyperparameter werden automatisch angepasst.

Das Einstellen von Adams Hyperparametern hat hier eine gute Verbesserung der Genauigkeit. 77% auf resnet Es gab eine 75% ige Verbesserung gegenüber alex-net.

Datenänderung

Hier habe ich mich für einen Ansatz entschieden, z. B. die Datenmenge zu erhöhen und die Auflösung zu ändern.

Daten erhöhen

Erstens verbesserte sich die Genauigkeit auf etwa 83%, als wir die Datenmenge verdoppelten. Danach, als ich die Auflösung verbesserte, lag die Genauigkeit bei etwa 90%.

Überprüfung der Gültigkeit der Beurteilungsergebnisse durch Guided-Gradcam

Was ist Guided-Gradcam?

Ich werde hier nicht ins Detail gehen, aber kurz gesagt, es ist eine Technologie, die visualisiert, wo CNN aussieht und Entscheidungen trifft, unter Berücksichtigung des Einflusses jeder Klasse.

Implementierung

https://github.com/kazuto1011/grad-cam-pytorch Hier werden Methoden wie gradcam implementiert, damit sie mit pytorch verwendet werden können, und ich habe sie unter Bezugnahme auf diese Demo implementiert.

Ergebnis

Bild Bild bei der Beurteilung als F. Bild bei der Beurteilung als T.

Implementierung in der Anwendung

tweepy Eine Bibliothek, die die von Twitter bereitgestellte API umschließt, in der Sie die Zeitleiste lernen und Benutzern folgen können. Allerdings als Einschränkung

Es ist geworden. Der Ablauf dieses Prozesses besteht darin, zuerst die Tweets auf der Timeline zu lernen und dann zu bestimmen, welches das Bild hat.

Verfahren, um festzustellen, ob die URL ein Bild enthält


import tweepy
import keys
import classifierImage
def main():
    auth = tweepy.OAuthHandler(keys.consumer_key,keys.consumer_secret)
    auth.set_access_token(keys.access_token,keys.access_token_secret)

    api = tweepy.API(auth)

    public_tweets = api.home_timeline(count=200)
    urls = []
    for tweet in public_tweets:
        if 'media' in tweet.entities:
            for media in tweet.entities['media']:
                #print(media['media_url'])
                urls.append(media['media_url'])
    classifierImage.downloadImage(urls)
            

if __name__=='__main__':
    main()

Rufen Sie als nächstes das gespeicherte trainierte Modell auf. Lernen Sie Bilddaten aus der Argument-URL und konvertieren Sie die Binärdaten in ein PIL-Bildobjekt. Verarbeiten Sie es mit Fackelvision, beurteilen Sie es anhand des Modells und legen Sie das Download-Ziel fest.

Ein Programm, das Bilder beurteilt und speichert


import urllib.request
import torch
import numpy as np
import io
from PIL import Image
import cv2
from torchvision import transforms,models
import torch.nn as nn

def downloadImage(imageUrls):
    
    tgts=[]
    for url in imageUrls:
        filename = url.split('/')[-1]
        tgt = urllib.request.urlopen(url).read()
        tgts.append((tgt,filename))
    
    toTe = transforms.ToTensor()
    nor = transforms.Normalize([0.5,0.5,0.5],[0.5,0.5,0.5])
    
    co = transforms.Compose([
        transforms.Resize(512),
        transforms.CenterCrop(448),
        transforms.ToTensor(),
        transforms.Normalize([0.5,0.5,0.5],[0.5,0.5,0.5])
        ])
    
    #tensors = torch.cat(tgs,dim=0)
    
    classfier_anime_model = models.resnet18(pretrained=True)
    num_ftrs = classfier_anime_model.fc.in_features

    classfier_anime_model.fc = nn.Linear(num_ftrs, 2)
    classfier_anime_model.load_state_dict(torch.load('classfierAnime'))
    classfier_anime_model.eval()

    classfier_Koishi_model = models.resnet18(pretrained=True)
    num_ftrs_k = classfier_Koishi_model.fc.in_features

    classfier_Koishi_model.fc = nn.Linear(num_ftrs_k, 2)
    classfier_Koishi_model.load_state_dict(torch.load('classfierKoishi1'))
    classfier_Koishi_model.eval()

    with torch.no_grad():
        for i,tg in enumerate(tgts):
            t = Image.open(io.BytesIO(tg[0])).convert('RGB')
            print(t)
            t = co(t)
            t = t.unsqueeze(0)
            
            out = classfier_anime_model(t)
            _,preds = torch.max(out,1)
            print(out)

            if preds[0]==1:
                out_k = classfier_Koishi_model(t)
                _,preds_k = torch.max(out_k,1)
                if preds_k[0]==0:
                    with open("img/"+tg[1], mode='wb') as f:
                        f.write(tg[0])
                else:
                    with open("imgKoishi/"+tg[1], mode='wb') as f:
                        f.write(tg[0])

            else:
                with open("realImg/"+tg[1], mode='wb') as f:
                    f.write(tg[0])

Das Ergebnis der tatsächlichen Nutzung der App

Ergebnisse durch tatsächliche Bewegung erhalten

Die Erkennungsrate, ob es sich um ein echtes Bild handelte, war sehr gut und zufriedenstellend. Es gab fast kein Versehen bei der Feststellung, ob es einen bestimmten Charakter gab, aber viele der Gegenstände, die als wahr eingestuft wurden, erfüllten die Bedingungen nicht. (Rückruf ist teuer, aber Druck ist so viel) Es ist wahrscheinlich, dass die Ursache dafür darin besteht, dass die gespeicherten Bilder verzerrt sind und die Identifizierung von Bildern, die die nicht gespeicherten Bedingungen nicht erfüllen, nicht erfolgreich war. Ein weiteres Problem war, dass das Bild des Zielcharakters zunächst nicht auf der Timeline angezeigt wurde. Daher war ich verwirrt, weil ich nicht beurteilen konnte, ob es identifiziert werden konnte. Durch einen solchen tatsächlichen Betrieb war es gut zu erfahren, dass Daten, die nicht gelernt wurden, die Identifizierung beeinträchtigten.

Was ich in Zukunft machen möchte

――Ich möchte es regelmäßig speichern können, aber ich kann meinen Heimcomputer nicht eingeschaltet lassen, daher möchte ich es mit einem Himbeerkuchen verarbeiten können.

Referenzierte Site

https://www.slideshare.net/takahirokubo7792/ss-71453093 https://qiita.com/koki-sato/items/c16c8e3445287698b3a8 http://docs.tweepy.org/en/v3.5.0/index.html https://pytorch.org/tutorials/beginner/transfer_learning_tutorial.html https://qiita.com/enmaru/items/2770df602dd7778d4ce6

Recommended Posts

Ich habe eine Twitter-App erstellt, die das Bild eines bestimmten Charakters auf der Twitter-Timeline durch Pytorch-Transfer-Lernen identifiziert und speichert
Ich habe versucht, ein Skript zu erstellen, das die Tweets eines bestimmten Benutzers auf Twitter verfolgt und das veröffentlichte Bild sofort speichert
Ich habe eine Twitter-App erstellt, die die Zeichen der Vorverbindung mit Heroku entschlüsselt (Fehler).
Ich habe "Ich habe versucht, ein Skript zu erstellen, das gepostete Bilder sofort speichert, indem ich zu den Tweets eines bestimmten Benutzers auf Twitter zurückgekehrt bin" überarbeitet.
Ich habe einen Linienbot erstellt, der das Geschlecht und das Alter einer Person anhand des Bildes errät
Ich habe ein Punktbild des Bildes von Irasutoya gemacht. (Teil 1)
Ich habe ein Punktbild des Bildes von Irasutoya gemacht. (Teil 2)
pandas Ruft den Namen einer Spalte ab, die ein bestimmtes Zeichen enthält
Ich habe einen Twitter-Bot erstellt, der das von #PokemonGO gefangene Pokemon murmelt
Ich habe einen schlaffen Bot gemacht, der mich über die Temperatur informiert
Ich habe das Bild der Science University auf Twitter mit Word2Vec überprüft.
[Python] Ich habe das Tagebuch eines Mannes im ersten Jahr des Arbeitslebens analysiert und das Arbeitsleben positiv / negativ beurteilt.
Ich habe einen Kalender erstellt, der den Verteilungsplan von Vtuber automatisch aktualisiert
Ich habe GAN mit Keras gemacht, also habe ich ein Video des Lernprozesses gemacht.
[Python] Ich habe einen Web-Scraping-Code erstellt, der automatisch den Nachrichtentitel und die URL von Nihon Keizai Shimbun erfasst.
Ich habe einen LINE BOT erstellt, der mithilfe der Flickr-API ein Bild von Reis-Terroristen zurückgibt
Ich habe einen Appdo-Befehl erstellt, um Befehle im Kontext der App auszuführen
Mit LINEBot habe ich eine Anwendung erstellt, die mich über die "Buszeit" informiert.
Ich habe einen Linebot erstellt, der mich über nahegelegene Evakuierungsstellen auf AWS informiert
Implementierung eines Modells, das Wechselkurse (Dollar-Yen-Kurs) durch maschinelles Lernen vorhersagt
Ich habe ein Docker-Image erstellt, das RSS liest und automatisch regelmäßig twittert, und es veröffentlicht.
[Python / C] Ich habe versucht, ein Gerät zu erstellen, das den Bildschirm eines PCs drahtlos aus der Ferne scrollt.
Ich habe einen Kalender erstellt, der den Verteilungsplan von Vtuber automatisch aktualisiert (Google Kalender Edition).
#Eine Funktion, die den Zeichencode einer Zeichenfolge zurückgibt
Eine Bibliothek, die Leben und Tod anderer Maschinen durch Ping von Python aus überwacht
Eine konkrete Methode zur Vorhersage von Pferderennen und zur Simulation der Wiederherstellungsrate durch maschinelles Lernen
Ein Beispiel für einen Mechanismus, der eine Vorhersage von HTTP aus dem Ergebnis des maschinellen Lernens zurückgibt
Ich habe versucht, die Yin- und Yang-Klassifikation hololiver Mitglieder durch maschinelles Lernen zu überprüfen
Ich habe mit Docker eine API erstellt, die den vorhergesagten Wert des maschinellen Lernmodells zurückgibt
Ich habe eine Funktion zum Trimmen des Bildes von Python openCV erstellt. Verwenden Sie sie daher bitte.
Verändert TensorFlow das Bild des tiefen Lernens? Was ich dachte, nachdem ich ein wenig berührt hatte