把keras的model當layer來用
- 2021 年 3 月 29 日
- AI
1 在自定義的模型上
How to concatenate two layers in keras?
first = Sequential()
first.add(Dense(1, input_shape=(2,), activation='sigmoid'))
second = Sequential()
second.add(Dense(1, input_shape=(1,), activation='sigmoid'))
third = Sequential()
# of course you must provide the input to result which will be your x3
third.add(Dense(1, input_shape=(1,), activation='sigmoid'))
# lets say you add a few more layers to first and second.
# concatenate them
merged = Concatenate([first, second])
# then concatenate the two outputs
result = Concatenate([merged, third])
ada_grad = Adagrad(lr=0.1, epsilon=1e-08, decay=0.0)
result.compile(optimizer=ada_grad, loss='binary_crossentropy',
metrics=['accuracy'])
這裡的sequential是一個已經構建完畢的model,我們也可以加載一些預訓練的model進來(這個不能這麼簡單的直接當layer用,否則會報錯下面有例子),不過從function api的角度更好理解,function api也是我個人非常推薦使用的,sequence式的api不是特別靈活和直觀.
from keras.models import Model
from keras.layers import Concatenate, Dense, LSTM, Input, concatenate
from keras.optimizers import Adagrad
first_input = Input(shape=(2, ))
first_dense = Dense(1, )(first_input)
second_input = Input(shape=(2, ))
second_dense = Dense(1, )(second_input)
merge_one = concatenate([first_dense, second_dense])
third_input = Input(shape=(1, ))
merge_two = concatenate([merge_one, third_input])
model = Model(inputs=[first_input, second_input, third_input], outputs=merge_two)
ada_grad = Adagrad(lr=0.1, epsilon=1e-08, decay=0.0)
model.compile(optimizer=ada_grad, loss='binary_crossentropy',
metrics=['accuracy'])
這樣的方法對於多模態的問題寫起代碼來比較方便,比如輸入有表格和圖像,可以自定義一個cnn的模型結構作為多模態的輸入之一,然後構建另外一個model用於處理表格數據,最後二者concat在一起就可以,非常的方便和easy,同時function api也可以很容易構建多目標優化問題的code,只要這樣寫,這裡為了好理解加了一些中文變量名:
Python">
models=Model(inputs=[圖像輸入, 表格輸入, 時間序列數據], outputs=[二分類目標,多分類目標,回歸目標])
losses = {
"二分類目標": "損失函數1",
"color_output": "損失函數2",
"回歸目標": "損失函數3"
}
lossWeights = {"損失函數1": 1.0, "損失函數2": 1.0,"損失函數2": 1.0}
model.compile(optimizer='adam', loss=losses, loss_weights=lossWeights,metrics=["accuracy"])
這裡如果涉及到多個目標的metric則可以選擇使用train_on_batch或者是一次fit一個epoch,然後直接model predict之後自己寫一些評估指標評估不同任務的表現,比直接自定義metrics方便,雖然代碼量提升了但是避免了不少bug,寫起來也簡單.
2 使用預訓練模型或者是已經訓練過的model
這裡有一個使用VGG16的預訓練model的例子:
Combining Pretrained model with new layers · Issue #3465 · keras-team/keras
from keras.applications.vgg16 import VGG16
from keras.models import Model
from keras.layers import Flatten, Dense, Dropout
from keras.layers.normalization import BatchNormalization
#load vgg16 without dense layer and with theano dim ordering
base_model = VGG16(weights = 'imagenet', include_top = False, input_shape = (3,224,224))
#number of classes in your dataset e.g. 20
num_classes = 20
x = Flatten()(base_model.output)
x = Dense(4096, activation='relu')(x)
x = Dropout(0.5)(x)
x = BatchNormalization()(x)
predictions = Dense(num_classes, activation = 'softmax')(x)
#create graph of your new model
head_model = Model(input = base_model.input, output = predictions)
#compile the model
head_model.compile(optimizer='rmsprop', loss='categorical_crossentropy', metrics=['accuracy'])
head_model.summary()
.
.
.
#train your model on data
head_model.fit(x, y, batch_size = batch_size, verbose = 1)Combining Pretrained model with new layers · Issue #3465 · keras-team/kerasfrom keras.applications.vgg16 import VGG16
from keras.models import Model
from keras.layers import Flatten, Dense, Dropout
from keras.layers.normalization import BatchNormalization
#load vgg16 without dense layer and with theano dim ordering
base_model = VGG16(weights = 'imagenet', include_top = False, input_shape = (3,224,224))
#number of classes in your dataset e.g. 20
num_classes = 20
x = Flatten()(base_model.output)
x = Dense(4096, activation='relu')(x)
x = Dropout(0.5)(x)
x = BatchNormalization()(x)
predictions = Dense(num_classes, activation = 'softmax')(x)
#create graph of your new model
head_model = Model(input = base_model.input, output = predictions)
#compile the model
head_model.compile(optimizer='rmsprop', loss='categorical_crossentropy', metrics=['accuracy'])
head_model.summary()
.
.
.
#train your model on data
head_model.fit(x, y, batch_size = batch_size, verbose = 1)
通過model.inpu和model.output的方式(注意 include_top = False),結合function api的語法就可以做出來了,當然了,第一種情況也可以用第二種的方式來寫.