keras實現多個模型融合(非keras自帶模型,這裡以3個自己的模型為例)
阿新 • • 發佈:2018-11-01
該程式碼可以實現類似圖片的效果,多個模型採用第一個輸入。
圖片來源:https://github.com/keras-team/keras/issues/4205
step 1:重新定義模型(這是我自己的模型,你們可以用你們自己的),與預訓練不一樣,這裡定義模型inp要採用公共的,程式碼如下:
def get_model(inp):#重新建立模型,與原來不一樣的是這裡inp是傳入 n_classes = 10 #inp=Input(shape=(120,39))#原來的inp是函式裡,傳入可以三個公用 reshape=Reshape((1,120,39))(inp) # pre=ZeroPadding2D(padding=(1, 1))(reshape) # 1 #reshape=BatchNormalization()(reshape) conv1=Convolution2D(32, 3, 3, border_mode='same',init='glorot_uniform')(reshape) #model.add(Activation('relu')) l1=PReLU()(conv1) l1=BatchNormalization()(l1) conv2=ZeroPadding2D(padding=(1, 1))(l1) conv2=Convolution2D(32, 3, 3, border_mode='same',init='glorot_uniform')(conv2) #model.add(Activation('relu')) l2=PReLU()(conv2) l2=BatchNormalization()(l2) m2=AveragePooling2D((3, 3), strides=(3, 3))(l2) d2=Dropout(0.25)(m2) # 2 conv3=ZeroPadding2D(padding=(1, 1))(d2) conv3=Convolution2D(64, 3, 3, border_mode='same',init='glorot_uniform')(conv3) #model.add(Activation('relu')) l3=PReLU()(conv3) l3=BatchNormalization()(l3) conv4=ZeroPadding2D(padding=(1, 1))(l3) conv4=Convolution2D(64, 3, 3, border_mode='same',init='glorot_uniform')(conv4) #model.add(Activation('relu')) l4=PReLU()(conv4) l4=BatchNormalization()(l4) m4=AveragePooling2D((3, 3), strides=(3, 3))(l4) d4=Dropout(0.25)(m4) g=GlobalAveragePooling2D()(d4) #4 # conv4=Convolution2D(32, 3, 3, border_mode='same',init='glorot_uniform')(d3) # conv4=BatchNormalization()(conv4) # #model.add(Activation('relu')) # l4=LeakyReLU(alpha=0.33)(conv4) # m4=MaxPooling2D((2, 2))(l4) # d4=Dropout(0.25)(m4) #f=Flatten()(g) Den=Dense(1024)(g) #model.add(Activation('relu')) ld=PReLU()(Den) ld=Dropout(0.5)(ld) result=Dense(n_classes, activation='softmax')(ld) model=Model(input=inp,outputs=result) return model
step2:載入模型引數,融合模型,程式碼如下:
def merge_model(): inp=Input(shape=(120,39))#融合主要就是Input是同樣的,所以重新建立模型 model1=get_model(inp) model2=get_model(inp) model3=get_model(inp) model1.load_weights(model_path+"CNN_mfcc1.h5")#載入各自權重 model2.load_weights(model_path+"CNN_mfcc2.h5")#載入各自權重 model3.load_weights(model_path+"CNN_mfcc3.h5")#載入各自權重 r1=model1.output#獲得輸出 r2=model2.output r3=model3.output x=concatenate([r1,r2,r3],axis=1)#拼接輸出,融合成功 model=Model(input=inp,outputs=x) return model
step3:根據自己的需要修改模型,我這裡只是新增全連線層做分類,程式碼如下:
def modify():#這裡修改模型 origin_model=merge_model() for layer in origin_model.layers: layer.trainable = False#原來的不訓練 inp=origin_model.input x=origin_model.output den=Dense(200,name="fine_dense")(x) l=PReLU()(den) l=Dropout(0.5)(l) result=Dense(10,activation="softmax")(l) model=Model(input=inp,outputs=result) model.summary() #編譯model adam = keras.optimizers.Adam(lr = 0.0005, beta_1=0.95, beta_2=0.999,epsilon=1e-08) #adam = keras.optimizers.Adam(lr = 0.001, beta_1=0.95, beta_2=0.999,epsilon=1e-08) #sgd = keras.optimizers.SGD(lr = 0.001, decay = 1e-06, momentum = 0.9, nesterov = False) #reduce_lr = ReduceLROnPlateau(monitor = 'loss', factor = 0.1, patience = 2,verbose = 1, min_lr = 0.00000001, mode = 'min') model.compile(loss='categorical_crossentropy', optimizer=adam, metrics=['accuracy']) return model