0

事前定義されたモデルなしで ax^2 分布を探すニューラル ネットワークを作成したいと考えています。正確には、[-1,1] 内のいくつかの点とそれらの四角形をトレーニングするために与えられ、[-10,10] などについても同様に再現および予測する必要があります。私は多かれ少なかれそれをしました-データセットなしで。しかし、データセットを使用してその使用方法を学ぶために、それを変更しようとしました。さて、プログラムを実行することに成功しましたが、出力は以前よりも悪くなり、主に定数 0 です。

以前のバージョンは [-1,1] の x^2 のような線形延長で、これはより優れていました。以前の出力 では青い線がフラットになりました。そして、目標は赤いものと一致することです..

ここで、コメントはポーランド語で、申し訳ありません。

# square2.py - drugie podejscie do trenowania sieci za pomocą Tensorflow
# cel: nauczyć sieć rozpoznawać rozkład x**2
# analiza skryptu z:
# https://stackoverflow.com/questions/43140591/neural-network-to-predict-nth-square

import tensorflow as tf
import matplotlib.pyplot as plt
import numpy as np
from tensorflow.python.framework.ops import reset_default_graph

# def. danych do trenowania sieci
# x_train = (np.random.rand(10**3)*4-2).reshape(-1,1)
# y_train = x_train**2
square2_dane = np.load("square2_dane.npz")
x_train = square2_dane['x_tren'].reshape(-1,1)
y_train = square2_dane['y_tren'].reshape(-1,1) 

# zoptymalizować dzielenie danych
# x_train = square2_dane['x_tren'].reshape(-1,1)
# ds_x = tf.data.Dataset.from_tensor_slices(x_train)
# batch_x = ds_x.batch(rozm_paczki)
# iterator = ds_x.make_one_shot_iterator()

# określenie parametrów sieci
wymiary = [50,50,50,1]
epoki = 500
rozm_paczki = 200

reset_default_graph()
X = tf.placeholder(tf.float32, shape=[None,1])
Y = tf.placeholder(tf.float32, shape=[None,1])

weights = []
biases = []
n_inputs = 1

# inicjalizacja zmiennych
for i,n_outputs in enumerate(wymiary):
    with tf.variable_scope("layer_{}".format(i)):
        w = tf.get_variable(name="W", shape=[n_inputs,n_outputs],initializer = tf.random_normal_initializer(mean=0.0,stddev=0.02,seed=42))
        b=tf.get_variable(name="b",shape=[n_outputs],initializer=tf.zeros_initializer)
        weights.append(w)
        biases.append(b)
        n_inputs=n_outputs

def forward_pass(X,weights,biases):
    h=X
    for i in range(len(weights)):
        h=tf.add(tf.matmul(h,weights[i]),biases[i])
        h=tf.nn.relu(h)
    return h    

output_layer = forward_pass(X,weights,biases)
f_strat = tf.reduce_mean(tf.squared_difference(output_layer,Y),1)
f_strat = tf.reduce_sum(f_strat)
# alternatywna funkcja straty
#f_strat2 = tf.reduce_sum(tf.abs(Y-y_train)/y_train)
optimizer = tf.train.AdamOptimizer(learning_rate=0.003).minimize(f_strat)

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    # trenowanie
    dataset = tf.data.Dataset.from_tensor_slices((x_train,y_train))
    dataset = dataset.batch(rozm_paczki)
    dataset = dataset.repeat(epoki)
    iterator = dataset.make_one_shot_iterator()
    ds_x, ds_y = iterator.get_next()
    sess.run(optimizer, {X: sess.run(ds_x), Y: sess.run(ds_y)})
    saver = tf.train.Saver()
    save = saver.save(sess, "./model.ckpt")
    print("Model zapisano jako: %s" % save)

    # puszczenie sieci na danych
    x_test = np.linspace(-1,1,600)
    network_outputs = sess.run(output_layer,feed_dict = {X :x_test.reshape(-1,1)})

plt.plot(x_test,x_test**2,color='r',label='y=x^2')
plt.plot(x_test,network_outputs,color='b',label='sieć NN')
plt.legend(loc='right')
plt.show()

