[PYTHON] Rank Learning über ein neuronales Netzwerk (RankNet-Implementierung von Chainer)

Was ist dieser Artikel?

Im Rahmen des maschinellen Lernens gibt es Ranglernen (Rankinglernen, Rankinglernen). RankNet, das ein neuronales Netzwerk verwendet, ist eines der Ranglernmodelle. In diesem Artikel werde ich über die Implementierung von RankNet mit Chainer sprechen.

Wenn man sich die Vorhersageergebnisse ansieht, scheint die Implementierung korrekt zu sein, aber wenn es Fehler wie die Verwendung von Chainer gibt, wäre ich dankbar, wenn Sie darauf hinweisen könnten.

Was ist Ranglernen überhaupt?

Beim Ranglernen wird eine Menge von $ ({\ mathbf x}, y) = $ (Merkmale, Eignungsgrad) gelernt. Lernen Sie die Funktion $ f $ kennen, die einen großen Wert für Elemente mit einem hohen Konformitätsgrad und einen kleinen Wert für Elemente mit einem niedrigen Konformitätsgrad zurückgibt.

Angenommen, zwei Elemente $ A $ und $ B $ werden wie folgt dargestellt.

A=(\mathbf{x}_A, y_A) \\
B=(\mathbf{x}_B, y_B)

Nehmen Sie außerdem an, dass $ A $ besser geeignet ist als $ B $. Angenommen, $ y_A> y_B $ gilt. Zu diesem Zeitpunkt wird die Funktion $ f $ gelernt, so dass die folgende Beziehung gilt.

f(\mathbf{x}_A)>f(\mathbf{x}_B)

Es fühlt sich an, als ob etwas nicht stimmt, also liebe es zu leben! Ich werde mit erklären. Zuallererst Liebe leben! Fügen wir dem Charakter von den Eignungsgrad (☆, ☆☆, ☆☆☆) hinzu. Je größer die Anzahl von ☆ ist, desto höher ist der Konformitätsgrad (Favorit).

cat_1.png

Wenn Sie das folgende Paar lernen, sollten Sie die Funktion $ f $ wie folgt erhalten. learning.PNG

Wenn $ f ({\ bf x}) = {\ bf w} ^ T {\ bf x} $, wird das Gewicht $ {\ bf w} $ orthogonal als Merkmalsmenge projiziert, wie in der folgenden Abbildung gezeigt. Es wird geschätzt, dass die Punkte in der Reihenfolge ihrer Konformität angeordnet sind. In einem echten Problem würde es kein $ {\ bf w} $ geben, das in der Reihenfolge seiner Eignung perfekt ausgerichtet wäre ...

wpredict_1.png

Mit der als Ergebnis des Lernens erhaltenen Funktion $ f $ ist es möglich, die Rangfolge von Zeichen vorherzusagen, die noch nicht angepasst wurden.

calc_f1.png

Hier habe ich "Lernpaare" geschrieben, aber tatsächlich gibt es ungefähr drei Methoden für das Ranglernen, und sie entsprechen der Methode, die paarweise genannt wird. Es gibt andere Methoden, z. B. punktweise und listweise. Informationen zu diesen Methoden finden Sie in den folgenden Materialien.

Über RankNet

RankNet ist ein Modell des Ranglernens basierend auf einem neuronalen Netzwerk und eine paarweise Methode. Das Vorhersagemodell selbst ist dasselbe wie ein normales neuronales Netzwerk, aber das Design der Kostenfunktion ist unterschiedlich. Die Idee ist jedoch dieselbe wie die Kreuzentropiefunktion, die häufig als Kostenfunktion verwendet wird.

Angenommen, die Elemente $ A $ und $ B $ werden wie oben dargestellt und $ A $ ist passender als $ B $.

A=(\mathbf{x}_A, y_A) \\
B=(\mathbf{x}_B, y_B)

Die Punktzahlen von $ A $ und $ B $ durch die Funktion $ f $ werden wie folgt berechnet.

s_A=f(\mathbf{x}_A) \\
s_B=f(\mathbf{x}_B)

Die Wahrscheinlichkeit, dass $ A $ höher eingestuft wird als die von RankNet ausgegebene $ B $, wird unter Verwendung von $ s_A $ und $ s_B $ wie folgt ausgedrückt.

P_{AB}=\frac{1}{1+e^{-\sigma(s_A-s_B)}}

