[PYTHON] Expliquez le code de Tensorflow_in_ROS

Préface

résultat

Avant d'entrer dans la description détaillée du code, je vais simplement vous montrer ce que vous pouvez en faire.![Capture d'écran du 23/11/2016 15_44_07.png](https: //qiita-image-store.s3.amazonaws. com / 0/134368 / b426cc2e-e963-0897-f2d0-f83a5ec7a3d0.png)

Comme ça, la droite est une entrée manuscrite 9 de la caméra La gauche est le résultat de l'estimation du CNN formé, et 9 est renvoyé correctement après avoir vu 9. Cette fois, j'ai écrit le code qui permet à CNN comme celui-ci de fonctionner sur ROS. Voir Article précédent de Qiita pour plus de détails sur les méthodes d'exécution et les préparatifs.

Aperçu du traitement

Si vous passez en revue les grandes lignes du processus

  1. Configurez CNN pour lire les fichiers entraînés
  2. Abonnez-vous aux informations d'image à partir du nœud de caméra
  3. Compressez les informations de l'image en 28 * 28 et binarisez le noir et blanc pour qu'elles entrent CNN de MNIST
  4. Montrez l'image à CNN et estimez le nombre
  5. Publiez le résultat

C'est comme ça.

Code entier

Le code entier ressemble à ceci:

tensorflow_in_ros_mnist.py


import rospy
from sensor_msgs.msg import Image
from std_msgs.msg import Int16
from cv_bridge import CvBridge
import cv2
import numpy as np
import tensorflow as tf


def weight_variable(shape):
  initial = tf.truncated_normal(shape, stddev=0.1)
  return tf.Variable(initial)

def bias_variable(shape):
  initial = tf.constant(0.1, shape=shape)
  return tf.Variable(initial)

def conv2d(x, W):
  return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], 
                      padding='SAME')

def max_pool_2x2(x):
  return tf.nn.max_pool(x, ksize=[1, 2, 2, 1],
                        strides=[1, 2, 2, 1], padding='SAME')


def makeCNN(x,keep_prob):
    # --- define CNN model
    W_conv1 = weight_variable([5, 5, 1, 32])
    b_conv1 = bias_variable([32])
    h_conv1 = tf.nn.relu(conv2d(x, W_conv1) + b_conv1)

    h_pool1 = max_pool_2x2(h_conv1)

    W_conv2 = weight_variable([3, 3, 32, 64])
    b_conv2 = bias_variable([64])
    h_conv2 = tf.nn.relu(conv2d(h_pool1, W_conv2) + b_conv2)

    h_pool2 = max_pool_2x2(h_conv2)

    W_fc1 = weight_variable([7 * 7 * 64, 1024])
    b_fc1 = bias_variable([1024])
    h_pool2_flat = tf.reshape(h_pool2, [-1, 7 * 7 * 64])
    h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1)
    
    h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob)

    W_fc2 = weight_variable([1024, 10])
    b_fc2 = bias_variable([10])

    y_conv = tf.nn.softmax(tf.matmul(h_fc1_drop, W_fc2) + b_fc2)
 
    return y_conv



class RosTensorFlow():
    def __init__(self):
        self._cv_bridge = CvBridge()
        self._sub = rospy.Subscriber('image', Image, self.callback, queue_size=1)
        self._pub = rospy.Publisher('result', Int16, queue_size=1)

        self.x = tf.placeholder(tf.float32, [None,28,28,1], name="x")
        self.keep_prob = tf.placeholder("float")
        self.y_conv = makeCNN(self.x,self.keep_prob)

        self._saver = tf.train.Saver()
        self._session = tf.InteractiveSession()
        
        init_op = tf.initialize_all_variables()
        self._session.run(init_op)

        self._saver.restore(self._session, "model.ckpt")


    def callback(self, image_msg):
        cv_image = self._cv_bridge.imgmsg_to_cv2(image_msg, "bgr8")
        cv_image_gray = cv2.cvtColor(cv_image, cv2.COLOR_RGB2GRAY)
        ret,cv_image_binary = cv2.threshold(cv_image_gray,128,255,cv2.THRESH_BINARY_INV)
        cv_image_28 = cv2.resize(cv_image_binary,(28,28))
        np_image = np.reshape(cv_image_28,(1,28,28,1))
        predict_num = self._session.run(self.y_conv, feed_dict={self.x:np_image,self.keep_prob:1.0})
        answer = np.argmax(predict_num,1)
        rospy.loginfo('%d' % answer)
        self._pub.publish(answer)

    def main(self):
        rospy.spin()