問題はトレーニングデータの入力 sess.run(optimizer, {X: sess.run(ds_x), Y: sess.run(ds_y)}) か、ds_x、ds_yの定義にあると思います。それは私の最初のそのようなプログラムです..これは行の出力でした(「sees」ブロックの代わりに)

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    # trenowanie
    for i in range(epoki):
        idx = np.arange(len(x_train))
        np.random.shuffle(idx)
        for j in range(len(x_train)//rozm_paczki):
            cur_idx = idx[rozm_paczki*j:(rozm_paczki+1)*j]
            sess.run(optimizer,feed_dict = {X:x_train[cur_idx],Y:y_train[cur_idx]})
    saver = tf.train.Saver()
    save = saver.save(sess, "./model.ckpt")
    print("Model zapisano jako: %s" % save)

ありがとう!

PS: n 番目の正方形を予測するために、ニューラル ネットワークに大いに触発されました。

4

1 に答える 1

1

モデルの精度を低下させる原因となる 2 つの問題があり、どちらも次の行に関係しています。

sess.run(optimizer, {X: sess.run(ds_x), Y: sess.run(ds_y)})
  1. このコードはループ内にないため、1 つのトレーニング ステップのみが実行されます。元のコードはlen(x_train)//rozm_paczkiステップを実行しましたが、これはさらに進行するはずです。

  2. との 2 つの呼び出しは別々のステップで実行されます。つまり、関連のない異なるバッチからの値が含まsess.run(ds_x)ます。各呼び出しは次のバッチに移動するか、次のバッチに移動し、呼び出しで明示的に要求しなかった入力要素のすべての部分を破棄します。基本的に、バッチiとバッチi+1 (またはその逆) から取得し、モデルは無効なデータでトレーニングします。同じバッチから値を取得する場合は、1 回の呼び出しで行う必要があります。sess.run(ds_y)sess.run(ds_x)sess.run(ds_y)Iteratorsess.run()XYsess.run([ds_x, ds_y])

効率に影響を与える可能性のある懸念事項がさらに 2 つあります。

  1. Datasetシャッフルされません。元のコードはnp.random.shuffle()、各エポックの開始時に呼び出します。dataset = dataset.shuffle(len(x_train))beforeを含める必要がありますdataset = dataset.repeat()

  2. バックから Pythonに値をフェッチしてIterator(たとえば、 を実行する場合sess.run(ds_x))、それらをトレーニング ステップにフィードバックするのは非効率的です。Iterator.get_next()操作の出力を直接フィードフォワード ステップに入力として渡す方が効率的です。

これらをすべてまとめると、これら 4 つの点に対処し、正しい結果を達成するプログラムの書き直されたバージョンがここにあります。(残念ながら、私のポーランド語はコメントを保存するのに十分ではないため、英語に翻訳しました。)

import tensorflow as tf
import matplotlib.pyplot as plt
import numpy as np

# Generate training data.
x_train = np.random.rand(10**3, 1).astype(np.float32) * 4 - 2
y_train = x_train ** 2

# Define hyperparameters.
DIMENSIONS = [50,50,50,1]
NUM_EPOCHS = 500
BATCH_SIZE = 200

dataset = tf.data.Dataset.from_tensor_slices((x_train,y_train))
dataset = dataset.shuffle(len(x_train))  # (Point 3.) Shuffle each epoch.
dataset = dataset.repeat(NUM_EPOCHS)
dataset = dataset.batch(BATCH_SIZE)
iterator = dataset.make_one_shot_iterator()

# (Point 2.) Ensure that `X` and `Y` correspond to the same batch of data.
# (Point 4.) Pass the tensors returned from `iterator.get_next()`
# directly as the input of the network.
X, Y = iterator.get_next()

# Initialize variables.
weights = []
biases = []
n_inputs = 1
for i, n_outputs in enumerate(DIMENSIONS):
  with tf.variable_scope("layer_{}".format(i)):
    w = tf.get_variable(name="W", shape=[n_inputs, n_outputs],
                        initializer=tf.random_normal_initializer(
                            mean=0.0, stddev=0.02, seed=42))
    b = tf.get_variable(name="b", shape=[n_outputs],
                        initializer=tf.zeros_initializer)
    weights.append(w)
    biases.append(b)
    n_inputs = n_outputs

def forward_pass(X,weights,biases):
  h = X
  for i in range(len(weights)):
    h=tf.add(tf.matmul(h, weights[i]), biases[i])
    h=tf.nn.relu(h)
  return h

output_layer = forward_pass(X, weights, biases)
loss = tf.reduce_sum(tf.reduce_mean(
    tf.squared_difference(output_layer, Y), 1))
optimizer = tf.train.AdamOptimizer(learning_rate=0.003).minimize(loss)
saver = tf.train.Saver()

with tf.Session() as sess:
  sess.run(tf.global_variables_initializer())

  # (Point 1.) Run the `optimizer` in a loop. Use try-while-except to iterate
  # until all elements in `dataset` have been consumed.
  try:
    while True:
      sess.run(optimizer)
  except tf.errors.OutOfRangeError:
    pass

  save = saver.save(sess, "./model.ckpt")
  print("Model saved to path: %s" % save)

  # Evaluate network.
  x_test = np.linspace(-1, 1, 600)
  network_outputs = sess.run(output_layer, feed_dict={X: x_test.reshape(-1, 1)})

plt.plot(x_test,x_test**2,color='r',label='y=x^2')
plt.plot(x_test,network_outputs,color='b',label='NN prediction')
plt.legend(loc='right')
plt.show()
于 2017-12-05T17:04:40.793 に答える