Разделение набора данных TensorFlow, созданного с помощью make_csv_dataset, на 3 части (X1_Train, X2_Train и Y_Train) для модели с несколькими входами - PullRequest
0 голосов
/ 05 августа 2020

Я обучаю модель глубокого обучения с помощью Tensorflow 2 и Keras. Я прочитал свой большой CSV-файл с tf.data.experimental.make_csv_dataset, а затем разделил его на наборы данных для обучения и тестирования. Однако мне нужно разделить набор данных поезда на три части, поскольку моя модель глубокого обучения принимает два набора входных данных на разных уровнях, поэтому мне нужно передать [x1_train, x2_train],y_train в model.fit.

Мой вопрос в том, как можно Я разделил train_dataset на x1_train,x2_train и y_train? (некоторые функции должны быть в x1_train, а некоторые должны быть в x2_train).

Мой код:

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

1 Ответ

1 голос
/ 10 августа 2020

Как упоминалось в разделах комментариев, вы можете использовать объект map method Dataset, который возвращается make_csv_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

Теперь предположим, что мы хотим прочитать этот файл CSV с помощью функции maks_csv_dataset; однако наша модель имеет два входных слоя с именами input1 и input2 (задается с помощью аргумента name уровня Input), где 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)>)
"""

Как видите, Первый элемент каждого пакета - это словарь, сопоставляющий имена столбцов с соответствующими значениями функций. Теперь давайте воспользуемся методом map, чтобы разделить и объединить эти значения функций в правильный формат для нашей модели:

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)>)

"""

Вот и все! Теперь вы можете дополнительно изменить этот новый измененный набор данных (например, использовать take, shuffle, et c.), И когда будете готовы, вы можете передать его методу fit вашей модели (не забудьте дать имена для входные слои вашей модели).

...