if __name__ == '__main__':
    rospy.init_node('rostensorflow')
    tensor = RosTensorFlow()
    tensor.main()

Commentaire de code

** pièce d'importation **

tensorflow_in_ros_mnist.py


import rospy
from sensor_msgs.msg import Image
from std_msgs.msg import Int16
from cv_bridge import CvBridge
import cv2
import numpy as np
import tensorflow as tf

Cette fois, je voulais configurer un nœud ROS en Python, j'ai donc ajouté rospy. J'ai également inclus Image pour lire des images, Int16 pour l'exportation, cv_bridge pour transmettre des fichiers de messages ROS à OpenCV, OpenCV, Numpy et Tensorflow pour l'apprentissage automatique.

** Partie définition CNN **

tensorflow_in_ros_mnist.py


def weight_variable(shape):
  initial = tf.truncated_normal(shape, stddev=0.1)
  return tf.Variable(initial)

def bias_variable(shape):
  initial = tf.constant(0.1, shape=shape)
  return tf.Variable(initial)

def conv2d(x, W):
  return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], 
                      padding='SAME')

def max_pool_2x2(x):
  return tf.nn.max_pool(x, ksize=[1, 2, 2, 1],
                        strides=[1, 2, 2, 1], padding='SAME')


def makeCNN(x,keep_prob):
    # --- define CNN model
    W_conv1 = weight_variable([5, 5, 1, 32])
    b_conv1 = bias_variable([32])
    h_conv1 = tf.nn.relu(conv2d(x, W_conv1) + b_conv1)

    h_pool1 = max_pool_2x2(h_conv1)

    W_conv2 = weight_variable([3, 3, 32, 64])
    b_conv2 = bias_variable([64])
    h_conv2 = tf.nn.relu(conv2d(h_pool1, W_conv2) + b_conv2)

    h_pool2 = max_pool_2x2(h_conv2)

    W_fc1 = weight_variable([7 * 7 * 64, 1024])
    b_fc1 = bias_variable([1024])
    h_pool2_flat = tf.reshape(h_pool2, [-1, 7 * 7 * 64])
    h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1)
    
    h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob)

    W_fc2 = weight_variable([1024, 10])
    b_fc2 = bias_variable([10])

    y_conv = tf.nn.softmax(tf.matmul(h_fc1_drop, W_fc2) + b_fc2)
 
    return y_conv

J'ai créé une fonction pour définir CNN avec la configuration selon le tutoriel de Tensorflow (Deep MNIST for Expert) .. La configuration est un modèle dans lequel, après avoir effectué deux fois la mise en commun de convolution, une couche entièrement connectée est insérée et la probabilité pour chaque nombre est calculée.

** Première moitié de init partie de la classe **

tensorflow_in_ros_mnist.py


class RosTensorFlow():
    def __init__(self):
        self._cv_bridge = CvBridge()
        self._sub = rospy.Subscriber('image', Image, self.callback, queue_size=1)
        self._pub = rospy.Publisher('result', Int16, queue_size=1)

La première moitié est le traitement ROS. Ici, nous appelons la fonction CvBridge et définissons l'abonné et l'éditeur. Cette fois, l'abonné reçoit le message de type Image et l'éditeur remet le message de type Int16. Fondamentalement, comme dans l'exemple de ROS. En incluant le rappel dans l'argument de la sous-partie, la fonction de rappel est appelée à chaque fois qu'un message Image est reçu.

** Deuxième moitié de init partie de la classe **

tensorflow_in_ros_mnist.py


        self.x = tf.placeholder(tf.float32, [None,28,28,1], name="x")
        self.keep_prob = tf.placeholder("float")
        self.y_conv = makeCNN(self.x,self.keep_prob)

        self._saver = tf.train.Saver()
        self._session = tf.InteractiveSession()
        
        init_op = tf.initialize_all_variables()
        self._session.run(init_op)

        self._saver.restore(self._session, "model.ckpt")

La seconde moitié est le traitement Tensorflow. Tout d'abord, nous définissons x, qui est l'espace réservé contenant l'image, et keep_prob, qui est l'espace réservé qui contient le taux de DropOut. Un espace réservé est comme une entrée de données, et au moment de l'exécution, les données y pénètrent de plus en plus.

Ensuite, définissez le CNN utilisé cette fois comme y_conv. Imagewise, il définit le chemin vers lequel les données sortent de l'entrée de données de x, keep_prob via le CNN jusqu'à la sortie nommée y_conv.

