[PYTHON] Zusammenfassung des Schärfens und Glättens der Wahrscheinlichkeit + Anwendbar auf einfache Dokumentgenerierung

Vor kurzem. Ich lese eine Arbeit über molekulares Design [1], habe aber über die Neuskalierung der Wahrscheinlichkeit gesprochen und sie zusammengefasst.

Die Wahrscheinlichkeitsskalierung wird zum Schärfen und Glätten diskreter Wahrscheinlichkeitsverteilungen verwendet.

Das Schärfen der Wahrscheinlichkeit ist eine Operation, die eine hohe Wahrscheinlichkeit in eine höhere Wahrscheinlichkeit und eine niedrige Wahrscheinlichkeit in eine niedrigere Wahrscheinlichkeit umwandelt. Durch diese Operation nähert sich die diskrete Wahrscheinlichkeitsverteilung einer One-Hot-Wahrscheinlichkeitsverteilung (1 für einige Elemente und 0 für andere).

Andererseits ist die Wahrscheinlichkeitsglättung eine Operation, die die Wahrscheinlichkeitsverteilung glättet. Dies ist eine Operation, die die diskrete Wahrscheinlichkeitsverteilung einer gleichmäßigen Verteilung näher bringt.

sample.png

Beim Anpassen der Wahrscheinlichkeitsverteilung für die Stichprobenerzeugung werden Schärfen und Glätten verwendet. Wenn Sie bei der Dokumentgenerierung das Schärfen für die Verarbeitung natürlicher Sprache verwenden, werden häufiger verwendete Sätze generiert. Andererseits erzeugt das Glätten eine breite Palette von Sätzen.

Diese Idee wird nicht nur in der Verarbeitung natürlicher Sprache verwendet, sondern auch an verschiedenen Orten wie unbeaufsichtigtem Clustering und der Erzeugung molekularer Designs.

Hier werde ich zwei Methoden zur Neuskalierung vorstellen und sie mit einem einfachen Problem bei der Satzgenerierung ausprobieren.

Thermal Rescaling Diese Methode verwendet die in der statistischen Mechanik verwendete Boltzmann-Verteilung. Unter der Annahme, dass die Wahrscheinlichkeitsverteilung vor der Neuskalierung q_i und die Wahrscheinlichkeitsverteilung nach der Neuskalierung p_i ist, ist die thermische Neuskalierung wie folgt.

p_i = \frac{\exp(\frac{q_i}{T})}{\sum_{j}\exp(\frac{q_j}{T})}

Hier ist T ein Temperaturparameter, und wenn T klein ist, wird es geschärft, und wenn T groß ist, wird es geglättet. Die Änderung der Wahrscheinlichkeitsverteilung aufgrund der thermischen Neuskalierung ist wie folgt.

example_thermal.png

Die Merkmale der thermischen Neuskalierung sind die folgenden drei Punkte.

  1. Wenn sich T 0 nähert, nähert es sich der One-Hot-Wahrscheinlichkeitsverteilung "v".
  2. Wenn T zunimmt, nähert es sich der gleichmäßigen Verteilung "u".
  3. Es gibt nicht immer einen Temperaturparameter "T", der der Wahrscheinlichkeitsverteilung vor der Konvertierung entspricht **.

Als System von Merkmal 3 ist es wichtig, dass Elemente mit einer Wahrscheinlichkeit von 0 nicht erhalten bleiben (Element 3 in der obigen Abbildung). Dieses Problem kann gegen die Regeln der Wahrscheinlichkeitsverteilung verstoßen, die vor der Neuskalierung angenommen wurden.

Das Folgende zeigt die KL-Informationen der Verteilung nach dem erneuten Skalieren, (A) die ursprüngliche Verteilung q, (B) die gleichmäßige Verteilung u und (C) die One-Hot-Wahrscheinlichkeitsverteilung v.

KL_thermal.png

Wenn sich T 0 nähert, nähert sich die Menge an KL-Informationen mit der Ein-Hot-Wahrscheinlichkeitsverteilung v 0, und wenn T zunimmt, nähert sich die Menge an KL-Informationen mit der Gleichverteilung u 0. Andererseits nähert sich die Menge an KL-Informationen mit der ursprünglichen Verteilung q niemals 0.

