20190727のTensorFlowに関する記事は6件です。

Windows端末にCUDAをインストールする際に、「Visual Studio Integration」のインストールに失敗する場合

【目的】

先に投稿した【Windows版TensorFlowでGPUを使う (CUDAのインストール)】の記事を元にWindows端末にCUDAインストール時に以下のような画面になり、インストールに失敗する場合があります。
本記事ではCUDAインストール時に「Visual Studio Integration」のインストールに失敗した場合の対処法を記載します。
image.png

なお、VisualStudio 2017 Proを入れている環境では本現象は発生しませんでした。

【内容】

Windows環境でCUDAのインストールに失敗するというという情報はインターネット上に多く見られます。
対処方法としては主に以下の3つに大別されます。

  1. NVIDIAの最新のGPUドライバをクリーンインストールする
  2. NVIDIAのサービスをすべて止めて、手動で関連ファイルを削除した後、CUDAをインストールする
  3. CUDAインストール時に、必要なモジュールのみに限定する

まず、1.に関しては実際にエラーに直面した際に実施してみましたが、問題は解決しませんでした。
2.に関しては操作があまりに怪しかったので実施していません。
今回対応した方法は3.の手法になります。

【CUDAインストール時に、必要なモジュールのみに限定する】

今回は「Visual Studio Integration」のインストールに失敗していますので、これを外してインストールします。
なお、「Visual Studio Integration」はVisualStudioへの統合機能のため、VisualStudioで直接CUDAを使ったアプリを開発しない限りは不要です。

まずはインストーラを起動して、インストールを進めます。
image.png

「インストール オプション」まで進めたら、「カスタム (詳細)」を選択し、次に進みます。
image.png

「カスタム インストール オプション」画面のツリーから「CUDA」を展開します。
その中に「Visual Studio Integration」の項目があるので、チェックを外します
image.png

「インストール場所の選択」はデフォルトで構いません。
image.png

「次へ」進むと、インストールが実行されます。
image.png
image.png

インストールが正常に完了します。
image.png

【動作確認】

CUDAのインストールが正常に完了し、【Windows版TensorFlowでGPUを使う (CUDAのインストール)】の手順がきちんと完了していれば、コマンドプロンプトで以下のコマンドを実行した際に、GPUを認識している結果が得られるはずです。

python -c "from tensorflow.python.client import device_lib;print(device_lib.list_local_devices());"

「出力結果」に tensorflow/core/common_runtime/gpu/gpu_device.cc:1640] Found device 0 with properties:device_type: "GPU" の文言が確認できればGPUを認識しています。
(本記事では「GeForce GTX 980」を認識しています)

出力結果.txt
2019-07-15 10:10:04.141549: I tensorflow/core/platform/cpu_feature_guard.cc:142] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2
2019-07-15 10:10:04.149333: I tensorflow/stream_executor/platform/default/dso_loader.cc:42] Successfully opened dynamic library nvcuda.dll
2019-07-15 10:10:04.283109: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1640] Found device 0 with properties:
name: GeForce GTX 980 major: 5 minor: 2 memoryClockRate(GHz): 1.2785
pciBusID: 0000:01:00.0
2019-07-15 10:10:04.289015: I tensorflow/stream_executor/platform/default/dlopen_checker_stub.cc:25] GPU libraries are statically linked, skip dlopen check.
2019-07-15 10:10:04.294041: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1763] Adding visible gpu devices: 0
2019-07-15 10:10:04.869417: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1181] Device interconnect StreamExecutor with strength 1 edge matrix:
2019-07-15 10:10:04.873142: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1187]      0
2019-07-15 10:10:04.875721: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1200] 0:   N
2019-07-15 10:10:04.878971: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1326] Created TensorFlow device (/device:GPU:0 with 3001 MB memory) -> physical GPU (device: 0, name: GeForce GTX 980, pci bus id: 0000:01:00.0, compute capability: 5.2)
[name: "/device:CPU:0"
device_type: "CPU"
memory_limit: 268435456
locality {
}
incarnation: 6353985342385400385
, name: "/device:GPU:0"
device_type: "GPU"
memory_limit: 3147238604
locality {
  bus_id: 1
  links {
  }
}
incarnation: 12171252068600957596
physical_device_desc: "device: 0, name: GeForce GTX 980, pci bus id: 0000:01:00.0, compute capability: 5.2"
]
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Windows版TensorFlowでGPUを使う (CUDAのインストール)

【目的】

