[PYTHON] Ich habe versucht, die Satzklassifizierung durch Self Attention mit PyTorch zu implementieren

Dieser Artikel ist der Artikel zum 25. Tag von Pytorch Adventskalender 2019!

Einführung

In Letztes Mal haben wir Attention im Encoder-Decoder-Modell implementiert, diesmal jedoch die Satzklassifizierung in Self Attention.

Die eingebetteten Ausdrücke von Sätzen in Self Attention werden in den folgenden Abhandlungen vorgestellt und auch in der berühmten Abhandlung "Attention Is All You Need" von Transformer zitiert.

Dieser Artikel implementiert die in diesem Dokument eingeführte Selbstaufmerksamkeit.

Referenz

In Bezug auf die Implementierung habe ich auf den folgenden Artikel Fast Marupakuri </ s> verwiesen.

[Selbstaufmerksamkeit] Implementieren Sie ein Dokumentklassifizierungsmodell, das den Grund für die Vorhersage leicht visualisieren kann

Darüber hinaus verwenden wir torchtext, das zur bequemen Vorverarbeitung für die Implementierung verwendet werden kann. Für torchtext habe ich jedoch auch auf den folgenden Artikel derselben Person verwiesen.

Einfache und tiefe Verarbeitung natürlicher Sprache mit torchtext

Wie es funktioniert

Der Mechanismus dieses Papiers wird in Referenz (1) kurz erläutert, der Algorithmus ist jedoch grob in die folgenden drei Schritte unterteilt.

  1. Konvertieren Sie einen Satz der Länge $ n $ mit bidirektionalem LSTM (die Dimension der verborgenen Ebene ist $ u $) (erhalten Sie jedes $ h_i, (n \ mal 2u) $ in (a) unten)
  2. Berechnen Sie die Aufmerksamkeit mit dem neuronalen Netz unter Verwendung des Werts jeder verborgenen Schicht von bidirektionalem LSTM als Eingabe ($ A = (A_ {ij}), 1 \ leq i \ leq r, 1 \ leq j \ leq in (b) unten). Holen Sie sich n $)
  3. Gewichten Sie den Vektor jeder verborgenen Schicht von bidirektionalem LSTM mit jeder Aufmerksamkeit $ A_ {ij} $, um die Einbettung von Sätzen in das neuronale Netzwerk zu erhalten

Hier sind $ d_a $ und $ r $ bei der Berechnung der Aufmerksamkeit Hyperparameter. $ d_a $ stellt die Größe der Gewichtsmatrix dar, wenn die Aufmerksamkeit mit einem neuronalen Netzwerk vorhergesagt wird, und $ r $ ist ein Parameter, der der Anzahl der gestapelten Aufmerksamkeitsebenen entspricht.

image.png

Die Idee ist sehr einfach. Es geht darum, das Neuronale Netz lernen zu lassen, welche Wörter bei der Klassifizierung von Sätzen hervorgehoben (gewichtet) werden sollen.

Implementierung

Dann werden wir den obigen Mechanismus mit PyTorch implementieren. Die zu lösende Aufgabe ist das negative / positive Urteil der IMDb-Filmkritik. Die Daten können von folgenden heruntergeladen werden.

  • http://ai.stanford.edu/~amaas/data/sentiment/
  • Das folgende Implementierungsbeispiel basiert auf der Annahme, dass es unter Google Colab ausgeführt wird.

Bibliothek importieren

  • Importieren Sie verschiedene Bibliotheken, die in der Implementierung verwendet werden ――Da der Datensatz auf Englisch ist, denke ich, dass die morphologische Analyse-Engine in Ordnung ist, aber vorerst habe ich eine Funktion vorbereitet, die eine Vorverarbeitung mit nltk durchführt (obwohl es einen Teil gibt, der unter Torchtext-Vorverarbeitung leidet, ist mir das kein einziges Mal wichtig). Weitere Informationen zu nltk finden Sie unter hier.
# torchtext
import torchtext
from torchtext import data
from torchtext import datasets
from torchtext.vocab import GloVe
from torchtext.vocab import Vectors

# pytorch
import torch.nn as nn
import torch.optim as optim
import torch.nn.functional as F
import torch

#Andere
import os
import pickle
import numpy as np
import pandas as pd
from itertools import chain
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report

#Schließlich wird es verwendet, um die Aufmerksamkeit zu visualisieren.
import itertools
import random
from IPython.display import display, HTML

