[PYTHON] J'ai essayé la décomposition matricielle non négative (NMF) avec TensorFlow

Il y avait peu d'exemples d'utilisation autres que les réseaux neuronaux et le Deep Learning dans les articles liés à TensorFlow, j'ai donc implémenté la décomposition matricielle non négative (NMF) à titre d'exemple.

Environnement de développement

OS: Ubuntu 14.04 CPU: Core i7-3770 3.40GHz×8 Mémoire: 16 Go TersorFlow: mode CPU ver.0.6.0 Python version: 2.7

Factorisation matricielle non négative

NMF est un algorithme qui se rapproche de la matrice de valeurs non négatives V par le produit de deux matrices de valeurs non négatives H et W. Il est utilisé dans un large éventail de domaines tels que l'extraction d'entités, la réduction de dimension, le traitement d'images comme méthode de regroupement et le langage naturel.

Problème de réglage

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

production:$\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} $

algorithme

Cette fois, nous utiliserons la règle de mise à jour multiplicative la plus simple pour optimiser NMF. L'algorithme MU exécute alternativement les expressions de mise à jour suivantes jusqu'à ce qu'elles convergent.

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}}

Lien de référence: Algorithms for Non-negative Matrix Factorization

la mise en oeuvre

Le corps de la classe est implémenté comme suit.

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):

        #Conversion de matrice Numpy en Tensor of TensorFlow
        V_ = tf.constant(V, dtype=tf.float32)
        shape = V.shape

        #Sqrt moyen(V.mean() / rank)Échelle à un nombre aléatoire uniforme
        scale = 2 * np.sqrt(V.mean() / rank)
        initializer = tf.random_uniform_initializer(maxval=scale)

        #Matrice H,Génération de variables W
        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)

        #Enregistrer W pour le jugement de convergence
        W_old = tf.get_variable(name="W_old", shape=[shape[0], rank])
        self._save_W = W_old.assign(W)

        #Algorithme MU
        #Mettre à jour 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'):
            #Convertit un élément contenant nan de 0% en 0
            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)

        #Mettre à jour W(H a été mis à jour)
        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'):
            #Convertit un élément contenant nan de 0% en 0
            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)

        #Changement total de chaque élément de 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

Temps d'exécution

Mesurez le temps d'exécution en modifiant le nombre de cœurs utilisés par le CPU. L'entrée est une matrice aléatoire de 10000 x 10000 et le nombre de rangs est de 10.

Le script d'exécution est le suivant.

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)

    #Calcul de l'erreur carrée
    W = np.mat(W)
    H = np.mat(H)
    error = np.power(V - W * H, 2).sum()
    print("Reconstruction Error: ", error)


if __name__ == '__main__':
    main()

C'est le résultat lorsqu'il est exécuté avec 8 cœurs. L'erreur de reconstruction représente l'erreur au carré, qui est la fonction objectif.

$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

C'est un graphique du temps d'exécution lorsque le nombre de cœurs passe de 1 à 8. time_10000.png

Huit cœurs sont environ 1,4 fois plus rapides qu'un cœur. La surcharge était plus importante que ce à quoi je m'attendais, et même si j'augmentais le nombre de cœurs, le temps d'exécution n'a pas augmenté de façon spectaculaire. Ce n'est peut-être pas une méthode très efficace pour faire sess.run () chaque fois que W et H sont mis à jour.

en conclusion

Cette fois, j'ai utilisé TensorFlow uniquement pour le calcul matriciel, donc j'ai senti que ce n'était pas utile, mais c'est merveilleux de pouvoir décrire facilement le calcul parallèle. La prochaine fois, j'essaierai d'implémenter la décomposition tensorielle.

Recommended Posts

J'ai essayé la décomposition matricielle non négative (NMF) avec TensorFlow
Factorisation matricielle non négative (NMF) avec scikit-learn
J'ai essayé de refaire la factorisation matricielle non négative (NMF)
J'ai essayé d'implémenter Autoencoder avec TensorFlow
J'ai essayé de visualiser AutoEncoder avec TensorFlow
Visualisation de l'apprentissage NMF (Non-Negative Matrix Factor Decomposition)
J'ai essayé d'exécuter TensorFlow
Problème de valeur initiale de NMF (Décomposition en facteurs matriciels non négatifs)
J'ai essayé Smith en standardisant une matrice entière avec Numpy
J'ai essayé d'implémenter Grad-CAM avec keras et tensorflow
J'ai essayé de trouver la classe alternative avec tensorflow
J'ai essayé de gratter avec Python
J'ai essayé le clustering avec PyCaret
J'ai essayé d'utiliser magenta / TensorFlow
J'ai essayé gRPC avec Python
J'ai essayé de gratter avec du python
J'ai essayé de trouver la moyenne de plusieurs colonnes avec TensorFlow
[TensorFlow] J'ai essayé de produire en masse un message comme "Rencontrez le jugement après la mort" avec LSTM
J'ai essayé le tutoriel TensorFlow 1er
J'ai essayé l'apprentissage automatique avec liblinear
J'ai essayé webScraping avec python.
J'ai essayé de déplacer de la nourriture avec SinGAN
J'ai essayé le tutoriel TensorFlow 2ème
Tutoriel TensorFlow J'ai essayé CNN 4th
J'ai essayé d'implémenter DeepPose avec PyTorch
J'ai essayé la détection de visage avec MTCNN
J'ai essayé d'exécuter prolog avec python 3.8.2.
J'ai essayé la communication SMTP avec Python
J'ai essayé la génération de phrases avec GPT-2
J'ai essayé d'apprendre LightGBM avec Yellowbrick
J'ai essayé la reconnaissance faciale avec OpenCV
J'ai essayé d'exécuter le didacticiel TensorFlow avec des commentaires (_TensorFlow_2_0_Introduction pour les débutants)
J'ai essayé l'analyse de régression multiple avec régression polypoly
J'ai essayé d'envoyer un SMS avec Twilio
J'ai essayé d'utiliser Amazon SQS avec django-celery
J'ai essayé la détection d'objets avec YOLO v3 (TensorFlow 2.0) sur un processeur Windows!
J'ai essayé linebot avec flacon (anaconda) + heroku
J'ai essayé tensorflow pour la première fois
J'ai essayé de commencer avec Hy
J'ai essayé de jouer au jeu ○ ✕ en utilisant TensorFlow
J'ai essayé d'utiliser du sélénium avec du chrome sans tête
J'ai essayé l'analyse factorielle avec des données Titanic!
J'ai essayé d'apprendre avec le Titanic de Kaggle (kaggle②)
J'ai essayé le rendu non réaliste avec Python + opencv
J'ai essayé de classer le texte en utilisant TensorFlow
J'ai essayé un langage fonctionnel avec Python
J'ai essayé la récurrence avec Python ② (séquence de nombres Fibonatch)
J'ai essayé d'implémenter DeepPose avec PyTorch PartⅡ
J'ai essayé d'implémenter CVAE avec PyTorch
J'ai essayé de jouer avec l'image avec Pillow
J'ai essayé de résoudre TSP avec QAOA
J'ai essayé la reconnaissance d'image simple avec Jupyter
J'ai essayé le réglage fin de CNN avec Resnet
J'ai essayé le traitement du langage naturel avec des transformateurs.
# J'ai essayé quelque chose comme Vlookup avec Python # 2
J'ai couru le tutoriel TensorFlow avec des commentaires (classification du texte des critiques de films)
J'ai essayé la détection d'objets avec YOLO v3 (TensorFlow 2.1) sur le GPU de windows!