Microsoft-cognitive-toolkit-neural-network-regression

提供:Dev Guides
移動先:案内検索

CNTK-ニューラルネットワーク回帰

この章は、CNTKに関するニューラルネットワーク回帰の理解に役立ちます。

前書き

ご存知のように、1つ以上の予測変数から数値を予測するために、回帰を使用します。 たとえば、100の町の1つにある家の中央値を予測する例を見てみましょう。 そうするために、我々は含むデータがあります-

  • 各町の犯罪統計。
  • 各町の住宅の築年数。
  • 各町から一等地までの距離の目安。
  • 各町の生徒と教師の比率。
  • 各町の人種人口統計。
  • 各町の住宅価値の中央値。

これらの5つの予測変数に基づいて、住宅価値の中央値を予測します。 このために、次の線に沿って線形回帰モデルを作成できます。

Y = a0+a1(crime)+a2(house-age)+(a3)(distance)+(a4)(ratio)+(a5)(racial)

上記の方程式では-

*Y* は予測中央値
  • _ a _ * 0は定数であり、
  • _ a ' * 1から* ' a _ * 5まではすべて、上で説明した5つの予測子に関連付けられた定数です。

ニューラルネットワークを使用する別の方法もあります。 より正確な予測モデルを作成します。

ここでは、CNTKを使用してニューラルネットワーク回帰モデルを作成します。

データセットの読み込み

CNTKを使用してニューラルネットワーク回帰を実装するには、ボストンエリアの家の値のデータセットを使用します。 データセットは、https://archive.ics.uci.edu/ml/machine-learning-databases/housing/にあるUCI Machine Learning Repositoryからダウンロードできます。 このデータセットには、合計14個の変数と506個のインスタンスがあります。

ただし、実装プログラムでは、14個の変数のうち6個と100個のインスタンスを使用します。 6つのうち5つは予測子として、1つは予測する値として。 100個のインスタンスから、トレーニング用に80個、テスト用に20個を使用します。 予測したい値は、町の中央値です。 使用する5つの予測子を見てみましょう-

  • 町の一人当たりの犯罪-この予測因子には、より小さな値が関連付けられると予想されます。
  • 所有者の割合-1940年より前に建てられた占有ユニット-大きい値は古い家を意味するため、この予測値に関連付けられる値は小さいと予想されます。
  • 町から5つのボストン雇用センターまでの重量を測った。
  • 地域の学校の生徒と教師の比率。
  • 町の黒人居住者の割合の間接的な指標。

トレーニングとテストファイルの準備

前と同じように、最初に生データをCNTK形式に変換する必要があります。 最初の80個のデータ項目をトレーニング目的で使用するので、タブ区切りのCNTK形式は次のようになります-

|predictors 1.612820 96.90 3.76 21.00 248.31 |medval 13.50
|predictors 0.064170 68.20 3.36 19.20 396.90 |medval 18.90
|predictors 0.097440 61.40 3.38 19.20 377.56 |medval 20.00
. . .

次の20項目もCNTK形式に変換され、テスト目的で使用されます。

回帰モデルの構築

最初に、データファイルをCNTK形式で処理する必要があります。そのために、次のように create_reader という名前のヘルパー関数を使用します-

def create_reader(path, input_dim, output_dim, rnd_order, sweeps):
x_strm = C.io.StreamDef(field='predictors', shape=input_dim, is_sparse=False)
y_strm = C.io.StreamDef(field='medval', shape=output_dim, is_sparse=False)
streams = C.io.StreamDefs(x_src=x_strm, y_src=y_strm)
deserial = C.io.CTFDeserializer(path, streams)
mb_src = C.io.MinibatchSource(deserial, randomize=rnd_order, max_sweeps=sweeps)
return mb_src

次に、CNTKミニバッチオブジェクトを受け入れ、カスタム精度メトリックを計算するヘルパー関数を作成する必要があります。

def mb_accuracy(mb, x_var, y_var, model, delta):
   num_correct = 0
   num_wrong = 0
   x_mat = mb[x_var].asarray()
   y_mat = mb[y_var].asarray()
for i in range(mb[x_var].shape[0]):
  v = model.eval(x_mat[i])
  y = y_mat[i]
if np.abs(v[0,0] – y[0,0]) < delta:
   num_correct += 1
else:
   num_wrong += 1
return (num_correct * 100.0)/(num_correct + num_wrong)

次に、NNのアーキテクチャー引数を設定し、データファイルの場所を指定する必要があります。 それは次のpythonコードの助けを借りて行うことができます-

def main():
print("Using CNTK version = " + str(C.__version__) + "\n")
input_dim = 5
hidden_dim = 20
output_dim = 1
train_file = ".\\...\\" #provide the name of the training file(80 data items)
test_file = ".\\...\\" #provide the name of the test file(20 data items)