#Zur Vorverarbeitung durch nltk
import re
import nltk
from nltk import stem
nltk.download('punkt')

#Vorbereiteter morphologischer Motor von nltk
def nltk_analyzer(text):
    stemmer = stem.LancasterStemmer()
    text = re.sub(re.compile(r'[!-\/:-@[-`{-~]'), ' ', text)
    text = stemmer.stem(text)
    text = text.replace('\n', '') #Zeilenumbrüche löschen
    text = text.replace('\t', '') #Registerkarte löschen
    morph = nltk.word_tokenize(text)
    return morph

Datenaufbereitung

  • Laden Sie das Dataset von der obigen URL herunter und bereiten Sie eine tsv-Datei im folgenden Format vor.
  • Sowohl Zug als auch Test sind verfügbar
  • Das Label wird mit 0 für positiv und 1 für negativ quantifiziert.

Referenz

Die Vorbereitung der Daten war beispielsweise wie folgt.

train_pos_dir = 'aclImdb/train/pos/'
train_neg_dir = 'aclImdb/train/neg/'

test_pos_dir = 'aclImdb/test/pos/'
test_neg_dir = 'aclImdb/test/neg/'

header = ['text', 'label', 'label_id']

train_pos_files = os.listdir(train_pos_dir)
train_neg_files = os.listdir(train_neg_dir)
test_pos_files = os.listdir(test_pos_dir)
test_neg_files = os.listdir(test_neg_dir)


def make_row(root_dir, files, label, idx):
    row = []
    for file in files:
        tmp = []
        with open(root_dir + file, 'r') as f:
            text = f.read()
            tmp.append(text)
            tmp.append(label)
            tmp.append(idx)
        row.append(tmp)
    return row

row = make_row(train_pos_dir, train_pos_files, 'pos', 0)
row += make_row(train_neg_dir, train_neg_files, 'neg', 1)
train_df = pd.DataFrame(row, columns=header)


row = make_row(test_pos_dir, test_pos_files, 'pos', 0)
row += make_row(test_neg_dir, test_neg_files, 'neg', 1)
test_df = pd.DataFrame(row, columns=header)

Bereiten Sie die Daten wie oben beschrieben vor und erstellen Sie schließlich den folgenden Datenrahmen (während Sie die Beschriftungsspalte löschen, da sie nicht einmal benötigt wird).

train_df = pd.read_csv(imdb_dir + 'train.tsv', delimiter="\t", header=None)
train_df

image.png

Vorverarbeitung mit torchtext

  • Mit torchtext können Sie Daten schnell vorverarbeiten, verteilte Wortausdrücke, Mini-Batch usw. abrufen. ――Für die verteilte Darstellung von Wörtern haben wir 200-dimensionales GloVe verwendet. Sie können es mit torchtext herunterladen, aber ich habe mir glove.6B.200d.txt von hier ausgeliehen, da ich es nicht jedes Mal herunterladen möchte. Seien Sie vorsichtig, denn die Größe ist groß!
# train.tsv, test.Setzen Sie tsv hier
imdb_dir = "drive/My Drive/Colab Notebooks/imdb_datasets/"

# glove.6B.200d.Geben Sie hier txt ein
word_embedding_dir = "drive/My Drive/Colab Notebooks/word_embedding_models/"

TEXT = data.Field(sequential=True, tokenize=nltk_analyzer, lower=True, include_lengths=True, batch_first=True)
LABEL = data.Field(sequential=False, use_vocab=False, is_target=True)

train, test = data.TabularDataset.splits(
      path=imdb_dir, train='train.tsv', test='test.tsv', format='tsv',
      fields=[('Text', TEXT), ('Label', LABEL)])

glove_vectors = Vectors(name=word_embedding_dir + "glove.6B.200d.txt")
TEXT.build_vocab(train, test, vectors=glove_vectors, min_freq=1)

Hyperparametereinstellungen usw.

――Es gibt keinen besonderen Grund, aber ich habe die folgenden Parameter verwendet. ――Achtungsebene Die folgende Abbildung zeigt 3 Ebenen.

#Ich möchte GPU verwenden
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