Es ist nicht so viel wie Code, aber wenn Sie numpy verwenden, sieht es so aus:

#Ursprüngliche diskrete Wahrscheinlichkeitsverteilung
q = np.array([0.1,0.05,0.6,0,0.2,0.05])
#Temperaturparameter
T = 0.05
#Neuskalierung
p = np.exp(q/T) / np.sum(np.exp(q/T))

Freezing function

Es gibt eine Einfrierfunktion als Neuskalierungsmethode, die die Wahrscheinlichkeit exponentiell multipliziert. Diese Idee wird auch in der unbeaufsichtigten Lernmethode Deep Embedded Clustering (DEC) verwendet [2]. Unter der Annahme, dass die Wahrscheinlichkeitsverteilung vor der Neuskalierung q_i und die Wahrscheinlichkeitsverteilung nach der Neuskalierung p_i ist, ist die Einfrierfunktion wie folgt.

p_i = \frac{q_i^{\frac{1}{T}}}{\sum_{j}q_j^{\frac{1}{T}}}

Ähnlich wie bei der thermischen Neuskalierung ist T ein Temperaturparameter, der geschärft wird, wenn T klein ist, und geglättet wird, wenn T groß ist. Die Änderung der Wahrscheinlichkeitsverteilung aufgrund der thermischen Neuskalierung ist wie folgt.

example_freesing.png

Die Merkmale der Einfrierfunktion sind die folgenden drei Punkte.

  1. Wenn sich T 0 nähert, nähert es sich der One-Hot-Wahrscheinlichkeitsverteilung "v".
  2. Wenn T zunimmt, nähert es sich nicht immer der gleichmäßigen Verteilung "u" **.
  3. Wenn T = 1 ist, stimmt es mit der Wahrscheinlichkeitsverteilung vor der Konvertierung überein.

Im Gegensatz zur thermischen Neuskalierung werden Elemente mit einer Wahrscheinlichkeit von 0 gespeichert. Wenn es also ein Element mit einer Wahrscheinlichkeit von 0 gibt, führt die Glättung nicht zu einer gleichmäßigen Verteilung.

Das Folgende zeigt die KL-Informationen der Verteilung nach dem erneuten Skalieren, (A) die ursprüngliche Verteilung, (B) die gleichmäßige Verteilung u und (C) die One-Hot-Wahrscheinlichkeitsverteilung v. (D(u||p)Kann nicht berechnet werden, also D.(p||u)Wurde berechnet. )

KL_freesing.png

Ähnlich wie bei der thermischen Neuskalierung nähert sich, wenn T sich 0 nähert, die Menge an KL-Informationen mit der Ein-Heiß-Wahrscheinlichkeitsverteilung v 0, aber selbst wenn T zunimmt, nähert sich die Menge an KL-Informationen mit der Gleichverteilung u nicht 0. Hmm. Wenn andererseits T = 1 ist, konvergiert die Menge an KL-Informationen mit der ursprünglichen Verteilung q gegen 0.

Es ist nicht so viel wie Code, aber wenn Sie numpy verwenden, sieht es so aus:

#Ursprüngliche diskrete Wahrscheinlichkeitsverteilung
q = np.array([0.1,0.05,0.6,0,0.2,0.05])
#Temperaturparameter
T = 0.2
#Neuskalierung
p = q**(1/T) / np.sum(q**(1/T))

Anwendung zur Dokumentenerstellung

Die folgenden drei Sätze werden zum Lernen verwendet.

I have a pen. 
I have a dog. 
I buy a pen.

Dieses Mal verwendet das Satzgenerierungsmodell ein einfaches 1-Gramm. Wenn Sie ungefähr 10 Sätze mit 1 Gramm erstellen, ist dies wie folgt.

 [SoS] I have a pen [EoS]
 [SoS] I have a pen [EoS]
 [SoS] I have a pen [EoS]
 [SoS] I have a pen [EoS]
 [SoS] I have a pen [EoS]
 [SoS] I have a dog [EoS]
 [SoS] I have a pen [EoS]
 [SoS] I buy a dog [EoS]
 [SoS] I buy a dog [EoS]
 [SoS] I have a pen [EoS]

Ein bestimmter unordentlicher Satz wird erzeugt.