今、次のコードラインの助けを借りて、私たちのプログラムは訓練されていないNNを作成します-

X = C.ops.input_variable(input_dim, np.float32)
Y = C.ops.input_variable(output_dim, np.float32)
with C.layers.default_options(init=C.initializer.uniform(scale=0.01, seed=1)):
hLayer = C.layers.Dense(hidden_dim, activation=C.ops.tanh, name='hidLayer')(X)
oLayer = C.layers.Dense(output_dim, activation=None, name='outLayer')(hLayer)
model = C.ops.alias(oLayer)

次に、トレーニングされていないデュアルモデルを作成したら、学習者アルゴリズムオブジェクトを設定する必要があります。 SGD学習器と squared_error 損失関数を使用します-

tr_loss = C.squared_error(model, Y)
max_iter = 3000
batch_size = 5
base_learn_rate = 0.02
sch=C.learning_parameter_schedule([base_learn_rate, base_learn_rate/2], minibatch_size=batch_size, epoch_size=int((max_iter*batch_size)/2))
learner = C.sgd(model.parameters, sch)
trainer = C.Trainer(model, (tr_loss), [learner])

ここで、学習アルゴリズムオブジェクトを使い終わったら、トレーニングデータを読み取るリーダー関数を作成する必要があります。

rdr = create_reader(train_file, input_dim, output_dim, rnd_order=True, sweeps=C.io.INFINITELY_REPEAT)
boston_input_map = { X : rdr.streams.x_src, Y : rdr.streams.y_src }

さあ、NNモデルをトレーニングする時が来ました-

for i in range(0, max_iter):
curr_batch = rdr.next_minibatch(batch_size, input_map=boston_input_map) trainer.train_minibatch(curr_batch)
if i % int(max_iter/10) == 0:
mcee = trainer.previous_minibatch_loss_average
acc = mb_accuracy(curr_batch, X, Y, model, delta=3.00)
print("batch %4d: mean squared error = %8.4f, accuracy = %5.2f%% " \ % (i, mcee, acc))

トレーニングが完了したら、テストデータアイテムを使用してモデルを評価しましょう-

print("\nEvaluating test data \n")
rdr = create_reader(test_file, input_dim, output_dim, rnd_order=False, sweeps=1)
boston_input_map = { X : rdr.streams.x_src, Y : rdr.streams.y_src }
num_test = 20
all_test = rdr.next_minibatch(num_test, input_map=boston_input_map)
acc = mb_accuracy(all_test, X, Y, model, delta=3.00)
print("Prediction accuracy = %0.2f%%" % acc)

訓練されたNNモデルの精度を評価した後、目に見えないデータの予測を行うためにそれを使用します-

