Mes données peuvent être vues comme une matrice d'entrées 10B (100M x 100), ce qui est très rare (<1/100 * 1/100 des entrées sont non nulles). Je voudrais alimenter les données dans un modèle Keras Neural Network que j'ai créé, en utilisant un backend Tensorflow.
Ma première pensée a été d'étendre les données pour qu'elles soient denses, c'est-à-dire d'écrire toutes les entrées 10B dans une série de CSV, la plupart des entrées étant nulles. Cependant, cela accable rapidement mes ressources (même en faisant l'ETL submergé pandas et provoque des difficultés avec les postgres). J'ai donc besoin d'utiliser de vraies matrices clairsemées.
Comment puis-je faire cela avec Keras (et Tensorflow)? Alors que numpy ne prend pas en charge les matrices clairsemées, scipy et tensorflow le font tous les deux. Il y a beaucoup de discussions (par exemple https://github.com/fchollet/keras/pull/1886https://github.com/fchollet/keras/pull/3695/fileshttps://github.com/pplonski/keras-sparse-checkhttps://groups.google.com/forum/#!topic/keras-users/odsQBcNCdZg ) à propos de cette idée - soit en utilisant les matrices clairsemées de scipy soit en allant directement aux matrices clairsemées de Tensorflow. Mais je ne parviens pas à une conclusion claire et je n'ai rien pu faire travailler (ni même savoir clairement où aller!).
Comment puis-je faire ceci?
Je pense qu'il y a deux approches possibles:
Je pense aussi que le n ° 2 est préféré, car vous obtiendrez de bien meilleures performances tout au long (je crois), mais le n ° 1 est probablement plus facile et sera adéquat. Je serai content non plus.
Comment peut-on les mettre en œuvre?
Désolé, je n'ai pas la réputation de commenter, mais je pense que vous devriez jeter un œil à la réponse ici: Keras, problème de matrice clairsemée . Je l'ai essayé et cela fonctionne correctement, juste une note cependant, au moins dans mon cas, le brassage a conduit à de très mauvais résultats, j'ai donc utilisé cette alternative légèrement modifiée non mélangée:
def nn_batch_generator(X_data, y_data, batch_size):
samples_per_Epoch = X_data.shape[0]
number_of_batches = samples_per_Epoch/batch_size
counter=0
index = np.arange(np.shape(y_data)[0])
while 1:
index_batch = index[batch_size*counter:batch_size*(counter+1)]
X_batch = X_data[index_batch,:].todense()
y_batch = y_data[index_batch]
counter += 1
yield np.array(X_batch),y_batch
if (counter > number_of_batches):
counter=0
Il produit des précisions comparables à celles obtenues par l'implémentation aléatoire des keras (paramètre shuffle=True
dans fit
).
Cette réponse répond à la deuxième approche mentionnée dans la question. Il est possible d'utiliser des matrices clairsemées comme entrées d'un modèle Keras avec le backend Tensorflow si vous écrivez une boucle d'apprentissage personnalisée. Dans l'exemple ci-dessous, le modèle prend une matrice clairsemée en entrée et génère une matrice dense.
from keras.layers import Dense, Input
from keras.models import Model
import scipy
import numpy as np
trainX = scipy.sparse.random(1024, 1024)
trainY = np.random.Rand(1024, 1024)
inputs = Input(shape=(trainX.shape[1],), sparse=True)
outputs = Dense(trainY.shape[1], activation='softmax')(inputs)
model = Model(inputs=inputs, outputs=outputs)
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
steps = 10
for i in range(steps):
# For simplicity, we directly use trainX and trainY in this example
# Usually, this is where batches are prepared
print(model.train_on_batch(trainX, trainY))
# [3549.2546, 0.0]
# ...
# [3545.6448, 0.0009765625]
Cependant, l'utilité de cette approche dépend de la nécessité ou non de densifier la matrice clairsemée de votre modèle. En effet, le modèle ci-dessus a une couche qui transforme la matrice clairsemée en une matrice dense. Cela peut être un problème si votre matrice clairsemée ne tient pas en mémoire.