Windows環境のTensorFlowでGPUを使えるようにします。

【内容】

Windows環境のTensorFlowでCPUよりも高速で処理が行えるGPUを使えるようにします。
大まかには以下の手順を行います。

  • ディスプレイドライバのインストールまたは更新
  • CUDA 10.0のインストール
  • cuDNN SDKのインストール
  • PATHの設定
  • GPU版TensorFlowのインストール

詳細手順はTensorFlowの公式手順を参照してください。

【TensorFlow - GPU support】

【システム構成】

本記事を書いている2019年4月15日時点では以下の通り。

  • CUDA 3.5以上に対応しているGPUが搭載されているPC
     【NVIDIA - CUDA GPUs】
     (※ なお GeoForce MX150 上記サイトに記載されていませんが、動作確認できました)
  • Windows 10/8.1/7 または Windows Server 2019/2016/2012 R2
  • Python 3.4以上 (本記事では3.7.3で確認)
  • TensorFlow 1.13.0以上 (本記事では1.13.1で確認)
     (※2.0 Alphaは未確認ですがCUDA10.0で動くようです)
  • CUDA 10.0
     (※最新の10.1では動作せず)
  • cuDNN 7.5.0 for CUDA 10.0
     (※ 最新のfor CUDA 10.1では動作せず)

【前提条件】

本記事ではPyhon3.4以上およびpipが使える状態になっていることを想定しています。
なお、Anaconda環境は想定していません。

【1. ディスプレイドライバのインストールまたは更新】

下記サイトより対応するGPUの最新のドライバを取得して、インストールします。
【NVIDIA Driver Downloads】

すでにドライバが入っている場合、可能ならばカスタムインストールからクリーンインストールを選択します。
その場合、設定済みの項目は全て初期化されます。

【2. CUDA 10.0のインストール】

下記サイトよりCUDAをダウンロードしてインストールします。
【NVIDIA - CUDA Zone】

なお、2019年4月15日現在で最新バージョンの「10.1」では動作確認ができませんでした。
[Legacy Releases]から「CUDA Toolkit 10.0 (Sept 2018)」をダウンロードしてください。
【直リン】
【CUDA Toolkit 10.0 Archive】

image.png

インストール自体はデフォルトで構いません。

【2.1 CUDAインストール時に「Visual Studio Integration」のインストールに失敗する場合】(2019/07/15 追記)

以下の記事を参考にしてください。
【Windows端末にCUDAをインストールする際に、「Visual Studio Integration」のインストールに失敗する場合】

【3. cuDNN SDKのインストール】

下記URLからcuDNNをダウンロードします。
上記でダウンロードしたCUDAのバージョンに合ったものをダウンロードしてください。
なお、ダウンロード時には開発者登録を行う必要があります。

【NVIDIA - NVIDIA cuDNN】

image.png

ダウンロードしたらzipファイルを解凍して適当な場所に展開します。
場所はどこでも構いませんが、TensorFlowの手順に合わせるのであれば「C:\tools\cuda\bin」に「cuDNN64_7.dll」が含まれるように解凍します。

【4. PATHの設定】

下記を参考にCUDAおよびcuDNNにPATHが通るように設定します。
最低限cuDNNの「cuDNN64_7.dll」が置いてあるディレクトリにPATHが通っている必要があります。

【必須設定】

  • C:\tools\cuda\bin (← 上記の例の場合のcuDNN64_7.dllの置き場所)
     ※ここにPATHに通っていないとimport TensorFlowでエラーになる

以下オプション (TensorFlowの手順には書いてあるが特に必要ない?)

  • C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v10.0\bin
  • C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v10.0\extras\CUPTI\libx64
  • C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v10.0\include

【5. GPU版TensorFlowのインストール】

TensorFlowはCPUのみを使うバージョンと、GPUを使うバージョンの2種類があります。
GPUを使うバージョンは以下のコマンドでインストールできます。

pip install tensorflow-gpu

なお、事前にCPU版がインストールされている場合は上書きされるようです。
気になる場合は『事前に』CPU版をアンインストールしておいたほうが良さそうです。
アンインストールする場合は以下のコマンドを実行。

pip uninstall tensorflow

GPU版を入れてから上記コマンドを実行するとimport tensorflowでエラーになるので注意してください。
その場合は再度GPU版をインストールしなおせば直ります。

【動作確認】

以下のコマンドを実行します。
「出力結果」に tensorflow/core/common_runtime/gpu/gpu_device.cc:1640] Found device 0 with properties:device_type: "GPU" の文言が確認できればGPUを認識しています。
(本記事では「GeForce MX150」を認識しています)