BATCH_SIZE = 100 #Chargengröße
EMBEDDING_DIM = 200 #Anzahl der eingebetteten Dimensionen von Wörtern
LSTM_DIM = 128 #Anzahl der Dimensionen der verborgenen Schicht von LSTM
VOCAB_SIZE =TEXT.vocab.vectors.size()[0] #Gesamtzahl der Wörter
TAG_SIZE = 2 #Dieses Mal werden wir eine negative / positive Beurteilung abgeben, sodass die endgültige Größe des Netzwerks 2 beträgt.
DA = 64 #Größe der Gewichtsmatrix bei der Berechnung der Aufmerksamkeit mit dem neuronalen Netz
R = 3 #Aufmerksamkeit in 3 Ebenen anzeigen

Modelldefinition

Bidirectional LSTM

  • Konvertieren Sie Sätze mit bidirektionalem LSTM
  • Bitte beziehen Sie sich auf hier für die Spezifikationen des bidirektionalen LSTM von PyTorch.
class BiLSTMEncoder(nn.Module):
    def __init__(self, embedding_dim, lstm_dim, vocab_size):
        super(BiLSTMEncoder, self).__init__()
        self.lstm_dim = lstm_dim
        self.word_embeddings = nn.Embedding(vocab_size, embedding_dim)

        #Stellen Sie den gelernten Wortvektor als Einbettung ein
        self.word_embeddings.weight.data.copy_(TEXT.vocab.vectors)

        #Erfordert, um zu verhindern, dass der Wortvektor durch Fehler-Backpropagation aktualisiert wird_Setze grad auf False
        self.word_embeddings.requires_grad_ = False

        # bidirectional=Richtig und einfach, bidirektionales LSTM zu erstellen
        self.bilstm = nn.LSTM(embedding_dim, lstm_dim, batch_first=True, bidirectional=True)
  
    def forward(self, text):
        embeds = self.word_embeddings(text)

        #Erhalten Sie den ersten Rückgabewert, da wir den Vektor jeder verborgenen Ebene wollen
        out, _ = self.bilstm(embeds)

        #Gibt die vorderen und hinteren verborgenen Ebenenvektoren zurück, wenn sie kombiniert werden
        return out

Selbstaufmerksamkeitsschicht

  • Empfangen Sie den Vektor jeder verborgenen Schicht von bidirektionalem LSTM und berechnen Sie die Aufmerksamkeit mit dem neuronalen Netzwerk "Gemäß dem Artikel wird" Tanh () "für die Aktivierungsfunktion verwendet, aber der in Referenz" eingeführte Artikel verwendet "ReLU ()", so dass beide in Ordnung zu sein scheinen.
class SelfAttention(nn.Module):
  def __init__(self, lstm_dim, da, r):
    super(SelfAttention, self).__init__()
    self.lstm_dim = lstm_dim
    self.da = da
    self.r = r
    self.main = nn.Sequential(
        #Da es bidirektional ist, wird die Größe des Vektors jeder verborgenen Schicht in der Größe verdoppelt.
        nn.Linear(lstm_dim * 2, da), 
        nn.Tanh(),
        nn.Linear(da, r)
    )
  def forward(self, out):
    return F.softmax(self.main(out), dim=1)

Wo unter Berücksichtigung der Aufmerksamkeit zu klassifizieren

  • Das Aufmerksamkeitsgewicht gewichtet den Vektor jeder verborgenen Schicht und das neuronale Netzwerk gibt die Vorhersage für die binäre Klassifizierung zurück. ――Ich verstehe die Verarbeitung nach dem Gewichten in jeder Attenion-Schicht ehrlich gesagt nicht, daher habe ich diesmal vorerst die folgenden Schritte ausprobiert.
  1. Gewichten Sie den Vektor jeder verborgenen Schicht von bidirektionalem LSTM mit dem Gewicht von 3 Aufmerksamkeitsschichten
  2. Addiere jeden gewichteten Vektor, um m1, m2, m3 zu erhalten
  3. Kombinieren Sie die drei Vektoren m1, m2 und m3 so wie sie sind (die Anzahl der Dimensionen wird zu "lstm_dim * 2 * 3").

