У меня проблема с дизайном 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)
Типичный вывод:
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']
)
Расчетный график:
И модель резюме:
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
заполнитель не был загружен. Я чувствую себя немного странно из-за этой ошибки, потому что я ее кормил. Что не так с этим кодом? Что я должен изменить в этом коде, чтобы обучить модель?