提问人:chockeyblocky 提问时间:10/31/2023 最后编辑:chockeyblocky 更新时间:11/1/2023 访问量:42
如何使用具有多个输入张量的 tensorflow 生成器 (tf.keras.utils.Sequence)?
How do I use a tensorflow generator (tf.keras.utils.Sequence) with more than one input tensor?
问:
我正在尝试使用 tensorflow 训练深度网络,其第一层/模块是图转换器。问题是,这个图转换器将几个张量作为其输入,每个张量都有不同的形状。我正在训练的数据集也非常大,其原始文件中的数据在加载后需要进行一些预处理,以使其转换为正确的形状/格式,以用于图形转换器的输入。这意味着我正在尝试使用自定义生成器类(继承自 tf.keras.utils.Sequence)为我进行此预处理。但是,当我尝试在 getitem 中返回批处理时,存在一个明显的问题,因为它需要形状(batch_size、*input_dims)的张量或 numpy 数组,这与我的问题不兼容。
我尝试过使用输入张量元组的 numpy 数组进行批处理,并且尝试使用张量元组列表,但似乎没有任何效果,因为它期望这种形状并尝试转换为张量,但没有成功。有没有人对我可以尝试什么有任何建议?我对传入生成器来训练模型时进行的幕后处理没有深入的了解,因此任何见解都会有所帮助。例如,如果有人知道对“批处理”的约束(getitem 的返回值),或者任何绕过它似乎需要是 numpy 数组或张量这一事实的方法。
编辑:
我试图实现的代码示例,以及相关的错误:
import tensorflow as tf
import keras
import numpy as np
class DataGenerator(tf.keras.utils.Sequence):
'Generates data for Keras'
def __init__(self, list_IDs, labels, batch_size=32, dim=(32, 32, 32), n_channels=1,
n_classes=10, shuffle=True):
'Initialization'
self.dim = dim
self.batch_size = batch_size
self.labels = labels
self.list_IDs = list_IDs
self.n_channels = n_channels
self.n_classes = n_classes
self.shuffle = shuffle
self.on_epoch_end()
def __len__(self):
'Denotes the number of batches per epoch'
return int(np.floor(len(self.list_IDs) / self.batch_size))
def __getitem__(self, index):
'Generate one batch of data'
# Generate indexes of the batch
indexes = self.indexes[index * self.batch_size:(index + 1) * self.batch_size]
# Find list of IDs
list_IDs_temp = [self.list_IDs[k] for k in indexes]
# Generate data
X = [[tf.constant([1, 2]), tf.constant([3])]] * self.batch_size
y = [tf.constant([1])] * self.batch_size
return X, y
def on_epoch_end(self):
'Updates indexes after each epoch'
self.indexes = np.arange(len(self.list_IDs))
if self.shuffle == True:
np.random.shuffle(self.indexes)
class Net(tf.keras.Model):
def __init__(self):
super().__init__()
self.dense1 = tf.keras.layers.Dense(5, activation=tf.nn.relu)
self.dense2 = tf.keras.layers.Dense(5, activation=tf.nn.softmax)
def call(self, inputs):
# actual desired behaviour calls layer(inputs[0], inputs[1]) but this is a representative example
x = self.dense1(inputs[0])
x += self.dense2(inputs[1])
return x
model = Net()
train_gen = DataGenerator([], [])
model.compile(loss=tf.keras.losses.mean_squared_error)
model.fit(x=train_gen, epochs=1, verbose=1, batch_size=4)
收到错误:
Traceback (most recent call last):
File "generator_test.py", line 69, in <module>
model.fit(x=train_gen, epochs=1, verbose=1, batch_size=4)
File "\venv\Lib\site-packages\keras\src\utils\traceback_utils.py", line 70, in error_handler
raise e.with_traceback(filtered_tb) from None
File "generator_test.py", line 59, in call
x = self.dense1(inputs[0])
^^^^^^^^^^^^^^^^^^^^^^
ValueError: Exception encountered when calling layer 'net' (type Net).
Layer "dense" expects 1 input(s), but it received 2 input tensors. Inputs received: [<tf.Tensor: shape=(2,), dtype=int32, numpy=array([1, 2])>, <tf.Tensor: shape=(1,), dtype=int32, numpy=array([3])>]
Call arguments received by layer 'net' (type Net):
• inputs=(('tf.Tensor(shape=(2,), dtype=int32)', 'tf.Tensor(shape=(1,), dtype=int32)'), ('tf.Tensor(shape=(2,), dtype=int32)', 'tf.Tensor(shape=(1,), dtype=int32)'), ('tf.Tensor(shape=(2,), dtype=int32)', 'tf.Tensor(shape=(1,), dtype=int32)'), ('tf.Tensor(shape=(2,), dtype=int32)', 'tf.Tensor(shape=(1,), dtype=int32)'), ('tf.Tensor(shape=(2,), dtype=int32)', 'tf.Tensor(shape=(1,), dtype=int32)'), ('tf.Tensor(shape=(2,), dtype=int32)', 'tf.Tensor(shape=(1,), dtype=int32)'), ('tf.Tensor(shape=(2,), dtype=int32)', 'tf.Tensor(shape=(1,), dtype=int32)'), ('tf.Tensor(shape=(2,), dtype=int32)', 'tf.Tensor(shape=(1,), dtype=int32)'), ('tf.Tensor(shape=(2,), dtype=int32)', 'tf.Tensor(shape=(1,), dtype=int32)'), ('tf.Tensor(shape=(2,), dtype=int32)', 'tf.Tensor(shape=(1,), dtype=int32)'), ('tf.Tensor(shape=(2,), dtype=int32)', 'tf.Tensor(shape=(1,), dtype=int32)'), ('tf.Tensor(shape=(2,), dtype=int32)', 'tf.Tensor(shape=(1,), dtype=int32)'), ('tf.Tensor(shape=(2,), dtype=int32)', 'tf.Tensor(shape=(1,), dtype=int32)'), ('tf.Tensor(shape=(2,), dtype=int32)', 'tf.Tensor(shape=(1,), dtype=int32)'), ('tf.Tensor(shape=(2,), dtype=int32)', 'tf.Tensor(shape=(1,), dtype=int32)'), ('tf.Tensor(shape=(2,), dtype=int32)', 'tf.Tensor(shape=(1,), dtype=int32)'), ('tf.Tensor(shape=(2,), dtype=int32)', 'tf.Tensor(shape=(1,), dtype=int32)'), ('tf.Tensor(shape=(2,), dtype=int32)', 'tf.Tensor(shape=(1,), dtype=int32)'), ('tf.Tensor(shape=(2,), dtype=int32)', 'tf.Tensor(shape=(1,), dtype=int32)'), ('tf.Tensor(shape=(2,), dtype=int32)', 'tf.Tensor(shape=(1,), dtype=int32)'), ('tf.Tensor(shape=(2,), dtype=int32)', 'tf.Tensor(shape=(1,), dtype=int32)'), ('tf.Tensor(shape=(2,), dtype=int32)', 'tf.Tensor(shape=(1,), dtype=int32)'), ('tf.Tensor(shape=(2,), dtype=int32)', 'tf.Tensor(shape=(1,), dtype=int32)'), ('tf.Tensor(shape=(2,), dtype=int32)', 'tf.Tensor(shape=(1,), dtype=int32)'), ('tf.Tensor(shape=(2,), dtype=int32)', 'tf.Tensor(shape=(1,), dtype=int32)'), ('tf.Tensor(shape=(2,), dtype=int32)', 'tf.Tensor(shape=(1,), dtype=int32)'), ('tf.Tensor(shape=(2,), dtype=int32)', 'tf.Tensor(shape=(1,), dtype=int32)'), ('tf.Tensor(shape=(2,), dtype=int32)', 'tf.Tensor(shape=(1,), dtype=int32)'), ('tf.Tensor(shape=(2,), dtype=int32)', 'tf.Tensor(shape=(1,), dtype=int32)'), ('tf.Tensor(shape=(2,), dtype=int32)', 'tf.Tensor(shape=(1,), dtype=int32)'), ('tf.Tensor(shape=(2,), dtype=int32)', 'tf.Tensor(shape=(1,), dtype=int32)'), ('tf.Tensor(shape=(2,), dtype=int32)', 'tf.Tensor(shape=(1,), dtype=int32)'))
Process finished with exit code 1
答: 暂无答案
上一个:什么是“预抽发电机协程”?
评论