class SelfAttentionClassifier(nn.Module):
  def __init__(self, lstm_dim, da, r, tagset_size):
    super(SelfAttentionClassifier, self).__init__()
    self.lstm_dim = lstm_dim
    self.r = r
    self.attn = SelfAttention(lstm_dim, da, r)
    self.main = nn.Linear(lstm_dim * 6, tagset_size)

  def forward(self, out):
    attention_weight = self.attn(out)
    m1 = (out * attention_weight[:,:,0].unsqueeze(2)).sum(dim=1)
    m2 = (out * attention_weight[:,:,1].unsqueeze(2)).sum(dim=1)
    m3 = (out * attention_weight[:,:,2].unsqueeze(2)).sum(dim=1)
    feats = torch.cat([m1, m2, m3], dim=1)
    return F.log_softmax(self.main(feats)), attention_weight

Modelldeklaration

encoder = BiLSTMEncoder(EMBEDDING_DIM, LSTM_DIM, VOCAB_SIZE).to(device)
classifier = SelfAttentionClassifier(LSTM_DIM, DA, R, TAG_SIZE).to(device)
loss_function = nn.NLLLoss()

#Wenn Sie mehrere Modelle aus der itertools-Importkette einschließen, können Sie Optimierer zu einem kombinieren.
optimizer = optim.Adam(chain(encoder.parameters(), classifier.parameters()), lr=0.001)

train_iter, test_iter = data.Iterator.splits((train, test), batch_sizes=(BATCH_SIZE, BATCH_SIZE), device=device, repeat=False, sort=False)

Lernen

»Vorerst habe ich versucht, mit Epoche 10 zu lernen.

  • Der Verlust nimmt stetig ab, daher ist dies vorerst in Ordnung
losses = []
for epoch in range(10):
    all_loss = 0

    for idx, batch in enumerate(train_iter):
        batch_loss = 0
        encoder.zero_grad()
        classifier.zero_grad()

        text_tensor = batch.Text[0]
        label_tensor = batch.Label
        out = encoder(text_tensor)
        score, attn = classifier(out)
        batch_loss = loss_function(score, label_tensor)
        batch_loss.backward()
        optimizer.step()
        all_loss += batch_loss.item()
    print("epoch", epoch, "\t" , "loss", all_loss)
#epoch 0 	 loss 97.37978366017342
#epoch 1 	 loss 50.07680431008339
#epoch 2 	 loss 27.79373042844236
#epoch 3 	 loss 9.353876578621566
#epoch 4 	 loss 1.9509600398596376
#epoch 5 	 loss 0.22650832029466983
#epoch 6 	 loss 0.021685686125238135
#epoch 7 	 loss 0.011305359620109812
#epoch 8 	 loss 0.007448446772286843
#epoch 9 	 loss 0.005398457038154447

Vorhersage & Genauigkeit

――Ich glaube nicht, dass die Genauigkeit besser ist als ich erwartet hatte ... --Referenz (1) besagt, dass die Genauigkeit etwa 90% betrug, und es scheint, dass es in einigen verschiedenen Implementierungen verschiedene Fehlzündungen gibt ...

answer = []
prediction = []
with torch.no_grad():
    for batch in test_iter:

        text_tensor = batch.Text[0]
        label_tensor = batch.Label
    
        out = encoder(text_tensor)
        score, _ = classifier(out)
        _, pred = torch.max(score, 1)

        prediction += list(pred.cpu().numpy())
        answer += list(label_tensor.cpu().numpy())
print(classification_report(prediction, answer, target_names=['positive', 'negative']))
#              precision    recall  f1-score   support
#
#    positive       0.86      0.88      0.87     12103
#    negative       0.89      0.86      0.87     12897
#
#    accuracy                           0.87     25000
#   macro avg       0.87      0.87      0.87     25000
#weighted avg       0.87      0.87      0.87     25000

Aufmerksamkeitsvisualisierung

  • Markieren und visualisieren Sie, welche Wörter Aufmerksamkeit sind.
  • Für die Hervorhebungsfunktion habe ich die Referenzquelle ① so wie sie ist ausgeliehen. --Bitte beachten Sie hier, wenn Sie HTML auf einem Jupyter-Notizbuch anzeigen. ――Ich mache eine seltsame Verarbeitung wie for-Schleife, aber ich wollte nur eine zufällig aus den Testdaten auswählen und vorhersagen. Entschuldigung für die lächerliche Implementierung ...
def highlight(word, attn):
    html_color = '#%02X%02X%02X' % (255, int(255*(1 - attn)), int(255*(1 - attn)))
    return '<span style="background-color: {}">{}</span>'.format(html_color, word)

def mk_html(sentence, attns):
    html = ""
    for word, attn in zip(sentence, attns):
        html += ' ' + highlight(
            TEXT.vocab.itos[word],
            attn
        )
    return html


