[PYTHON] Werfen wir einen Blick auf die Feature-Map von YOLO v3

Ich möchte die Feature-Map von YOLO v3 sehen

Ich denke, dass die Visualisierung der Urteilsgrundlage oft als neuer Trend angesehen wird. Ich habe an der Universität mit Python angefangen und da ich mich ein wenig mit yolov3 beschäftige, wünschte ich mir, ich könnte die Feature-Map visualisieren. Da ich ein Anfänger bin, bin ich mit dem Programm nicht vertraut oder habe keinen grundlegenden Schreibstil. Seien Sie also bitte freundlich zu mir. Hier ist der Code von yolov3, mit dem ich mich jetzt beschäftige Github : "qqwweee/keras-yolo3" Ist der Code von. Ich möchte ein wenig mit diesem Code spielen, um die Feature-Map zu visualisieren.

Wo ich es vermasselt habe

yolov3 scheint drei auszugeben, klein, mittel und groß, also habe ich drei herausgenommen. Die Teile, mit denen ich in yolo.py herumgespielt habe, sind der erste Init, der letzte Teil von generate und detect_image. Bitte schauen Sie sich die Kommentare an.

    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()
 #Feature_get erhöht.
        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)
 # Fügen Sie Folgendes hinzu. Entscheiden Sie sich für 3 Ebenen, für die Sie eine Feature-Map erhalten möchten
 Ich habe mir #summary und die Aktivierungsschicht kurz vor der Ausgabe angesehen.
        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.

 #Feature_get um eins erhöht
        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

Schreiben Sie nun den Code, um die Feature-Map zu erhalten Wenn Sie es so ausgeben, wie es ist, wird es viel herauskommen. Daher werde ich vorerst versuchen, die Karte mit dem höchsten Durchschnittswert für klein, mittel und groß zu extrahieren.

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): 
 #Ich möchte die Karte mit dem höchsten Durchschnittswert erhalten.
	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

Schließlich habe ich mich mit yolo_video.py angelegt.

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)
 # Feature-Map anzeigen Führen Sie die folgenden Schritte aus.
            img_feature = feature_img.feature(feature_get)
            cv2.imwrite("feature_map.png " , img_feature)
            r_image.show()
    yolo.close_session()

Jetzt sollten Sie eine Feature-Map erhalten, indem Sie yolo_video.py --image ausführen.

Ausführungsbeispiel

Dieses Mal habe ich mir eine Katze von Pakutaso ausgeliehen, ein kostenloses Material, also werde ich versuchen, es zu entdecken. Das Gewicht verwendete übrigens das Standard-yolo.h5 ↓ Es ist eine erkannte Katze

ccccc.png

Die Feature-Map sieht folgendermaßen aus

feature_map.png

Ich bin mir nicht sicher. Es sieht so aus, als wären die Augen und der Mund der Katze charakteristisch. Übrigens wird die Größe der Katze im Eingabebild geändert, indem sie auf das graue Bild 416 x 416 eingefügt wird, wobei die Breite beim Einfügen in das Netzwerk angepasst wird. Die Feature-Map wird an ihre Größe angepasst. Ist yolov3 auf Gitterzellen zentriert? Ich weiß nicht, wo ich in die Mitte schaue, und ich weiß nicht, auf welche der drei Karten ich schaue, um festzustellen, dass es sich um eine Katze handelt, also muss ich sie sichtbar machen. Ich dachte es wäre nicht so. Auch dieses Mal habe ich mir die zuletzt aktivierte Ebene angesehen, aber wenn Sie sich eine andere Ebene ansehen, kann sich dies auf verschiedene Arten ändern. Ich weiß nicht, wie ich den erfassten Kartenwert verarbeiten soll, daher denke ich, dass es einen besseren Weg gibt.

Ich habe zum ersten Mal einen Artikel wie diesen geschrieben und hoffe, dass er für dieselben Anfänger hilfreich sein wird.

Recommended Posts

Werfen wir einen Blick auf die Feature-Map von YOLO v3
Schauen wir uns den Waldbrand an der Westküste der USA mit Satellitenbildern an.
Werfen Sie einen Blick auf die Verarbeitung von LightGBM Tuner
Werfen wir einen Blick auf den Scapy-Code. Wie bearbeiten Sie die Struktur?
Schauen Sie sich das Kaggle / Titanic-Tutorial genauer an
Werfen wir einen Blick auf den Scapy-Code. Überladung spezieller Methoden __div__, __getitem__.
Sehen Sie sich die in Python integrierte Ausnahmebaumstruktur an
Schauen Sie sich die Django-Vorlage an.
Fordern Sie die Bildklassifizierung mit TensorFlow2 + Keras 2 heraus ~ Schauen wir uns die Eingabedaten genauer an ~
Sehen Sie sich die in Python 3.8.2 integrierte Ausnahmebaumstruktur an
Werfen wir einen Blick auf die Infektionstendenz des neuen Coronavirus COVID-19 in jedem Land und den Status der medizinischen Reaktion (zusätzliche Informationen).
[GoLang] Setzen Sie am Anfang des Kommentars ein Leerzeichen
Machen Sie LCD-Screenshots mit Python-LEGO Mindstorms
Schauen wir uns das Streudiagramm vor der Datenanalyse an
Schauen Sie sich die Go-Punktzahl eines professionellen Go-Spielers an
Ich habe mir den Inhalt von sklearn (scikit-learn) angesehen. (1) ~ Was ist mit der Implementierung von CountVectorizer? ~
Aufgaben zu Beginn eines neuen Python-Projekts
Sehen Sie sich das Profiling und Dumping mit Dataflow an
Werfen wir einen kurzen Blick auf CornerNet, einen Objektdetektor, der keine Anker verwendet.
Holen Sie sich UNIXTIME zu Beginn des heutigen Tages mit einem Befehl
Ein kurzer Blick auf Ihr Profil in der Django-App
Zusammenfassung des mit einer Geschwindigkeit von einer Sekunde durchgeführten Bildcrawls
Machen wir eine Karte der neuen Korona-Infektionsstelle [FastAPI / PostGIS / deck.gl (React)] (Datenverarbeitung)
Wenn Sie eine Programmiersprache lernen, sollten Sie sich zunächst das Familiendiagramm der Programmiersprache ansehen.
So ermitteln Sie die Scheitelpunktkoordinaten eines Features in ArcPy
Nimm das Ausführungsprotokoll von Sellerie
Lassen Sie uns die Karte mit der Grundkarte anzeigen
Die Geschichte des Exportierens eines Programms
Lassen Sie uns den Gewinner des Bingo bestimmen
Was ist die XX-Datei im Stammverzeichnis eines beliebten Python-Projekts?
So setzen Sie eine Zeilennummer am Anfang einer CSV-Datei
Holen Sie sich zu jeder Tageszeit eine Datums- / Uhrzeitinstanz in Python
Fassen Sie den Titel von Hottentori in Hateb zusammen und schauen Sie sich die Gegenwart des Web an