質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.65%

VAEをkerasで実装.GPUメモリ不足なのでfit_generatorを使おうとしたがエラーが発生.

受付中

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 565

unisci

score 6

前提・実現したいこと

2層のGRU-VAEをkerasで実装しています.入力データが(データ数,タイムステップ,特徴量)=(11414,615,13)なのですが,データサイズが大きすぎてGPUのメモリに収まりきっていない状態です.そこでこの方(https://qiita.com/simonritchie/items/d7168d1d9cea9ceb6af7)のサイトを参考に一旦訓練データをmemmapに保存し,保存したファイルX_train_data.npyからデータを読み込んでkerasのfit_generatorで解決できるとのことなので,実装してみたのですが,エラーが出てしまいます.何が問題なのでしょうか.またこの方法以外で大量のデータを扱う方法はありますか?どなたか回答よろしくお願いいたします.

import math
import os 
import subprocess
import keras
import numpy as np
from keras import backend as K
from keras.models import Sequential, Model
from keras.layers import Input,InputLayer, CuDNNGRU, RepeatVector,TimeDistributed
from keras.layers.core import Flatten, Dense, Dropout, Lambda
from keras.optimizers import SGD, RMSprop, Adam
from keras import objectives
from keras.utils import Sequence

def gru_vae():

    LATENT_DIM1=200 #潜在次元1
    LATENT_DIM2=50 #潜在次元2
    CODING_DIM=50 #コーディング層
    NUM_TIMESTEPS=615 #MFCCの最大タイムステップ
    NUM_INPUT_DIM=13 #MFCCの次元

    #コーディング層からのサンプリング,reparameterization trick
    def sampling(args):
        z_mean, z_log_var = args
        batch = K.shape(z_mean)[0]
        dim = K.int_shape(z_mean)[1]
        # 平均0 ,標準偏差1のランダム誤差
        epsilon = K.random_normal(shape=(batch, dim),mean=0., stddev=1.)
        return z_mean + K.exp(0.5 * z_log_var) * epsilon

    # エンコーダの定義
    #エンコーダの入力層の定義
    inputs = Input(shape=(NUM_TIMESTEPS, NUM_INPUT_DIM))
    #入力から潜在次元数に次元圧縮する.
    #2層のRNN層
    x = CuDNNGRU(LATENT_DIM1,return_sequences=True)(inputs)
    x = CuDNNGRU(LATENT_DIM2)(x)
    #潜在次元からコーディング層の確率変数次元へ
    z_mean = Dense(CODING_DIM, name='z_mean')(x)  # コーディング層の平均を出力
    z_log_var = Dense(CODING_DIM, name='z_log_var')(x)  # コーディング層の標準偏差を出力

    # reparameterization trick
    z = Lambda(sampling, output_shape=(CODING_DIM,), name='z')([z_mean, z_log_var])  # コーディングの分布からサンプリング
    #エンコーダ内の層をインスタンス化する.
    encoder = Model(inputs, [z_mean, z_log_var, z], name="encoder")
    # encoder部分は入力を受けて平均、分散、そこからランダムサンプリングしたものの3つを返す

    # デコーダの定義
    #デコーダの入力層はコーディング層からの出力zをタイムステップ分生成する.
    latent_inputs = RepeatVector(NUM_TIMESTEPS)(z)
    #コーディング次元から潜在次元へデコーディング
    x = CuDNNGRU(LATENT_DIM2,return_sequences=True)(latent_inputs)
    x = CuDNNGRU(LATENT_DIM1,return_sequences=True)(x)
    outputs = CuDNNGRU(NUM_INPUT_DIM,return_sequences=True)(x)


    # デコーダーとエンコーダーの結合
    vae = Model(inputs, outputs, name='gru_vae')

    # 損失関数をこのモデルに加える
    def loss(inputs, outputs):
        z_mean, z_log_var, _ = encoder(inputs)
        rec_loss = objectives.mse(K.flatten(inputs), K.flatten(outputs))
        #rec_loss *= NUM_INPUT_DIM*NUM_TIMESTEPS
        kl_loss = - 0.5 * K.mean(1 + z_log_var - K.square(z_mean) - K.exp(z_log_var))
        BETA=1
        total_loss = rec_loss + BETA*kl_loss
        return total_loss

    vae.add_loss(loss(inputs, outputs))
    print("gru_vaeの構成")
    vae.summary()
    return vae
class LearningSequence(Sequence):
    def __init__(self, batch_size):
        DATA_ROW_NUM = 11414
        self.batch_size = batch_size
        self.X_train = np.memmap('X_train_data.npy', dtype='float32', mode='r', shape=(DATA_ROW_NUM, 615, 13))
        self.y_train = np.memmap('y_train_data.npy', dtype='float32', mode='r', shape=(DATA_ROW_NUM))
        self.length = math.ceil(DATA_ROW_NUM / batch_size)

    def __getitem__(self, idx):
        start_idx = idx * self.batch_size
        last_idx = start_idx + self.batch_size
        X = self.X_train[start_idx:last_idx]
        y = self.y_train[start_idx:last_idx]
        return X,y

    def __len__(self):
        return self.length

    def on_epoch_end(self):
        pass
#GRU-VAEの学習
BATCH_SIZE=32
EPOCH_NUM=10
gru_vae = gru_vae()
optimizer=Adam(lr=0.001,beta_1=0.99,beta_2=0.99)
gru_vae.compile(optimizer=optimizer)
learning_sequence=LearningSequence(batch_size=BATCH_SIZE)
gru_vae.fit_generator(generator=learning_sequence, epochs=EPOCH_NUM)

発生している問題・エラーメッセージ

gru_vaeの構成
__________________________________________________________________________________________________
Layer (type)                    Output Shape         Param #     Connected to                     
==================================================================================================
input_1 (InputLayer)            (None, 615, 13)      0                                            
__________________________________________________________________________________________________
cu_dnngru_1 (CuDNNGRU)          (None, 615, 200)     129000      input_1[0][0]                    
__________________________________________________________________________________________________
cu_dnngru_2 (CuDNNGRU)          (None, 50)           37800       cu_dnngru_1[0][0]                
__________________________________________________________________________________________________
z_mean (Dense)                  (None, 50)           2550        cu_dnngru_2[0][0]                
__________________________________________________________________________________________________
z_log_var (Dense)               (None, 50)           2550        cu_dnngru_2[0][0]                
__________________________________________________________________________________________________
z (Lambda)                      (None, 50)           0           z_mean[0][0]                     
                                                                 z_log_var[0][0]                  
__________________________________________________________________________________________________
repeat_vector_1 (RepeatVector)  (None, 615, 50)      0           z[0][0]                          
__________________________________________________________________________________________________
cu_dnngru_3 (CuDNNGRU)          (None, 615, 50)      15300       repeat_vector_1[0][0]            
__________________________________________________________________________________________________
cu_dnngru_4 (CuDNNGRU)          (None, 615, 200)     151200      cu_dnngru_3[0][0]                
__________________________________________________________________________________________________
cu_dnngru_5 (CuDNNGRU)          (None, 615, 13)      8385        cu_dnngru_4[0][0]                
==================================================================================================
Total params: 346,785
Trainable params: 346,785
Non-trainable params: 0
__________________________________________________________________________________________________
Epoch 1/10
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-3-4f57106607b2> in <module>
     15             #validation_split=0.15)
     16 
---> 17 gru_vae.fit_generator(generator=learning_sequence, epochs=EPOCH_NUM)

~\Anaconda3\envs\master2\lib\site-packages\keras\legacy\interfaces.py in wrapper(*args, **kwargs)
     89                 warnings.warn('Update your `' + object_name + '` call to the ' +
     90                               'Keras 2 API: ' + signature, stacklevel=2)
---> 91             return func(*args, **kwargs)
     92         wrapper._original_function = func
     93         return wrapper

~\Anaconda3\envs\master2\lib\site-packages\keras\engine\training.py in fit_generator(self, generator, steps_per_epoch, epochs, verbose, callbacks, validation_data, validation_steps, class_weight, max_queue_size, workers, use_multiprocessing, shuffle, initial_epoch)
   1416             use_multiprocessing=use_multiprocessing,
   1417             shuffle=shuffle,
-> 1418             initial_epoch=initial_epoch)
   1419 
   1420     @interfaces.legacy_generator_methods_support

