20210613のTensorFlowに関する記事は5件です。

30行未満の HTML+JavaScript でカスタムモデルを使った画像分類を試す(TFJS Task API を利用)【Google I/O 2021】

以下の記事でも取り扱っている「TFJS Task API」の話で、TensorFlow Lite用のモデルを JavaScript で簡単に呼び出して利用するというものです。  ●TensorFlow Lite のモデルを Web で扱えるという話についてのざっくりなメモ【Google I/O 2021】 - Qiita   https://qiita.com/youtoy/items/3963f7f2cee431eca835 上記の記事や以下の公式情報にも書かれていますが、「TFJS Task API」は記事執筆時点ではアルファ版です。  ●TensorFlow.js API   https://js.tensorflow.org/api_tasks/0.0.1-alpha.8/ なお、今回の HTML+JavaScript は、冒頭で紹介した Qiita の記事でも紹介している、以下の公式デモを元にしています。  ●TFJS Task API - Image Classification   https://codepen.io/jinjingforever/pen/VwPOePq ソースコードや実行結果など ソースコード HTML+JavaScript のソースコードは以下のとおりで、公式デモからカスタムモデルを使った処理以外の部分を除いて、さらにちょっとだけ書きかえたりなどしています。 <!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <title>TFJS Task API:カスタムモデルでの画像分類</title> </head> <body> <div class="container"> <img id="img" src="https://storage.googleapis.com/tfweb/demos/static/wine.jpeg" crossorigin="anonymous" width="400"> <button id="button">推論を実行</button> <div id="result"></div> </div> <script src='https://cdn.jsdelivr.net/npm/@tensorflow-models/tasks@0.0.1-alpha.8'></script> <script type="text/javascript"> document.getElementById('button').addEventListener('click', async () => { const model = await tfTask.ImageClassification.CustomModel.TFLite.load({ model: 'https://storage.googleapis.com/tfweb/models/mobilenet_v2_1.0_224_1_metadata_1.tflite', maxResults: 1, }); const result = await model.predict(document.getElementById('img')); const resultEle = document.getElementById('result'); resultEle.textContent = `${result.classes[0].className} (${result.classes[0].score.toFixed(3)}).`; }); </script> </body> </html> 推論の実行 上記の内容の html をブラウザ開くと、以下のようのページが表示されます。 ここでページ内の「推論を実行」ボタンを押してみます。 そうすると以下のように、ページ内の画像の下に機械学習の推論結果が表示されます。 推論結果として、「className がワインボトル、score が 0.833」という結果が得られました。 恐ろしいほど短い処理で、画像分類の推論が試せてしましました。 モデルの読み込みと推論に関わる部分 今回の全体のソースコードが短いのは、機械学習周りのソースコードがめちゃくちゃ短くてすむのが主な要因です。 まず、以下を読み込むのに 1行。 <script src='https://cdn.jsdelivr.net/npm/@tensorflow-models/tasks@0.0.1-alpha.8'></script> そして、モデルの読み込みの処理、その後のイメージタグの画像に対して推論を行うのに、以下の部分だけという短さです。 const model = await tfTask.ImageClassification.CustomModel.TFLite.load({ model: 'https://storage.googleapis.com/tfweb/models/mobilenet_v2_1.0_224_1_metadata_1.tflite', maxResults: 1, }); const result = await model.predict(document.getElementById('img')); おわりに 「TFJS Task API」は、元々は「TensorFlow Lite のモデルを Web で使える」という部分に対する興味で試したものでしたが、公式サンプルを削った内容を作ったら機械学習周りの部分の処理の短さにビックリでした。 以下のページで「Clean and powerful APIs」・「Simple installation」と謳っているだけはある! という感じでした。  ●@tensorflow-models/tasks - npm   https://www.npmjs.com/package/@tensorflow-models/tasks 【追記】その後のお試し その後、このようなことをやって記事にも書きました。 ●TensorFlow Hub の TensorFlow Lite用モデルを HTML+JavaScript から使って画像分類(TFJS Task API を利用) - Qiita  https://qiita.com/youtoy/items/f6482f6a57d593e9fd3e
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

lobeで出力したtfliteをラズパイに組み込む方法

