【问题标题】:What this error means: `y` argument is not supported when using python generator as input此错误的含义:使用 python 生成器作为输入时不支持 `y` 参数
【发布时间】:2023-11-22 03:04:01
【问题描述】:

我尝试开发一个网络,并使用 python 生成器作为数据提供者。在模型开始拟合之前一切正常,然后我收到此错误:

ValueError: `y` argument is not supported when using dataset as input.

我对每一行都进行了校对,我认为问题在于x_testy_test 向网络提供的格式。经过数小时的谷歌搜索,并多次更改格式,错误仍然存​​在。

你能帮我解决它吗?您可以在下面找到整个代码:

import os
import numpy as np
import pandas as pd
import re  # To match regular expression for extracting labels

import tensorflow as tf

print(tf.__version__)


def xfiles(filename):
    if re.match('^\w{12}_x\.csv$', filename) is None:
        return False
    else:
        return True


def data_generator():
    folder = "i:/Stockpred/csvdbase/datasets/DS0002"
    file_list = os.listdir(folder)
    x_files = list(filter(xfiles, file_list))
    x_files.sort()
    np.random.seed(1729)
    np.random.shuffle(x_files)

    for file in x_files:
        filespec = folder + '/' + file
        xs = pd.read_csv(filespec, header=None)

        yfile = file.replace('_x', '_y')
        yfilespec = folder + '/' + yfile
        ys = pd.read_csv(open(yfilespec, 'r'), header=None, usecols=[1])

        xs = np.asarray(xs, dtype=np.float32)
        ys = np.asarray(ys, dtype=np.float32)

        for i in range(xs.shape[0]):
            yield xs[i][1:169], ys[i][0]


dataset = tf.data.Dataset.from_generator(
    data_generator,
    (tf.float32, tf.float32),
    (tf.TensorShape([168, ]), tf.TensorShape([])))
dataset = dataset.shuffle(buffer_size=16000, seed=1729)
# dataset = dataset.batch(4000, drop_remainder=True)
dataset = dataset.cache('R:/Temp/model')


def is_test(i, d):
    return i % 4 == 0


def is_train(i, d):
    return not is_test(i, d)


recover = lambda i, d: d

test_dataset = dataset.enumerate().filter(is_test).map(recover)
train_dataset = dataset.enumerate().filter(is_train).map(recover)

x_test = test_dataset.map(lambda x, y: x)
y_test = test_dataset.map(lambda x, y: y)

x_train = train_dataset.map(lambda x, y: x)
y_train = train_dataset.map(lambda x, y: y)

print(x_train.element_spec)
print(y_train.element_spec)
print(x_test.element_spec)
print(y_test.element_spec)

# define an object (initializing RNN)
model = tf.keras.models.Sequential()

# first LSTM layer
model.add(tf.keras.layers.LSTM(units=168, activation='relu', return_sequences=True, input_shape=(168, 1)))
# dropout layer
model.add(tf.keras.layers.Dropout(0.2))

# second LSTM layer
model.add(tf.keras.layers.LSTM(units=168, activation='relu', return_sequences=True))
# dropout layer
model.add(tf.keras.layers.Dropout(0.2))

# third LSTM layer
model.add(tf.keras.layers.LSTM(units=80, activation='relu', return_sequences=True))
# dropout layer
model.add(tf.keras.layers.Dropout(0.2))

# fourth LSTM layer
model.add(tf.keras.layers.LSTM(units=120, activation='relu'))
# dropout layer
model.add(tf.keras.layers.Dropout(0.2))

# output layer
model.add(tf.keras.layers.Dense(units=1))

model.summary()

# compile the model
model.compile(optimizer='adam', loss='mean_squared_error')

model.fit(x_train.as_numpy_iterator(), y_train.as_numpy_iterator(), batch_size=32, epochs=100)

predicted_stock_price = model.predict(x_test)

在模型开始拟合之前,一切看起来都不错。我收到了这个错误:

ValueError: `y` argument is not supported when using dataset as input.

你能帮忙解决吗?

【问题讨论】:

  • 尝试将输入作为元组提供给 model.fit() 函数:(x_train.as_numpy_iterator(), y_train.as_numpy_iterator())
  • 其实我的做法和你评论的一样。但还不行!

标签: python tensorflow keras deep-learning lstm


【解决方案1】:

正如docs 所说:

y - 目标数据。与输入数据 x 一样,它可以是 Numpy 数组或 TensorFlow 张量。它应该与 x 一致(你不能有 Numpy 输入和张量目标,或者相反)。 如果 x 是数据集、生成器或 keras.utils.Sequence 实例,则不应指定 y(因为目标将从 x 获取)

所以,我想你应该有一个生成器来提供样本和标签的元组。

【讨论】:

    【解决方案2】:

    如果您提供数据集作为输入,那么

    type(train_dataset) 应该是tensorflow.python.data.ops.dataset_ops.BatchDataset

    如果是这样,只需将此数据集(包括您的 X 和 y 包)输入到模型中,

    model.fit(train_dataset, batch_size=32, epochs=100)

    (是的,这与我们在 sklearn 中所做的约定略有不同 - X 和 y 分开。)

    同时,如果您希望 tensorflow 明确使用单独的数据集进行验证,则必须使用 kwarg 如下:

    model.fit(train_dataset, validation_data=val_dataset, batch_size=32, epochs=100)

    其中val_dataset 是您在模型训练期间为验证而保留的单独数据集。 (未测试)。

    【讨论】:

      【解决方案3】:

      使用model.fit_generator,并使用输入数据和标签的元组(x,y)。总之:

      model.fit_generator(train_dataset.as_numpy_iterator(),epochs=100)
      

      【讨论】: