[PYTHON] Ich habe mit TensorFlow eine nicht negative Matrixzerlegung (NMF) versucht

In Artikeln zu TensorFlow gab es nur wenige Anwendungsbeispiele außer neuronalen Netzen und Deep Learning. Daher habe ich als Beispiel die nicht-negative Matrixzerlegung (NMF) implementiert.

Entwicklungsumgebung

OS: Ubuntu 14.04 CPU: Core i7-3770 3.40GHz×8 Speicher: 16 GB TersorFlow: Ver.0.6.0 CPU-Modus Python version: 2.7

Nicht negative Matrixfaktorisierung

NMF ist ein Algorithmus, der die nicht negative Wertematrix V durch das Produkt zweier nicht negativer Wertmatrizen H und W approximiert. Es wird in einer Vielzahl von Bereichen wie Merkmalsextraktion, Dimensionsreduzierung, Bildverarbeitung als Clustering-Methode und natürlicher Sprache verwendet.

Problemstellung

Eingabe: $ V \ in \ mathcal {R} ^ {m \ times n} _ {+}, \ r \ in \ mathcal {N} ^ + $

Ausgabe:$\underset{W,H} {\arg\min} ||V-WH||_{F}^{2}\ \ s.t.\ W \in \mathcal{R} _{+} ^{m \times r}, H \in \mathcal{R} _{+} ^ {r \times n} $

Algorithmus

Dieses Mal verwenden wir die einfachste multiplikative Aktualisierungsregel, um NMF zu optimieren. Der MU-Algorithmus führt abwechselnd die folgenden Aktualisierungsausdrücke aus, bis sie konvergieren.

H_{a\mu} \leftarrow H_{a\mu}\frac{(W^TV)_{a\mu}}{(W^TWH)_{a\mu}},\ \ 
W_{ia} \leftarrow W_{ia}\frac{(VH^T)_{ia}}{(WHH^T)_{ia}}

Referenzlink: Algorithmen für die nicht negative Matrixfaktorisierung

Implementierung

Der Klassenkörper wird wie folgt implementiert.

tfnmf.py


# -*- coding: utf-8 -*-
from __future__ import division
import numpy as np
import tensorflow as tf

class TFNMF(object):
    """Non-negative Matrix Factorization by TensorFlow"""
    def __init__(self, V, rank):

        #Konvertieren Sie von der Numpy-Matrix in den Tensor von TensorFlow
        V_ = tf.constant(V, dtype=tf.float32)
        shape = V.shape

        #Durchschnittliche sqrt(V.mean() / rank)Skalieren Sie auf eine einheitliche Zufallszahl
        scale = 2 * np.sqrt(V.mean() / rank)
        initializer = tf.random_uniform_initializer(maxval=scale)

        #Matrix H.,W Variablengenerierung
        self.H = H = tf.get_variable("H", [rank, shape[1]],
                                     initializer=initializer)
        self.W = W = tf.get_variable(name="W", shape=[shape[0], rank],
                                     initializer=initializer)

        #Speichern Sie W für die Konvergenzbeurteilung
        W_old = tf.get_variable(name="W_old", shape=[shape[0], rank])
        self._save_W = W_old.assign(W)

        #MU-Algorithmus
        #Update H.
        Wt = tf.transpose(W)
        WV = tf.matmul(Wt, V_)
        WWH = tf.matmul(tf.matmul(Wt, W), H)
        WV_WWH = WV / WWH
        with tf.device('/cpu:0'):
            #Wandelt ein Element, das nan enthält, um 0% in 0 um
            WV_WWH = tf.select(tf.is_nan(WV_WWH),
                              tf.zeros_like(WV_WWH),
                              WV_WWH)
        H_new = H * WV_WWH
        self._update_H = H.assign(H_new)

        #Update W.(H wurde aktualisiert)
        Ht = tf.transpose(H)
        VH = tf.matmul(V_, Ht)
        WHH = tf.matmul(W, tf.matmul(H, Ht))
        VH_WHH = VH / WHH
        with tf.device('/cpu:0'):
            #Wandelt ein Element, das nan enthält, um 0% in 0 um
            WV_WWH = tf.select(tf.is_nan(WV_WWH),
                              tf.zeros_like(WV_WWH),
                              WV_WWH)
        W_new = W * VH_WHH
        self._update_W = W.assign(W_new)

        #Gesamtänderung jedes Elements von W.
        self._delta = tf.reduce_sum(tf.abs(W_old - W))

    def run(self, sess, max_iter=200):
        tf.initialize_all_variables().run()
        for i in range(max_iter):
            sess.run(self._save_W)
            H, _ = sess.run([self.H, self._update_H])
            W, _ = sess.run([self.W, self._update_W])
            delta = sess.run(self._delta)
            if delta < 0.001:
                break
        return W, H

