我想出了这个实现,但它在我目前拥有的所有模型中都适用,但远非完美。我将不胜感激使用其他模型进行进一步测试。我把它留在这里供参考。
def modifySISO(model,inp,out): # Modify Single Input Single Output image classification model.
ci,co = validation(model,inp,out)
if(ci): #change input
model = changeInp(model,inp)
if(co): #change ouput
model = changeOut(model,out)
return model, any([ci,co]) # modified or original model, modified
def validation(model,inp,out):
n_in = len(model.inputs)
n_out =len(model.outputs)
assert (n_in) > 0, 'Model has not detectable inputs.'
assert (n_out) > 0, 'Model has not detectable outputs.'
assert (n_in) <= 1, 'Model has multiple %d inputs tensors. Cannot apply input transformation.' % (n_in)
assert (n_out) <= 1, 'Model has multiple %d output tensors Cannot apply output transformation.' % (n_out)
inp_old = model.input_shape
assert len(inp_old) == 4, 'Model input tensor shape != 4: Not a valid image classification model (B x X x X x X).'
assert isinstance(inp,tuple), 'Input parameter is not a valid tuple.'
assert len(inp) == 4, 'Input parameter is not a valid 4-rank tensor shape.'
out_old = model.output_shape
assert len(out_old) == 2, 'Model output tensor shape !=2: Not a valid image classification model (B x C).'
assert isinstance(out,tuple), 'Output parameter is not a valid tuple.'
assert len(out) == 2, 'Output parameter is not a valid 2-rank tensor shape.'
ci = any([inp[i] != inp_old[i] for i in range(0,len(inp))])
co = any([out[i] != out_old[i] for i in range(0,len(out))])
return ci,co
def changeInp(model,inp):
return clone_model(model,Input(batch_shape=inp))
def changeOut(model,out):
idx = findPreTop(model) # Finds the pre-topping layer (must be tested more extensively)
preds = reshapeOutput(model,idx,out)
model = Model(inputs=model.input, outputs=preds)
def findPreTop(model):
i = len(model.layers)-1
cos = model.output_shape
while(model.layers[i].output_shape == cos):
i -= 1
return i
def reshapeOutput(model,i,out): # Reshapes model accordingly to https://keras.io/applications/#usage-examples-for-image-classification-models
layer=model.layers[i]
pool = layer.output_shape[-1]
x = layer.output
x = Dense(int(pool/2),activation='relu')(x)
x = Dense(out[1], activation='softmax')(x)
return x
newmodel = modifySISO(model,(None,100,100,3),(None,6)) #Implementation