Wenn $ s_A $ zunimmt, nähert sich $ P_ {AB} $ intuitiv 1, und wenn $ s_B $ zunimmt, nähert sich $ P_ {AB} $ 0.

Unter Verwendung von $ P_ {AB} $ wird die Kostenfunktion wie folgt ausgedrückt.

C_{AB}=-\bar{P}_{AB}\log{P_{AB}}-(1-\bar{P}_{AB})\log(1-P_{AB})

Hier ist $ \ bar {P} _ {AB} $ eine bekannte Wahrscheinlichkeit, dass $ A $ höher als $ B $ eingestuft wird. In Referenz wurde Folgendes festgelegt.

\bar{P}_{AB}=\begin{cases}
1 & (A \succ B) \\
0 & (A \prec B) \\
\frac{1}{2} & (otherwise)
\end{cases}

$ C_ {AB} $ ist nur eine Kreuzentropiefunktion, und je weiter $ P_ {AB} $ $ \ bar {P} _ {AB} $ ist, desto größer ist der Wert. RankNet lernt, diese Kostenfunktion zu minimieren.

Implementierung von RankNet in Chainer

Lassen Sie uns nun RankNet mit Chainer implementieren. Die Verlustfunktion softmax_cross_entropy () ist in Chainer implementiert, softmax_cross_entropy () kann jedoch nicht verwendet werden, da nur der Typ int32 als Zielvariable empfangen werden kann. ($ \ Bar {P} _ {AB} $ kann $ \ frac {1} {2} $ sein.)

Daher muss ich die Kostenfunktion $ C_ {AB} $ selbst implementieren, aber ich konnte lernen, ohne ** backward () zu implementieren, das in anderen Verlustfunktionen * implementiert ist. *… Ich frage mich, ob backward () nicht implementiert ist, um automatisch eine numerische Differenzierung durchzuführen, und ich wäre Ihnen dankbar, wenn Sie dies kommentieren könnten.

Im Folgenden wird die Implementierung von RankNet beschrieben. Als Modell des neuronalen Netzwerks wird ein einfaches mehrschichtiges Perzeptron von [Eingabeschicht] -> [verborgene Schicht] -> [verborgene Schicht] -> [Ausgangsschicht] verwendet.

net.py


from chainer import Chain
import chainer.functions as F
import chainer.links as L


class MLP(Chain):

    def __init__(self, n_in, n_hidden):
        super(MLP, self).__init__(
            l1=L.Linear(n_in, n_hidden),
            l2=L.Linear(n_hidden, n_hidden),
            l3=L.Linear(n_hidden, 1)
        )

    def __call__(self, x):
        h1 = F.relu(self.l1(x))
        h2 = F.relu(self.l2(h1))
        return self.l3(h2)


class RankNet(Chain):

    def __init__(self, predictor):
        super(RankNet, self).__init__(predictor=predictor)

    def __call__(self, x_i, x_j, t_i, t_j):
        s_i = self.predictor(x_i)
        s_j = self.predictor(x_j)
        s_diff = s_i - s_j
        if t_i.data > t_j.data:
            S_ij = 1
        elif t_i.data < t_j.data:
            S_ij = -1
        else:
            S_ij = 0
        self.loss = (1 - S_ij) * s_diff / 2. + \
            F.math.exponential.Log()(1 + F.math.exponential.Exp()(-s_diff))
        return self.loss

Wenden wir das implementierte RankNet auf künstliche Daten an. Die künstlichen Daten wurden wie folgt erzeugt.

X=({\bf x}_1, {\bf x}_2, \dots, {\bf x}_{1000})^{\rm T} \\
{\bf y}=(y_1, y_2, \dots, y_{1000}) \\
{\bf w} = {\mathcal N}({\bf 0}, {\bf 1}) \\
y_i = uniform(1,5) \\
{\bf x}_i={\mathcal N}(0, 5) + y_i{\bf w}

Es gibt 1000 50-dimensionale Daten, und der Konformitätsgrad beträgt entweder [1,2,3,4,5]. Bei Darstellung im PCA-Raum ist die Abbildung wie folgt.

pca_fig.png

Irgendwie scheint der Konformitätsgrad oben links in der Figur höher und unten rechts kleiner zu sein.

Unten finden Sie den Lern- und Bewertungscode. Das Training verwendet die stochastische Gradientenabstiegsmethode und die Trainingsdaten werden jedes Mal zufällig abgetastet. NDCG @ 100 wurde verwendet, um die Vorhersagegenauigkeit zu bewerten.

train_toy.py