はじめに lobeを使うと機械学習のモデルが簡単に作れます。 機械学習を組み込んだIoTが増えると楽しいと思うので、作成した学習モデルをラズパイ上で組み込む方法を記載します。参考にしていただけると幸いです。 手探りで動かしているので、もっといい方法があればコメントいただけるとありがたいです。 記事作成時のLobeのバージョンは「0.9.421.4」です。 学習モデルの作り方 lobeを起動して、NewProjectをクリックします。 NewProgectが立ち上がったら、Labelをクリックして、学習したいモデルを登録します。 私は子豚がいる画像といない画像を学習させたかったので、このような画像を5枚ずつ登録させました。 次に、UseをクリックしてExportをクリックすると、出力する学習モデルの形式を選択できるので、FeaturedのTensorFlowLiteをクリックして、学習モデルをExportします。 Exportしたファイルのフォルダ構成 Exportすると作成したプロジェクト名のフォルダが出来上がります。 中にはいろいろなファイルが入っていて、構成は以下のようになっています。 PigletModel_TFLete ├example │ ├README.md │ ├requirements.txt │ └tflite_example.py ├labels.txt ├saved_model.tflite  └signature.json ラズパイ上で学習モデルを実行させる方法と、実行結果 この学習モデルをラズパイで使用する場合、Exportしたファイル一式をラズパイ上に配置します。 ここでは、/home/pi/PigletModel_TFLiteというような形で配置しています。 配置後に、exampleの下でtflite_example.pyに画像ファイルを指定して実行すると、このようにラベルごとの信頼度を得ることができます。 (以下の場合、NoPigletの結果のほうが大きいので子豚はいないんだなと判断できます) pi@raspberrypi:~/PigletModel_TFLite/example $ python3 tflite_example.py XXXXX.jpg Predicted: {'predictions': [{'label': 'NoPiglet', 'confidence': 0.963566243648529}, {'label': 'piglet', 'confidence': 0.036433834582567215}]} pi@raspberrypi:~/PigletModel_TFLite/example $ 環境に合わせたパスの変更方法 一度実行してみるとわかると思うのですが、tflite_example.pyデフォルトのファイルパスが相対パスになっているので、tflite_example.pyを実行する場所によってはエラーになってしまいます。 なので、tflite_example.pyの中でファイルのパスを使う処理を行っている箇所を環境に合わせたパスに変える必要があります。 以下が変更例です。コメントに★ある2か所です。 # ------------------------------------------------------------- # Copyright (c) Microsoft Corporation. All rights reserved. # ------------------------------------------------------------- """ Skeleton code showing how to load and run the TensorFlow Lite export package from Lobe. """ import argparse import json import os import numpy as np from PIL import Image import tflite_runtime.interpreter as tflite EXPORT_MODEL_VERSION = 1 class TFLiteModel: def __init__(self, model_dir) -> None: """Method to get name of model file. Assumes model is in the parent directory for script.""" #with open(os.path.join(model_dir, "signature.json"), "r") as f: with open("/home/pi/PigletModel_TFLite/signature.json","r") as f: #★jsonファイルをフルパスで指定 self.signature = json.load(f) #self.model_file = "../" + self.signature.get("filename") self.model_file = "/home/pi/PigletModel_TFLite/saved_model.tflite" #★tfliteファイルをフルパスで指定 if not os.path.isfile(self.model_file): raise FileNotFoundError(f"Model file does not exist") self.interpreter = None self.signature_inputs = self.signature.get("inputs") self.signature_outputs = self.signature.get("outputs") # Look for the version in signature file. # If it's not found or the doesn't match expected, print a message version = self.signature.get("export_model_version") if version is None or version != EXPORT_MODEL_VERSION: print( f"There has been a change to the model format. Please use a model with a signature 'export_model_version' that matches {EXPORT_MODEL_VERSION}." ) def load(self) -> None: """Load the model from path to model file""" # Load TFLite model and allocate tensors. self.interpreter = tflite.Interpreter(model_path=self.model_file) self.interpreter.allocate_tensors() # Combine the information about the inputs and outputs from the signature.json file with the Interpreter runtime input_details = {detail.get("name"): detail for detail in self.interpreter.get_input_details()} self.model_inputs = {key: {**sig, **input_details.get(sig.get("name"))} for key, sig in self.signature_inputs.items()} output_details = {detail.get("name"): detail for detail in self.interpreter.get_output_details()} self.model_outputs = {key: {**sig, **output_details.get(sig.get("name"))} for key, sig in self.signature_outputs.items()} if "Image" not in self.model_inputs: raise ValueError("Tensorflow Lite model doesn't have 'Image' input! Check signature.json, and please report issue to Lobe.") def predict(self, image) -> dict: """ Predict with the TFLite interpreter! """ if self.interpreter is None: self.load() # process image to be compatible with the model input_data = self.process_image(image, self.model_inputs.get("Image").get("shape")) # set the input to run self.interpreter.set_tensor(self.model_inputs.get("Image").get("index"), input_data) self.interpreter.invoke() # grab our desired outputs from the interpreter! # un-batch since we ran an image with batch size of 1, and convert to normal python types with tolist() outputs = {key: self.interpreter.get_tensor(value.get("index")).tolist()[0] for key, value in self.model_outputs.items()} return self.process_output(outputs) def process_image(self, image, input_shape) -> np.ndarray: """ Given a PIL Image, center square crop and resize to fit the expected model input, and convert from [0,255] to [0,1] values. """ width, height = image.size # ensure image type is compatible with model and convert if not if image.mode != "RGB": image = image.convert("RGB") # center crop image (you can substitute any other method to make a square image, such as just resizing or padding edges with 0) if width != height: square_size = min(width, height) left = (width - square_size) / 2 top = (height - square_size) / 2 right = (width + square_size) / 2 bottom = (height + square_size) / 2 # Crop the center of the image image = image.crop((left, top, right, bottom)) # now the image is square, resize it to be the right shape for the model input input_width, input_height = input_shape[1:3] if image.width != input_width or image.height != input_height: image = image.resize((input_width, input_height)) # make 0-1 float instead of 0-255 int (that PIL Image loads by default) image = np.asarray(image) / 255.0 # format input as model expects return image.reshape(input_shape).astype(np.float32) def process_output(self, outputs) -> dict: # postprocessing! convert any byte strings to normal strings with .decode() out_keys = ["label", "confidence"] for key, val in outputs.items(): if isinstance(val, bytes): outputs[key] = val.decode() # get list of confidences from prediction confs = list(outputs.values())[0] labels = self.signature.get("classes").get("Label") output = [dict(zip(out_keys, group)) for group in zip(labels, confs)] sorted_output = {"predictions": sorted(output, key=lambda k: k["confidence"], reverse=True)} return sorted_output if __name__ == "__main__": parser = argparse.ArgumentParser(description="Predict a label for an image.") parser.add_argument("image", help="Path to your image file.") args = parser.parse_args() # Assume model is in the parent directory for this file model_dir = os.path.join(os.getcwd(), "..") if os.path.isfile(args.image): image = Image.open(args.image) model = TFLiteModel(model_dir) model.load() outputs = model.predict(image) print(f"Predicted: {outputs}") else: print(f"Couldn't find image file {args.image}")
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Lobeで出力したtfliteをラズパイに組み込む方法