np.set_printoptions(precision = 2, suppress=True)
unknown = np.array([[dtype=np.float32)
print("\nPredicting median home value for feature/predictor values: ")
print(unknown[0])
pred_prob = model.eval({X: unknown)
print("\nPredicted value is: ")
print(“$%0.2f (x1000)” %pred_value[0,0])

完全な回帰モデル

import numpy as np
import cntk as C
def create_reader(path, input_dim, output_dim, rnd_order, sweeps):
x_strm = C.io.StreamDef(field='predictors', shape=input_dim, is_sparse=False)
y_strm = C.io.StreamDef(field='medval', shape=output_dim, is_sparse=False)
streams = C.io.StreamDefs(x_src=x_strm, y_src=y_strm)
deserial = C.io.CTFDeserializer(path, streams)
mb_src = C.io.MinibatchSource(deserial, randomize=rnd_order, max_sweeps=sweeps)
return mb_src
def mb_accuracy(mb, x_var, y_var, model, delta):
num_correct = 0
num_wrong = 0
x_mat = mb[x_var].asarray()
y_mat = mb[y_var].asarray()
for i in range(mb[x_var].shape[0]):
   v = model.eval(x_mat[i])
   y = y_mat[i]
if np.abs(v[0,0] – y[0,0]) < delta:
   num_correct += 1
else:
   num_wrong += 1
return (num_correct * 100.0)/(num_correct + num_wrong)
def main():
print("Using CNTK version = " + str(C.__version__) + "\n")
input_dim = 5
hidden_dim = 20
output_dim = 1
train_file = ".\\...\\" #provide the name of the training file(80 data items)
test_file = ".\\...\\" #provide the name of the test file(20 data items)
X = C.ops.input_variable(input_dim, np.float32)
Y = C.ops.input_variable(output_dim, np.float32)
with C.layers.default_options(init=C.initializer.uniform(scale=0.01, seed=1)):
hLayer = C.layers.Dense(hidden_dim, activation=C.ops.tanh, name='hidLayer')(X)
oLayer = C.layers.Dense(output_dim, activation=None, name='outLayer')(hLayer)
model = C.ops.alias(oLayer)
tr_loss = C.squared_error(model, Y)
max_iter = 3000
batch_size = 5
base_learn_rate = 0.02
sch = C.learning_parameter_schedule([base_learn_rate, base_learn_rate/2], minibatch_size=batch_size, epoch_size=int((max_iter*batch_size)/2))
learner = C.sgd(model.parameters, sch)
trainer = C.Trainer(model, (tr_loss), [learner])
rdr = create_reader(train_file, input_dim, output_dim, rnd_order=True, sweeps=C.io.INFINITELY_REPEAT)
boston_input_map = { X : rdr.streams.x_src, Y : rdr.streams.y_src }
for i in range(0, max_iter):
curr_batch = rdr.next_minibatch(batch_size, input_map=boston_input_map) trainer.train_minibatch(curr_batch)
if i % int(max_iter/10) == 0:
   mcee = trainer.previous_minibatch_loss_average
   acc = mb_accuracy(curr_batch, X, Y, model, delta=3.00)
   print("batch %4d: mean squared error = %8.4f, accuracy = %5.2f%% " \ % (i, mcee, acc))
   print("\nEvaluating test data \n")
   rdr = create_reader(test_file, input_dim, output_dim, rnd_order=False, sweeps=1)
   boston_input_map = { X : rdr.streams.x_src, Y : rdr.streams.y_src }
   num_test = 20
all_test = rdr.next_minibatch(num_test, input_map=boston_input_map)
acc = mb_accuracy(all_test, X, Y, model, delta=3.00)
print("Prediction accuracy = %0.2f%%" % acc)
np.set_printoptions(precision = 2, suppress=True)
unknown = np.array([[dtype=np.float32)
print("\nPredicting median home value for feature/predictor values: ")
print(unknown[0])
pred_prob = model.eval({X: unknown)
print("\nPredicted value is: ")
print(“$%0.2f (x1000)” %pred_value[0,0])
if __name__== ”__main__”:
   main()

出力

Using CNTK version = 2.7
batch 0: mean squared error = 385.6727, accuracy = 0.00%
batch 300: mean squared error = 41.6229, accuracy = 20.00%
batch 600: mean squared error = 28.7667, accuracy = 40.00%
batch 900: mean squared error = 48.6435, accuracy = 40.00%
batch 1200: mean squared error = 77.9562, accuracy = 80.00%
batch 1500: mean squared error = 7.8342, accuracy = 60.00%
batch 1800: mean squared error = 47.7062, accuracy = 60.00%
batch 2100: mean squared error = 40.5068, accuracy = 40.00%
batch 2400: mean squared error = 46.5023, accuracy = 40.00%
batch 2700: mean squared error = 15.6235, accuracy = 60.00%
Evaluating test data
Prediction accuracy = 64.00%
Predicting median home value for feature/predictor values:
[0.09 50. 4.5 17. 350.]
Predicted value is:
$21.02(x1000)

トレーニング済みモデルを保存する

このBoston Homeの値のデータセットには、506のデータアイテムしかありません(そのうち100のみを訴えました)。 したがって、NNリグレッサモデルのトレーニングには数秒しかかかりませんが、数百または数千のデータアイテムを含む大規模なデータセットのトレーニングには、数時間または数日かかる場合があります。

モデルを保存できるので、モデルを最初から保持する必要はありません。 次のPythonコードの助けを借りて、訓練されたNNを保存できます-

nn_regressor = “.\\neuralregressor.model” #provide the name of the file
model.save(nn_regressor, format=C.ModelFormat.CNTKv2)

以下は、上記で使用されたsave()関数の引数です-

  • ファイル名は* save()*関数の最初の引数です。 ファイルのパスとともに書き込むこともできます。
  • 別のパラメーターは format パラメーターで、デフォルト値は C.ModelFormat.CNTKv2 です。

トレーニング済みモデルの読み込み

トレーニング済みモデルを保存すると、そのモデルを非常に簡単にロードできます。 load()関数を使用するだけです。 次の例でこれを確認しましょう-

import numpy as np
import cntk as C
model = C.ops.functions.Function.load(“.\\neuralregressor.model”)
np.set_printoptions(precision = 2, suppress=True)
unknown = np.array([[dtype=np.float32)
print("\nPredicting area median home value for feature/predictor values: ")
print(unknown[0])
pred_prob = model.eval({X: unknown)
print("\nPredicted value is: ")
print(“$%0.2f (x1000)” %pred_value[0,0])

保存されたモデルの利点は、保存されたモデルをロードすると、モデルがトレーニングされたばかりのように使用できることです。