web-dev-qa-db-ja.com

特定のネットワークをトレーニングするとき、Keras(Tensorflowバックエンド)がGPUでCPUよりも遅い

GPUとCPUの速度が小さなサイズのネットワークで似ている理由(CPUが時々高速である)を正確に理解できず、GPUが大きなサイズのネットワークで高速である。質問の最後のコードはi7-6700kで103.7秒で実行されますが、tensorflow-gpuを使用すると、コードは29.5秒で実行されます。

ただし、下の例のように1000個ではなく、100個の隠れたニューロンがあるネットワークをトレーニングすると、GPUを使用する場合は〜20秒、CPUを使用する場合は〜15秒になります。

CPUからGPUへの転送には時間がかかるという別のスタックオーバーフローの回答を読みました。これは、GPUにデータの例をロードすることに関するものだと思います。

誰かがこれが発生する理由を説明できますか?速度を最大化するために行うことができるコードのいくつかの変更を参照できますか?

import numpy as np
import tensorflow as tf
import keras
from keras.models import Sequential
from keras.utils import np_utils
from keras.layers.core import Dense, Activation, Flatten, Dropout
from sklearn.preprocessing import normalize

## Importing the MNIST dataset using Keras
from keras.datasets import mnist
(X_train, y_train), (X_test, y_test) = mnist.load_data()

# reshape for vector input
N, x, y = X_train.shape
X_train = normalize(np.reshape(X_train, (N, x * y)))

N, x, y = X_test.shape
X_test = normalize(np.reshape(X_test, (N, x * y)))

# one-hot encoding
y_train = np_utils.to_categorical(y_train)
y_test = np_utils.to_categorical(y_test)

model = Sequential()
model.add(Dense(output_dim=750, input_dim=784))
model.add(Activation('relu'))
model.add(Dropout(0.2))

model.add(Dense(150))
model.add(Activation('relu'))
model.add(Dropout(0.2))

model.add(Dense(50))
model.add(Activation('relu'))
model.add(Dropout(0.2))

model.add(Dense(50))
model.add(Activation('relu'))
model.add(Dropout(0.2))

model.add(Dense(10))
model.add(Activation('softmax'))

model.compile(loss='categorical_crossentropy', optimizer='Nadam', metrics=['accuracy'])

fit = model.fit(X_train, y_train, batch_size=128, nb_Epoch=10, verbose=0)

## Printing the accuracy of our model, according to the loss function specified in model.compile above
score = model.evaluate(X_test, y_test, verbose=0)
print('Test score:', score[0])
print('Test accuracy:', score[1])
13
Enrico Borba

小さなネットワークの場合、バッチ読み込みが原因かもしれません。

Kerasは各イタレーションの開始時にRAMからGPUに各ミニバッチをロードしているため、小さなネットワーク(前方/後方計算が非常に速い)でボトルネックが発生します)。
model.fit_generatorプレーンfitの代わりに、ミニバッチをロードするCPUスレッドが並列で動作するようにします。

残念ながら、KerasのGPUにデータセット全体をプリロードする方法を知っている方法はありません( 私の問題 を参照)

Tensorflowバックエンドを使用している場合は、Googleタイムラインプロファイリングツールを使用して、速度低下の原因を確認できます。参考のために、 この問題 を参照してください

8
Alex Serikov