はじめに Lobeを使うと機械学習のモデルが簡単に作れます。 機械学習を組み込んだIoTが増えると楽しいと思うので、作成した学習モデルをラズパイ上で組み込む方法を記載します。参考にしていただけると幸いです。 手探りで動かしているので、もっといい方法があればコメントいただけるとありがたいです。 記事作成時のLobeのバージョンは「0.9.421.4」です。 学習モデルの作り方 lobeを起動して、NewProjectをクリックします。 NewProgectが立ち上がったら、Labelをクリックして、学習したいモデルを登録します。 私は子豚がいる画像といない画像を学習させたかったので、このような画像を5枚ずつ登録させました。 次に、UseをクリックしてExportをクリックすると、出力する学習モデルの形式を選択できるので、FeaturedのTensorFlowLiteをクリックして、学習モデルをExportします。 Exportしたファイルのフォルダ構成 Exportすると作成したプロジェクト名のフォルダが出来上がります。 中にはいろいろなファイルが入っていて、構成は以下のようになっています。 PigletModel_TFLete ├example │ ├README.md │ ├requirements.txt │ └tflite_example.py ├labels.txt ├saved_model.tflite  └signature.json ラズパイ上で学習モデルを実行させる方法と、実行結果 この学習モデルをラズパイで使用する場合、Exportしたファイル一式をラズパイ上に配置します。 ここでは、/home/pi/PigletModel_TFLiteというような形で配置しています。 配置後に、exampleの下でtflite_example.pyに画像ファイルを指定して実行すると、このようにラベルごとの信頼度を得ることができます。 (以下の場合、NoPigletの結果のほうが大きいので子豚はいないんだなと判断できます) pi@raspberrypi:~/PigletModel_TFLite/example $ python3 tflite_example.py XXXXX.jpg Predicted: {'predictions': [{'label': 'NoPiglet', 'confidence': 0.963566243648529}, {'label': 'piglet', 'confidence': 0.036433834582567215}]} pi@raspberrypi:~/PigletModel_TFLite/example $ 環境に合わせたパスの変更方法 一度実行してみるとわかると思うのですが、tflite_example.pyデフォルトのファイルパスが相対パスになっているので、tflite_example.pyを実行する場所によってはエラーになってしまいます。 なので、tflite_example.pyの中でファイルのパスを使う処理を行っている箇所を環境に合わせたパスに変える必要があります。 以下が変更例です。コメントに★ある2か所です。 # ------------------------------------------------------------- # Copyright (c) Microsoft Corporation. All rights reserved. # ------------------------------------------------------------- """ Skeleton code showing how to load and run the TensorFlow Lite export package from Lobe. """ import argparse import json import os import numpy as np from PIL import Image import tflite_runtime.interpreter as tflite EXPORT_MODEL_VERSION = 1 class TFLiteModel: def __init__(self, model_dir) -> None: """Method to get name of model file. Assumes model is in the parent directory for script.""" #with open(os.path.join(model_dir, "signature.json"), "r") as f: with open("/home/pi/PigletModel_TFLite/signature.json","r") as f: #★jsonファイルをフルパスで指定 self.signature = json.load(f) #self.model_file = "../" + self.signature.get("filename") self.model_file = "/home/pi/PigletModel_TFLite/saved_model.tflite" #★tfliteファイルをフルパスで指定 if not os.path.isfile(self.model_file): raise FileNotFoundError(f"Model file does not exist") self.interpreter = None self.signature_inputs = self.signature.get("inputs") self.signature_outputs = self.signature.get("outputs") # Look for the version in signature file. # If it's not found or the doesn't match expected, print a message version = self.signature.get("export_model_version") if version is None or version != EXPORT_MODEL_VERSION: print( f"There has been a change to the model format. Please use a model with a signature 'export_model_version' that matches {EXPORT_MODEL_VERSION}." ) def load(self) -> None: """Load the model from path to model file""" # Load TFLite model and allocate tensors. self.interpreter = tflite.Interpreter(model_path=self.model_file) self.interpreter.allocate_tensors() # Combine the information about the inputs and outputs from the signature.json file with the Interpreter runtime input_details = {detail.get("name"): detail for detail in self.interpreter.get_input_details()} self.model_inputs = {key: {**sig, **input_details.get(sig.get("name"))} for key, sig in self.signature_inputs.items()} output_details = {detail.get("name"): detail for detail in self.interpreter.get_output_details()} self.model_outputs = {key: {**sig, **output_details.get(sig.get("name"))} for key, sig in self.signature_outputs.items()} if "Image" not in self.model_inputs: raise ValueError("Tensorflow Lite model doesn't have 'Image' input! Check signature.json, and please report issue to Lobe.") def predict(self, image) -> dict: """ Predict with the TFLite interpreter! """ if self.interpreter is None: self.load() # process image to be compatible with the model input_data = self.process_image(image, self.model_inputs.get("Image").get("shape")) # set the input to run self.interpreter.set_tensor(self.model_inputs.get("Image").get("index"), input_data) self.interpreter.invoke() # grab our desired outputs from the interpreter! # un-batch since we ran an image with batch size of 1, and convert to normal python types with tolist() outputs = {key: self.interpreter.get_tensor(value.get("index")).tolist()[0] for key, value in self.model_outputs.items()} return self.process_output(outputs) def process_image(self, image, input_shape) -> np.ndarray: """ Given a PIL Image, center square crop and resize to fit the expected model input, and convert from [0,255] to [0,1] values. """ width, height = image.size # ensure image type is compatible with model and convert if not if image.mode != "RGB": image = image.convert("RGB") # center crop image (you can substitute any other method to make a square image, such as just resizing or padding edges with 0) if width != height: square_size = min(width, height) left = (width - square_size) / 2 top = (height - square_size) / 2 right = (width + square_size) / 2 bottom = (height + square_size) / 2 # Crop the center of the image image = image.crop((left, top, right, bottom)) # now the image is square, resize it to be the right shape for the model input input_width, input_height = input_shape[1:3] if image.width != input_width or image.height != input_height: image = image.resize((input_width, input_height)) # make 0-1 float instead of 0-255 int (that PIL Image loads by default) image = np.asarray(image) / 255.0 # format input as model expects return image.reshape(input_shape).astype(np.float32) def process_output(self, outputs) -> dict: # postprocessing! convert any byte strings to normal strings with .decode() out_keys = ["label", "confidence"] for key, val in outputs.items(): if isinstance(val, bytes): outputs[key] = val.decode() # get list of confidences from prediction confs = list(outputs.values())[0] labels = self.signature.get("classes").get("Label") output = [dict(zip(out_keys, group)) for group in zip(labels, confs)] sorted_output = {"predictions": sorted(output, key=lambda k: k["confidence"], reverse=True)} return sorted_output if __name__ == "__main__": parser = argparse.ArgumentParser(description="Predict a label for an image.") parser.add_argument("image", help="Path to your image file.") args = parser.parse_args() # Assume model is in the parent directory for this file model_dir = os.path.join(os.getcwd(), "..") if os.path.isfile(args.image): image = Image.open(args.image) model = TFLiteModel(model_dir) model.load() outputs = model.predict(image) print(f"Predicted: {outputs}") else: print(f"Couldn't find image file {args.image}")
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Lobeで出力したtfliteをラズパイで動かす方法

