Проблема в проектировании TensorFlow NN с предварительной обработкой ввода - PullRequest
0 голосов
/ 13 января 2019

У меня проблема с дизайном TensorFlow. По сути, я хочу решить проблему классификации 2D-точек, где:

  • загружаю 2D точки X(N,2) и известные категории C(N,3);
  • Затем я предварительно обработал и расширил ввод до xp(N,8);
  • Наконец я тренирую модель на xp и C.

Keras

При keras данные предварительно обрабатываются с использованием numpy перед подачей модели, работает следующий код:

# xp.shape # (3000, 8)
model = Sequential()
model.add(Dense(units=16, activation='relu', input_dim=xp.shape[1]))
model.add(Dense(units=32, activation='relu'))
model.add(Dense(units=3, activation='softmax'))
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy']) 
model.fit(xp, C, epochs=6)

Типичный вывод:

enter image description here

TensorFlow

Теперь я хочу реализовать ту же идею, используя TensorFlow, чтобы делегировать предварительную обработку TensorFlow:

import tensorflow as tf

# Placeholder for training data:
x0 = tf.placeholder("float", shape=(None,2), name="Inputs")

# Pre-Processing:
xsq = tf.square(x0, name="xsq")
xsin = tf.sin(x0, name="xsin")
sqdist = tf.reduce_sum(xsq, 1, keepdims=True, name="sqdist")
xprod = tf.reduce_prod(x0, 1, keepdims=True, name="xprod")

# Concatenate Inputs:
inputList = [x0, xsq, xsin, sqdist, xprod]
xp = tf.concat(inputList, axis=1, name="ProcessedInputs")

Затем я строю эквивалентную модель, используя функциональный API вместо Sequential:

# Build NN Model:
I = tf.keras.layers.InputLayer(input_tensor=xp, name="InputBinder").output
HL1 = tf.keras.layers.Dense(16, activation=tf.nn.relu, name="HiddenLayer1")(I)
HL2 = tf.keras.layers.Dense(32, activation=tf.nn.relu, name="HiddenLayer2")(HL1)
O = tf.keras.layers.Dense(3, activation=tf.nn.softmax, name="Category")(HL2)
model = tf.keras.Model(inputs=I, outputs=[O])

# Compile Model:
model.compile(
    optimizer=tf.train.AdamOptimizer(), 
    loss='categorical_crossentropy',
    metrics=['accuracy']
)

Расчетный график:

enter image description here

И модель резюме:

model.summary()
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
InputBinder (InputLayer)     (None, 8)                 0         
_________________________________________________________________
HiddenLayer1 (Dense)         (None, 16)                144       
_________________________________________________________________
HiddenLayer2 (Dense)         (None, 32)                544       
_________________________________________________________________
Category (Dense)             (None, 3)                 99        
=================================================================
Total params: 787
Trainable params: 787
Non-trainable params: 0
_________________________________________________________________

Затем я могу загрузить тренировочные данные (здесь пример для MCVE):

import numpy as np

X = np.array([
    [-0.12522489, -0.31196794],
    [ 2.76848979, -0.3322014 ],
    [-1.1856116 , -0.44192351],
    [ 0.46340079, -0.71422553],
    [ 1.97867338, -1.14048926]
])

C = np.array([
    [1, 0, 0],
    [0, 1, 0],
    [0, 1, 0],
    [1, 0, 0],
    [0, 0, 1]
], dtype=np.int64)

И я запускаю сеанс TensorFlow для предварительной обработки входных данных и обучения модели:

# Run Model:
with tf.Session() as session:

    # TensorBoard:
    writer = tf.summary.FileWriter("output", session.graph)

    # Pre-Process:
    res = session.run(x0, feed_dict={x0: X})
    print(res.shape)

    res = session.run(I, feed_dict={x0: X})
    print(res.shape)

    # Train:
    model.fit(I, C, steps_per_epoch=20, epochs=5)

    writer.close()

Этап предварительной обработки, кажется, работает хорошо, он генерирует новый тензор желаемой формы с правильными значениями. Но тренировка начинается и терпит неудачу, говоря:

(3000, 2)
(3000, 8)
Epoch 1/5

---------------------------------------------------------------------------
InvalidArgumentError                      Traceback (most recent call last)
<ipython-input-7-68442e718256> in <module>()
     10 
     11     # Train:
---> 12     model.fit(I, C, steps_per_epoch=20, epochs=5)
     13 
     14     writer.close()

C:\ProgramData\Anaconda3\lib\site-packages\tensorflow\python\keras\engine\training.py in fit(self, x, y, batch_size, epochs, verbose, callbacks, validation_split, validation_data, shuffle, class_weight, sample_weight, initial_epoch, steps_per_epoch, validation_steps, max_queue_size, workers, use_multiprocessing, **kwargs)
   1637           initial_epoch=initial_epoch,
   1638           steps_per_epoch=steps_per_epoch,
-> 1639           validation_steps=validation_steps)
   1640 
   1641   def evaluate(self,

C:\ProgramData\Anaconda3\lib\site-packages\tensorflow\python\keras\engine\training_arrays.py in fit_loop(model, inputs, targets, sample_weights, batch_size, epochs, verbose, callbacks, val_inputs, val_targets, val_sample_weights, shuffle, initial_epoch, steps_per_epoch, validation_steps)
    152         callbacks.on_batch_begin(step_index, batch_logs)
    153         try:
--> 154           outs = f(ins)
    155         except errors.OutOfRangeError:
    156           logging.warning('Your dataset iterator ran out of data; '

C:\ProgramData\Anaconda3\lib\site-packages\tensorflow\python\keras\backend.py in __call__(self, inputs)
   2984 
   2985     fetched = self._callable_fn(*array_vals,
-> 2986                                 run_metadata=self.run_metadata)
   2987     self._call_fetch_callbacks(fetched[-len(self._fetches):])
   2988     return fetched[:len(self.outputs)]

C:\ProgramData\Anaconda3\lib\site-packages\tensorflow\python\client\session.py in __call__(self, *args, **kwargs)
   1437           ret = tf_session.TF_SessionRunCallable(
   1438               self._session._session, self._handle, args, status,
-> 1439               run_metadata_ptr)
   1440         if run_metadata:
   1441           proto_data = tf_session.TF_GetBuffer(run_metadata_ptr)

C:\ProgramData\Anaconda3\lib\site-packages\tensorflow\python\framework\errors_impl.py in __exit__(self, type_arg, value_arg, traceback_arg)
    526             None, None,
    527             compat.as_text(c_api.TF_Message(self.status.status)),
--> 528             c_api.TF_GetCode(self.status.status))
    529     # Delete the underlying status object from memory otherwise it stays alive
    530     # as there is a reference to status from this from the traceback due to

InvalidArgumentError: You must feed a value for placeholder tensor 'Inputs' with dtype float and shape [?,2]
     [[{{node Inputs}} = Placeholder[dtype=DT_FLOAT, shape=[?,2], _device="/job:localhost/replica:0/task:0/device:CPU:0"]()]]

Кажется, Inputs заполнитель не был загружен. Я чувствую себя немного странно из-за этой ошибки, потому что я ее кормил. Что не так с этим кодом? Что я должен изменить в этом коде, чтобы обучить модель?

1 Ответ

0 голосов
/ 13 января 2019

tf.keras.layers.Input подпадает под функциональный API, который нельзя использовать с последовательной моделью. Вы можете создать модель, используя functional API или sequential API. Проверьте эту ссылку https://keras.io/getting-started/functional-api-guide/

...