id2ans = {'0': 'positive', '1':'negative'}

_, test_iter = data.Iterator.splits((train, test), batch_sizes=(1, 1), device=device, repeat=False, sort=False)

n = random.randrange(len(test_iter))

for batch in itertools.islice(test_iter, n-1,n):
    x = batch.Text[0]
    y = batch.Label
    encoder_outputs = encoder(x)
    output, attn = classifier(encoder_outputs)
    pred = output.data.max(1, keepdim=True)[1]

    display(HTML('[Richtige Antwort]' + id2ans[str(y.item())] + '\t [Vorhersage]' + id2ans[str(pred.item())] + '<br><br>'))
    for i in range(attn.size()[2]):
      display(HTML(mk_html(x.data[0], attn.data[0,:,i]) + '<br><br>'))

Es tut mir leid, dass es winzig ist, aber wenn Sie es sich vorstellen, sieht es so aus. Es werden drei gleiche Sätze angezeigt, aber da es drei Aufmerksamkeitsebenen gibt, zeigt jede Ebene, welches Wort Aufmerksamkeit ist. Der Grad der Aufmerksamkeit von Wörtern ist in jeder Aufmerksamkeitsebene leicht unterschiedlich, aber es scheint, dass sie fast auf die gleiche Weise anziehen.

image.png

Ergänzung

Ohne Selbstaufmerksamkeit ...

Übrigens, als ich dieses negative / positive Urteil nur mit bidirektionalem LSTM ohne Selbstaufmerksamkeit löste, betrug die Genauigkeit etwa 79,4%.

  • Wenn Sie nur mit bidirektionalem LSTM lösen, verwenden Sie das folgende Netzwerk und lassen Sie die anderen Parameter unverändert. ――Selbstaufmerksamkeit scheint wesentlich zur Erhöhung der Genauigkeit beizutragen.
class BiLSTMEncoder(nn.Module):
    def __init__(self, embedding_dim, lstm_dim, vocab_size, tagset_size):
        super(BiLSTMEncoder, self).__init__()
        self.lstm_dim = lstm_dim
        self.word_embeddings = nn.Embedding(vocab_size, embedding_dim)
        self.word_embeddings.weight.data.copy_(TEXT.vocab.vectors)
        self.word_embeddings.requires_grad_ = False
        self.bilstm = nn.LSTM(embedding_dim, lstm_dim, batch_first=True, bidirectional=True)
        self.hidden2tag = nn.Linear(lstm_dim * 2, tagset_size)
        self.softmax = nn.LogSoftmax()
  
    def forward(self, text):
        embeds = self.word_embeddings(text)
        _, bilstm_hc = self.bilstm(embeds)
        bilstm_out = torch.cat([bilstm_hc[0][0], bilstm_hc[0][1]], dim=1)
        tag_space = self.hidden2tag(bilstm_out)
        tag_scores = self.softmax(tag_space.squeeze())
        return tag_scores

abschließend

――Ich bin ein wenig besorgt über das Muster, das die Aufmerksamkeit lexikografisch berechnet, wie es in Transformer usw. implementiert ist (das die Einbettung von Wörtern in Abfrage, Schlüssel, Wert unterteilt), und über das neuronale Netzwerk dieses Dokuments, um die Aufmerksamkeit vorherzusagen. Ich verstehe den Unterschied in den Mustern nicht wirklich. Bevor ich dieses Papier kannte, dachte ich, wenn ich zu Attention gehen würde, wäre es eine Menge Arbeit, das innere Produkt zu erhalten, also frage ich mich, ob es verschiedene Berechnungsmethoden für Attention gibt. ――Nächste, ich möchte etwas über Transformer schreiben!

Ende

Recommended Posts