はじめに Lobeを使うと機械学習のモデルが簡単に作れます。 機械学習を組み込んだIoTが増えると楽しいと思うので、作成した学習モデルをラズパイ上で動かす方法を記載します。参考にしていただけると幸いです。 手探りで動かしているので、もっといい方法があればコメントいただけるとありがたいです。 記事作成時のLobeのバージョンは「0.9.421.4」です。 学習モデルの作り方 Lobeを起動して、NewProjectをクリックします。 NewProgectが立ち上がったら、Labelをクリックして、学習したいモデルを登録します。 私は子豚がいる画像といない画像を学習させたかったので、このような画像を5枚ずつ登録させました。 次に、UseをクリックしてExportをクリックすると、出力する学習モデルの形式を選択できるので、FeaturedのTensorFlowLiteをクリックして、学習モデルをExportします。 Exportしたファイルのフォルダ構成 Exportすると作成したプロジェクト名のフォルダが出来上がります。 中にはいろいろなファイルが入っていて、構成は以下のようになっています。 PigletModel_TFLete ├example │ ├README.md │ ├requirements.txt │ └tflite_example.py ├labels.txt ├saved_model.tflite  └signature.json ラズパイ上で学習モデルを実行させる方法と、実行結果 この学習モデルをラズパイで使用する場合、Exportしたファイル一式をラズパイ上に配置します。 ここでは、/home/pi/PigletModel_TFLiteというような形で配置しています。 配置後に、exampleの下でtflite_example.pyに画像ファイルを指定して実行すると、このようにラベルごとの信頼度を得ることができます。 (以下の場合、NoPigletの結果のほうが大きいので子豚はいないんだなと判断できます) pi@raspberrypi:~/PigletModel_TFLite/example $ python3 tflite_example.py XXXXX.jpg Predicted: {'predictions': [{'label': 'NoPiglet', 'confidence': 0.963566243648529}, {'label': 'piglet', 'confidence': 0.036433834582567215}]} pi@raspberrypi:~/PigletModel_TFLite/example $ 環境に合わせたパスの変更方法 一度実行してみるとわかると思うのですが、tflite_example.pyデフォルトのファイルパスが相対パスになっているので、tflite_example.pyを実行する場所によってはエラーになってしまいます。 なので、tflite_example.pyの中でファイルのパスを使う処理を行っている箇所を環境に合わせたパスに変える必要があります。 以下が変更例です。コメントに★ある2か所です。 # ------------------------------------------------------------- # Copyright (c) Microsoft Corporation. All rights reserved. # ------------------------------------------------------------- """ Skeleton code showing how to load and run the TensorFlow Lite export package from Lobe. """ import argparse import json import os import numpy as np from PIL import Image import tflite_runtime.interpreter as tflite EXPORT_MODEL_VERSION = 1 class TFLiteModel: def __init__(self, model_dir) -> None: """Method to get name of model file. Assumes model is in the parent directory for script.""" #with open(os.path.join(model_dir, "signature.json"), "r") as f: with open("/home/pi/PigletModel_TFLite/signature.json","r") as f: #★jsonファイルをフルパスで指定 self.signature = json.load(f) #self.model_file = "../" + self.signature.get("filename") self.model_file = "/home/pi/PigletModel_TFLite/saved_model.tflite" #★tfliteファイルをフルパスで指定 if not os.path.isfile(self.model_file): raise FileNotFoundError(f"Model file does not exist") self.interpreter = None self.signature_inputs = self.signature.get("inputs") self.signature_outputs = self.signature.get("outputs") # Look for the version in signature file. # If it's not found or the doesn't match expected, print a message version = self.signature.get("export_model_version") if version is None or version != EXPORT_MODEL_VERSION: print( f"There has been a change to the model format. Please use a model with a signature 'export_model_version' that matches {EXPORT_MODEL_VERSION}." ) def load(self) -> None: """Load the model from path to model file""" # Load TFLite model and allocate tensors. self.interpreter = tflite.Interpreter(model_path=self.model_file) self.interpreter.allocate_tensors() # Combine the information about the inputs and outputs from the signature.json file with the Interpreter runtime input_details = {detail.get("name"): detail for detail in self.interpreter.get_input_details()} self.model_inputs = {key: {**sig, **input_details.get(sig.get("name"))} for key, sig in self.signature_inputs.items()} output_details = {detail.get("name"): detail for detail in self.interpreter.get_output_details()} self.model_outputs = {key: {**sig, **output_details.get(sig.get("name"))} for key, sig in self.signature_outputs.items()} if "Image" not in self.model_inputs: raise ValueError("Tensorflow Lite model doesn't have 'Image' input! Check signature.json, and please report issue to Lobe.") def predict(self, image) -> dict: """ Predict with the TFLite interpreter! """ if self.interpreter is None: self.load() # process image to be compatible with the model input_data = self.process_image(image, self.model_inputs.get("Image").get("shape")) # set the input to run self.interpreter.set_tensor(self.model_inputs.get("Image").get("index"), input_data) self.interpreter.invoke() # grab our desired outputs from the interpreter! # un-batch since we ran an image with batch size of 1, and convert to normal python types with tolist() outputs = {key: self.interpreter.get_tensor(value.get("index")).tolist()[0] for key, value in self.model_outputs.items()} return self.process_output(outputs) def process_image(self, image, input_shape) -> np.ndarray: """ Given a PIL Image, center square crop and resize to fit the expected model input, and convert from [0,255] to [0,1] values. """ width, height = image.size # ensure image type is compatible with model and convert if not if image.mode != "RGB": image = image.convert("RGB") # center crop image (you can substitute any other method to make a square image, such as just resizing or padding edges with 0) if width != height: square_size = min(width, height) left = (width - square_size) / 2 top = (height - square_size) / 2 right = (width + square_size) / 2 bottom = (height + square_size) / 2 # Crop the center of the image image = image.crop((left, top, right, bottom)) # now the image is square, resize it to be the right shape for the model input input_width, input_height = input_shape[1:3] if image.width != input_width or image.height != input_height: image = image.resize((input_width, input_height)) # make 0-1 float instead of 0-255 int (that PIL Image loads by default) image = np.asarray(image) / 255.0 # format input as model expects return image.reshape(input_shape).astype(np.float32) def process_output(self, outputs) -> dict: # postprocessing! convert any byte strings to normal strings with .decode() out_keys = ["label", "confidence"] for key, val in outputs.items(): if isinstance(val, bytes): outputs[key] = val.decode() # get list of confidences from prediction confs = list(outputs.values())[0] labels = self.signature.get("classes").get("Label") output = [dict(zip(out_keys, group)) for group in zip(labels, confs)] sorted_output = {"predictions": sorted(output, key=lambda k: k["confidence"], reverse=True)} return sorted_output if __name__ == "__main__": parser = argparse.ArgumentParser(description="Predict a label for an image.") parser.add_argument("image", help="Path to your image file.") args = parser.parse_args() # Assume model is in the parent directory for this file model_dir = os.path.join(os.getcwd(), "..") if os.path.isfile(args.image): image = Image.open(args.image) model = TFLiteModel(model_dir) model.load() outputs = model.predict(image) print(f"Predicted: {outputs}") else: print(f"Couldn't find image file {args.image}")
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

