[PYTHON] QR-Code mit CNN entschlüsseln

Einführung

CNNs, die Faltung verwenden, sind relativ gut darin, Merkmale in zweidimensionalen Schwarzweißbildern zu extrahieren. Ein Schwarzweißbild ist ein QR-Code. Lassen Sie uns also sehen, ob der Wert dieses QR-Codes von CNN gelesen werden kann. Eigentlich kann welches Bit in Schwarzweiß welcher Wert auf Regelbasis gelesen werden, und NN ohne Faltung ist ausreichend, aber hier wage ich es, CNN zu verwenden.

Dies und das des QR-Codes

Die QR-Code-Version hängt von der Größe des QR-Codes und der Anzahl der darin enthaltenen Zeichen ab. Zum Beispiel ist Version = 1 21x21 groß und kann "www.wikipedia.org" und eine 17-stellige Zeichenfolge enthalten, wie unten gezeigt. Da es sich bei E1 bis E7 um Fehlerkorrekturen handelt, ist das Lesen nicht unbedingt erforderlich. Mit anderen Worten, in diesem Fall besteht jedes Zeichen aus 8 Bit. Wenn Sie also den Wert von insgesamt 136 Bit überprüfen, können Sie lesen, was in dieser Größe geschrieben ist, auch auf der Regelbasis. Derzeit besteht der Zweck darin, die auf diesem Mindest-QR-Code 21x21 geschriebenen Zahlen zu lesen. 1280px-QR_Character_Placement.svg.png

Code

Ich habe folgendes in Keras geschrieben. Ich habe die 6-stellige Zahl in eine Zeichenkette umgewandelt und 40.000 QR-Codes mit der kleinsten Größe erstellt, die als Trainings- und Testdaten verwendet werden können. Wenn es sich um das ursprüngliche CNN handelt, kann es auch erforderlich sein, Pooling zu verwenden, um die Bildgröße zu halbieren. In diesem Fall beträgt die Eingabegröße jedoch nur 21 × 21, sodass conv2d allein den Faltungsteil darstellt.

qr.py


import qrcode
import numpy as np
import random
from keras.utils import np_utils
from keras.layers import Input, Conv2D, MaxPooling2D, AveragePooling2D, BatchNormalization, Concatenate
from keras.models import Model

batch_size = 128
num_classes = 10
epochs = 30

X, Y = [], []
sample_list = random.sample(range(10**6), k=40000)
for i in sample_list:
    qr = qrcode.QRCode(
        version=1,
        error_correction=qrcode.constants.ERROR_CORRECT_H,
        box_size=1, border=0 )

    qr.add_data('%06d' % (i))
    qr.make()
    img = qr.make_image()
    X.append(np.asarray(img))
    Y.append([int(d) for d in format(i, '06d')])

X = np.reshape(np.asarray(X),(-1,21,21,1))/1.0
Y = np.reshape(np_utils.to_categorical(np.asarray(Y)), (-1,1,6,10))
print(X.shape)
print(Y.shape)


inputs = Input((21,21,1))
x = Conv2D(256, (3,3), padding='same', activation='relu')(inputs)
x = BatchNormalization()(x)
x = Conv2D(256, (3,3), padding='same', activation='relu')(x)
x = BatchNormalization()(x)
x = Conv2D(256, (3,3), padding='same', activation='relu')(x)
x = BatchNormalization()(x)
x = Conv2D(256, (3,3), padding='same', activation='relu')(x)
x = BatchNormalization()(x)
x = Conv2D(256, (3,3), padding='same', activation='relu')(x)
x = BatchNormalization()(x)
x = Conv2D(512, (3,3), padding='same', activation='relu')(x)
x = BatchNormalization()(x)
x = Conv2D(512, (3,3), padding='same', activation='relu')(x)
x = MaxPooling2D(pool_size=(21, 21))(x)
y = [Conv2D(10, (1,1), activation='softmax')(x) for i in range(6)]
y = Concatenate(axis=-2)(y)