python -c "from tensorflow.python.client import device_lib;print(device_lib.list_local_devices());"
出力結果.txt
2019-07-27 19:43:40.377037: I tensorflow/core/platform/cpu_feature_guard.cc:141] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2
2019-07-27 19:43:41.132310: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1433] Found device 0 with properties:
name: GeForce MX150 major: 6 minor: 1 memoryClockRate(GHz): 1.5315
pciBusID: 0000:01:00.0
totalMemory: 2.00GiB freeMemory: 1.62GiB
2019-07-27 19:43:41.143239: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1512] Adding visible gpu devices: 0
2019-07-27 19:43:41.779110: I tensorflow/core/common_runtime/gpu/gpu_device.cc:984] Device interconnect StreamExecutor with strength 1 edge matrix:
2019-07-27 19:43:41.783984: I tensorflow/core/common_runtime/gpu/gpu_device.cc:990]      0
2019-07-27 19:43:41.787937: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1003] 0:   N
2019-07-27 19:43:41.791116: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1115] Created TensorFlow device (/device:GPU:0 with 1364 MB memory) -> physical GPU (device: 0, name: GeForce MX150, pci bus id: 0000:01:00.0, compute capability: 6.1)
[name: "/device:CPU:0"
device_type: "CPU"
memory_limit: 268435456
locality {
}
incarnation: 12884386107899363910
, name: "/device:GPU:0"
device_type: "GPU"
memory_limit: 1431112499
locality {
  bus_id: 1
  links {
  }
}
incarnation: 16905718725287129387
physical_device_desc: "device: 0, name: GeForce MX150, pci bus id: 0000:01:00.0, compute capability: 6.1"
]

【TensorFlowとCUDA】

TensorFlowを使ったプログラムは、CPU版で動いていたものはそのままGPU版で動きます。
内部処理がすべてCUDAを利用するように変更されているため、プログラムを変更すことなくGPUを利用できるようになります。

ちなみにChainerの場合、numpyによる演算処理をcupyというCUDAを使ったnumpy互換のライブラリに置き換えることでGPUを使った処理ができるようになるようです。
cupy自体はChainerの機能ではありません。
そのためcupyを単体で利用することで、どんなプログラムでもGPUを使うように変更できますが、CPU版との互換はありません。
(そもそもCUDA対応のGPUが搭載されていないとCUDAがインストールできない上に、CUDAが入っていないとcupyがインストールできない)

【GPU利用時の速度差】

Yolo v3で物体検知を行った場合

スペック 処理時間 備考
Core i5 4200 2.3GHz 2.5~2.6秒 GPU非搭載 CPUのみ
Core i7 8550U 1.8GHz 0.9~1.1秒 CPU版
上記 + GeForce MX150 0.24~0.25秒 GPU版
Jetson Nano (参考) 0.22~0.25秒 GPU版

下記のリポジトリをもとにしてWebカメラでリアルタイムで物体認識できるように改変したもので測定しました。
(認識サイズ416×416 RGB)
【GitHub - keras-yolo3】

ショボいモバイルGPUでもそれなりに効果は出ますね。
でもエッジデバイスのJetson Nanoと同等とは…

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

DeepLearningでアボカドの硬さ推定[2]

DeepLearningでアボカドの硬さを推定する話

DeepLearningでアボカドの硬さ推定[1]ではデータのサンプリングを行いました。
今回はサンプリングしたデータを加工します。
もしかして、データマイニングってやつ?

FFT(高速フーリエ変換)

音声データを機械学習させるときにはフーリエ変換というものをするらしいのです。
先人の知恵をお借りして何とかFFTのコードを書くことができました。
特にIAMASの小林先生の機械学習とRaspberry Piを用いてレーザー加工機の動作状態を判定するを参考にさせていただきました。

# モジュールをインポート
import glob
import numpy as np
import matplotlib.pyplot as plt
import random as rn
import librosa
import os
import sys
import pandas as pd

# WAVファイルのパスを指定
path = 'bachi/*.wav'
sampling_rate = 44100
raw_sounds = []
wav_file_names = []

# glob関数でWAVファイルパスをpython標準Listへ
for wav_file_name in sorted(glob.glob(path)):
    data, sample_rate = librosa.load(wav_file_name, sr=sampling_rate , duration=0.8)
    print('{} ({} Hz) '.format(wav_file_name, sample_rate))
    raw_sounds.append(data)
    wav_file_names.append(wav_file_name)