TensorFlow Lite のモデルを Web で扱えるという話についてのざっくりなメモ【Google I/O 2021】

内容はタイトルの通りで、先日参加したイベントで聞いた話が元になっています。 TensorFlow.js のモデルだけじゃなく、TensorFlow Lite のモデルも Web で使える!!これはめちゃくちゃ気になる! #tfug pic.twitter.com/KVugwHeQm5— you (@youtoy) June 7, 2021 ちなみに、参加していたイベントというのはこちらです。 【I/O Extended Japan 2021 - Machine Learning】 #googleio2021 #io21jp ML振り返りイベント視聴URLはこちらです!お時間時間あればぜひご覧下さい~ ✨ #tfug #gdgtokyohttps://t.co/oyOa0x2GZ1— Shoco Sato (@satoshoco) June 7, 2021 今回の話に関する公式の動画 TensorFlow Lite のモデルを Web で扱えるという話の公式の動画を掲載します。 今回の話に関する公式のデモ 上で掲載した動画の説明欄に、以下の 2つのデモへのリンクが掲載されていました。 Resources: Demo 1 → https://goo.gle/3vxb62N Demo 2 → https://goo.gle/3gLY79b それぞれの内容を見てみると、CodePen上で試せるもので「TFJS Task API Demo - Movie Review Sentiment Classification」というものと、「TFJS: TFLite Model Runner Demo」というものでした。 2つ目はページのタイトルから分かりにくいですが、画像の Cartoonize を行うものです。 個人的には、過去にもいろいろ触っている画像分類が気になったので、上記の公式デモを公開しているアカウントの Pen にそれがあるかどうか探してみました。 画像分類のデモ そうすると、以下のツイートに書いているデモページを見つけることができました。 画像分類もあった。並んでいるボタンを見ると TFLite の MobileNet の下に Custom ってあるけど、EfficientNet-Lite のものとか動いたりするのかな?(前に #TensorFlow Lite Model Maker で作ったやつとか)●TFJS Task API - Image Classification https://t.co/YaTX3up1Pi#TensorFlowJS pic.twitter.com/5vZbrUxRVo— you (@youtoy) June 12, 2021 上記のツイートに書いている「前に...」と書いているものは、以下の記事を書いたころに試していたものです。  ●TensorFlow Lite Model Maker による転移学習の過程で accuracy・loss を可視化(グラフ化)する - Qiita   https://qiita.com/youtoy/items/4f198afb3254613efc75 その後、キーワードで検索をしていて、カスタムモデルの要件に関する情報をたどれそうなリンクを見つけられました。 #TensorFlow Lite の画像分類のモデルを JavaScript で扱う時、MobileNet じゃないカスタムモデルでどんなモデルが使えるか、ここから情報をたどれそう、というのがあった。tensorflow-models/tasks - npm https://t.co/JV5lEnDGIR#TensorFlowJS pic.twitter.com/7g2H3tyOoj— you (@youtoy) June 12, 2021 そこから要件が書かれたページにとんでみたのですが、今の自分の知識だとぱっと見ではすぐに分からない... 実際のモデルを用意して、デモのソースコードの必要な部分を切り出して動かす、とかやったほうが早そうな予感がします。 モデルの要件が書いてあるページにたどり着いたけど、自分の場合は、先ほどのデモのページのソースコードを使って実際のモデルを使ってみて、とりあえず動くか試してみる、という進め方のほうが早そうな感じがしてきた。 pic.twitter.com/6Jo5YGrOdL— you (@youtoy) June 12, 2021 API の利用方法 記事の途中に出てきた npm のページを見てみると、以下のスクリプトタグを記載し、モデルの読み込みの処理を読み込みたいモデルに合わせて書くようです。  ●@tensorflow-models/tasks - npm   https://www.npmjs.com/package/@tensorflow-models/tasks 上で書いていたカスタムモデルかそうでないかという話についてですが、上記のモデルの読み込み処理(以下に抜き出したもの)を見ると、独自のモデルを外部から読み込むか、あらかじめ準備されているモデルを読み込むかの違いのようでした。 // Load the TFJS mobilenet model. const model1 = await tfTask.ImageClassification.MobileNet.TFJS.load({ backend: 'wasm'}); // Load the TFLite mobilenet model. const model2 = await tfTask.ImageClassification.MobileNet.TFLite.load(); // Load a custom image classification TFLite model. const model3 = await tfTask.ImageClassification.CustomModel.TFLite.load({ model: 'url/to/your/bird_classifier.tflite'}); おわりに とりあえず、TensorFlow Lite のモデルを Web で扱えるという話を追っていく前の、ざっくりな情報をメモ的にまとめました。 この後、続きを進めていって記事に書こうと思ってます。 【追記】 とりあえず動くものを試してみた その後、サンプルに手を加えたものをちょっと動かしたりしてみてます。 #TensorFlow Lite のモデルを JavaScript で扱う話のその後。とりあえず、静止画に画像分類の推論を行うサンプルに手を加えて、PC のカメラ映像に対して画像分類の推論を行うようにして動かしてみた(iPod 笑)。●TFJS Task API - Image Classification https://t.co/YaTX3up1Pi#TensorFlowJS pic.twitter.com/EDk3TuEnQr— you (@youtoy) June 12, 2021 【追記】 続きの記事をまず 1つ書きました ●30行未満の HTML+JavaScript でカスタムモデルを使った画像分類を試す(TFJS Task API を利用) - Qiita  https://qiita.com/youtoy/items/7b42ce2973a457cc5844 【追記】 余談2 そういえば、対応してるモデルを実際に動かして確かめる話は、わざわざ転移学習とかしてモデルを用意しなくても TensorFlow Hub の TFLite のモデルをとってくれば良いのでは?、と後から思ったりしました。 そういえば、TFJS Task API で #TensorFlow Lite のモデルを試す話、特定のモデルが動くか試してみるだけなら転移学習とかして用意しなくても TensorFlow Hub のモデルを呼び出せば良いのでは、とふと思った。●TFLite | TensorFlow Hub https://t.co/113ThD2cFk#TensorFlowJS— you (@youtoy) June 12, 2021 余談 記事の途中に出てきた以下のページで気になった部分を、最後にいくつかメモしておきます。  ●@tensorflow-models/tasks - npm   https://www.npmjs.com/package/@tensorflow-models/tasks 現状、「WORK IN PROGRESS」という状態のようです。 また、インストールについては「この 20K より小さいパッケージのみ利用すれば、依存関係等を気にせず使える」などといった説明が書かれていて、非常に使いやすい構成のようです。 【追記】 上記の話、デモのソースコードを見たら、外部から読み込んでるファイルのバージョンで 0.0.1-alpha.8 とか書いてました(まだベータにもなってない、という位置付けっぽい)。 <script src='https://cdn.jsdelivr.net/npm/@tensorflow-models/tasks@0.0.1-alpha.8'></script> 対応しているタスク・モデル等の全体像は、以下のようになるようです。 また「(The initial version only supports the web browser environment. NodeJS support is coming soon)」という記載があり、初期バージョンはブラウザ上での動作のみ対応という状態のようです。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む