In diesem Material wird vorgeschlagen, mit ein wenig Aufwand Python 3.7 + Kolben + Tensorflow 2.0 + Keras + kleine Einschlüsse von js zu verbinden und eine bestimmte Interaktivität auf der Webseite anzuzeigen. Der Benutzer, der auf der Leinwand zeichnet, sendet Zahlen zur Erkennung, und das zuvor trainierte Modell, das die CNN-Architektur verwendet, erkennt die resultierende Zeichnung und gibt das Ergebnis aus. Das Modell wird auf dem bekannten Satz handgeschriebener Ziffern MNIST trainiert, daher erkennt es nur Ziffern von 0 bis einschließlich 9. Windows 7 wird als das System verwendet, auf dem sich all dies dreht.
Kleine Einführung
Das Traurige an Büchern zum maschinellen Lernen ist, dass der Code fast veraltet ist, sobald das Buch selbst veröffentlicht wird. Und es ist gut, wenn der Autor der Veröffentlichung sein Kind unterstützt, den Code pflegt und aktualisiert, aber oft beschränkt sich alles auf das, was sie schreiben - hier ist die Anforderung.txt, installieren Sie veraltete Pakete und alles wird funktionieren.
Diesmal ist es auch passiert. Beim Lesen von Python Deep Learning für das Web zum Anfassen von Anubhav Singh, Sayak Paul, lief zunächst alles gut. Nach dem ersten Kapitel war der Urlaub jedoch vorbei. Das Unangenehmste war, dass die in den Anforderungen angegebenen Anforderungen im Allgemeinen eingehalten wurden.
Die Entwickler der Tensorflow- und Keras-Pakete selbst fügten dem Feuer Treibstoff hinzu. Ein Paket funktioniert nur mit einem bestimmten anderen und entweder mit einem Downgrade eines von ihnen oder mit einem Schamanen-Tamburin.
Aber das ist nicht alles. Es stellt sich heraus, dass einige Pakete auch architekturabhängig sind!
Da es keine Alternative zu Eisen gab, wurde Tensorflow 2.0 auf einer Plattform mit Celeron j1900 installiert, und wie sich herausstellte, gibt es dort keine AVX2-Anweisung:
Und die Option über Pip Install Tensorflow funktionierte nicht.
Aber nicht alles ist so traurig mit dem Wunsch und dem Internet!
Die Variante mit Tensorflow 2.0 wurde über das Rad implementiert - github.com/fo40225/tensorflow-windows-wheel/tree/master/2.0.0/py37/CPU/sse2 und x86 Installation: vc_redist.x86.exe, x64: vc_redist.x64 . exe (https://support.microsoft.com/en-us/help/2977003/the-latest-supported-visual-c-downloads).
Keras wurde mit der Mindestversion installiert, mit der es mit Tensorflow "kompatibel" wurde - Keras == 2.3.0.
deshalb
pip install tensorflow-2.0.0-cp37-cp37m-win_amd64.whl
und
pip install keras==2.3.0
Hauptanwendung
Betrachten wir den Code des Hauptprogramms.
flask_app.py
#code work with scipy==1.6.1, tensorflow @ file:///D:/python64/tensorflow-2.0.0-cp37-cp37m-win_amd64.whl,
#Keras==2.3.0
from flask import Flask, render_template, request
import imageio
#https://imageio.readthedocs.io/en/stable/examples.html
#from scipy.misc import imread, imresize
#from matplotlib.pyplot import imread
import numpy as np
import tensorflow as tf
from tensorflow.keras.models import model_from_json
from skimage import transform,io
json_file = open('model.json','r')
model_json = json_file.read()
json_file.close()
model = model_from_json(model_json)
model.load_weights("weights.h5")
model.compile(loss='categorical_crossentropy',optimizer='adam',metrics=['accuracy'])
#graph = tf.get_default_graph()
graph = tf.compat.v1.get_default_graph()
app = Flask(__name__)
@app.route('/')
def index():
return render_template("index.html")
import re
import base64
def convertImage(imgData1):
imgstr = re.search(r'base64,(.*)', str(imgData1)).group(1)
with open('output.png', 'wb') as output:
output.write(base64.b64decode(imgstr))
@app.route('/predict/', methods=['GET', 'POST'])
def predict():
global model, graph
imgData = request.get_data()
convertImage(imgData)
#print(imgData)
#x = imread('output.png', mode='L')
#x.shape
#(280, 280)
x = imageio.imread('output.png',pilmode='L')
#x = imresize(x, (28, 28))
#x = x.resize(x, (28, 28))
x = transform.resize(x, (28,28), mode='symmetric', preserve_range=True)
#(28, 28)
#type(x)
#<class 'numpy.ndarray'>
x = x.reshape(1, 28, 28, 1)
#(1, 28, 28, 1)
x = tf.cast(x, tf.float32)
# perform the prediction
out = model.predict(x)
#print(np.argmax(out, axis=1))
# convert the response to a string
response = np.argmax(out, axis=1)
return str(response[0])
if __name__ == "__main__":
# run the app locally on the given port
app.run(host='0.0.0.0', port=80)
# optional if we want to run in debugging mode
app.run(debug=True)
Hochgeladene Pakete:
from flask import Flask, render_template, request
import imageio
#https://imageio.readthedocs.io/en/stable/examples.html
#from scipy.misc import imread, imresize
#from matplotlib.pyplot import imread
import numpy as np
import tensorflow as tf
from tensorflow.keras.models import model_from_json
from skimage import transform,io
Wie imread herausgefunden hat, ist imresize seit scipy == 1.0 veraltet. Es ist unklar, wie alles für den Autor funktioniert hat, da das Buch relativ neu ist (2019). Mit modernem scipy == 1.6.1 funktionierte die Buchversion des Codes nicht.
Wir laden von der Festplatte, kompilieren das neuronale Netzwerkmodell:
json_file = open('model.json','r')
model_json = json_file.read()
json_file.close()
model = model_from_json(model_json)
model.load_weights("weights.h5")
model.compile(loss='categorical_crossentropy',optimizer='adam',metrics=['accuracy'])
#graph = tf.get_default_graph()
graph = tf.compat.v1.get_default_graph()
Hier haben wir es aufgrund von Inkompatibilität durch tf.compat.v1.get_default_graph () ersetzt.
Als nächstes kommt der Kolbenserverteil. "Zeichnen" der Seitenvorlage:
@app.route('/')
def index():
return render_template("index.html")
Der Teil, der das Bild in ein numerisches Array konvertiert:
import re
import base64
def convertImage(imgData1):
imgstr = re.search(r'base64,(.*)', str(imgData1)).group(1)
with open('output.png', 'wb') as output:
output.write(base64.b64decode(imgstr))
Hauptvorhersagefunktion:
def predict():
global model, graph
imgData = request.get_data()
convertImage(imgData)
#print(imgData)
#x = imread('output.png', mode='L')
#x.shape
#(280, 280)
x = imageio.imread('output.png',pilmode='L')
#x = imresize(x, (28, 28))
#x = x.resize(x, (28, 28))
x = transform.resize(x, (28,28), mode='symmetric', preserve_range=True)
#(28, 28)
#type(x)
#<class 'numpy.ndarray'>
x = x.reshape(1, 28, 28, 1)
#(1, 28, 28, 1)
x = tf.cast(x, tf.float32)
# perform the prediction
out = model.predict(x)
#print(np.argmax(out, axis=1))
# convert the response to a string
response = np.argmax(out, axis=1)
return str(response[0])
Die Zeilen wurden auskommentiert und durch funktionierende ersetzt, und die Schlussfolgerungen der einzelnen Zeilen wurden ebenfalls der Klarheit halber belassen.
Wie es funktioniert
Nach dem Start mit dem Befehl python flask_app.py wird der lokale Flask- Server gestartet, der index.html mit js durchsetzt anzeigt.
Der Benutzer zeichnet eine Zahl auf die Leinwand und klickt auf "Vorhersagen". Das Bild "fliegt" zum Server, wo es gespeichert und in ein digitales Array umgewandelt wird. Als nächstes tritt CNN in den Kampf ein, erkennt die Ziffer und gibt die Antwort in Form einer Ziffer zurück.
Das Netzwerk gibt nicht immer die richtige Antwort, weil studierte nur für 10 Epochen. Dies kann beobachtet werden, wenn Sie eine "kontroverse" Figur zeichnen, die auf unterschiedliche Weise interpretiert werden kann.
* Sie können den Schieberegler drehen, um die Dicke des Umrisses der Zahl zu Erkennungszwecken zu erhöhen oder zu verringern.
Die zweite Version des Programms erfolgt über die API curl
Der Benutzer lädt sein Bild mit einer Nummer zur Erkennung auf den Server
hoch und klickt auf " Senden ": Ersetzen wir index.js durch Folgendes:
index.js:
$("form").submit(function(evt){
evt.preventDefault();
var formData = new FormData($(this)[0]);
$.ajax({
url: '/predict/',
type: 'POST',
data: formData,
async: false,
cache: false,
contentType: false,
enctype: 'multipart/form-data',
processData: false,
success: function (response) {
$('#result').empty().append(response);
}
});
return false;
});
Die Seitenvorlage ändert sich auch:
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<title>MNIST CNN</title>
</head>
<body>
<h1>MNIST Handwritten Digits Prediction</h1>
<form>
<input type="file" name="img"></input>
<input type="submit"></input>
</form>
<hr>
<h3>Prediction: <span id="result"></span></h3>
<script
src='https://code.jquery.com/jquery-3.6.0.min.js'></script>
<script src="{{ url_for('static',filename='index.js') }}"></script>
</body>
</html>
Das Hauptprogramm wird sich ebenfalls geringfügig ändern:
flask_app2.py
#code work with scipy==1.6.1, tensorflow @ file:///D:/python64/tensorflow-2.0.0-cp37-cp37m-win_amd64.whl,
#Keras==2.3.0
from flask import Flask, render_template, request
import imageio
#https://imageio.readthedocs.io/en/stable/examples.html
#from scipy.misc import imread, imresize
#from matplotlib.pyplot import imread
import numpy as np
import tensorflow as tf
from tensorflow.keras.models import model_from_json
from skimage import transform,io
json_file = open('model.json','r')
model_json = json_file.read()
json_file.close()
model = model_from_json(model_json)
model.load_weights("weights.h5")
model.compile(loss='categorical_crossentropy',optimizer='adam',metrics=['accuracy'])
#graph = tf.get_default_graph()
graph = tf.compat.v1.get_default_graph()
app = Flask(__name__)
@app.route('/')
def index():
return render_template("index.html")
import re
import base64
def convertImage(imgData1):
imgstr = re.search(r'base64,(.*)', str(imgData1)).group(1)
with open('output.png', 'wb') as output:
output.write(base64.b64decode(imgstr))
@app.route('/predict/', methods=['POST'])
def predict():
global model, graph
imgData = request.get_data()
try:
stringToImage(imgData)
except:
f = request.files['img']
f.save('image.png')
#x = imread('output.png', mode='L')
#x.shape
#(280, 280)
x = imageio.imread('image.png',pilmode='L')
#x = imresize(x, (28, 28))
#x = x.resize(x, (28, 28))
x = transform.resize(x, (28,28), mode='symmetric', preserve_range=True)
#(28, 28)
#type(x)
#<class 'numpy.ndarray'>
x = x.reshape(1, 28, 28, 1)
#(1, 28, 28, 1)
x = tf.cast(x, tf.float32)
# perform the prediction
out = model.predict(x)
#print(np.argmax(out, axis=1))
# convert the response to a string
response = np.argmax(out, axis=1)
return str(response[0])
if __name__ == "__main__":
# run the app locally on the given port
app.run(host='0.0.0.0', port=80)
# optional if we want to run in debugging mode
app.run(debug=True)
Alles beginnt ähnlich - python flask_app2.py
Curl-Option (für Fenster)
Download curl
Senden Sie in der Windows-Befehlszeile den folgenden Befehl:
curl -X POST -F img=@1.png http://localhost/predict/
Dabei ist 1.png ein Bild mit einer Nummer (oder mit einem Pfad dazu).
Eine erkannte Ziffer wird als Antwort eintreffen.
Dateien zum Herunterladen - herunterladen .