# FFTサイズの設定
fft_size = 8192
stft_matrix_size = 1 + fft_size // 2
test = np.empty((0, stft_matrix_size))
# FFTの実行
for i, wav_file_name in enumerate(wav_file_names):
    d00 = np.abs(librosa.stft(raw_sounds[i], n_fft=fft_size, window='hamming'))
    d0 = np.sum(d00, axis=1,dtype='float32') / d00.shape[1]
    d = d0  # / np.amax(d0)
    test = np.append(test, np.array([d]), axis=0)

# アボカドのサンプル数を指定
num_data = 25
# 何回分の打撃FFTデータを平均するか指定
mean_data = 10
# 打撃FFTデータを平均する処理を実行
X_data = np.empty((0, d.shape[0]))
for yy in range(num_data):
    c = np.empty((0, d.shape[0]))
    for i in range(d.shape[0]):
        b = test[yy*mean_data:yy*mean_data+mean_data,i:1+i].sum() / num_data
        c = np.append(c, b)
    X_data = np.append(X_data, np.array([c]), axis=0)

# FFTの結果を保存
np.savetxt('bachi_X_all.csv',X_data,delimiter=',')

FFTの結果

image.png

人間の目で見てもどこに特徴があるかわかりませんよね。
なんのこっちゃって感じです。
なんとなく601Hz以下に特徴があるような気もしますね。憶測ですが。

精度の確認

ちなみここの時点でKerasとTensorFlowでて回帰分析を行い、結果として得られた決定係数を下図に示します。
TrainとTestの分割を50通りに行ったので、計50回分の決定係数値のヒストグラムになっております。
(KerasとTensorFlowを使った回帰分析のコードは次回)
image.png
平均するとTrainデータに対する決定係数は0.99、Testデータに対する決定係数は0.81でそんなに悪くなく見えますが、
Testデータに対する決定係数が0.4以下だった場合も少なからずあります。
これでは精度が高いとは言えないでしょう。

次回、[3]特徴量選択へ続きます。(投稿は8月に入ってから)

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

DeepLearningでアボカドの硬さ推定[1]

DeepLearningでアボカドの硬さを推定する話

DeepLearningでアボカドの硬さ推定[0]ではイントロダクション的な内容を投稿しました。
今回はアボカドから叩いた音と硬さのデータをサンプリングします。

アボカドからデータ収集

使ったデバイス

・RaspberryPi3
image.png

・USBとマイクジャックを変換するアダプター(Amazonで700円くらいのやつ)
・マイク(Amazonで300円くらいのやつ)
・どこのおうちにでもある貫入硬度計(笑)多分お高い
image.png

どうやったの?

打音(X)の方

アボカドをペシペシ叩いて、台座に仕込んだマイクから打音を保存します。
形式は皆さんおなじみの拡張子のWAVです。
image.png
実際のところ、PCに直接マイクを接続して録音する方法の方がいいと思うんです。
しかしながら、今回は回りくどくラズパイにマイクを接続してやりました。
当時の私はラズパイにも手を出してみたかったんです。ロマン追求ってやつです。

得られたデータはこんな感じ
image.png
20秒間に17回たたいてます。
最終的にアボカド50個分のデータをサンプリングすることになりました。

硬さ(Y)の方

どこにでもある機材ってわけではないので、ちゃんと書いてもあれなんですけど、
アボカドの赤道部3カ所に12mmほど治具を貫入して測定し、ある位相での値の平均値を硬度としました。
ここちらも同様に50個分のデータをサンプリングしました。
image.png

データサンプリング編はこれで終わりです。
次回は[2]データの加工になります。
やっとコードを書きますよ。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Dataset を使った TensorFlow のモデルを SavedModel 形式のファイルから復元して推論を行う(C++編)

Dataset を使った TensorFlow のモデルを SavedModel 形式のファイルから復元して推論を行う(C++編)

はじめに

前回の記事 では Python で TensorFlow の Dataset を使用して学習を行い、モデルを SavedModel の形式で保存しました。

今回は、そのモデルを C++ のコードから読み込んで推論を実行してみたいと思います。

本記事で説明しているソースコードは こちら に載せてあります。

実行環境

  • Windows
  • Visual Studio 2015
  • tensorflow 1.10.0

モデルの読み込み

初めにモデルを読み込みます。

