Генератор для `model.fit ()` Вход, а не Коллекция? (данные тренировки слишком велики для памяти) - PullRequest
0 голосов
/ 28 июня 2018

Функция подбора моделей TF-Learn может быть передана для обучения и тестирования данных, например, так:

model = tflearn.DNN(nn)

model.fit({'input': X_train},
          {'targets': Y_train},
          n_epoch=10,
          validation_set=(
              {'input': X_test},
              {'targets': Y_test}
          ))

, где nn - определение модели. Однако что, если коллекции, такие как X_train, слишком велики для памяти?

В моем случае я сжал разреженные двоичные векторы (ячейки либо 1, либо 0) в виде списка индексов и целочисленного кодирования для числа измерений вектора, которые позволяют мне восстанавливать исходные векторы.

Что наборы сжатых векторов помещаются в память, а не наборы, содержащие полные векторы. Поэтому вместо этого я попытался передать генератор над X_train и другими коллекциями (теперь содержащими сжатые векторы), которые на лету восстанавливают полные векторы, но для model.fit требовалась функция len(). Итак, я определил пользовательский класс фидера следующим образом:

class Feeder:
    def __init__(self, data, convert):
        self.data = data
        self.convert = convert

    def __len__(self):
        return len(self.data)

    def __iter__(self):
        return self

    def __next__(self):
        for item in self.data:
            yield self.convert(item)

который я называю так:

def reconstruct_vector(non_zero_indices, dimensionality):
    """
    returns a vector of zeros and ones reconstructed from a sparse vector
    and a dimensions value
    """
    vec = np.zeros(dimensionality)
    for i in non_zero_intraining data too large for memorydices:
        vec[i] = 1
    return vec

item_to_input_vector = lambda item : reconstruct_vector(item[0], item[1])
item_to_target_vector = lambda item : np.array([1,0]) if item else np.array([0,1])

model.fit({'input': Feeder(X_train, item_to_input_vector)},
          {'targets': Feeder(Y_train, item_to_target_vector)},
          n_epoch=10,
          validation_set=(
              {'input': Feeder(X_test, item_to_input_vector)},
              {'targets': Feeder(Y_test, item_to_target_vector)}
          ))

Но это также не работает, поскольку я получаю некоторую загадочную ошибку:

Exception in thread Thread-3:
Traceback (most recent call last):
  File "/usr/lib64/python3.6/threading.py", line 916, in _bootstrap_inner
    self.run()
  File "/usr/lib64/python3.6/threading.py", line 864, in run
    self._target(*self._args, **self._kwargs)
  File "/usr/lib/python3.6/site-packages/tflearn/data_flow.py", line 187, in fill_feed_dict_queue
    data = self.retrieve_data(batch_ids)
  File "/usr/lib/python3.6/site-packages/tflearn/data_flow.py", line 222, in retrieve_data
    utils.slice_array(self.feed_dict[key], batch_ids)
  File "/usr/lib/python3.6/site-packages/tflearn/utils.py", line 187, in slice_array
    return X[start]
TypeError: only integer scalar arrays can be converted to a scalar index

Итак, как правильно поступить?

...