2016-12-08 5 views
3

이미지 분류 자 ​​미세 조정에 대해 this keras blog을 모방하려고합니다. Inceptionv3을 사용하여 on a fchollet repo을 사용하고 싶습니다.Keras 기능 모델에 결합

시작은 Model (기능적 API)이므로 Sequential에 예약 된 model.add(top_model)을 사용할 수 없습니다.

두 기능을 결합하여 추가 할 수있는 방법은 무엇입니까? Model? 이 전

inputs = Input(shape=input_shape) 
x = Flatten()(inputs) 
predictions = Dense(4, name='final1')(x) 

model1 = Model(input=inputs, output=predictions) 
첫 번째 모델

과 초

inputs_2 = Input(shape=(4,)) 
y = Dense(5)(l_inputs) 
y = Dense(2, name='final2')(y) 
predictions_2 = Dense(29)(y) 
model2 = Model(input=inputs2, output=predictions2) 

있다고 가정 해 봅시다. 이제는 inputs에서 predicions_2으로 연결되고 predictions에서 inputs_2으로 연결되는 엔드 - 투 - 엔드를 원합니다.

model1.get_layer('final1').output을 사용해 보았지만 유형이 맞지 않아 작동하지 못했습니다. 당신에 대한

(A) predictions_1 및 predictions_2 문제 :

답변

4

나는 당신이 필요에 따라이 옵션이 있습니다 생각합니다. 이 경우 2 개의 출력으로 네트워크를 학습 할 수 있습니다. 여기에 귀하의 게시물에서 파생 예 : 다중 입력 다중 출력 모델 다음 .fit 및 .predict를 들어

input_shape = [3, 20] 
inputs = Input(shape=input_shape) 
x = Flatten()(inputs) 
predictions_1 = Dense(4, name='predictions_1')(x) 

# here the predictions_1 just corresponds to your next layer's input 
y = Dense(5)(predictions_1) 
y = Dense(2)(y) 
predictions_2 = Dense(29, name='predictions_2')(y) 

# you specify here that you have 2 outputs 
model = Model(input=inputs, output=[predictions_1, predictions_2]) 

, 당신은 https://keras.io/getting-started/functional-api-guide/ 섹션에서 자세한 내용을 많이 찾을 수 있습니다.

(b) 예측에만 관심이있는 경우는입니다. 이 경우에, 당신은 다만 할 수 있습니다

input_shape = [3, 20] 
inputs = Input(shape=input_shape) 
x = Flatten()(inputs) 
predictions_1 = Dense(4, name='predictions_1')(x) 

# here the predictions_1 just corresponds to your next layer's input 
y = Dense(5)(predictions_1) 
y = Dense(2)(y) 
predictions_2 = Dense(29, name='predictions_2')(y) 

# you specify here that your only output is predictions_2 
model = Model(input=inputs, output=predictions_2) 

지금 inception_v3에 관하여. 건축물을 사용자가 직접 정의하고 필요에 따라 깊은 층을 수정할 수 있습니다 (이 층에 특정 이름을 지정하면 Keras가 자동으로 이름을 지정하지 않습니다).

는 그 후,이 문제를 해결해야

# you can load weights for only the part that corresponds to the true 
# inception_v3 architecture. The other part will be initialized 
# randomly 
model.load_weights("inception_v3.hdf5", by_name=True) 