import numpy as np
from chainer import Variable, optimizers
from sklearn.cross_validation import train_test_split
import net
import matplotlib.pyplot as plt
import seaborn as sns


def make_dataset(n_dim, n_rank, n_sample, sigma):
    ys = np.random.random_integers(n_rank, size=n_sample)
    w = np.random.randn(n_dim)
    X = [sigma * np.random.randn(n_dim) + w * y for y in ys]
    X = np.array(X).astype(np.float32)
    ys = np.reshape(np.array(ys), (-1, 1))
    return X, ys


def ndcg(y_true, y_score, k=100):
    y_true = y_true.ravel()
    y_score = y_score.ravel()
    y_true_sorted = sorted(y_true, reverse=True)
    ideal_dcg = 0
    for i in range(k):
        ideal_dcg += (2 ** y_true_sorted[i] - 1.) / np.log2(i + 2)
    dcg = 0
    argsort_indices = np.argsort(y_score)[::-1]
    for i in range(k):
        dcg += (2 ** y_true[argsort_indices[i]] - 1.) / np.log2(i + 2)
    ndcg = dcg / ideal_dcg
    return ndcg

if __name__ == '__main__':
    np.random.seed(0)
    n_dim = 50
    n_rank = 5
    n_sample = 1000
    sigma = 5.
    X, ys = make_dataset(n_dim, n_rank, n_sample, sigma)
    X_train, X_test, y_train, y_test = train_test_split(X, ys, test_size=0.33)

    n_iter = 2000
    n_hidden = 20
    loss_step = 50
    N_train = np.shape(X_train)[0]

    model = net.RankNet(net.MLP(n_dim, n_hidden))
    optimizer = optimizers.Adam()
    optimizer.setup(model)

    N_train = np.shape(X_train)[0]
    train_ndcgs = []
    test_ndcgs = []
    for step in range(n_iter):
        i, j = np.random.randint(N_train, size=2)
        x_i = Variable(X_train[i].reshape(1, -1))
        x_j = Variable(X_train[j].reshape(1, -1))
        y_i = Variable(y_train[i])
        y_j = Variable(y_train[j])
        model.zerograds()
        loss = model(x_i, x_j, y_i, y_j)
        loss.backward()
        optimizer.update()
        if (step + 1) % loss_step == 0:
            train_score = model.predictor(Variable(X_train))
            test_score = model.predictor(Variable(X_test))
            train_ndcg = ndcg(y_train, train_score.data)
            test_ndcg = ndcg(y_test, test_score.data)
            train_ndcgs.append(train_ndcg)
            test_ndcgs.append(test_ndcg)
            print("step: {0}".format(step + 1))
            print("NDCG@100 | train: {0}, test: {1}".format(train_ndcg, test_ndcg))

    plt.plot(train_ndcgs, label="Train")
    plt.plot(test_ndcgs, label="Test")
    xx = np.linspace(0, n_iter / loss_step, num=n_iter / loss_step + 1)
    labels = np.arange(loss_step, n_iter + 1, loss_step)
    plt.xticks(xx, labels, rotation=45)
    plt.legend(loc="best")
    plt.xlabel("step")
    plt.ylabel("NDCG@10")
    plt.ylim(0, 1.1)
    plt.tight_layout()
    plt.savefig("result.pdf")

result.PNG

Da sowohl Trainingsdaten als auch Testdaten aus derselben Verteilung generiert werden, ist es natürlich zu sagen, dass dies natürlich ist, aber Sie können sehen, wie sich die Bewertungswerte zusammen erhöhen.

Andere

Ich möchte etwas interessantes machen

Recommended Posts

