Microsoft-cognitive-toolkit-out-of-memory-datasets
CNTK-メモリ不足のデータセット
この章では、メモリ不足のデータセットのパフォーマンスを測定する方法について説明します。
前のセクションでは、NNのパフォーマンスを検証するさまざまな方法について説明しましたが、ここで説明した方法は、メモリに収まるデータセットを処理する方法です。
ここでは、メモリ不足のデータセットについての質問が発生します。本番シナリオでは、 NN をトレーニングするために大量のデータが必要になるためです。 このセクションでは、ミニバッチソースと手動ミニバッチループを使用する場合のパフォーマンスを測定する方法について説明します。
ミニバッチソース
メモリ不足のデータセットを操作しているとき、つまり ミニバッチソースの場合、小さなデータセットを操作するときに使用したセットアップとは少し異なる、セットアップとメトリックのセットアップが必要です。 インメモリデータセット。 最初に、NNモデルのトレーナーにデータをフィードする方法を設定する方法を説明します。
次に、実装手順を示します。
- ステップ1 *-まず、cntk。 ioモジュールから、次のようにミニバッチソースを作成するためのコンポーネントをインポートします-
from cntk.io import StreamDef, StreamDefs, MinibatchSource, CTFDeserializer,
INFINITY_REPEAT
ステップ2 *-次に、say *create_datasource という名前の新しい関数を作成します。 この関数には、ファイル名と制限という2つのパラメーターがあり、デフォルト値は INFINITELY_REPEAT です。
def create_datasource(filename, limit =INFINITELY_REPEAT)
ステップ3 *-関数内で、 *StreamDef クラスを使用して、3つの機能を持つラベルフィールドから読み取るラベルのストリーム定義を作成します。 また、次のように is_sparse を False に設定する必要があります
labels_stream = StreamDef(field=’labels’, shape=3, is_sparse=False)
ステップ4 *-次に、入力ファイルからファイルされた機能を読み取るために作成し、次のように *StreamDef の別のインスタンスを作成します。
feature_stream = StreamDef(field=’features’, shape=4, is_sparse=False)
ステップ5 *-次に、 *CTFDeserializer インスタンスクラスを初期化します。 次のように、逆シリアル化する必要があるファイル名とストリームを指定します-
deserializer = CTFDeserializer(filename, StreamDefs(labels=
label_stream, features=features_stream)
- ステップ6 *-次に、次のようにデシリアライザを使用してminisourceBatchのインスタンスを作成する必要があります-
Minibatch_source = MinibatchSource(deserializer, randomize=True, max_sweeps=limit)
return minibatch_source
- ステップ7 *-最後に、前のセクションでも作成したトレーニングとテストのソースを提供する必要があります。 アイリスの花のデータセットを使用しています。
training_source = create_datasource(‘Iris_train.ctf’)
test_source = create_datasource(‘Iris_test.ctf’, limit=1)
*MinibatchSource* インスタンスを作成したら、それをトレーニングする必要があります。 小さなインメモリデータセットで作業したときと同じトレーニングロジックを使用できます。 ここでは、次のように、損失関数の学習メソッドの入力として *MinibatchSource* インスタンスを使用します-
次に、実装手順を示します。
ステップ1 *-トレーニングセッションの出力をログに記録するには、まず次のように *cntk.logging モジュールから ProgressPrinter をインポートします-
from cntk.logging import ProgressPrinter
ステップ2 *-次に、トレーニングセッションを設定するには、次のように *cntk.train モジュールから trainer および training_session をインポートします。
from cntk.train import Trainer, training_session
ステップ3 *-ここで、 *minibatch_size 、 samples_per_epoch 、 num_epochs などの定数のセットを次のように定義する必要があります-
minbatch_size = 16
samples_per_epoch = 150
num_epochs = 30
max_samples = samples_per_epoch * num_epochs
- ステップ4 *-次に、CNTKでのトレーニング中にデータを読み取る方法を知るために、ネットワークの入力変数とミニバッチソースのストリーム間のマッピングを定義する必要があります。
input_map = {
features: training_source.streams.features,
labels: training_source.streams.labels
}
ステップ5 *-次にトレーニングプロセスの出力をログに記録するには、 *progress_printer 変数を新しい ProgressPrinter インスタンスで初期化します。 また、 trainer を初期化し、次のようにモデルを提供します
progress_writer = ProgressPrinter(0)
trainer: training_source.streams.labels
ステップ6 *-最後に、トレーニングプロセスを開始するには、次のように *training_session 関数を呼び出す必要があります-
session = training_session(trainer,
mb_source=training_source,
mb_size=minibatch_size,
model_inputs_to_streams=input_map,
max_samples=max_samples,
test_config=test_config)
session.train()
モデルをトレーニングしたら、 TestConfig オブジェクトを使用してこの設定に検証を追加し、 train_session 関数の test_config キーワード引数に割り当てることができます。
次に、実装手順を示します。
ステップ1 *-最初に、次のように *cntk.train モジュールから TestConfig クラスをインポートする必要があります-
from cntk.train import TestConfig
ステップ2 *-次に、 *test_source を入力として TestConfig の新しいインスタンスを作成する必要があります-
Test_config = TestConfig(test_source)
完全な例
from cntk.io import StreamDef, StreamDefs, MinibatchSource, CTFDeserializer, INFINITY_REPEAT
def create_datasource(filename, limit =INFINITELY_REPEAT)
labels_stream = StreamDef(field=’labels’, shape=3, is_sparse=False)
feature_stream = StreamDef(field=’features’, shape=4, is_sparse=False)
deserializer = CTFDeserializer(filename, StreamDefs(labels=label_stream, features=features_stream)
Minibatch_source = MinibatchSource(deserializer, randomize=True, max_sweeps=limit)
return minibatch_source
training_source = create_datasource(‘Iris_train.ctf’)
test_source = create_datasource(‘Iris_test.ctf’, limit=1)
from cntk.logging import ProgressPrinter
from cntk.train import Trainer, training_session
minbatch_size = 16
samples_per_epoch = 150
num_epochs = 30
max_samples = samples_per_epoch * num_epochs
input_map = {
features: training_source.streams.features,
labels: training_source.streams.labels
}
progress_writer = ProgressPrinter(0)
trainer: training_source.streams.labels
session = training_session(trainer,
mb_source=training_source,
mb_size=minibatch_size,
model_inputs_to_streams=input_map,
max_samples=max_samples,
test_config=test_config)
session.train()
from cntk.train import TestConfig
Test_config = TestConfig(test_source)
出力
-------------------------------------------------------------------
average since average since examples
loss last metric last
------------------------------------------------------
Learning rate per minibatch: 0.1
1.57 1.57 0.214 0.214 16
1.38 1.28 0.264 0.289 48
[………]
Finished Evaluation [1]: Minibatch[1-1]:metric = 69.65*30;
手動ミニバッチループ
上記のように、CNTKで通常のAPIを使用してトレーニングするときにメトリックを使用すると、トレーニング中およびトレーニング後のNNモデルのパフォーマンスを簡単に測定できます。 しかし、一方で、手動のミニバッチループで作業している間は、それほど簡単ではありません。
ここでは、前のセクションでも作成したIris Flowerデータセットからの4つの入力と3つの出力を使用して、以下のモデルを使用しています。
from cntk import default_options, input_variable
from cntk.layers import Dense, Sequential
from cntk.ops import log_softmax, relu, sigmoid
from cntk.learners import sgd
model = Sequential([
Dense(4, activation=sigmoid),
Dense(3, activation=log_softmax)
])
features = input_variable(4)
labels = input_variable(3)
z = model(features)
次に、モデルの損失は、クロスエントロピー損失関数と、前のセクションで使用したFメジャーメトリックの組み合わせとして定義されます。 以下に示すように、 criterion_factory ユーティリティを使用して、これをCNTK関数オブジェクトとして作成します。
import cntk
from cntk.losses import cross_entropy_with_softmax, fmeasure
@cntk.Function
def criterion_factory(outputs, targets):
loss = cross_entropy_with_softmax(outputs, targets)
metric = fmeasure(outputs, targets, beta=1)
return loss, metric
loss = criterion_factory(z, labels)
learner = sgd(z.parameters, 0.1)
label_mapping = {
'Iris-setosa': 0,
'Iris-versicolor': 1,
'Iris-virginica': 2
}
これで損失関数を定義したので、トレーナーでそれを使用して手動トレーニングセッションをセットアップする方法を確認します。
以下は実装手順です-
ステップ1 *-最初に、データをロードして前処理するために *numpy や pandas などの必要なパッケージをインポートする必要があります。
import pandas as pd
import numpy as np
ステップ2 *-次に、トレーニング中に情報をログに記録するために、次のように *ProgressPrinter クラスをインポートします-
from cntk.logging import ProgressPrinter
- ステップ3 *-次に、次のようにcntk.trainモジュールからトレーナーモジュールをインポートする必要があります-
from cntk.train import Trainer
ステップ4 *-次に、次のように *ProgressPrinter の新しいインスタンスを作成します-
progress_writer = ProgressPrinter(0)
ステップ5 *-次に、損失、学習者、 *progress_writer のパラメーターを使用してトレーナーを次のように初期化する必要があります-
trainer = Trainer(z, loss, learner, progress_writer)
- ステップ6 *-次に、モデルをトレーニングするために、データセットを30回反復するループを作成します。 これが外側のトレーニングループになります。
for _ in range(0,30):
ステップ7 *-次に、パンダを使用してディスクからデータをロードする必要があります。 次に、 *mini-batches にデータセットをロードするために、 chunksize キーワード引数を16に設定します。
input_data = pd.read_csv('iris.csv',
names=['sepal_length', 'sepal_width','petal_length','petal_width', 'species'],
index_col=False, chunksize=16)
- ステップ8 *-次に、各*ミニバッチ*を反復するループの内部トレーニングを作成します。
for df_batch in input_data:
ステップ9 *-このループの内部で、 *iloc インデクサーを使用して最初の4つの列を、トレーニングおよびfloat32に変換する*機能*として読み取ります-
feature_values = df_batch.iloc[:,:4].values
feature_values = feature_values.astype(np.float32)
- ステップ10 *-次のように、最後の列をトレーニング元のラベルとして読み取ります-
label_values = df_batch.iloc[:,-1]
- ステップ11 *-次に、次のようにワンホットベクトルを使用して、ラベル文字列を数値表現に変換します-
label_values = label_values.map(lambda x: label_mapping[x])
- ステップ12 *-その後、ラベルの数値表示を行います。 次に、それらをnumpy配列に変換しますので、次のようにそれらを扱うのが簡単です-
label_values = label_values.values
- ステップ13 *-次に、変換したラベル値と同じ行数を持つ新しいnumpy配列を作成する必要があります。
encoded_labels = np.zeros((label_values.shape[0], 3))
- ステップ14 *-ここで、ワンホットエンコードされたラベルを作成するために、数値ラベル値に基づいて列を選択します。
encoded_labels[np.arange(label_values.shape[0]), label_values] = 1.
ステップ15 *-最後に、トレーナーで *train_minibatch メソッドを呼び出し、ミニバッチの処理済みの機能とラベルを提供する必要があります。
trainer.train_minibatch({features: feature_values, labels: encoded_labels})
完全な例
from cntk import default_options, input_variable
from cntk.layers import Dense, Sequential
from cntk.ops import log_softmax, relu, sigmoid
from cntk.learners import sgd
model = Sequential([
Dense(4, activation=sigmoid),
Dense(3, activation=log_softmax)
])
features = input_variable(4)
labels = input_variable(3)
z = model(features)
import cntk
from cntk.losses import cross_entropy_with_softmax, fmeasure
@cntk.Function
def criterion_factory(outputs, targets):
loss = cross_entropy_with_softmax(outputs, targets)
metric = fmeasure(outputs, targets, beta=1)
return loss, metric
loss = criterion_factory(z, labels)
learner = sgd(z.parameters, 0.1)
label_mapping = {
'Iris-setosa': 0,
'Iris-versicolor': 1,
'Iris-virginica': 2
}
import pandas as pd
import numpy as np
from cntk.logging import ProgressPrinter
from cntk.train import Trainer
progress_writer = ProgressPrinter(0)
trainer = Trainer(z, loss, learner, progress_writer)
for _ in range(0,30):
input_data = pd.read_csv('iris.csv',
names=['sepal_length', 'sepal_width','petal_length','petal_width', 'species'],
index_col=False, chunksize=16)
for df_batch in input_data:
feature_values = df_batch.iloc[:,:4].values
feature_values = feature_values.astype(np.float32)
label_values = df_batch.iloc[:,-1]
label_values = label_values.map(lambda x: label_mapping[x])
label_values = label_values.values
encoded_labels = np.zeros((label_values.shape[0], 3))
encoded_labels[np.arange(label_values.shape[0]),
label_values] = 1.
trainer.train_minibatch({features: feature_values, labels: encoded_labels})
出力
-------------------------------------------------------------------
average since average since examples
loss last metric last
------------------------------------------------------
Learning rate per minibatch: 0.1
1.45 1.45 -0.189 -0.189 16
1.24 1.13 -0.0382 0.0371 48
[………]
上記の出力では、トレーニング中の損失とメトリックの両方の出力が得られました。 これは、関数オブジェクトでメトリックと損失を組み合わせ、トレーナー構成でプログレスプリンターを使用したためです。
ここで、モデルのパフォーマンスを評価するために、モデルのトレーニングと同じタスクを実行する必要がありますが、今回は Evaluator インスタンスを使用してモデルをテストする必要があります。 次のPythonコードに示されています
from cntk import Evaluator
evaluator = Evaluator(loss.outputs[1], [progress_writer])
input_data = pd.read_csv('iris.csv',
names=['sepal_length', 'sepal_width','petal_length','petal_width', 'species'],
index_col=False, chunksize=16)
for df_batch in input_data:
feature_values = df_batch.iloc[:,:4].values
feature_values = feature_values.astype(np.float32)
label_values = df_batch.iloc[:,-1]
label_values = label_values.map(lambda x: label_mapping[x])
label_values = label_values.values
encoded_labels = np.zeros((label_values.shape[0], 3))
encoded_labels[np.arange(label_values.shape[0]), label_values] = 1.
evaluator.test_minibatch({ features: feature_values, labels:
encoded_labels})
evaluator.summarize_test_progress()
今、私たちは次のような出力を取得します-
出力
Finished Evaluation [1]: Minibatch[1-11]:metric = 74.62*143;