python - feed_dict - from_tensor_slices()
TransmisiĆ³n continua de grandes archivos de entrenamiento y prueba en el DNNClassifier de Tensorflow (1)
Tengo un enorme archivo CSV de entrenamiento (709M) y un gran archivo CSV de prueba (125M) que deseo enviar a un DNNClassifier
en el contexto del uso de la API Tensorflow de alto nivel.
Parece que el input_fn
aceptado por fit
and evaluate
debe contener todos los datos de características y etiquetas en la memoria, pero actualmente me gustaría ejecutar esto en mi máquina local, y así esperar que se agote la memoria bastante rápido si leo estos archivos en la memoria y luego procesarlos.
Revisé el documento en lectura en flujo de datos , pero el código de muestra para leer CSV parece ser para la API Tensorflow de bajo nivel.
Y, si perdonas un poco de lloriqueo, parece demasiado complejo para el caso de uso trivial de enviar archivos bien preparados de entrenamiento y datos de prueba a un Estimator
... aunque, tal vez ese nivel de complejidad sea realmente necesario para entrenando y probando grandes volúmenes de datos en Tensorflow?
En cualquier caso, realmente agradecería un ejemplo de usar ese enfoque con la API de alto nivel, si es posible, y estoy empezando a dudar.
Después de hurgar, logré encontrar DNNClassifier#partial_fit
e intentaré utilizarlo para el entrenamiento.
Los ejemplos de cómo usar este método me ahorrarían algo de tiempo, aunque espero encontrar el uso correcto en las próximas horas.
Sin embargo, no parece haber un DNNClassifier#partial_evaluate
correspondiente ... aunque sospecho que podría dividir los datos de prueba en piezas más pequeñas y ejecutar DNNClassifier#evaluate
sucesivamente en cada lote, lo que en realidad podría ser una excelente manera de hágalo ya que podría segmentar los datos de prueba en cohortes, y así obtener precisión por cohorte.
==== Actualización ====
Version corta:
La recomendación de DomJack debería ser la respuesta aceptada.
Sin embargo, la Mac de 16 GB de RAM es suficiente para mantener todo el conjunto de datos de entrenamiento de 709 Mb en la memoria sin que se bloquee. Entonces, aunque usaré la función DataSets cuando finalmente implemente la aplicación, aún no la estoy usando para el trabajo de desarrollo local.
Versión más larga:
Comencé utilizando la API partial_fit
como se describe arriba, pero con cada uso emitía una advertencia.
Entonces, fui a ver el origen del método aquí y descubrí que su implementación completa se ve así:
logging.warning(''The current implementation of partial_fit is not optimized''
'' for use in a loop. Consider using fit() instead.'')
return self.fit(x=x, y=y, input_fn=input_fn, steps=steps,
batch_size=batch_size, monitors=monitors)
... que me recuerda esta escena de la Guía del autoestopista:
Arthur Dent: ¿Qué sucede si presiono este botón?
Ford Prefect: Yo no ...
Arthur Dent: Oh.
Ford Prefect: ¿Qué pasó?
Arthur Dent: Se encendió un letrero que decía "No vuelva a presionar este botón".
Lo que quiere decir: partial_fit
parece existir con el único propósito de decirle que no lo use.
Además, el modelo generado al usar partial_fit
iterativamente en los fragmentos de archivos de entrenamiento fue mucho más pequeño que el generado al usar fit
en todo el archivo de entrenamiento, lo que sugiere que solo el último trozo de entrenamiento de partial_fit
realmente "tomó".
Consulte la API tf.contrib.data.Dataset
. Sospecho que será mejor que convierta sus archivos CSV a archivos TfRecord y que use TfRecordDataset . Hay un tutorial completo aquí .
Paso 1: Convierta a datos csv para registrar datos. Ejemplo de código a continuación.
import tensorflow as tf
def read_csv(filename):
with open(filename, ''r'') as f:
out = [line.rstrip().split('','') for line in f.readlines()]
return out
csv = read_csv(''data.csv'')
with tf.python_io.TFRecordWriter("data.tfrecords") as writer:
for row in csv:
features, label = row[:-1], row[-1]
features = [float(f) for f in features]
label = int(label)
example = tf.train.Example()
example.features.feature[
"features"].float_list.value.extend(features)
example.features.feature[
"label"].int64_list.value.append(label)
writer.write(example.SerializeToString())
Esto supone que las etiquetas son enteros en la última columna con características flotantes en las columnas anteriores. Esto solo necesita ejecutarse una vez.
Paso 2: escriba un conjunto de datos para decodificar estos archivos de registro.
def parse_function(example_proto):
features = {
''features'': tf.FixedLenFeature((n_features,), tf.float32),
''label'': tf.FixedLenFeature((), tf.int64)
}
parsed_features = tf.parse_single_example(example_proto, features)
return parsed_features[''features''], parsed_features[''label'']
def input_fn():
dataset = tf.contrib.data.TFRecordDataset([''data.tfrecords''])
dataset = dataset.map(parse_function)
dataset = dataset.shuffle(shuffle_size)
dataset = dataset.repeat() # repeat indefinitely
dataset = dataset.batch(batch_size)
print(dataset.output_shapes)
features, label = dataset.make_one_shot_iterator().get_next()
return features, label
Para probar (independientemente del estimador):
batch_size = 4
shuffle_size = 10000
features, labels = input_fn()
with tf.Session() as sess:
f_data, l_data = sess.run([features, labels])
print(f_data, l_data)
Para usar con tf.estimator.Estimator:
estimator.train(input_fn, max_steps=1e7)