Python 对于多输入模型,将使用make_csv_数据集创建的TensorFlow数据集拆分为3个部分(X1_序列、X2_序列和Y_序列)

Python 对于多输入模型,将使用make_csv_数据集创建的TensorFlow数据集拆分为3个部分(X1_序列、X2_序列和Y_序列),python,tensorflow,machine-learning,keras,tensorflow-datasets,Python,Tensorflow,Machine Learning,Keras,Tensorflow Datasets,我正在使用Tensorflow 2和Keras培训深度学习模型。我用tf.data.experimental.make_CSV_dataset读取我的大CSV文件,然后将其拆分为训练和测试数据集。但是,我需要将我的训练数据集分为三部分,因为我的深度学习模型在不同的层中接受两组输入,所以我需要将[x1\u训练,x2\u训练]、y\u训练传递到模型。fit 我的问题是如何将train\u数据集拆分为x1\u列、x2\u列和y\u列?(一些特征应在x1\u列中,一些特征应在x2\u列中) 我的代码:

我正在使用Tensorflow 2和Keras培训深度学习模型。我用
tf.data.experimental.make_CSV_dataset
读取我的大CSV文件,然后将其拆分为训练和测试数据集。但是,我需要将我的训练数据集分为三部分,因为我的深度学习模型在不同的层中接受两组输入,所以我需要将
[x1\u训练,x2\u训练]、y\u训练
传递到
模型。fit

我的问题是如何将
train\u数据集
拆分为
x1\u列、x2\u列
y\u列
?(一些特征应在
x1\u列
中,一些特征应在
x2\u列
中)

我的代码:

def get_dataset(file_path, **kwargs):
  dataset = tf.data.experimental.make_csv_dataset(
      file_path,
      batch_size=64, 
      label_name=LABEL_COLUMN,
      na_value="?",
      num_epochs=1,
      ignore_errors=True, 
      **kwargs)
  return dataset

full_dataset = get_dataset(dataset_path)
full_dataset = full_dataset.shuffle(buffer_size=400000)
train_dataset = full_dataset.take(360000)
test_dataset = full_dataset.skip(360000)
test_dataset = test_dataset.take(40000)
x1_train =train_dataset[:,0:2820]
x2_train =train_dataset[:,2820:2822]
y_train=train_dataset[:,2822]
x1_test =x_test[:,0:2820]
x2_test =x_test[:,2820:2822]
y_test=test_dataset[:,2822]
model.fit([x1_train,x2_train],y_train,validation_data=[x1_test,x2_test],y_test, callbacks=callbacks_list, verbose=1,epochs=EPC)
错误消息:

x1_train =train_dataset[:,0:2820]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'TakeDataset' object is not subscriptable
x1\u train=train\u数据集[:,0:2820]
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
TypeError:“TakeDataset”对象不可订阅

如评论部分所述,您可以使用
map
方法
Dataset
对象,该对象由
make\u csv\u Dataset
返回,以便根据模型的预期输入格式拆分和组合样本

例如,假设我们有一个包含以下数据的CSV文件:

a,b,c,d,e
1,2,3,4,111
5,6,7,8,222
9,10,11,12,333
13,14,15,16,444
现在,假设我们想用
maks\u CSV\u dataset
函数读取这个CSV文件;但是,我们的模型有两个输入层,分别命名为
input1
input2
(使用
input
层的
name
参数设置),其中
input1
被输入列
a
b
中的特征值,而
input2
使用列
c
d
中的特征值。此外,
e
列是我们的目标(即标签)列

让我们先看看这些数据,看看它是什么样子的:

from pprint import pprint

dataset = tf.data.experimental.make_csv_dataset(
      'data.csv',
      batch_size=2,
      label_name='e',
      num_epochs=1,
)

for x in dataset:
    pprint(x)