infer.cpp
  const std::string export_dir = "./model";
  SavedModelBundle bundle;
  SessionOptions session_options;
  RunOptions run_options;

  Status status = tensorflow::LoadSavedModel(session_options, run_options, export_dir, {tensorflow::kSavedModelTagServe}, &bundle);
  if (!status.ok()) {
    std::cout << status.ToString() << std::endl;
    return -1;
  }

入力データの作成

入力用データ(Tensor 型)を作成します。

infer.cpp
  Tensor batch_size(tensorflow::DT_INT64, tensorflow::TensorShape());
  auto dst = batch_size.flat<long long>().data();
  long long bsize = 3L;
  memcpy(dst, &bsize, sizeof(bsize));

  Tensor input(tensorflow::DT_FLOAT, TensorShape({3, 1}));
  auto input_dst = input.flat<float>().data();
  float arr[3] = {2.0, 3.0, 4.0};
  memcpy(input_dst, arr, sizeof(arr));

Iterator の初期化

Iterator の初期化を行います。"dataset_init" はモデル作成時に指定した initializer の名前です。
また、"input", "target", "batch_size" は同様にモデル作成時に指定した placeholder の名前です。

infer.cpp
  status = bundle.session->Run(
      {{"input", input}, {"target", input}, {"batch_size", batch_size}},
      {},
      {"dataset_init"},
      nullptr);
  if (!status.ok()) {
    std::cout << "Failed to run sesssion (dataset_init)" << std::endl;
    std::cout << status.ToString() << std::endl;
    return -1;
  }

推論の実行

最後に推論を実行します。"output:0" はモデル作成時に指定した出力ノードの名前です。

infer.cpp
  std::vector<Tensor> outputs;
  status = bundle.session->Run({}, {"output:0"}, {}, &outputs);
  if (!status.ok()) {
    std::cout << "Failed to run sesssion (output:0)" << std::endl;
    std::cout << status.ToString() << std::endl;
    return -1;
  }

  Tensor a = outputs.at(0);
  const int out_dim = 3;
  for (int i = 0; i < out_dim; i++) {
    std::cout << a.flat<float>()(i) << std::endl;
  }

実行すると以下のように Python 版とほぼ同じ推論結果が得られます。

2 4.16
3 6.12808
4 8.09616
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Dataset を使った TensorFlow のモデルを SavedModel を使用して保存・復元する

Dataset を使った TensorFlow のモデルを SavedModel を使用して保存・復元する

はじめに

TensorFlow の tf.data.Dataset を使用したモデルを SavedModel 保存・復元する方法について説明したいと思います。
保存したモデルを C++ で復元・利用する方法についてはこちらで説明しています。

本記事で説明しているソースコードは こちら に載せてあります。

実行環境

  • Windows
  • Python 3.6
  • tensorflow 1.10.0

モデルの学習から保存まで

はじめに学習用データとその正解ラベル、検証用のデータを作成します。
今回は y = 2 * x を学習してみることにします。

train.py
# 学習用データ
train = np.array(np.random.sample((100, 1)) * 10, dtype='float32')
train_label = 2 * train

# 検証用データ
test_data = np.array([[1.0], [2.0], [3.0]], dtype='float32')
test_label = test_data

実行時に指定されるデータのための placeholder を作成します。
後で利用しやすいように、各々に name も付けておきます。

train.py
batch_size = tf.placeholder(tf.int64, name='batch_size')
x = tf.placeholder(tf.float32, shape=[None, 1], name='input')
y = tf.placeholder(tf.float32, shape=[None, 1], name='target')

上記の placeholder を用いて Dataset と Iterator を生成します。
Iterator が返すデータ自体は改めて指定するので、ここでは tf.data.Iterator.from_structure を使用して形だけを作成しておきます。

train.py
dataset = tf.data.Dataset.from_tensor_slices((x, y)).batch(batch_size).repeat()
iter = tf.data.Iterator.from_structure(dataset.output_types, dataset.output_shapes)
dataset_init_op = iter.make_initializer(dataset, name='dataset_init')

上記の Iterator からモデルへの入力となるデータ(tensor)を取得します。

train.py
x_, y_ = iter.get_next()

上記のデータを使用してモデルを作成します。

train.py
# make a simple model
prediction = tf.identity(tf.layers.dense(x_, 1), name='output')

# Optimize loss
loss = tf.reduce_mean(tf.square(prediction - y_), name='loss')
optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.01)
train_op = optimizer.minimize(loss, name='train')

ここから学習を開始していきます。初めに dataset_init_op を実行して、学習に使用するデータを指定します。

