1

CUDA を備えた Tesla K80 GPU を備えた AWS P2 インスタンスで実行するように設定された Keras と Theano を使用して、さまざまなアーキテクチャとパラメーターを持つ一連の再帰型ニューラル ネットワークのモデル選択とパフォーマンス推定のためにネストされた交差検証を実行しています。 cuDNN がインストールされている/有効になっている。

モデル選択を実行するために、パラメーター空間からサンプリングされた 30 個のモデルを比較します。

param_grid = {
             'nb_hidden_layers': [1, 2, 3],
             'dropout_frac': [0.15, 0.20],
             'output_activation': ['sigmoid', 'softmax'],
             'optimization': ['Adedelta', 'RMSprop', 'Adam'],
             'learning_rate': [0.001, 0.005, 0.010],
             'batch_size': [64, 100, 150, 200],
             'nb_epoch': [10, 15, 20],
             'perform_batchnormalization': [True, False]
             }
params_list = list(ParameterSampler(param_grid, n_iter = 30))

NeuralNetworkClassifier()次に、以下に定義する関数を使用して RNN モデルを構築します

def NeuralNetworkClassifier(params, units_in_hidden_layer = [50, 75, 100, 125, 150]):
    nb_units_in_hidden_layers = np.random.choice(units_in_hidden_layer, size = params['nb_hidden_layers'], replace = False)

    layers = [8]    # number of features in every week
    layers.extend(nb_units_in_hidden_layers)
    layers.extend([1])  # node identifying quit/stay

    model = Sequential()

    # constructing all layers up to, but not including, the penultimate one
    layer_idx = -1  # this ensures proper generalization nb_hidden_layers = 1 (for which the loop below will never run)
    for layer_idx in range(len(layers) - 3):
        model.add(LSTM(input_dim = layers[layer_idx], output_dim = layers[layer_idx + 1], init = 'he_uniform', return_sequences = True))    # all LSTM layers, up to and including the penultimate one, need return_sequences = True
        if params['perform_batchnormalization'] == True:
            model.add(BatchNormalization())
            model.add(Activation('relu'))
        model.add(Dropout(params['dropout_frac']))
    # constructing the penultimate layer
    model.add(LSTM(input_dim = layers[layer_idx + 1], output_dim = layers[(layer_idx + 1) + 1], init = 'he_uniform', return_sequences = False)) # the last LSTM layer needs return_sequences = False
    if params['perform_batchnormalization'] == True:
        model.add(BatchNormalization())
        model.add(Activation('relu'))
    model.add(Dropout(params['dropout_frac']))
    # constructing the final layer
    model.add(Dense(output_dim = layers[-1], init = 'he_normal'))
    model.add(Activation(params['output_activation']))

    if params['optimization'] == 'SGD':
        optim = SGD()
        optim.lr.set_value(params['learning_rate'])
    elif params['optimization'] == 'RMSprop':
        optim = RMSprop()
        optim.lr.set_value(params['learning_rate'])
    elif params['optimization'] == 'Adam':
        optim = Adam()
    elif params['optimization'] == 'Adedelta':
        optim = Adadelta()

    model.compile(loss = 'binary_crossentropy', optimizer = optim, metrics = ['precision'])

    return model

'nb_hidden_layers'隠れ層の数がパラメーターin で指定され、各層param_gridの隠れユニットの数が list からランダムにサンプリングされる RNN を構築します[50, 75, 100, 125, 150]。最後に、この関数compileはモデルを返します。

ネストされた相互検証 (CV) 中に、内側のループ (IN時間を実行) は、ランダムに選択された 30 個のモデルのパフォーマンスを比較します。このステップの後、外側のループで最もパフォーマンスの高いモデルを選択し、ホールドアウト データセットでそのパフォーマンスを推定します。このスキームは何OUT度も繰り返されます。したがって、私はcompileRNN モデルをOUTx INx30 回実行していますが、これには非常に長い時間がかかります。たとえば、いつOUT=4との場合IN=3、私のメソッドは完了するまでに 6 ~ 7 時間かかります。

GPU が散発的に使用されていることがわかります (ただし、GPU 使用率が 40% を超えることはありません)。ただし、ほとんどの場合、使用されているのは CPU です。私の (無知な) 推測では、これcompileは CPU で何度も行われ、計算時間の大部分を占めますが、モデルのフィッティングと予測は GPU で行われ、短時間で済みます。

私の質問:

  1. この状況を改善する方法はありますか?
  2. compile実際にCPU上で行われますか?
  3. ネストされた CV を使用して最適な RNN アーキテクチャを選択するにはどうすればよいでしょうか?
  4. 本番サーバーでこのスキームを実行することは合理的ですか? 最高のパフォーマンスを発揮するモデルを選択し、その後その 1 つのモデルを本番サーバーで使用するために、24 時間かかるかもしれない 1 つの大きなネストされた CV を実行することをお勧めしますか?

皆さん、ありがとうございました。

4

1 に答える 1

2

すべての質問にお答えすることはできませんが、お役に立てば幸いです。

コンパイルは、主にシンボリック グラフ操作とコード生成で構成されているため、CPU で行われます。さらに悪いことに、theano グラフの最適化は純粋な Python コードを使用するため、C/C++ 実装と比較してオーバーヘッドになる可能性があります。

theano のコンパイル時間を改善するには (実行時のパフォーマンスを犠牲にして):

あまり積極的でない最適化を使用する

追加/home/ec2-user/.theanorc行:

optimizer = fast_compile

または、次の方法で最適化を完全に無効にします。

optimizer = None

一部のブロックをプリコンパイルする

モデル間で共有される共通ブロックがある場合は、それらを次のようにプリコンパイルできます。theano.OpFromGraph

ただし、Keras だけでこれを行うことはできません。

フレームワークを切り替える

Keras は tensorflow バックエンドをサポートしています。theano と比較すると、tensorflow はコンパイラというよりも VM のように機能します。通常、TF は theano よりも低速で実行されますが、コンパイルははるかに高速です。

于 2017-01-13T05:19:12.120 に答える