我尝试开发一个网络,并使用python generator作为数据提供者。一切看起来都很好,直到模型开始适合为止,然后我收到此错误:
ValueError: `y` argument is not supported when using dataset as input.
我对每一行都进行了校对,我认为问题在于x_test
和y_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.
您能帮助修复它吗?
答案 0 :(得分:1)
如果要提供数据集作为输入,则
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
是一个单独的数据集,您可以在模型训练期间保留该数据集进行验证。 (未测试)。
答案 1 :(得分:0)
docs说:
y-目标数据。像输入数据x一样,它可以是Numpy数组或TensorFlow张量。它应该与x一致(您不能有Numpy输入和张量目标,或者相反)。 如果x是数据集,生成器或keras.utils.Sequence实例,则不应指定y(因为将从x获得目标)。
因此,我想您应该有一个生成器,用于提供样品和标签的元组。
答案 2 :(得分:0)
使用model.fit_generator
,并使用输入数据和标签的元组(x,y)
。总共:
model.fit_generator(train_dataset.as_numpy_iterator(),epochs=100)