~\Anaconda3\envs\master2\lib\site-packages\keras\engine\training_generator.py in fit_generator(model, generator, steps_per_epoch, epochs, verbose, callbacks, validation_data, validation_steps, class_weight, max_queue_size, workers, use_multiprocessing, shuffle, initial_epoch)
    215                 outs = model.train_on_batch(x, y,
    216                                             sample_weight=sample_weight,
--> 217                                             class_weight=class_weight)
    218 
    219                 outs = to_list(outs)

~\Anaconda3\envs\master2\lib\site-packages\keras\engine\training.py in train_on_batch(self, x, y, sample_weight, class_weight)
   1209             x, y,
   1210             sample_weight=sample_weight,
-> 1211             class_weight=class_weight)
   1212         if self._uses_dynamic_learning_phase():
   1213             ins = x + y + sample_weights + [1.]

~\Anaconda3\envs\master2\lib\site-packages\keras\engine\training.py in _standardize_user_data(self, x, y, sample_weight, class_weight, check_array_lengths, batch_size)
    787                 feed_output_shapes,
    788                 check_batch_axis=False,  # Don't enforce the batch size.
--> 789                 exception_prefix='target')
    790 
    791             # Generate sample-wise weight values given the `sample_weight` and

~\Anaconda3\envs\master2\lib\site-packages\keras\engine\training_utils.py in standardize_input_data(data, names, shapes, check_batch_axis, exception_prefix)
     61             raise ValueError('Error when checking model ' +
     62                              exception_prefix + ': '
---> 63                              'expected no data, but got:', data)
     64         return []
     65     if data is None:

ValueError: ('Error when checking model target: expected no data, but got:', memmap([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
        0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
       dtype=float32))
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

0

勘違いだったらすみません.
エラーメッセージを見ると, target(正解)データは"ない"ことが期待されていたが実際にはあった(memmap)となっているので, memmapのy_trainを定義する必要はないのではないでしょうか.

VAEはオートエンコーダなので,入力X_trainを一度潜在次元に圧縮した上で再びそれを復元して元のX_trainに戻す(つまり正解データはX_train)という構造だと思うのですが...

もし参考にした元々のサンプルなどがあるようでしたらそちらを確認してみるのもよいかと思います.
余計に混乱させてしまったらすみません.

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.65%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る