[PYTHON] Jetons un coup d'œil à la carte des fonctionnalités de YOLO v3

Je veux voir la carte des fonctionnalités de YOLO v3

Je pense que la visualisation de la base du jugement est souvent considérée comme une tendance récente. J'ai commencé python à l'université, et comme je m'occupe un peu de yolov3, j'aimerais pouvoir visualiser la carte des fonctionnalités. De plus, comme je suis débutant, je ne suis pas familier avec le programme ou n'ai pas un style d'écriture de base, alors soyez gentil avec moi. Ici, le code de yolov3 que je traite maintenant est Github : "qqwweee/keras-yolo3" Est le code de. J'aimerais jouer un peu avec ce code pour visualiser la carte des fonctionnalités.

Où j'ai raté

yolov3 semble en sortir trois, petit, moyen et grand, alors j'en ai sorti trois. Les parties que j'ai manipulées dans yolo.py sont le premier init, la dernière partie de generate et detect_image. Veuillez jeter un œil aux commentaires.

    def __init__(self, **kwargs):
        self.__dict__.update(self._defaults) # set up default values
        self.__dict__.update(kwargs) # and update with user overrides
        self.class_names = self._get_class()
        self.anchors = self._get_anchors()
        self.sess = K.get_session()
 Augmentation de #feature_get.
        self.boxes, self.scores, self.classes ,self.feature_get= self.generate()


    def generate(self):
        model_path = os.path.expanduser(self.model_path)
        assert model_path.endswith('.h5'), 'Keras model or weights must be a .h5 file.'

        # Load model, or construct model and load weights.
        num_anchors = len(self.anchors)
        num_classes = len(self.class_names)
        is_tiny_version = num_anchors==6 # default setting
        try:
            self.yolo_model = load_model(model_path, compile=False)
        except:
            self.yolo_model = tiny_yolo_body(Input(shape=(None,None,3)), num_anchors//2, num_classes) \
                if is_tiny_version else yolo_body(Input(shape=(None,None,3)), num_anchors//3, num_classes)
            self.yolo_model.load_weights(self.model_path) # make sure model, anchors and classes match
        else:
            assert self.yolo_model.layers[-1].output_shape[-1] == \
                num_anchors/len(self.yolo_model.output) * (num_classes + 5), \
                'Mismatch between model and given anchor and class sizes'

        print('{} model, anchors, and classes loaded.'.format(model_path))

        # Generate colors for drawing bounding boxes.
        hsv_tuples = [(x / len(self.class_names), 1., 1.)
                      for x in range(len(self.class_names))]
        self.colors = list(map(lambda x: colorsys.hsv_to_rgb(*x), hsv_tuples))
        self.colors = list(
            map(lambda x: (int(x[0] * 255), int(x[1] * 255), int(x[2] * 255)),
                self.colors))
        np.random.seed(10101)  # Fixed seed for consistent colors across runs.
        np.random.shuffle(self.colors)  # Shuffle colors to decorrelate adjacent classes.
        np.random.seed(None)  # Reset seed to default.
        # Generate output tensor targets for filtered bounding boxes.
        self.input_image_shape = K.placeholder(shape=(2, ))
        if self.gpu_num>=2:
            self.yolo_model = multi_gpu_model(self.yolo_model, gpus=self.gpu_num)
        boxes, scores, classes = yolo_eval(self.yolo_model.output, self.anchors,
                len(self.class_names), self.input_image_shape,
                score_threshold=self.score, iou_threshold=self.iou)
 # Ajoutez ce qui suit. Choisissez 3 couches pour lesquelles vous souhaitez obtenir une carte d'entités
 J'ai regardé #summary et regardé la couche d'activation juste avant la sortie.
        feature_get = [self.yolo_model.get_layer("leaky_re_lu_58").output , self.yolo_model.get_layer("leaky_re_lu_65").output , self.yolo_model.get_layer("leaky_re_lu_72").output]
        return boxes, scores, classes, feature_get



    def detect_image(self, image):
        start = timer()
        if self.model_image_size != (None, None):
            assert self.model_image_size[0]%32 == 0, 'Multiples of 32 required'
            assert self.model_image_size[1]%32 == 0, 'Multiples of 32 required'
            boxed_image = letterbox_image(image, tuple(reversed(self.model_image_size)))
        else:
            new_image_size = (image.width - (image.width % 32),
                              image.height - (image.height % 32))
            boxed_image = letterbox_image(image, new_image_size)
        image_data = np.array(boxed_image, dtype='float32')
        print(image_data.shape)
        image_data /= 255.
        image_data = np.expand_dims(image_data, 0)  # Add batch dimension.

 Augmentation de #feature_get de un
        out_boxes, out_scores, out_classes, feature_get= self.sess.run(
            [self.boxes, self.scores, self.classes, self.feature_get],
            feed_dict={
                self.yolo_model.input: image_data,
                self.input_image_shape: [image.size[1], image.size[0]],
                K.learning_phase(): 0
            })

        print('Found {} boxes for {}'.format(len(out_boxes), 'img'))

        font = ImageFont.truetype(font='font/FiraMono-Medium.otf',
                    size=np.floor(3e-2 * image.size[1] + 0.5).astype('int32'))
        thickness = (image.size[0] + image.size[1]) // 300
        
        

        for i, c in reversed(list(enumerate(out_classes))):
            predicted_class = self.class_names[c]
            box = out_boxes[i]
            score = out_scores[i]

            label = '{} {:.2f}'.format(predicted_class, score)
            draw = ImageDraw.Draw(image)
            label_size = draw.textsize(label, font)

            top, left, bottom, right = box
            top = max(0, np.floor(top + 0.5).astype('int32'))
            left = max(0, np.floor(left + 0.5).astype('int32'))
            bottom = min(image.size[1], np.floor(bottom + 0.5).astype('int32'))
            right = min(image.size[0], np.floor(right + 0.5).astype('int32'))
            print(label, (left, top), (right, bottom))
            

            if top - label_size[1] >= 0:
                text_origin = np.array([left, top - label_size[1]])
            else:
                text_origin = np.array([left, top + 1])

            # My kingdom for a good redistributable image drawing library.
            for i in range(thickness):
                draw.rectangle(
                    [left + i, top + i, right - i, bottom - i],
                    outline=self.colors[c])
            draw.rectangle(
                [tuple(text_origin), tuple(text_origin + label_size)],
                fill=self.colors[c])
            draw.text(text_origin, label, fill=(0, 0, 0), font=font)
            del draw

        end = timer()
        return image, feature_get

Maintenant, écrivez le code pour obtenir la carte des caractéristiques Si vous le sortez tel quel, il sortira beaucoup, donc pour le moment, je vais essayer d'extraire la carte avec la valeur moyenne la plus élevée pour petit, moyen et grand respectivement.

import numpy as np
import keras.backend as K
from keras.models import load_model
from keras.layers import Input
from PIL import Image, ImageDraw,ImageOps 
import tensorflow as tf
import cv2
import math
import collections

def feature(conv_list): 
 #Je veux obtenir la carte avec la valeur moyenne la plus élevée.
	conv_list1 = np.asarray(conv_list[0])
	conv_list2 = np.asarray(conv_list[1])
	conv_list3 = np.asarray(conv_list[2])
	bg = np.zeros((720,720))
    ave1 = []
    ave2 = []
    ave3 = []

	for i in range(conv_list1.shape[3]):
		conv = conv_list1[0,:,:,i]
		norm1 = np.max(conv)
		conv = conv / norm1
		ave1.append(np.mean(conv))
	max1 = np.max(ave1)
	index1 = ave1.index(max1)
	conv1 = conv_list1[0,:,:,index1]
	norm1 = np.max(conv1)
	conv1 = conv1 / norm1

	for i in range(conv_list2.shape[3]):
		conv = conv_list2[0,:,:,i]
		norm2 = np.max(conv)
		conv = conv / norm2
		ave2.append(np.mean(conv))
	max2 = np.max(ave2)
	index2 = ave2.index(max2)
	conv2 = conv_list2[0,:,:,index2]
	norm2 = np.max(conv2)
	conv2 = conv2 / norm2

	for i in range(conv_list3.shape[3]):
		conv = conv_list3[0,:,:,i]
		norm3 = np.max(conv)
		conv = conv / norm3
		ave3.append(np.mean(conv))
	max3 = np.max(ave3)
	index3 = ave3.index(max3)
	conv3 = conv_list3[0,:,:,index3]
	norm3 = np.max(conv3)
	conv3 = conv3 / norm3

	conv1 = conv1 * 255
	conv2 = conv2 * 255
	conv3 = conv3 * 255
	conv1 = cv2.resize(conv1, (350, 350), interpolation=cv2.INTER_NEAREST)
	conv2 = cv2.resize(conv2, (350, 350), interpolation=cv2.INTER_NEAREST)
	conv3 = cv2.resize(conv3, (350, 350), interpolation=cv2.INTER_NEAREST)

	bg[5:355,5:355] = conv1
	bg[5:355,365:715] = conv2
	bg[365:715,5:355] = conv3

	return bg

Enfin, j'ai joué avec yolo_video.py.

def detect_img(yolo):
    while True:
        img = input('Input image filename:')
        
        try:
            image = Image.open(img)
        except:
            print('Open Error! Try again!')
            continue
        else:
            r_image , feature_get = yolo.detect_image(image)
 #Afficher la carte des fonctionnalités Procédez comme suit.
            img_feature = feature_img.feature(feature_get)
            cv2.imwrite("feature_map.png " , img_feature)
            r_image.show()
    yolo.close_session()

Vous devriez maintenant obtenir une carte des fonctionnalités en exécutant yolo_video.py --image.

Exemple d'exécution

Cette fois, j'ai emprunté un chat à Pakutaso, un matériau gratuit, je vais donc essayer de le détecter. À propos, le poids utilisé par défaut yolo.h5 ↓ C'est un chat détecté

ccccc.png

La carte des caractéristiques ressemble à ceci

feature_map.png

Je ne suis pas sûr. On dirait que les yeux et la bouche du chat sont caractéristiques. À propos, le chat dans l'image d'entrée est redimensionné en le collant sur l'image grise 416 x 416 avec la largeur ajustée lorsqu'il est mis dans le réseau. La carte des caractéristiques est adaptée à sa taille. Yolov3 est-il centré sur les cellules de la grille? Je ne sais pas où je regarde au centre, et je ne sais pas laquelle des trois cartes je regarde pour déterminer que c'est un chat, donc je dois le rendre visible. Je pensais que ce ne serait pas le cas. De plus, cette fois, j'ai regardé le dernier calque activé, mais si vous regardez un autre calque, il peut changer de différentes manières. Je ne sais pas comment traiter la valeur de la carte acquise, donc je pense qu'il existe un meilleur moyen.

J'ai écrit un article comme celui-ci pour la première fois et j'espère qu'il sera utile pour les mêmes débutants.

Recommended Posts

Jetons un coup d'œil à la carte des fonctionnalités de YOLO v3
Jetons un coup d'œil à l'incendie de forêt sur la côte ouest des États-Unis avec des images satellites.
Jetez un œil au traitement de LightGBM Tuner
Jetons un coup d'œil au code Scapy. Comment traitez-vous la structure?
Regardez de plus près le tutoriel Kaggle / Titanic
Jetons un coup d'œil au code Scapy. Surcharge des méthodes spéciales __div__, __getitem__.
Jetez un œil à l'arborescence des exceptions intégrée à Python
Jetez un œil au modèle Django.
Challenge classification des images par TensorFlow2 + Keras 2 ~ Regardons de plus près les données d'entrée ~
Jetez un œil à l'arborescence des exceptions intégrée dans Python 3.8.2
Jetons un coup d'œil à la tendance infectieuse du nouveau coronavirus COVID-19 dans chaque pays et à l'état de la réponse médicale (informations supplémentaires).
[GoLang] Définissez un espace au début du commentaire
Prenez des captures d'écran LCD avec Python-LEGO Mindstorms
Regardons le diagramme de dispersion avant l'analyse des données
Regardez le score de Go d'un joueur de Go professionnel
J'ai jeté un œil au contenu de sklearn (scikit-learn) (1) ~ Qu'en est-il de l'implémentation de CountVectorizer? ~
Tâches au démarrage d'un nouveau projet python
Jetez un œil au profilage et au vidage avec Dataflow
Jetons un coup d'œil à CornerNet, un détecteur d'objets qui n'utilise pas d'ancres.
Obtenez UNIXTIME au début d'aujourd'hui avec une commande
Un aperçu rapide de votre profil dans l'appli django
Résumé de l'exploration d'image effectuée à la vitesse d'une seconde
Faisons une carte du nouveau site d'infection corona [FastAPI / PostGIS / deck.gl (React)] (Traitement des données)
Lors de l'apprentissage d'un langage de programmation, il est judicieux de regarder d'abord le diagramme de famille du langage de programmation.
Comment obtenir les coordonnées de sommet d'une entité dans ArcPy
Prenez le journal d'exécution du céleri
Affichons la carte en utilisant Basemap
L'histoire de l'exportation d'un programme
Décidons le gagnant du bingo
Quel est le fichier XX à la racine d'un projet Python populaire?
Comment mettre un numéro de ligne au début d'un fichier CSV
Obtenez une instance datetime à tout moment de la journée en Python
Résumez le titre de Hottentori dans Hateb et regardez le présent du Web