model = Model(inputs=inputs, outputs=y)
model.summary()
model.compile(loss='categorical_crossentropy',
              optimizer='Adam',
              metrics=['accuracy'])
history = model.fit(X[:30000], Y[:30000], batch_size=batch_size, epochs=epochs, verbose=1, validation_data=(X[30000:], Y[30000:]))

model.save('qr_model.h5', include_optimizer=False)

Hier

qr.py


y = [Conv2D(10, (1,1), activation='softmax')(x) for i in range(6)]
y = Concatenate(axis=-2)(y)

Sie können den Teil wie folgt schreiben.

qr.py


y1 = Conv2D(10, (1,1), activation='softmax')(x)
y2 = Conv2D(10, (1,1), activation='softmax')(x)
y3 = Conv2D(10, (1,1), activation='softmax')(x)
y4 = Conv2D(10, (1,1), activation='softmax')(x)
y5 = Conv2D(10, (1,1), activation='softmax')(x)
y6 = Conv2D(10, (1,1), activation='softmax')(x)
y = Concatenate(axis=-2)([y1,y2,y3,y4,y5,y6])

Das Ergebnis der Codeausführung ist zu diesem Zeitpunkt wie folgt.

(40000, 21, 21, 1)
(40000, 1, 6, 10)
...
__________________________________________________________________________________________________
Layer (type)                    Output Shape         Param #     Connected to
==================================================================================================
input_1 (InputLayer)            (None, 21, 21, 1)    0
__________________________________________________________________________________________________
conv2d_1 (Conv2D)               (None, 21, 21, 256)  2560        input_1[0][0]
__________________________________________________________________________________________________
batch_normalization_1 (BatchNor (None, 21, 21, 256)  1024        conv2d_1[0][0]
__________________________________________________________________________________________________
conv2d_2 (Conv2D)               (None, 21, 21, 256)  590080      batch_normalization_1[0][0]
__________________________________________________________________________________________________
batch_normalization_2 (BatchNor (None, 21, 21, 256)  1024        conv2d_2[0][0]
__________________________________________________________________________________________________
conv2d_3 (Conv2D)               (None, 21, 21, 256)  590080      batch_normalization_2[0][0]
__________________________________________________________________________________________________
batch_normalization_3 (BatchNor (None, 21, 21, 256)  1024        conv2d_3[0][0]
__________________________________________________________________________________________________
conv2d_4 (Conv2D)               (None, 21, 21, 256)  590080      batch_normalization_3[0][0]
__________________________________________________________________________________________________
batch_normalization_4 (BatchNor (None, 21, 21, 256)  1024        conv2d_4[0][0]
__________________________________________________________________________________________________
conv2d_5 (Conv2D)               (None, 21, 21, 256)  590080      batch_normalization_4[0][0]
__________________________________________________________________________________________________
batch_normalization_5 (BatchNor (None, 21, 21, 256)  1024        conv2d_5[0][0]
__________________________________________________________________________________________________
conv2d_6 (Conv2D)               (None, 21, 21, 512)  1180160     batch_normalization_5[0][0]
__________________________________________________________________________________________________
batch_normalization_6 (BatchNor (None, 21, 21, 512)  2048        conv2d_6[0][0]
__________________________________________________________________________________________________
conv2d_7 (Conv2D)               (None, 21, 21, 512)  2359808     batch_normalization_6[0][0]
__________________________________________________________________________________________________
max_pooling2d_1 (MaxPooling2D)  (None, 1, 1, 512)    0           conv2d_7[0][0]
__________________________________________________________________________________________________
conv2d_8 (Conv2D)               (None, 1, 1, 10)     5130        max_pooling2d_1[0][0]
__________________________________________________________________________________________________
conv2d_9 (Conv2D)               (None, 1, 1, 10)     5130        max_pooling2d_1[0][0]
__________________________________________________________________________________________________
conv2d_10 (Conv2D)              (None, 1, 1, 10)     5130        max_pooling2d_1[0][0]
__________________________________________________________________________________________________
conv2d_11 (Conv2D)              (None, 1, 1, 10)     5130        max_pooling2d_1[0][0]
__________________________________________________________________________________________________
conv2d_12 (Conv2D)              (None, 1, 1, 10)     5130        max_pooling2d_1[0][0]
__________________________________________________________________________________________________
conv2d_13 (Conv2D)              (None, 1, 1, 10)     5130        max_pooling2d_1[0][0]
__________________________________________________________________________________________________
concatenate_1 (Concatenate)     (None, 1, 6, 10)     0           conv2d_8[0][0]
                                                                 conv2d_9[0][0]
                                                                 conv2d_10[0][0]
                                                                 conv2d_11[0][0]
                                                                 conv2d_12[0][0]
                                                                 conv2d_13[0][0]
==================================================================================================
Total params: 5,940,796
Trainable params: 5,937,212
Non-trainable params: 3,584
__________________________________________________________________________________________________
Train on 30000 samples, validate on 10000 samples
Epoch 1/30
30000/30000 [==============================] - 66s 2ms/step - loss: 2.7801 - acc: 0.1714 - val_loss: 2.3467 - val_acc: 0.2484
Epoch 2/30
30000/30000 [==============================] - 62s 2ms/step - loss: 1.8426 - acc: 0.3493 - val_loss: 1.6885 - val_acc: 0.3941
Epoch 3/30
30000/30000 [==============================] - 64s 2ms/step - loss: 1.4841 - acc: 0.4555 - val_loss: 1.4549 - val_acc: 0.4547
...
Epoch 28/30
30000/30000 [==============================] - 64s 2ms/step - loss: 0.0401 - acc: 0.9868 - val_loss: 0.3695 - val_acc: 0.9110
Epoch 29/30
30000/30000 [==============================] - 64s 2ms/step - loss: 0.0435 - acc: 0.9853 - val_loss: 0.3403 - val_acc: 0.9184
Epoch 30/30
30000/30000 [==============================] - 63s 2ms/step - loss: 0.0339 - acc: 0.9889 - val_loss: 0.3164 - val_acc: 0.9231

Die endgültige Genauigkeit beträgt ** acc: 0,9889, val_acc: 0,9231 **. Die Epoche und das Modell sind geeignet, daher verbessert eine Anpassung die Genauigkeit ein wenig mehr.

Prüfung

Schreiben Sie Folgendes als Bestätigungscode. Das Ergebnis ist eine relativ kleine, eingeschränkte Bedingung von 21 x 21 mit Version = 1 des QR-Codes, aber ich konnte bis zu einem gewissen Grad eine 6-stellige Zahl vorhersagen.

qr2.py


import qrcode
import numpy as np
import random
from keras.models import load_model

X, Y = [], []
sample_list = random.sample(range(10**6), k=10)
for i in sample_list:
    qr = qrcode.QRCode(
        version=1,
        error_correction=qrcode.constants.ERROR_CORRECT_H,
        box_size=1, border=0 )

    qr.add_data('%06d' % (i))
    qr.make()
    img = qr.make_image()
    X.append(np.asarray(img))
    Y.append(i)

X = np.reshape(np.asarray(X),(-1,21,21,1))/1.0
model = load_model('qr_model.h5')

Y_pred = model.predict(X)

Y_pred_list = []
for i in range(10):
    Y_pred_value = 0
    for j in range(6):
        Y_pred_value += np.argmax(Y_pred[i,0,j])
        Y_pred_value *= 10
    Y_pred_list.append(Y_pred_value//10)
print(Y)
print(Y_pred_list)
[89127, 306184, 427806, 501649, 727976, 232504, 427216, 893062, 127368, 100207]
[89127, 306184, 427806, 501649, 727976, 234506, 431222, 893062, 127378, 100207]

Standortmerkmale

Im Allgemeinen weiß MaxPooling2D, ob das Bild eine Funktion enthält, erreicht diese Position jedoch in nachfolgenden Ebenen nicht. Apropos CNN, es wird häufig für Klassifizierungsprobleme verwendet, z. B. wenn Hunde und Katzen irgendwo im Bild enthalten sind. Andererseits dachte ich, dass es möglich ist, Merkmale (ohne Verwendung von Abflachung) zu extrahieren, um den Ort anzugeben, aber es ist möglich Und es scheint. Dies kann daran liegen, dass die Merkmalsmenge des Datenorts durch den Datenwert in der Kurzstreckenfaltung und den Abstand vom quadratischen festen Muster oben links, oben rechts und unten links in der Fernfaltung extrahiert wird. Wenn Sie nur den Datenwert lesen (8 Bit von 2,4 oder 4,2), sollte Conv2d mit 2 Schichten (entspricht 5,5) ausreichen, aber in Wirklichkeit ist die Genauigkeit beim Modell mit Conv2d mit 2 Schichten nicht so hoch Es war (val_acc: ungefähr 0,5). Wenn Sie den QR-Code mit CNN lesen, kann es daher erforderlich sein, die Merkmalsmenge des Ortes durch Falten über große Entfernungen zu extrahieren. (Oder vielleicht ist es besser, Flatten schnell als Modell zu verwenden ...)

Recommended Posts

QR-Code mit CNN entschlüsseln
Überprüfen Sie den Code mit flake8
QR-Code-Anzeige
Zeigen Sie den QR-Code schnell in der Befehlszeile an
Konvertieren Sie den Zeichencode der Datei mit Python3
Mit Codetest stärken ⑦
Mit Codetest stärken ⑨
Excel versuchte, QR-Code mit schwarzer Magie zu beschwören
Erstellen Sie unter Linux einen QR-Code für die URL
Mit Codetest stärken ⑤
Mit Codetest stärken ④
Lesen Sie den QR-Code aus der Bilddatei mit Python (Mac).
Mit Codetest stärken ②
Vorschau der QR-Code-Kamera
Summencode mit Numpy
Mit Codetest stärken ①
Zeigen Sie Matsuyas Gutschein (QR-Code) mit Pythonista für iOS an
Mit Codetest stärken ⑧
Mit Codetest stärken ⑨
CNN mit Keras Versuchen Sie es mit dem Bild, das Sie aufgenommen haben
Ich habe den Code für die japanische Satzgenerierung mit DeZero geschrieben
Genießen Sie das Gray-Scott-Modell mit Kurzcode mithilfe der Matrixberechnung
Einstellungen zum Eingeben und Debuggen des Inhalts der Bibliothek mit VS-Code
Die Geschichte, dass Python nicht mehr mit VS Code (Windows 10) arbeitet
Laden Sie den mit Gunicorn eingerichteten Server neu, wenn Sie den Code ändern
Systemhandel ab Python3: Holen Sie sich den neuesten Programmcode
Versuchen Sie, Merkmale von Sensordaten mit CNN zu extrahieren
Holen Sie sich den Ländercode mit Python
CNN-Implementierung mit nur Numpy
Setzen Sie den Debugger mit der Nase ein
Töte den Prozess mit sudo kill -9
Befehl zum Generieren von QR-Code
Versuchen Sie, CNN mit ChainerRL auszuführen
Erläutern Sie den Code von Tensorflow_in_ROS
Debuggen Sie Python mit VS-Code
Errate das Passwort mit klee
gethostbyaddr () kommuniziert mit der Außenwelt
Erstellen Sie einfach CNNs mit Keras
Verwenden Sie Maxout + CNN mit Pylearn2
Generieren Sie QR-Code in Python
Schaben Nikkei Durchschnitt mit Dramatiker-Python
Kalibrieren Sie das Modell mit PyCaret
Überlebe Weihnachten mit CNN auf Charakterebene
Rufen Sie die API mit python3 auf.
Dokumentieren Sie Python-Code mit Doxygen
Holen Sie sich die stärkste Umgebung mit VS Code, Remote-Containern und Remote-Docker-Daemon
Überprüfen Sie die Antwort des HTTP-Statuscodes mit dem Befehl curl (#Linux #Shell).
Überprüfen Sie den Speicherschutz von Linux Kern mit Code für ARM
Fassen wir den Grad der Kopplung zwischen Modulen mit Python-Code zusammen