Ausführungszeit

Messen Sie die Ausführungszeit, indem Sie die Anzahl der von der CPU verwendeten Kerne ändern. Die Eingabe war eine 10000 x 10000-Zufallsmatrix, und die Anzahl der Ränge betrug 10.

Das Ausführungsskript lautet wie folgt.

main.py


# -*- coding: utf-8 -*-
from __future__ import print_function
import time
import numpy as np
import tensorflow as tf
from tfnmf import TFNMF

def main():
    V = np.random.rand(10000,10000)
    rank = 10
    num_core = 8

    tfnmf = TFNMF(V, rank)
    config = tf.ConfigProto(inter_op_parallelism_threads=num_core,
                           intra_op_parallelism_threads=num_core)
    with tf.Session(config=config) as sess:
        start = time.time()
        W, H = tfnmf.run(sess)
        print("Computational Time: ", time.time() - start)

    #Quadratische Fehlerberechnung
    W = np.mat(W)
    H = np.mat(H)
    error = np.power(V - W * H, 2).sum()
    print("Reconstruction Error: ", error)


if __name__ == '__main__':
    main()

Dies ist das Ergebnis bei Ausführung mit 8 Kernen. Der Rekonstruktionsfehler repräsentiert den quadratischen Fehler, der die Zielfunktion ist.

$python main.py
I tensorflow/core/common_runtime/local_device.cc:40] Local device intra op parallelism threads: 8
I tensorflow/core/common_runtime/direct_session.cc:58] Direct session inter op parallelism threads: 8
Computational Time:  45.2025268078
Reconstruction Error:  8321195.31013

Es ist ein Diagramm der Ausführungszeit, wenn die Anzahl der Kerne von 1 auf 8 geändert wird. time_10000.png

Acht Kerne sind etwa 1,4-mal schneller als ein Kern. Der Overhead war größer als erwartet, und selbst wenn ich die Anzahl der Kerne erhöhte, erhöhte sich die Ausführungszeit nicht dramatisch. Es ist möglicherweise keine sehr effiziente Methode, jedes Mal, wenn W und H aktualisiert werden, sess.run () auszuführen.

abschließend

Dieses Mal habe ich TensorFlow nur für die Matrixberechnung verwendet, daher fand ich, dass es nicht nützlich war, aber es ist wunderbar, die parallele Berechnung einfach beschreiben zu können. Nächstes Mal werde ich versuchen, eine Tensorzerlegung zu implementieren.

Recommended Posts

