【发布时间】:2022-01-22 16:33:39
【问题描述】:
我有大量数据适合模型训练。并且在模型构建中,我们使用了 tf.keras.experimental.SequenceFeatures,它要求输入应该是 SpareTensor。 我厌倦了使用 generaotr,但不适用于 SparsTensor。 这是示例代码:
from models.model_attention import AttentionModel
import numpy as np
import tensorflow as tf
from tensorflow.keras.layers import LSTM, Dropout, Dense
inputs = {'f1': tf.keras.layers.Input(name='f1', sparse=True, shape=(40, 1), dtype='float32'),
'f2': tf.keras.layers.Input(name='f2', sparse=True, shape=(40, 1), dtype='float32')}
features = [tf.feature_column.sequence_numeric_column('f1', dtype=tf.float32),
tf.feature_column.sequence_numeric_column('f2', dtype=tf.float32)]
input_layer, _ = tf.keras.experimental.SequenceFeatures(features)(inputs)
lstm_out = LSTM(128, return_sequences=False)(input_layer)
lstm_out = Dropout(0.2)(lstm_out)
lstm_out = Dense(1, activation='tanh')(lstm_out)
model = tf.keras.models.Model(inputs, lstm_out)
model.compile(loss='mse', metrics='mae', optimizer='Adam')
def gen():
batch = 4
while True:
x1 = tf.sparse.from_dense(np.random.random((batch, 40, 1)))
x2 = tf.sparse.from_dense(np.random.random((batch, 40, 1)))
x = {'f1': x1, 'f2': x2}
y = np.random.random((batch, 1))
yield x, y
x, y = gen().__next__()
# x, y yielded from generator works
model.fit(x, y, epochs=2, verbose=2)
g = gen()
# TypeError: Input must be a SparseTensor.
model.fit(g, steps_per_epoch=2, epochs=2, verbose=2, validation_data=g, validation_steps=2)
gen() 函数用于正常的 numpy 数组生成器,但不适用于 SparseTensor 输入。 错误信息:
Traceback (most recent call last):
File "D:/PycharmProjects/infinity_stock/tmp2.py", line 36, in <module>
model.fit(g, steps_per_epoch=2, epochs=2, verbose=2, validation_data=g, validation_steps=2)
File "D:\anaconda3\envs\stock\lib\site-packages\tensorflow\python\keras\engine\training.py", line 1183, in fit
tmp_logs = self.train_function(iterator)
File "D:\anaconda3\envs\stock\lib\site-packages\tensorflow\python\eager\def_function.py", line 889, in __call__
result = self._call(*args, **kwds)
File "D:\anaconda3\envs\stock\lib\site-packages\tensorflow\python\eager\def_function.py", line 917, in _call
return self._stateless_fn(*args, **kwds) # pylint: disable=not-callable
File "D:\anaconda3\envs\stock\lib\site-packages\tensorflow\python\eager\function.py", line 3022, in __call__
filtered_flat_args) = self._maybe_define_function(args, kwargs)
File "D:\anaconda3\envs\stock\lib\site-packages\tensorflow\python\eager\function.py", line 3440, in _maybe_define_function
return self._define_function_with_shape_relaxation(
File "D:\anaconda3\envs\stock\lib\site-packages\tensorflow\python\eager\function.py", line 3362, in _define_function_with_shape_relaxation
graph_function = self._create_graph_function(
File "D:\anaconda3\envs\stock\lib\site-packages\tensorflow\python\eager\function.py", line 3279, in _create_graph_function
func_graph_module.func_graph_from_py_func(
File "D:\anaconda3\envs\stock\lib\site-packages\tensorflow\python\framework\func_graph.py", line 999, in func_graph_from_py_func
func_outputs = python_func(*func_args, **func_kwargs)
File "D:\anaconda3\envs\stock\lib\site-packages\tensorflow\python\eager\def_function.py", line 672, in wrapped_fn
out = weak_wrapped_fn().__wrapped__(*args, **kwds)
File "D:\anaconda3\envs\stock\lib\site-packages\tensorflow\python\framework\func_graph.py", line 986, in wrapper
raise e.ag_error_metadata.to_exception(e)
TypeError: in user code:
D:\anaconda3\envs\stock\lib\site-packages\tensorflow\python\keras\engine\training.py:855 train_function *
return step_function(self, iterator)
D:\anaconda3\envs\stock\lib\site-packages\tensorflow\python\keras\engine\training.py:845 step_function **
outputs = model.distribute_strategy.run(run_step, args=(data,))
D:\anaconda3\envs\stock\lib\site-packages\tensorflow\python\distribute\distribute_lib.py:1285 run
return self._extended.call_for_each_replica(fn, args=args, kwargs=kwargs)
D:\anaconda3\envs\stock\lib\site-packages\tensorflow\python\distribute\distribute_lib.py:2833 call_for_each_replica
return self._call_for_each_replica(fn, args, kwargs)
D:\anaconda3\envs\stock\lib\site-packages\tensorflow\python\distribute\distribute_lib.py:3608 _call_for_each_replica
return fn(*args, **kwargs)
D:\anaconda3\envs\stock\lib\site-packages\tensorflow\python\keras\engine\training.py:838 run_step **
outputs = model.train_step(data)
D:\anaconda3\envs\stock\lib\site-packages\tensorflow\python\keras\engine\training.py:795 train_step
y_pred = self(x, training=True)
D:\anaconda3\envs\stock\lib\site-packages\tensorflow\python\keras\engine\base_layer.py:1030 __call__
outputs = call_fn(inputs, *args, **kwargs)
D:\anaconda3\envs\stock\lib\site-packages\tensorflow\python\keras\engine\functional.py:420 call
return self._run_internal_graph(
D:\anaconda3\envs\stock\lib\site-packages\tensorflow\python\keras\engine\functional.py:556 _run_internal_graph
outputs = node.layer(*args, **kwargs)
D:\anaconda3\envs\stock\lib\site-packages\tensorflow\python\keras\engine\base_layer.py:1030 __call__
outputs = call_fn(inputs, *args, **kwargs)
D:\anaconda3\envs\stock\lib\site-packages\tensorflow\python\keras\feature_column\sequence_feature_column.py:159 call **
dense_tensor, sequence_length = column.get_sequence_dense_tensor(
D:\anaconda3\envs\stock\lib\site-packages\tensorflow\python\feature_column\sequence_feature_column.py:442 get_sequence_dense_tensor
dense_tensor = sparse_ops.sparse_tensor_to_dense(
D:\anaconda3\envs\stock\lib\site-packages\tensorflow\python\ops\sparse_ops.py:1714 sparse_tensor_to_dense
sp_input = _convert_to_sparse_tensor(sp_input)
D:\anaconda3\envs\stock\lib\site-packages\tensorflow\python\ops\sparse_ops.py:72 _convert_to_sparse_tensor
raise TypeError("Input must be a SparseTensor.")
TypeError: Input must be a SparseTensor.
对这个问题有什么建议吗?
【问题讨论】:
-
调用
gen()或fit()时是否出现错误 -
调用 fit() 时发生错误。错误信息:TypeError: Input must be a SparseTensor.
-
我认为当您调用
model.fit(g,.)时,您不会进入预期的 API。也许正确的方法应该是一些Generator类。为了证明这一点,您可以调试以检查何时进入fit -
它确实转到了使用生成器数据适配器的预期 API。通过调试,我们终于找到了原因:Keras 使用的是 TensorSpec,而不是 Generator 中的 SparseTensorSpec。有关详细信息,请参阅下面的答案。
标签: python tensorflow machine-learning keras generator