Essayer de construire un modèle simple pour comprendre comment traiter tf.data.Dataset.from_generator
. Je ne comprends pas comment définir l'argument output_shapes
. J'ai essayé plusieurs combinaisons, y compris en ne le spécifiant pas mais en recevant quand même des erreurs dues à la disparité de forme des tenseurs. L'idée est simplement de générer deux tableaux numpy avec SIZE = 10
et d'exécuter une régression linéaire avec eux. Voici le code:
SIZE = 10
def _generator():
feats = np.random.normal(0, 1, SIZE)
labels = np.random.normal(0, 1, SIZE)
yield feats, labels
def input_func_gen():
shapes = (SIZE, SIZE)
dataset = tf.data.Dataset.from_generator(generator=_generator,
output_types=(tf.float32, tf.float32),
output_shapes=shapes)
dataset = dataset.batch(10)
dataset = dataset.repeat(20)
iterator = dataset.make_one_shot_iterator()
features_tensors, labels = iterator.get_next()
features = {'x': features_tensors}
return features, labels
def train():
x_col = tf.feature_column.numeric_column(key='x', )
es = tf.estimator.LinearRegressor(feature_columns=[x_col])
es = es.train(input_fn=input_func_gen)
Une autre question est de savoir s’il est possible d’utiliser cette fonctionnalité pour fournir des données aux colonnes de caractéristiques qui sont tf.feature_column.crossed_column
? L'objectif global est d'utiliser la fonctionnalité Dataset.from_generator
dans la formation par lots, dans laquelle les données sont chargées sur des fragments d'une base de données dans les cas où les données ne tiennent pas dans la mémoire. Tous les avis et exemples sont très appréciés.
Merci!
L'argument output_shapes
optionnel de tf.data.Dataset.from_generator()
vous permet de spécifier les formes des valeurs générées par votre générateur. Son type comporte deux contraintes qui définissent comment il doit être spécifié:
L'argument output_shapes
est une "structure imbriquée" (par exemple, un tuple, un tuple de tuples, un dict de tuples, etc.) qui doit correspondre à la structure des valeurs fournies par votre générateur.
_generator()
contient dans votre programme l'instruction yield feats, labels
. Par conséquent, la "structure imbriquée" est un tuple de deux éléments (un pour chaque tableau).
Chaque composant de la structure output_shapes
doit correspondre à la forme du tenseur correspondant. La forme d'un tableau est toujours un Tuple de dimensions. (La forme d'un tf.Tensor
est plus générale: voir cette question de dépassement de capacité pour une discussion.) Regardons la forme réelle de feats
:
>>> SIZE = 10
>>> feats = np.random.normal(0, 1, SIZE)
>>> print feats.shape
(10,)
Par conséquent, l'argument output_shapes
doit être un tuple à 2 éléments, chaque élément étant (SIZE,)
:
shapes = ((SIZE,), (SIZE,))
dataset = tf.data.Dataset.from_generator(generator=_generator,
output_types=(tf.float32, tf.float32),
output_shapes=shapes)
Enfin, vous devrez fournir un peu plus d'informations sur les formes aux API tf.feature_column.numeric_column()
_ et tf.estimator.LinearRegressor()
:
x_col = tf.feature_column.numeric_column(key='x', shape=(SIZE,))
es = tf.estimator.LinearRegressor(feature_columns=[x_col],
label_dimension=10)
@crafet oui, vous ne pouvez pas le faire de cette façon. Vous pouvez seulement jouer avec la taille du lot pour que cela aille plus vite