train.py
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    sess.run(dataset_init_op, feed_dict={ x: train, y: train_label, batch_size: BATCH_SIZE })

次に、実際の学習を進めていきます。学習量データは入力済みのため、ここでは学習の実行(train_op)と loss の取得(loss)のみ run の引数で指定しています。

train.py
    for i in range(EPOCHS):
        _, loss_value = sess.run([train_op, loss])
        print("Iter: {}, Loss: {:.4f}".format(i, loss_value))

学習が完了したら dataset_init_op を再度実行して、検証用のデータを指定します。
更に prediction を実行して検証結果を取得・表示します。

train.py
    sess.run(dataset_init_op, feed_dict={ x: test_data, y: test_label, batch_size: test_data.shape[0] })
    results = sess.run(prediction)
    for i in range(len(results)):
        print("{} {}".format(test_data[i], results[i]))

最後に tf.saved_model.simple_save を使用して model というフォルダにモデルを保存します。

train.py
    inputs_dict = {
        "x": x,
        "y": y,
        "batch_size": batch_size
    }
    outputs_dict = {
        "output": prediction
    }
    tf.saved_model.simple_save(sess, './model', inputs_dict, outputs_dict)

上記を実行すると以下のような結果が得られます。

Iter: 0, Loss: 81.2936
Iter: 1, Loss: 11.0675
Iter: 2, Loss: 0.0215
Iter: 3, Loss: 0.0091
Iter: 4, Loss: 0.0231
Iter: 5, Loss: 0.0119
Iter: 6, Loss: 0.0125
Iter: 7, Loss: 0.0121
Iter: 8, Loss: 0.0144
Iter: 9, Loss: 0.0160
[1.] [2.1919134]
[2.] [4.1599956]
[3.] [6.1280775]

モデルの復元と推論

学習時と同様に入力データを生成します。

test.py
test_data = np.array([[2.0], [3.0], [4.0]], dtype='float32')
test_label = test_data

model フォルダからモデルのデータを復元します。

test.py
graph = tf.Graph()
with graph.as_default():
    with tf.Session(graph=graph) as sess:
        tf.saved_model.loader.load(
            sess,
            [tag_constants.SERVING],
            './model'
        )

次に、iterator を初期化する dataset_init をグラフから取得します。

test.py
        dataset_init_op = graph.get_operation_by_name('dataset_init')

この dataset_init と上記の入力データを使用して iterator の初期化を行います。

test.py
        sess.run(dataset_init_op, feed_dict={
            'input:0': test_data,
            'target:0': test_label,
            'batch_size:0': test_data.shape[0]
            }
        )

最後に推論を行い、結果を取得します。

test.py
        results = sess.run('output:0')
        for i in range(len(results)):
            print("{} {}".format(test_data[i], results[i]))

実行すると以下のような結果が得られます。

[2.] [4.1599956]
[3.] [6.1280775]
[4.] [8.09616]

ハマりどころ1

上記の結論に達するまでに、下記の例外が発生する問題がなかなか解決できずに苦労しました。

FailedPreconditionError (see above for traceback): GetNext() failed because the iterator has not been initialized

以下のようなコードを書いていたところ

test_data = np.array([[1.0], [2.0], [3.0]], dtype='float32')
test_label = test_data

dataset = tf.data.Dataset.from_tensor_slices((test_data, test_label))
iter = dataset.make_initializable_iterator()
x_, y_ = iterator.get_next()


graph = tf.Graph()
with graph.as_default():
    with tf.Session(graph=graph) as sess:
        tf.saved_model.loader.load(
            sess,
            [tag_constants.SERVING],
            './model'
        )

        sess.run(iter.initializer, feed_dict={
            'input:0': test_data,
            'target:0': test_label,
            'batch_size:0': test_data.shape[0]
            }
        )

        results = sess.run('output:0')

sess.run('output:0') の実行時に下記の例外が発生してしまいました。

FailedPreconditionError (see above for traceback): GetNext() failed because the iterator has not been initialized

これは、上記のコード内で iter.initializer を実行した場合でも、モデルの中に保存されている Iterator を初期化することにはならない為のようです。

ハマりどころ2

初めは SavedModel ではなく、freeze した .pb 形式のモデルを保存・復元しようとしていたのですがこのやり方だと Iterator の保存・復元が上手くできませんでした。(やり方はあるかも知れませんが、できるという情報もできないという情報も見つけられなかったため、途中で諦めてしまいました)

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む