Erstens sind unter Verwendung der Einfrierfunktion die geschärften Sätze wie folgt (T = 0,1).

 [SoS] I have a pen [EoS]
 [SoS] I have a pen [EoS]
 [SoS] I have a pen [EoS]
 [SoS] I have a pen [EoS]
 [SoS] I have a pen [EoS]
 [SoS] I have a pen [EoS]
 [SoS] I have a pen [EoS]
 [SoS] I have a pen [EoS]
 [SoS] I have a pen [EoS]
 [SoS] I have a pen [EoS]

Da es viele Lernsätze gibt, die "haben" nach "ich" und "Stift" nach "a" verwenden, wurde nur ein Satz durch Schärfen erzeugt.

Als nächstes wird der mit der Funktion "Einfrieren" geglättete Text wie folgt geglättet (T = 2,0).

 [SoS] I have a dog [EoS]
 [SoS] I buy a dog [EoS]
 [SoS] I have a pen [EoS]
 [SoS] I have a pen [EoS]
 [SoS] I have a pen [EoS]
 [SoS] I have a dog [EoS]
 [SoS] I buy a dog [EoS]
 [SoS] I buy a pen [EoS]
 [SoS] I buy a pen [EoS]
 [SoS] I have a dog [EoS]

Die Anzahl der Samples, die "buy" nach "I" verwenden, nimmt zu, aber die Schreibregeln werden nicht verletzt.

Schließlich ist der mit der thermischen Neuskalierung geglättete Text wie folgt. (T = 1,0)

 [SoS] a I have dog I have I [EoS]
 [SoS] [EoS]
 [SoS] have [SoS] I buy [EoS]
 [SoS] a a [EoS]
 [SoS] [SoS] [SoS] [EoS]
 [SoS] [EoS]
 [SoS] a buy a dog dog [SoS] I dog pen pen pen buy pen [EoS]
 [SoS] dog buy a I pen I have buy I buy a dog [EoS]
 [SoS] dog buy buy I dog a pen have dog pen [EoS]
 [SoS] I [SoS] buy dog [SoS] a pen pen [EoS]

Die Anweisungsregel ist fehlerhaft. Die thermische Neuskalierung ist darauf zurückzuführen, dass Elemente mit einer Wahrscheinlichkeit von 0 nicht gespeichert werden.

Der Code für die Satzgenerierung ist unten dargestellt. ..

import numpy as np

corpus = "I have a pen. I have a dog. I buy a pen."
#In Sätze teilen
sentences =  corpus.split('.')
#Mit dem Löschen von leerem Text[SoS],[EoS]Zugabe von
sentences = ['[SoS] ' + s + ' [EoS]' for s in sentences if s != '']
# [EoS]→[EoS]Hinzufügen
sentences.append("[EoS] [EoS]")
#Doppelte Speicherplatzentfernung
sentences = [s.replace('  ',' ')  for s in sentences]
#In Worte teilen
words =[]
for s in sentences:
    words.append(s.split(' '))
#Erstellen einer Wortliste
word_list = ['[SoS]'] + list(set(sum(words,[])) - set(['[SoS]','[EoS]'])) + ['[EoS]']
#Konvertieren Sie die Wortliste in die Elementnummer
num_list = np.arange(len(word_list))
word_dict = dict(zip(word_list,num_list))
#Übergangswahrscheinlichkeiten erstellen
A = np.zeros((len(word_list),len(word_list)))
for s in words:
    for i in range(len(s) - 1):
        #Anzahl
        A[word_dict[s[i+1]],word_dict[s[i]]] +=1
A = A / A.sum(axis = 0)
#Generierung von Originaldokumenten
sentences_g = []

for i in range(10):
    #Anfänglich[SoS]
    w = [0]
    while True:
        #Nächste Wahrscheinlichkeitsverteilung
        q = A[:,w[-1]]
        # sampling and append
        w.append(np.argmax(np.random.multinomial(1,q)))
        # if EoS then break
        if w[-1] == len(word_list)-1:
            break;
    #In String konvertieren
    s = ''
    for i in w:
        s = s + ' ' +word_list[i]  

    #Dokument hinzufügen
    sentences_g.append(s)
#Anzeige
for s in sentences_g:
    print(s)

Schärfcode durch Einfrieren:

