2017-09-07 6 views
0

J'utilise un CNN (Keras/Theano) pour reconnaître des nombres donnés dans un puzzle de sudoku. Parce que j'affiche la solution de manière «augmentée», je cherche à minimiser la vitesse pour la tâche de traitement d'image et pour la tâche de reconnaissance des nombres, afin que l'affichage reste fluide. Actuellement, j'obtiens un taux de 7 images par seconde (vous pouvez jeter un oeil ici: Augmented Reality Sudoku solver : OpenCV, Keras)CNN: comment améliorer la vitesse de prédiction?

Une grande partie du temps de traitement est consacré à la tâche de prédiction: la prédiction est faite pour chaque petit carré non vide (carré avec un nombre dedans). En moyenne, une prédiction prend 3,6 ms, un puzzle a environ 25 cases non vides, donc environ 90 ms par image juste pour la reconnaissance des nombres donnés.

Le modèle CNN que j'utilise pour la tâche de prédiction est presque exactement celle proposée par F.Chollet dans le Keras MNIST example:

img_rows, img_cols = 28, 28 # Image size of the small square 
num_classes = 9 # We want to recognize the numbers from 1 to 9 
input_shape = (1, img_rows, img_cols) 
model = Sequential() 
model.add(Conv2D(32, kernel_size=(3, 3), 
      activation='relu', 
      input_shape=input_shape)) 
model.add(Conv2D(64, (3, 3), activation='relu')) 
model.add(MaxPooling2D(pool_size=(2, 2))) 
model.add(Dropout(0.25)) 
model.add(Flatten()) 
model.add(Dense(128, activation='relu')) 
model.add(Dropout(0.5)) 
model.add(Dense(num_classes, activation='softmax')) 

model.compile(loss=keras.losses.categorical_crossentropy, 
      optimizer=keras.optimizers.Adadelta(), 
      metrics=['accuracy']) 

La précision que je reçois avec ce modèle est très bon, si bien que je me demande si je peux obtenir la même précision avec un modèle "plus petit". J'imagine qu'un plus petit modèle signifierait aussi plus rapide (je me concentre seulement sur l'amélioration de la vitesse de prédiction, la vitesse d'entraînement n'a pas d'importance).

Pensez-vous que mon hypothèse ("plus petit implique plus vite") est correcte et vaut-il mieux essayer de faire un modèle plus petit? Entre la partie convolutionnelle et la partie dense, laquelle (s) je devrais essayer de faire plus petite? Toute autre suggestion sur la façon d'améliorer la vitesse de prédiction?

Merci

EDIT:

Mon CPU est un ancien i5 4210U, sans GPU nvidia.

Code de prédiction:

def predict(img): # img: 28x28 binary image 

    img = img.astype('float32') 
    img /= 255. 
    result=model.predict(np.array([[img]])) 
    result=result[0]   
    idx=np.argsort(result) 
    best=idx[-1]+1 
    return best,result[best-1] 
+1

Il n'y a pas de code de votre tâche de prédiction. Et vous nous dites même si vous utilisez CPU/GPU (latence!)? En général, oui, le plus petit sera plus rapide, mais c'est très large et à prendre avec un grain de sel, car la parallélisation pourrait aussi être douloureuse. Assurez-vous, vous utilisez la prédiction par lots si vous êtes en mesure d'appeler des prédictions multiples à la fois! – sascha

+0

sascha, j'ai édité ma question pour ajouter le code de prédiction. Je n'étais pas conscient de l'importance de batch_size dans la fonction de prévision. En fait, il n'est pas clair pour moi comment l'utiliser dans la tâche de prédiction. Parce que je ne le spécifie pas, le batch_size par défaut est 32, je pense. Jusqu'à présent, je prédis l'image (petit carré avec un nombre à l'intérieur) par image. Je vais suivre votre suggestion de faire des prédictions multiples à la fois et vous le faire savoir. Merci – geaxgx

+0

Il vaut vraiment la peine d'utiliser des prédictions multiples. Pour un sudoku à 27 chiffres, faire 1 prédiction multi-prédictive (au lieu de 27) nécessite 67 ms (au lieu de 97 ms), soit un gain de 30 ms. Maintenant, j'ai un taux global de 9 images par seconde, au lieu de 7 images par seconde, 30% de mieux! J'ai gardé la valeur par défaut de batch_size (32). – geaxgx

Répondre

0

Peut-être que vous devriez essayer de former le réseau et prédire avec type « uint8 », et sans normaliser vos données entre 0 et 1.. Une image float32 peut être trop grande pour avoir une performance de prédiction rapide. Ce n'est qu'une supposition mais vous pouvez l'essayer.

+0

Mais dans le pipeline CNN, quel que soit le type d'entrée, les données sont traitées très rapidement comme float, ne sont-ils pas?Dans ce cas, s'il y a une amélioration de la vitesse dans l'utilisation de int au lieu de float, cela ne serait-il pas très petit? – geaxgx