Ich habe versucht, die Satzklassifizierung durch Self Attention mit PyTorch zu implementieren
Ich habe versucht, Satzklassifizierung und Aufmerksamkeitsvisualisierung durch das japanische BERT mit PyTorch zu implementieren
Ich habe versucht, CVAE mit PyTorch zu implementieren
Ich habe versucht, das Lesen von Dataset mit PyTorch zu implementieren
Ich habe versucht, DCGAN mit PyTorch zu implementieren und zu lernen
Ich habe versucht, SSD jetzt mit PyTorch zu implementieren (Dataset)
Ich habe versucht, MNIST nach GNN zu klassifizieren (mit PyTorch-Geometrie).
Ich habe versucht, SSD jetzt mit PyTorch zu implementieren (Modellversion)
Ich habe versucht, Autoencoder mit TensorFlow zu implementieren
Ich habe versucht, Faster R-CNN mit Pytorch auszuführen
Ich habe versucht, Mine Sweeper auf dem Terminal mit Python zu implementieren
Ich habe versucht, künstliches Perzeptron mit Python zu implementieren
[Einführung in Pytorch] Ich habe versucht, Cifar10 mit VGG16 ♬ zu kategorisieren
Ich habe versucht, Grad-CAM mit Keras und Tensorflow zu implementieren
Ich habe versucht, StarGAN (1) zu implementieren.
Ich habe versucht, die Genauigkeit der japanischen BERT- und der japanischen Distil-BERT-Satzklassifizierung mit PyTorch & Einführung der BERT-Technik zur Verbesserung der Genauigkeit zu vergleichen
Ich habe versucht, mit Quantx eine Linie mit gleitendem Durchschnitt des Volumens zu implementieren
Ich habe versucht, die Erkennung von Anomalien durch spärliches Strukturlernen zu implementieren
Ich habe versucht, mit Quantx einen Ausbruch (Typ der Täuschungsvermeidung) zu implementieren
[Django] Ich habe versucht, Zugriffsbeschränkungen durch Klassenvererbung zu implementieren.
Ich habe versucht, ListNet of Rank Learning mit Chainer zu implementieren
Ich habe versucht, Harry Potters Gruppierungshut mit CNN umzusetzen
Ich habe versucht, Deep VQE zu implementieren
Ich habe versucht, Attention Seq2Seq mit PyTorch zu implementieren
Ich habe versucht, eine kontroverse Validierung zu implementieren
Ich habe versucht, Pytorchs Datensatz zu erklären
Ich habe versucht, DeepPose mit PyTorch zu implementieren
Ich habe versucht, Realness GAN zu implementieren
Ich habe versucht, Sätze mit GPT-2 zu generieren
Ich habe versucht, PLSA in Python zu implementieren
Ich habe versucht, Permutation in Python zu implementieren
Ich habe versucht, AutoEncoder mit TensorFlow zu visualisieren
Ich habe versucht, mit Hy anzufangen
Ich habe versucht, PLSA in Python 2 zu implementieren
[Einführung in Pytorch] Ich habe mit sinGAN ♬ gespielt
Ich habe versucht, DeepPose mit PyTorch PartⅡ zu implementieren
Ich habe versucht, PPO in Python zu implementieren
Ich habe versucht, TSP mit QAOA zu lösen
Ich habe versucht, Deep Learning zu implementieren, das nicht nur mit NumPy tiefgreifend ist
Ich habe versucht, mit einem Remote-Server über Socket-Kommunikation mit Python zu kommunizieren.
Ich habe versucht, eine Blockchain zu implementieren, die tatsächlich mit ungefähr 170 Zeilen funktioniert
765 Ich habe versucht, die drei Berufsfamilien durch CNN zu identifizieren (mit Chainer 2.0.0).
Ich habe versucht, die Bayes'sche lineare Regression durch Gibbs-Sampling in Python zu implementieren
Ich habe versucht, nächstes Jahr mit AI vorherzusagen
Ich habe versucht, die Blasensortierung nach Sprache zu programmieren
Ich habe versucht, lightGBM, xg Boost mit Boruta zu verwenden
Ich habe versucht, mit TF Learn die logische Operation zu lernen
Ich habe versucht, GAN (mnist) mit Keras zu bewegen
Ich habe versucht, durch Schaben ein Bild zu bekommen
Ich habe versucht, die Daten mit Zwietracht zu speichern
Ich habe versucht, mit OpenCV Bewegungen schnell zu erkennen
Ich habe versucht, Keras in TFv1.1 zu integrieren
Ich habe versucht, LLVM IR mit Python auszugeben
Ich habe versucht, TOPIC MODEL in Python zu implementieren
Ich habe versucht, ein Objekt mit M2Det zu erkennen!
Ich habe versucht, die Herstellung von Sushi mit Python zu automatisieren
Ich habe versucht, das Überleben der Titanic mit PyCaret vorherzusagen
Ich habe versucht, Linux mit Discord Bot zu betreiben