Rank Learning über ein neuronales Netzwerk (RankNet-Implementierung von Chainer)
Implementierung von "verschwommenen" neuronalen Netzen mit Chainer
Einfache Implementierung eines neuronalen Netzwerks mit Chainer
Implementierung eines 3-Schicht-Neuronalen Netzwerks (kein Lernen)
Übersicht über DNC (Differentiable Neural Computers) + Implementierung durch Chainer
Bayesianische Optimierungsimplementierung von Hyperparametern des neuronalen Netzwerks (Chainer + GPyOpt)
Implementierung eines Faltungs-Neuronalen Netzwerks mit nur Numpy
Implementierung des Chainer-Serienlernens mit Mini-Batch variabler Länge
Implementierung eines zweischichtigen neuronalen Netzwerks 2
Implementierung eines Dialogsystems mit Chainer [seq2seq]
Einfache Implementierung eines neuronalen Netzwerks mithilfe der Chainer-Datenaufbereitung
Einfache Implementierung eines neuronalen Netzwerks mithilfe der Beschreibung des Chainer-Modells
[Chainer] Dokumentklassifizierung nach Faltungsnetzwerk
Python-Lernnotiz für maschinelles Lernen von Chainer Kapitel 13 Training für neuronale Netze ~ Chainer abgeschlossen
Python-Lernnotiz für maschinelles Lernen von Chainer Kapitel 13 Grundlagen des neuronalen Netzwerks
Einfache Implementierung eines neuronalen Netzwerks mit Chainer ~ Optimierungsalgorithmus einstellen ~
Verstärkungslernen 10 Versuchen Sie es mit einem trainierten neuronalen Netz.
Erkennung handgeschriebener Zahlen durch ein mehrschichtiges neuronales Netzwerk
Tiefes Lernen durch Implementierung (Segmentierung) ~ Implementierung von SegNet ~
Python vs Ruby "Deep Learning von Grund auf neu" Kapitel 3 Implementierung eines dreischichtigen neuronalen Netzwerks
[Deep Learning von Grund auf neu] Anfangswert des Gewichts des neuronalen Netzwerks unter Verwendung der Sigmoid-Funktion
[Für Anfänger im Deep Learning] Implementierung einer einfachen binären Klassifizierung durch vollständige Kopplung mit Keras
[Deep Learning von Grund auf neu] Anfangsgewicht des neuronalen Netzwerks bei Verwendung der Relu-Funktion
Implementierung von TF-IDF mit Gensim
Neuronales Netz beginnend mit Chainer
Ich habe versucht, ListNet of Rank Learning mit Chainer zu implementieren
Implementierung eines neuronalen Netzwerks in Python
Aufbau eines neuronalen Netzwerks, das XOR durch Z3 reproduziert
Implementierung eines neuronalen Netzwerks (nur NumPy)
Tiefes Lernen der Verstärkung 2 Implementierung des Lernens der Verstärkung
Untersuchung des wiederkehrenden neuronalen Netzes (RNN) durch Chainer ~ Überprüfung der Genauigkeit von Zufallszahlen in Excel und R ~
Versuchen Sie, eine Blackjack-Strategie zu entwickeln, indem Sie das Lernen stärken ((1) Implementierung von Blackjack)
Implementierungsbeispiel für das Hostile Generation Network (GAN) von Keras [Für Anfänger]
Zusammenfassung der grundlegenden Implementierung von PyTorch
PRML Kapitel 5 Python-Implementierung für neuronale Netze
Einfache Theorie und Implementierung des neuronalen Netzes
Stärkung des Lernens 8 Versuchen Sie, die Chainer-Benutzeroberfläche zu verwenden
Deep Learning durch Implementierung 1 gelernt (Return Edition)
Implementierung von Desktop-Benachrichtigungen mit Python
Berühren Sie das Objekt des neuronalen Netzes
Python-Lernnotiz für maschinelles Lernen von Chainer bis zum Ende von Kapitel 2
Überlebensvorhersage unter Verwendung des titanischen neuronalen Netzes von Kaggle [80,8%]
Deep Learning 2 durch Implementierung gelernt (Bildklassifizierung)
[Lernnotiz] Grundlagen des Unterrichts mit Python
Othello-Aus der dritten Zeile von "Implementation Deep Learning" (3)
Qiskit: Implementierung von Quantum Circuit Learning (QCL)
Versuchen Sie es mit TensorFlow-Part 2-Convolution Neural Network (MNIST).
Implementierung von SVM durch probabilistische Gradientenabstiegsmethode
Algorithmus für maschinelles Lernen (Implementierung einer Klassifizierung mit mehreren Klassen)
Python & Machine Learning Study Memo ③: Neuronales Netz
Othello-Aus der dritten Zeile von "Implementation Deep Learning" (2)
[Super Einführung] Maschinelles Lernen mit Python - Von der Umgebungskonstruktion bis zur Implementierung von Simple Perceptron-
Maschinelles Lernen: Bilderkennung von MNIST mithilfe von PCA und Gaussian Native Bayes
Überprüfung der Paging-Implementierung nach Relay-Stil in GraphQL (Version mit Fensterfunktion)
Implementierung eines Modells, das Wechselkurse (Dollar-Yen-Kurs) durch maschinelles Lernen vorhersagt