2017-12-29 4 views
1

私は(320 * 320)の形の3000画像とその撮影時間とそのラベルを持っています。これらの2種類のデータ(画像と時間)を使用してラベルを予測したいと考えています。メインのコードは次のよう:ケラスでは、異なるタイプの複数の入力データをどのように適合させるのですか

model.fit([main_input, additional_data], [labels], 
     epochs=50, batch_size=32) 

しかし、私はデータaugumentionを使用しているため、両方のfit_generatorを使用しても、時間の機能を使用する方法:

num_classes=10 
image_out=GlobalMaxPooling2D()(x) 
x=keras.layers.advanced_activations.LeakyReLU(alpha=0.3)(x) 

#add time 
time_input = Input(shape=(1,), name='time_input') 
x = keras.layers.concatenate([image_out, time_input],axis=-1) 
x=Dense(num_classes, activation='sigmoid')(x) 
predictions = Dense(num_classes,activation='softmax',name='main_output')(x) 

を私はモデルを訓練するために、次のコードを使用することができます知っていますモデルを訓練する?このような新しいジェネレータを定義する必要がありますか?

def generator_for2img(X1, X2, Y,batch_size): 
    datagen = ImageDataGenerator(featurewise_center=False, # set input mean to 0 over the dataset 
           samplewise_center=False, # set each sample mean to 0 
           featurewise_std_normalization=False, # divide inputs by std of the dataset 
           samplewise_std_normalization=False, # divide each input by its std 
           zca_whitening=False, # apply ZCA whitening 
           rotation_range=0, # randomly rotate images in the range (degrees, 0 to 180) 
           width_shift_range=0.1, # randomly shift images horizontally (fraction of total width) 
           height_shift_range=0.1, # randomly shift images vertically (fraction of total height) 
           horizontal_flip=True, # randomly flip images 
           vertical_flip=False) # randomly flip image 
    time_generator=Generator() 
    datagen.fit(X1) 
    genX1 = datagen.flow(X1,Y,batch_size=batch_size) 
    genX2 = time_generator.flow(X2,batch_size=batch_size) 
    while True: 
      X1i = genX1.next() 
      X2i = genX2.next() 
      yield [X1i[0], X2i ], X1i[1] 

model.fit_generator(generator_for2img(X_train_cv, X_train_time, y_train_cv,batch_size), 
            epochs=epochs, 
            validation_data=([X_valid,X_valid_time],y_valid), 
            workers=4, 

答えて

0

私は最近非常に似た問題に直面しました。私はCNN分類画像を持っていましたが、分類プロセスに画像のグローバルな特徴を含めることも考えました。私はこれらの機能を事前に計算してから、後で融合させる(つまり、softmaxレイヤーでマージする)ことでそれらの機能をネットワークに組み込むことを望んでいました。私は、KerasのImageDataGeneratorを使用することに加えて、3つのジェネレータを書く必要があることを発見しました(実際にはこれを2に減らすことができます)。これらのジェネレータを含む関数は次のとおりです。入力x_trainとx_testは画像入力であり、x_train_featとx_test_featはグローバル(「通常」)機能を表します。

def train_model(model, x_train, x_train_feat, y_train, x_test, x_test_feat, y_test, train_batch_size, test_batch_size, epochs, model_dir, model_name, num_classes, patience=5, monitor='val_acc'): 

    ''' 
    Training function 
    ''' 

    train_datagen = ImageDataGenerator(
     featurewise_center=False, # also use in test gen if activated AND fit test_gen on train data 
     samplewise_center=False, 
     featurewise_std_normalization=False, # also use in test gen if activated AND fit test_gen on train data 
     samplewise_std_normalization=False, 
     zca_whitening=False, 
     zca_epsilon=0, 
     rotation_range=0.05, 
     width_shift_range=0.05, 
     height_shift_range=0.05, 
     channel_shift_range=0, 
     fill_mode='nearest', 
     cval=0, 
     vertical_flip=False, 
     rescale=1./255, 
     shear_range=0., 
     zoom_range=0., 
     horizontal_flip=False) 

    train_datagen.fit(x_train) 

    test_datagen = ImageDataGenerator(
     rescale=1./255, 
     featurewise_std_normalization=False, 
     featurewise_center=False) 

    #test_datagen.fit(x_train) 

    train_generator = train_datagen.flow(
     x_train, 
     y_train, 
     batch_size=train_batch_size, 
     shuffle=False) 

    def train_feat_gen(x_train_feat, train_batch_size): 
     while True: 
      for batch in range(len(x_train_feat) // train_batch_size + 1): 
       if batch > max(range(len(x_train_feat) // train_batch_size)): 
        yield x_train_feat[batch*train_batch_size:] 
       else: 
        yield x_train_feat[batch*train_batch_size:(1+batch)*train_batch_size] 

    def val_feat_gen(x_val_feat, test_batch_size): 
     while True: 
      for batch in range(len(x_val_feat) // test_batch_size + 1): 
       if batch > max(range(len(x_val_feat) // test_batch_size)): 
        yield x_val_feat[batch*test_batch_size:] 
       else: 
        yield x_val_feat[batch*test_batch_size:(1+batch)*test_batch_size] 

    def merge_generator(gen1, gen2): 
     while True: 
      X1 = gen1.__next__() 
      X2 = gen2.__next__() 
      yield [X1[0], X2], X1[1] 

    validation_generator = test_datagen.flow(
     x_test, 
     y_test, 
     batch_size=test_batch_size) 

    final_train_gen = merge_generator(train_generator, train_feat_gen(x_train_feat, train_batch_size)) 
    final_val_gen = merge_generator(validation_generator, val_feat_gen(x_val_feat, test_batch_size)) 

    callbacks = [ModelCheckpoint(MODEL_DIR+model_name+'.h5', 
           monitor=monitor, 
           save_best_only=True), 
       EarlyStopping(monitor=monitor, patience=patience), 
       TensorBoard(LOG_DIR+model_name+'_'+str(time())), 
       ReduceLROnPlateau(monitor='val_loss', factor=0.75, patience=2)] 

    model.fit_generator(
     final_train_gen, 
     steps_per_epoch=len(x_train) // train_batch_size, 
     epochs=epochs, 
     validation_data=final_val_gen, 
     validation_steps=len(y_test) // test_batch_size, 
     callbacks=callbacks,) 

発電機train_feat_gen、val_feat_gen、およびmerge_generatorに注意してください。最初の2つはトレーニングと検証データのバッチ処理を行い、後者は2つのジェネレータ(train_feat_genとtrain_datagen; val_feat_genとtest_datagen)をラップし、異なるタイプの2つの入力を提供する1つのジェネレータを生成します。もちろん、train_feat_genとval_feat_genの両方を持つことは本質的に同じですが、異なるパラメータでインスタンス化されるので、ここでは冗長です。しかし、私はこのケースがそれをより明白にすると思います。お役に立てれば。

関連する問題