#  Sharpening by Freezing : T = 0.1
T = 0.1
sentences_g = []
for i in range(10):
    w = [0]
    while True:
        q = A[:,w[-1]]
        #Neuskalierung
        p = q**(1/T) / np.sum(q**(1/T))
        w.append(np.argmax(np.random.multinomial(1,p)))
        if w[-1] == len(word_list)-1:
            break;
    s = ''
    for i in w:
        s = s + ' ' +word_list[i]  
    sentences_g.append(s)
for s in sentences_g:
    print(s)

Glättungscode durch thermische Neuskalierung:

#  Smoothing by Thermal : T = 1.0
T = 1.0
sentences_g = []
for i in range(10):
    w = [0]
    while True:
        q = A[:,w[-1]]
        #Neuskalierung
        p = np.exp(q/T) / np.sum(np.exp(q/T))
        w.append(np.argmax(np.random.multinomial(1,p)))
        if w[-1] == len(word_list)-1:
            break;
    s = ''
    for i in w:
        s = s + ' ' +word_list[i]  

    sentences_g.append(s)
for s in sentences_g:
    print(s)

Wenn Sie voreingenommen und neu skalieren möchten

Wir können neu skalieren, um bestimmte Elemente erscheinen zu lassen. In diesem Fall möchten Sie möglicherweise die Gumbel-Softmax-Funktion [3] verwenden.

Unter der Annahme, dass die Wahrscheinlichkeitsverteilung vor der Neuskalierung $ q_i $ und die Wahrscheinlichkeitsverteilung nach der Neuskalierung $ p_i $ beträgt, lautet die Gumbel-Softmax-Funktion wie folgt.

p_i = \frac{\exp(\frac{\log(q_i)+ g_i}{T})}{\sum_{j}\exp(\frac{\log(q_j)+ g_j}{T})}

Hier ist T ein Temperaturparameter und wird wie die bisherige Neuskalierung geschärft, wenn T klein ist, und geglättet, wenn T groß ist. Außerdem ist g_i ein Parameter, der die Priorität bei der Neuskalierung bestimmt. In der Arbeit wird g_i aus der folgenden Verteilung generiert.

g_i = -\log (-\log u),\quad u\sim {\rm Uniform}(0, 1)

Neben der Gumbel-Softmax-Funktion gibt es meines Erachtens eine Methode zum Vorspannen und Neuskalieren. Ich möchte es je nach Situation verwenden.

Zusammenfassung

Wenn Sie das Element mit einer Wahrscheinlichkeit von 0 behalten möchten, verwenden Sie die Einfrierfunktion. Wenn Sie das Element nicht mit einer Wahrscheinlichkeit von 0 behalten möchten, verwenden Sie die thermische Neuskalierung.

code https://github.com/yuji0001/2020GenerativeModel

Author Yuji Okamoto: [email protected]

Reference [1] Elton, D. C., Boukouvalas, Z., Fuge, M. D., & Chung, P. W. (2019, August 1). Deep learning for molecular design - A review of the state of the art. Molecular Systems Design and Engineering, Vol. 4, pp. 828–849. https://doi.org/10.1039/c9me00039a

[2] Xie, J., Girshick, R., & Farhadi, A. (2015). Unsupervised Deep Embedding for Clustering Analysis. 48. Retrieved from http://arxiv.org/abs/1511.06335

[3] Jang, E., Gu, S., & Poole, B. (2019). Categorical reparameterization with gumbel-softmax. 5th International Conference on Learning Representations, ICLR 2017.

Recommended Posts

Zusammenfassung des Schärfens und Glättens der Wahrscheinlichkeit + Anwendbar auf einfache Dokumentgenerierung
[Python] Zusammenfassung zum Abrufen von Listen und Wörterbuchelementen
[Python] Zusammenfassung der Verwendung von Split- und Join-Funktionen
Sphinx-Erweiterung zur willkürlichen Konvertierung von Text in der Vorverarbeitung der Dokumentgenerierung
Zusammenfassung der Verwendung von pandas.DataFrame.loc
Zusammenfassung der Verwendung von pyenv-virtualenv
Erklärung und Implementierung von einfachem Perzeptron
Zusammenfassung der Verwendung von csvkit
Zusammenfassung der Python-Indizes und -Slices
Beschreibung und Zusammenfassung der Installation von Chainer auf einem Mac