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.
Si vous passez en revue les grandes lignes du processus
C'est comme ça.
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()
** 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.
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