(https://keras.io/models/about-keras-models/ 참조 기능 load_weights (..., by_name = 참)에서와 같이) 모델로드 가중치를 컴파일합니다. 그런데 추가 정보는 https://www.gradientzoo.com에서 확인할 수 있습니다. 박사.여러 저장 /로드/미세 조정 루틴 설명)

업데이트을 :

input_shape = [3, 20] 

# define model1 and model2 as you want 
inputs1 = Input(shape=input_shape) 
x = Flatten()(inputs1) 
predictions_1 = Dense(4, name='predictions_1')(x) 
model1 = Model(input=inputs1, output=predictions_1) 

inputs2 = Input(shape=(4,)) 
y = Dense(5)(inputs2) 
y = Dense(2)(y) 
predictions_2 = Dense(29, name='predictions_2')(y) 
model2 = Model(input=inputs2, output=predictions_2) 

# then define functions returning the image of an input through model1 or model2 
def give_model1(): 
    def f(x): 
     return model1(x) 
    return f 

def give_model2(): 
    def g(x): 
     return model2(x) 
    return g 

# now you can create a global model as follows: 
inputs = Input(shape=input_shape) 
x = model1(inputs) 
predictions = model2(x) 
model = Model(input=inputs, output=predictions) 
+0

감사합니다. 이 작업은 전체 시작 모델을 재정의하려는 경우에 유용합니다. 하지만 이미'Model' 객체를 가지고 있다면 어떻게 될까요? 처음부터 다시 정의 할 필요없이 새로운 모델에 직접 부착 할 수있는 방법이 있는지 궁금합니다 (매우 큰 모델이라고 생각할 때). 또한 링크 덕분에 – meto

+0

@meto 나는 그것을 얻는다. 귀하의 의견과 Omid의 제안을 바탕으로 방금 답변을 업데이트했습니다. 너에게 효과가 있니? – bn2nkm

7

나는이 시도하지 않은 : 당신은 당신이 다음과 같은 작업을 수행 할 수 처음부터 모델을 다시 정의하지 않으려면 하지만 documentation 기능 모델에 따라 호출 할 수 있습니다, 그래서 당신은 같은 것을 수행 할 수 있습니다 x이 입력에 가서 y 데이터가

y = model2(model1(x)) 

이입니다 결과 : predictions_2

2

VGG16을 미세 조정하는 동안이 문제도 발생했습니다. 여기 저를 위해 일한 것이고 Inception V3에 대해 비슷한 접근법을 취할 수 있다고 상상해 봅니다. Tensorflow 1.2 백엔드가있는 Keras 2.0.5에서 테스트되었습니다.

# NOTE: define the following variables 
#  top_model_weights_path 
#  num_classes 
#  dense_layer_1 = 4096 
#  dense_layer_2 = 4096 

vgg16 = applications.VGG16(
    include_top=False, 
    weights='imagenet', 
    input_shape=(224, 224, 3)) 

# Inspect the model 
vgg16.summary() 

# This shape has to match the last layer in VGG16 (without top) 
dense_input = Input(shape=(7, 7, 512)) 
dense_output = Flatten(name='flatten')(dense_input) 
dense_output = Dense(dense_layer_1, activation='relu', name='fc1')(dense_output) 
dense_output = Dense(dense_layer_2, activation='relu', name='fc2')(dense_output) 
dense_output = Dense(num_classes, activation='softmax', name='predictions')(dense_output) 

top_model = Model(inputs=dense_input, outputs=dense_output, name='top_model') 

# from: https://blog.keras.io/building-powerful-image-classification-models-using-very-little-data.html 
# note that it is necessary to start with a fully-trained 
# classifier, including the top classifier, 
# in order to successfully do fine-tuning 
top_model.load_weights(top_model_weights_path) 

block5_pool = vgg16.get_layer('block5_pool').output 

# Now combine the two models 
full_output = top_model(block5_pool) 
full_model = Model(inputs=vgg16.input, outputs=full_output) 

# set the first 15 layers (up to the last conv block) 
# to non-trainable (weights will not be updated) 
# WARNING: this may not be applicable for Inception V3 
for layer in full_model.layers[:15]: 
    layer.trainable = False 

# Verify things look as expected 
full_model.summary() 

# compile the model with a SGD/momentum optimizer 
# and a very slow learning rate. 
full_model.compile(
    loss='binary_crossentropy', 
    optimizer=optimizers.SGD(lr=5e-5, momentum=0.9), 
    metrics=['accuracy']) 

# Train the model...