Ich habe mit TensorFlow eine nicht negative Matrixzerlegung (NMF) versucht
Nicht negative Matrixfaktorisierung (NMF) mit Scikit-Learn
Ich habe versucht, die nicht negative Matrixfaktorisierung (NMF) zu wiederholen.
Ich habe versucht, Autoencoder mit TensorFlow zu implementieren
Ich habe versucht, AutoEncoder mit TensorFlow zu visualisieren
Visualisierung des NMF-Lernens (Non-Negative Matrix Factor Decomposition)
Ich habe versucht, TensorFlow auszuführen
Anfangswertproblem der NMF (nicht negative Matrixfaktorzerlegung)
Ich habe versucht, eine ganzzahlige Matrix mit Numpy zu standardisieren
Ich habe versucht, Grad-CAM mit Keras und Tensorflow zu implementieren
Ich habe versucht, die alternative Klasse mit Tensorflow zu finden
Ich habe versucht, mit Python zu kratzen
Ich habe versucht, mit PyCaret zu clustern
Ich habe versucht, Magenta / TensorFlow zu verwenden
Ich habe gRPC mit Python ausprobiert
Ich habe versucht, mit Python zu kratzen
Ich habe versucht, mit TensorFlow den Durchschnitt mehrerer Spalten zu ermitteln
[TensorFlow] Ich habe versucht, mit LSTM eine Nachricht wie "Treffen Sie das Urteil nach dem Tod" in Massenproduktion zu produzieren
Ich habe das TensorFlow-Tutorial als erstes ausprobiert
Ich habe maschinelles Lernen mit liblinear versucht
Ich habe versucht, WebScraping mit Python.
Ich habe versucht, Essen mit SinGAN zu bewegen
Ich habe das 2. TensorFlow-Tutorial ausprobiert
TensorFlow Tutorial Ich habe CNN 4th ausprobiert
Ich habe versucht, DeepPose mit PyTorch zu implementieren
Ich habe versucht, das Gesicht mit MTCNN zu erkennen
Ich habe versucht, Prolog mit Python 3.8.2 auszuführen.
Ich habe die SMTP-Kommunikation mit Python versucht
Ich habe versucht, Sätze mit GPT-2 zu generieren
Ich habe versucht, LightGBM mit Yellowbrick zu lernen
Ich habe versucht, das Gesicht mit OpenCV zu erkennen
Ich habe versucht, das TensorFlow-Tutorial mit Kommentaren auszuführen (_TensorFlow_2_0_Einführung für Anfänger).
Ich habe eine multiple Regressionsanalyse mit Polypoly-Regression versucht
Ich habe versucht, eine SMS mit Twilio zu senden
Ich habe versucht, Amazon SQS mit Django-Sellerie zu verwenden
Ich habe versucht, Objekte mit YOLO v3 (TensorFlow 2.0) auf einer Windows-CPU zu erkennen!
Ich habe Linebot mit Flasche (Anaconda) + Heroku ausprobiert
Ich habe zum ersten Mal Tensorflow ausprobiert
Ich habe versucht, mit Hy anzufangen
Ich habe versucht, ○ ✕ mit TensorFlow zu spielen
Ich habe versucht, Selen mit Headless-Chrom zu verwenden
Ich habe versucht, Faktoren mit Titanic-Daten zu analysieren!
Ich habe versucht, mit Kaggles Titanic (kaggle②) zu lernen.
Ich habe versucht, mit Python + opencv nicht realistisch zu rendern
Ich habe versucht, Text mit TensorFlow zu klassifizieren
Ich habe eine funktionale Sprache mit Python ausprobiert
Ich habe versucht, mit Python ② (Fibonacci-Zahlenfolge) aufzuklären.
Ich habe versucht, DeepPose mit PyTorch PartⅡ zu implementieren
Ich habe versucht, CVAE mit PyTorch zu implementieren
Ich habe versucht, mit Pillow mit dem Bild zu spielen
Ich habe versucht, TSP mit QAOA zu lösen
Ich habe mit Jupyter eine einfache Bilderkennung versucht
Ich habe versucht, CNN mit Resnet fein abzustimmen
Ich habe versucht, natürliche Sprache mit Transformatoren zu verarbeiten.
# Ich habe so etwas wie Vlookup mit Python # 2 ausprobiert
Ich habe das TensorFlow-Tutorial mit Kommentaren ausgeführt (Textklassifizierung von Filmkritiken).
Ich habe versucht, Objekte mit YOLO v3 (TensorFlow 2.1) auf der GPU von Windows zu erkennen!