- 投稿日:2021-01-13T20:11:18+09:00
TensorFlowで学習したモデルをNode.jsで利用
TensorFlow.js というライブラリでJavaScriptからTensorFlowを利用することができるようです。
PythonのTensorFlowで学習したモデルをNode.jsで読み込んで推論に利用してみました。PythonもNode.jsもGoogle Colaboratory上です。
手順
- TensorFlowで学習
- 学習したモデルをファイルに保存
- モデルのファイルをTensorFlow.js用に変換
- TensorFlow.js をインストール
- Node.jsでモデルを読み込んで推論を実行
TensorFlowのバージョン情報
!pip list | grep tensorflowtensorflow 2.4.0 tensorflow-addons 0.8.3 tensorflow-datasets 4.0.1 tensorflow-estimator 2.4.0 tensorflow-gcs-config 2.4.0 tensorflow-hub 0.10.0 tensorflow-metadata 0.26.0 tensorflow-privacy 0.2.2 tensorflow-probability 0.11.0※コマンドの実行結果は2021/01/08時点です。
1. TensorFlowで学習
サンプルとしてXORを学習させます。
import numpy as np from matplotlib import pyplot as plt import tensorflow as tf in_size = 2 out_size = 2 # XORの学習データ x = np.asarray([[0, 0], [0, 1], [1, 0], [1, 1]]) y = np.asarray([0, 1, 1, 0]) y_onehot = tf.keras.backend.one_hot(y, out_size) # モデル構造を定義 hidden_size = 2 model = tf.keras.models.Sequential() model.add(tf.keras.layers.Dense(hidden_size, activation='relu', input_shape=(in_size,))) model.add(tf.keras.layers.Dense(out_size, activation='softmax')) # モデルを構築 model.compile( loss = "categorical_crossentropy", optimizer = tf.optimizers.Adam(learning_rate=0.05), metrics=["accuracy"]) # 学習を実行 result = model.fit(x, y_onehot, batch_size=100, epochs=20, verbose=1, validation_data=(x, y_onehot)) # 手抜き # 学習の様子をグラフへ描画 def plotLearning(): # ロスの推移をプロット plt.plot(result.history['loss']) plt.plot(result.history['val_loss']) plt.title('Loss') plt.legend(['train', 'test'], loc='upper left') plt.show() # 正解率の推移をプロット plt.plot(result.history['accuracy']) plt.plot(result.history['val_accuracy']) plt.title('Accuracy') plt.legend(['train', 'test'], loc='upper left') plt.show() plotLearning()2. 学習したモデルをファイルに保存
ディレクトリ作成
!rm -rf model && mkdir model保存
model.save("model/sample1.h5")この名前でファイルが1つ作成されます。
3. モデルのファイルをTensorFlow.js用に変換
変換するツールをインストール
!pip install tensorflowjs
tensorflow-hub-0.9.0
とtensorflowjs-2.8.3
がインストールされます。!tensorflowjs_converter --input_format=keras model/sample1.h5 model/sample-tfjs保存結果を確認
!find model/sample-tfjsmodel/sample-tfjs model/sample-tfjs/group1-shard1of1.bin model/sample-tfjs/model.jsonディレクトリが作成され、その中に2つのファイルが作成されました。たぶんメタ情報のJSONと数値のバイナリ。
4. TensorFlow.js をインストール
!npm install @tensorflow/tfjs-node
@tensorflow/tfjs-node@2.8.3
がインストールされます。5. Node.jsでモデルを読み込んで推論を実行
JavaScriptソースファイル作成
%%writefile sample.js const tf = require('@tensorflow/tfjs-node'); tf.loadLayersModel('file://model/sample-tfjs/model.json').then((model) => { const inputs = [[0, 0], [0, 1], [1, 0], [1, 1]]; const result = model.predict(tf.tensor(inputs)).argMax(1).dataSync(); console.log(result); });実行
!node sample.jsnode-pre-gyp info This Node instance does not support builds for N-API version 6 node-pre-gyp info This Node instance does not support builds for N-API version 7 node-pre-gyp info This Node instance does not support builds for N-API version 6 node-pre-gyp info This Node instance does not support builds for N-API version 7 2021-01-08 12:43:44.532076: I tensorflow/core/platform/cpu_feature_guard.cc:142] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2 FMA 2021-01-08 12:43:44.546231: I tensorflow/core/platform/profile_utils/cpu_utils.cc:94] CPU Frequency: 2299995000 Hz 2021-01-08 12:43:44.546491: I tensorflow/compiler/xla/service/service.cc:168] XLA service 0x44c2e00 initialized for platform Host (this does not guarantee that XLA will be used). Devices: 2021-01-08 12:43:44.546547: I tensorflow/compiler/xla/service/service.cc:176] StreamExecutor device (0): Host, Default Version Int32Array [ 0, 1, 1, 0 ]なにやら警告っぽいのが表示されたのですが、よくわかっていないです。
最後の
[0, 1, 1, 0]
でXORが実行できているのを確認できます。
- 投稿日:2021-01-13T07:04:11+09:00
M1 Macに機械学習環境を最速で構築してみた (conda, jupyter notebook, tensorflow)
はじめに
M1対応のtensorflowを使うにはApple公式のGithubリポジトリ(Apple/tensorflow-macos)からパッケージをダウンロードして一つ一つインストールするなど面倒だったのですが、
conda-forge
にまとまったパッケージがあったのでそれを使ってM1 MacbookにM1対応のtensorflowをjupyter上で実行できる環境を構築する方法をメモします。(1/12/2021 現在)この記事では
- Jupyter Notebook上でM1対応のtensorflowを実行する簡単な方法を紹介します。
- 実際にM1のGPUを使って学習してみます。
目次
tensorflowを実行する環境を構築する
anaconda環境をインストール
まずは下のGitHubページの、OS X arm64 (Apple Silicon) Miniforge3-MacOSX-arm64を選び、Miniforgeのインストーラーをダウンロードします。
conda-forge/miniforgeダウンロードした
Miniforge3-MacOSX-arm64.sh
を使ってターミナルからMiniforgeをインストールします。$ bash Miniforge3-MacOSX-arm64.sh
必要なパッケージをインストール
# m1用tensorflowを含んだconda環境の作成、起動 $ conda create -n python38 tensorflow-addons tensorflow -c isuruf/label/tf -c conda-forge $ conda activate python38 # Jupyter notebookのインストール $ conda install -n python38 -c conda-forge notebook $ conda install -n python38 -c anaconda ipykernel # Jupyter Notebookに現在のpython環境をセット $ python -m ipykernel install --user --name=python38Jupyter notebookを起動し、pythonファイルから
tensorflow
がインポートきれば成功です。$ jupyter notebook .import tensorflow as tftensorflowを使ってみる
Jupyter上でPythonファイルを作り以下のコードを実行します。
import tensorflow.compat.v2 as tf mnist = tf.keras.datasets.mnist import time tf.enable_v2_behavior() from tensorflow.python.framework.ops import disable_eager_execution disable_eager_execution() from tensorflow.python.compiler.mlcompute import mlcompute mlcompute.set_mlc_device(device_name='gpu') (x_train, y_train),(x_test, y_test) = mnist.load_data() x_train, x_test = x_train / 255.0, x_test / 255.0 x_train = x_train.reshape(x_train.shape[0], 28, 28, 1) x_test = x_test.reshape(x_test.shape[0], 28, 28, 1) model = tf.keras.models.Sequential([ tf.keras.layers.Conv2D(1024, (3,3), activation='relu', input_shape=(28, 28, 1)), tf.keras.layers.MaxPooling2D(2,2), tf.keras.layers.Conv2D(512, (3,3), activation='relu'), tf.keras.layers.MaxPooling2D(2,2), tf.keras.layers.Flatten(), tf.keras.layers.Dense(256, activation='relu'), tf.keras.layers.Dense(10, activation='softmax') ]) model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy']) start = time.perf_counter() model.fit(x_train, y_train, epochs=5) end = time.perf_counter() print("Elapsed time : {0} s.".format(end-start)) model.evaluate(x_test, y_test)20分ほどで学習が終わりました。
device_name='gpu'
とするのを忘れるとCPUが使われて遅くなってしまいます。mlcompute.set_mlc_device(device_name='gpu')参考文献
- 投稿日:2021-01-13T01:15:41+09:00
TensorFlow Object Detection API の pipeline.config をコードから書き換える
TensorFlow Object Detection API の クラス数やチェックポイント・パス、トレーニングデータセットや各種パラメーターを設定する pipeline.config ファイル。
ファイルに直接上書きしてもいいのですが、コードで動的に変えたい場合は、以下のコードで各パラメーターを変更して保存、もしくは上書きできます。
1,Object Detection APIをインストール
import os import pathlib # クローン # Clone the tensorflow models repository if it doesn't already exist if "models" in pathlib.Path.cwd().parts: while "models" in pathlib.Path.cwd().parts: os.chdir('..') elif not pathlib.Path('models').exists(): !git clone --depth 1 https://github.com/tensorflow/models # Install the Object Detection API %cd models/research/ !protoc object_detection/protos/*.proto --python_out=. !cp object_detection/packages/tf2/setup.py . !python -m pip install .2,指定のパラメータで書き換え
from google.protobuf import text_format from object_detection.protos import pipeline_pb2 pipeline_config_path = 'ssd_resnet50_v1_fpn_640x640_coco17_tpu-8/pipeline.config' new_pipeline_config_path = './new_pipeline.config' pipeline_config = pipeline_pb2.TrainEvalPipelineConfig() with tf.io.gfile.GFile(pipeline_config_path, "r") as f: proto_str = f.read() text_format.Merge(proto_str, pipeline_config) # 変えたい設定パラメーター。ここでは、クラス数を10に変更する pipeline_config.model.ssd.num_classes = 10 pipeline_config.train_input_reader.tf_record_input_reader.input_path[:] = [tf_record_path] #このパラメータはこの形式で渡さないと失敗する config_text = text_format.MessageToString(pipeline_config) with tf.io.gfile.GFile(new_pipeline_config_path, "wb") as f: f.write(config_text)元の pipeline.config がこちら。
model { ssd { num_classes: 90 # このケースではデフォでCOCOデータセットのクラス数になっている image_resizer { fixed_shape_resizer { height: 640 width: 640 } } feature_extractor { type: "ssd_resnet50_v1_fpn_keras" depth_multiplier: 1.0 min_depth: 16 conv_hyperparams { regularizer { l2_regularizer { weight: 0.0004 } } initializer { truncated_normal_initializer { mean: 0.0 stddev: 0.03 } } activation: RELU_6 batch_norm { decay: 0.997 scale: true epsilon: 0.001 } } override_base_feature_extractor_hyperparams: true fpn { min_level: 3 max_level: 7 } } box_coder { faster_rcnn_box_coder { y_scale: 10.0 x_scale: 10.0 height_scale: 5.0 width_scale: 5.0 } } matcher { argmax_matcher { matched_threshold: 0.5 unmatched_threshold: 0.5 ignore_thresholds: false negatives_lower_than_unmatched: true force_match_for_each_row: true use_matmul_gather: true } } similarity_calculator { iou_similarity { } } box_predictor { weight_shared_convolutional_box_predictor { conv_hyperparams { regularizer { l2_regularizer { weight: 0.0004 } } initializer { random_normal_initializer { mean: 0.0 stddev: 0.01 } } activation: RELU_6 batch_norm { decay: 0.997 scale: true epsilon: 0.001 } } depth: 256 num_layers_before_predictor: 4 kernel_size: 3 class_prediction_bias_init: -4.6 } } anchor_generator { multiscale_anchor_generator { min_level: 3 max_level: 7 anchor_scale: 4.0 aspect_ratios: 1.0 aspect_ratios: 2.0 aspect_ratios: 0.5 scales_per_octave: 2 } } post_processing { batch_non_max_suppression { score_threshold: 1e-08 iou_threshold: 0.6 max_detections_per_class: 100 max_total_detections: 100 use_static_shapes: false } score_converter: SIGMOID } normalize_loss_by_num_matches: true loss { localization_loss { weighted_smooth_l1 { } } classification_loss { weighted_sigmoid_focal { gamma: 2.0 alpha: 0.25 } } classification_weight: 1.0 localization_weight: 1.0 } encode_background_as_zeros: true normalize_loc_loss_by_codesize: true inplace_batchnorm_update: true freeze_batchnorm: false } } train_config { batch_size: 64 data_augmentation_options { random_horizontal_flip { } } data_augmentation_options { random_crop_image { min_object_covered: 0.0 min_aspect_ratio: 0.75 max_aspect_ratio: 3.0 min_area: 0.75 max_area: 1.0 overlap_thresh: 0.0 } } sync_replicas: true optimizer { momentum_optimizer { learning_rate { cosine_decay_learning_rate { learning_rate_base: 0.04 total_steps: 25000 warmup_learning_rate: 0.013333 warmup_steps: 2000 } } momentum_optimizer_value: 0.9 } use_moving_average: false } fine_tune_checkpoint: "PATH_TO_BE_CONFIGURED" num_steps: 25000 startup_delay_steps: 0.0 replicas_to_aggregate: 8 max_number_of_boxes: 100 unpad_groundtruth_tensors: false fine_tune_checkpoint_type: "classification" use_bfloat16: true fine_tune_checkpoint_version: V2 } train_input_reader { label_map_path: "PATH_TO_BE_CONFIGURED" tf_record_input_reader { input_path: tf_record_path } } eval_config { metrics_set: "coco_detection_metrics" use_moving_averages: false } eval_input_reader { label_map_path: "PATH_TO_BE_CONFIGURED" shuffle: false num_epochs: 1 tf_record_input_reader { input_path: "PATH_TO_BE_CONFIGURED" } }クラス数の書き換え処理をした結果がこちら↓
model { ssd { num_classes: 10 # 指定した値に書きかわる ・・・ ・・・?
フリーランスエンジニアです。
お仕事のご相談こちらまで
rockyshikoku@gmail.comCore MLを使ったアプリを作っています。
機械学習関連の情報を発信しています。