Après avoir défini la route, préparez-vous à diffuser réellement les données avec la fonction de session. Initialisez le poids W et le biais b de CNN une fois avec la fonction tf.initialize_all_variables.

Lisez les paramètres appris ici. Pour lire les paramètres, vous devez faire saver.restore après avoir utilisé la fonction tf.train.Saver.

** partie de rappel **

tensorflow_in_ros_mnist.py


    def callback(self, image_msg):
        cv_image = self._cv_bridge.imgmsg_to_cv2(image_msg, "bgr8")
        cv_image_gray = cv2.cvtColor(cv_image, cv2.COLOR_RGB2GRAY)
        ret,cv_image_binary = cv2.threshold(cv_image_gray,128,255,cv2.THRESH_BINARY_INV)
        cv_image_28 = cv2.resize(cv_image_binary,(28,28))
        np_image = np.reshape(cv_image_28,(1,28,28,1))
        predict_num = self._session.run(self.y_conv, feed_dict={self.x:np_image,self.keep_prob:1.0})
        answer = np.argmax(predict_num,1)
        rospy.loginfo('%d' % answer)
        self._pub.publish(answer)

Ceci est lu à chaque fois qu'un message image entre. Après avoir converti le message en image avec cv_bridge, il est mis en échelle de gris, binarisé, noir et blanc inversé, et la taille ajustée, et l'image est projetée dans le CNN. Celui avec la probabilité la plus élevée du résultat d'estimation renvoyé prédict_num est défini comme réponse et publié.

La fonction principale est omise.

Épilogue

Vous pouvez désormais tout gérer avec ROS tant que vous disposez d'un modèle entraîné de Tensorflow. Je pense que FasterRCNN peut faire la reconnaissance d'objets et la reconnaissance faciale, alors j'aimerais l'essayer.

Recommended Posts

Expliquez le code de Tensorflow_in_ROS
Expliquer le mécanisme de la classe de données PEP557
[Python3] Réécrire l'objet code de la fonction
[Python] Récupère le code de caractère du fichier
[Python] Lire le code source de Bottle Part 2
[Python] Lire le code source de Bottle Part 1
L'histoire d'essayer Sourcetrail × macOS × VS Code
Code pour vérifier le fonctionnement de Python Matplot lib
Convertir le code de caractère du fichier avec Python3
Le début de cif2cell
Le sens de soi
L'histoire de sys.path.append ()
Expliquez la séquence associative
La vengeance des types: la vengeance des types
Décomposons les bases du code Python de TensorFlow
Récupérer le code retour d'un script Python depuis bat
#Une fonction qui renvoie le code de caractère d'une chaîne de caractères
J'ai essayé d'exécuter l'exemple de code du module Ansible
Aligner la version de chromedriver_binary
Grattage du résultat de "Schedule-kun"
10. Compter le nombre de lignes
Code qui définit les valeurs par défaut en cas d'AttributeError
L'histoire de la construction de Zabbix 4.4
Vers la retraite de Python2
Comparez les polices de jupyter-themes
Obtenez le nombre de chiffres
Paramètres pour entrer et déboguer le contenu de la bibliothèque avec VS Code
Réutiliser les résultats du clustering
2.x, 3.x code de caractères des séries python
Le processus de création et d'amélioration du code Python orienté objet
GoPiGo3 du vieil homme
Calculez le nombre de changements
Vérifiez le code avec flake8
Changer le thème de Jupyter
La popularité des langages de programmation
Changer le style de matplotlib
Visualisez la trajectoire de Hayabusa 2
À propos des composants de Luigi
Composants liés du graphique
Filtrer la sortie de tracemalloc
À propos des fonctionnalités de Python
Simulation du contenu du portefeuille
Le pouvoir des pandas: Python
Suivez le flux de QAOA (VQE) au niveau du code source de Blueqat
Mesurez la couverture de test du code python poussé sur GitHub.
Premier python ② Essayez d'écrire du code tout en examinant les fonctionnalités de python
Expliquez en détail le code magique des éléments de table IQ Bot
J'ai écrit le code pour écrire le code Brainf * ck en python
Enregistrement du code des études cliniques rejeté par le comité d'éthique
Vérifiez la protection de la mémoire de Linux Kerne avec le code pour ARM
Résumons le degré de couplage entre les modules avec du code Python
for, continue, break Expliquer le flux du traitement itératif dans Python3-Part 1
Les spécifications de pytz ont changé
Tester la version du module argparse
Trouvez la définition de la valeur de errno
Tracez la propagation du nouveau virus corona
L'histoire de Python et l'histoire de NaN
Élever la version de pyenv elle-même