【问题标题】:model ensemble with shared layers具有共享层的模型集成
【发布时间】:2017-05-26 23:32:09
【问题描述】:

在 keras 中,我想训练一组共享某些层的模型。它们的形式如下:

x ---> f(x) ---> g_1(f(x))

x ---> f(x) ---> g_2(f(x))

...

x ---> f(x) ---> g_n(f(x))

这里的 f(x) 是一些重要的共享层。 g_1 到 g_n 都有各自的具体参数。

在每个训练阶段,数据 x 被输入到 n 个网络之一,例如第 i 个网络。然后通过基于梯度的优化器最小化/减少 g_i(f(x)) 上的损失。如何定义和训练这样的模型?

提前致谢!

【问题讨论】:

    标签: keras keras-layer


    【解决方案1】:

    您可以通过使用功能模型轻松做到这一点。

    一个小例子..你可以在它的基础上构建:

    import numpy as np
    from keras.models import Model
    from keras.layers import Dense, Input
    
    X = np.empty(shape=(1000,100))
    Y1 = np.empty(shape=(1000))
    Y2 = np.empty(shape=(1000,2))
    Y3 = np.empty(shape=(1000,3))
    
    inp = Input(shape=(100,))
    dense_f1 = Dense(50)
    dense_f2 = Dense(20)
    
    f = dense_f2(dense_f1(inp))
    
    dense_g1 = Dense(1)
    g1 = dense_g1(f)
    
    dense_g2 = Dense(2)
    g2 = dense_g2(f)
    
    dense_g3 = Dense(3)
    g3 = dense_g3(f)
    
    
    model = Model([inp], [g1, g2, g3])
    model.compile(loss=['mse', 'binary_crossentropy', 'categorical_crossentropy'], optimizer='rmsprop')
    
    model.summary()
    
    model.fit([X], [Y1, Y2, Y3], nb_epoch=10)
    

    编辑:

    根据您的 cmets,您始终可以根据自己的训练需要制作不同的模型并自行编写训练循环。您可以在model.summary() 中看到所有模型都共享初始层。这是示例的扩展

    model1 = Model(inp, g1)
    model1.compile(loss=['mse'], optimizer='rmsprop')
    model2 = Model(inp, g2)
    model2.compile(loss=['binary_crossentropy'], optimizer='rmsprop')
    model3 = Model(inp, g3)
    model3.compile(loss=['categorical_crossentropy'], optimizer='rmsprop')
    model1.summary()
    model2.summary()
    model3.summary()
    
    batch_size = 10
    nb_epoch=10
    n_batches = X.shape[0]/batch_size
    
    
    for iepoch in range(nb_epoch):
        for ibatch in range(n_batches):
            x_batch = X[ibatch*batch_size:(ibatch+1)*batch_size]
            if ibatch%3==0:
                y_batch = Y1[ibatch*batch_size:(ibatch+1)*batch_size]
                model1.train_on_batch(x_batch, y_batch)      
            elif ibatch%3==1:
                y_batch = Y2[ibatch*batch_size:(ibatch+1)*batch_size]
                model2.train_on_batch(x_batch, y_batch)      
            else:
                y_batch = Y3[ibatch*batch_size:(ibatch+1)*batch_size]
                model3.train_on_batch(x_batch, y_batch)      
    

    【讨论】:

    • 感谢您的回复!这很有帮助,但仍然不能完全解决问题。在您的示例中,我希望仅通过三个管道之一推送 X 的每个小批量。换句话说,有一个指标变量可以选择三种损失中的一种。
    • 根据评论更新。
    • 这是一项很棒的工作!非常感谢!另一个问题:我相信 train_on_batch() 只采取了 SGD 步骤,没有使用更高级的优化技术,例如动量 SGD。是否可以改为调用 model_i.fit(x_batch_i, y_batch_i, optimizer='fancier optimizer'),其中 i=1,2,3。在这种情况下,我担心的是:对于函数 f 中的参数,这三个单独的调用是否共享相同的内部优化器状态(例如,动量 SGD 的速度)?在我看来,共享这些状态是应该进行优化的方式。
    • 1) 对于 SGD 动量:sgd = SGD(momentum=0.1) 然后optimizer=sgd ... 默认情况下,动量未启用。 2)train_on_batch() 将根据规则集更新内部变量,但每个模型都有独立的优化器,内部变量不在优化器之间共享。如果需要,您需要使用具有通用优化器的一个模型回退到以前的 sn-p 代码,然后您可以使用 compile(...., loss_weights=[1,0,0]) 并编写另一个回调类来根据批次更改 loss_weights。不过这会变得有点棘手。
    • 按照您的建议,要启用不同的 loss_weights,我应该使用不同的 loss_weights 重新编译现有模型吗?回调,据我了解(可能是错误的),是在训练期间检查内部模型状态或进行自定义验证。它不能改变编译好的模型,对吧?
    猜你喜欢
    • 2021-06-04
    • 1970-01-01
    • 2018-03-16
    • 1970-01-01
    • 1970-01-01
    • 2015-08-02
    • 2011-01-29
    • 2017-05-30
    • 2021-11-19
    相关资源
    最近更新 更多