"""
The printed result:

(OrderedDict([('a',
               <tf.Tensor: shape=(2,), dtype=int32, numpy=array([5, 1], dtype=int32)>),
              ('b',
               <tf.Tensor: shape=(2,), dtype=int32, numpy=array([6, 2], dtype=int32)>),
              ('c',
               <tf.Tensor: shape=(2,), dtype=int32, numpy=array([7, 3], dtype=int32)>),
              ('d',
               <tf.Tensor: shape=(2,), dtype=int32, numpy=array([8, 4], dtype=int32)>)]),
 <tf.Tensor: shape=(2,), dtype=int32, numpy=array([222, 111], dtype=int32)>)
(OrderedDict([('a',
               <tf.Tensor: shape=(2,), dtype=int32, numpy=array([13,  9], dtype=int32)>),
              ('b',
               <tf.Tensor: shape=(2,), dtype=int32, numpy=array([14, 10], dtype=int32)>),
              ('c',
               <tf.Tensor: shape=(2,), dtype=int32, numpy=array([15, 11], dtype=int32)>),
              ('d',
               <tf.Tensor: shape=(2,), dtype=int32, numpy=array([16, 12], dtype=int32)>)]),
 <tf.Tensor: shape=(2,), dtype=int32, numpy=array([444, 333], dtype=int32)>)
"""

就这样!现在,您可以进一步修改这个新修改的数据集(例如,使用
take
shuffle
等),准备好后,您可以将其交给模型的
fit
方法(不过,不要忘了给模型的输入层命名)。

在构建数据集之后,在执行任何其他操作之前,使用
tf.data.Dataset
对象的
map
方法拆分每个批次。请告诉我如何使用map拆分每个批次?由
make\u csv\u Dataset
返回的每个批次的第一个元素是将列名映射到其值的字典。因此,在map函数中,您可以将此字典拆分为两个单独的dict(并可能根据模型的输入格式将每个字典中的项组合为单独的张量)。谢谢。我应用了您的代码并添加了一些额外的行:
dataset=dataset.shuffle(buffer\u size=400000)
train\u dataset=dataset.take(360000)test\u dataset=test\u dataset.take(40000)
model.fit(train\u dataset,validation\u data=test\u dataset,callbacks=callbacks\u list,verbose=1,epoch=4)
其中,我的模型具有“input1”和“input2”作为输入层名称。然而,现在的训练仍停留在1/4阶段,我没有得到任何错误。问题是什么?@hsn15051数据和您的模型有多大?数据集:412k样本。我总共有2822个功能。我正在训练一个完全连接的神经网络。我将2820个特征传递到一些层中,然后将结果与另外两个特征连接起来,并提供给其他层,最后得到输出(我使用)。我正在尝试优化架构,所以我需要在GPU上培训/验证数千个模型(我使用的是MirroredStrategy.)。很快,我将有500k的功能,所以我需要扩展up@hsn15051如果您等待的时间更长,培训是否会显示任何进度/错误?模型中有多少个参数?使用
model.summary()
model.count\u params()
查找。你能监控GPU的使用情况,看看它在训练开始时是否被使用吗?@scribbles奇怪的是,你会出现这样的错误,因为这意味着
samples
是一个元组而不是一个字典;但是,
make_csv_数据集
将输入样本构造为特征词典,而不是元组(如我在回答中所示)。无论如何,要检查格式,请在构建的数据集中打印一个样本,然后在我的答案中相应地调整解决方案。这就是我在看不到您的代码/数据的情况下所能说的。
first_input_cols = ['a', 'b']
second_input_cols = ['c', 'd']

def split_and_combine_batch_samples(samples, targets):
    inp1 = []
    for k in first_input_cols:
        inp1.append(samples[k])
    inp2 = []
    for k in second_input_cols:
        inp2.append(samples[k])
    
    inp1 = tf.stack(inp1, axis=-1)
    inp2 = tf.stack(inp2, axis=-1)
    return {'input1': inp1, 'input2': inp2}, targets

dataset = dataset.map(split_and_combine_batch_samples)

for x in dataset:
    pprint(x)

"""
The printed values:

({'input1': <tf.Tensor: shape=(2, 2), dtype=int32, numpy=
array([[ 9, 10],
       [13, 14]], dtype=int32)>,
  'input2': <tf.Tensor: shape=(2, 2), dtype=int32, numpy=
array([[11, 12],
       [15, 16]], dtype=int32)>},
 <tf.Tensor: shape=(2,), dtype=int32, numpy=array([333, 444], dtype=int32)>)
({'input1': <tf.Tensor: shape=(2, 2), dtype=int32, numpy=
array([[5, 6],
       [1, 2]], dtype=int32)>,
  'input2': <tf.Tensor: shape=(2, 2), dtype=int32, numpy=
array([[7, 8],
       [3, 4]], dtype=int32)>},
 <tf.Tensor: shape=(2,), dtype=int32, numpy=array([222, 111], dtype=int32)>)

"""