我最近收集了几个Keras模型,正在使用keras.Models.model_from_json
函数为其导入其体系结构(请注意,尚未进行任何培训)。我的图像数据生成器可以进行自定义,以生成具有不同大小和形状的批次的样本(在同一流量生成器中有所不同)。例如,我可以生成形状为(*batchsize*,32,32,3)
且总共6个类的数据。当前,导入的模型具有不同的输入和输出形状,例如(5*100*100*3)
和2个分配给它们的层的类。
我的目标是更改此类图层的输入和输出形状,以便在模型性能中比较不同的图像大小。
首先,在输入层中,我尝试过:
model.layers[0].input.set_shape((None,32,32,3))
我收到以下错误:
Dimension 1 in both shapes must be equal, but are 100 and 32. Shapes are [?,100,100,3] and [?,32,32,3].
类似地,对于输出层,使用
model.layers[len(model.layers)-1].output.set_shape((None,6))
抛出相同的错误
Dimension 1 in both shapes must be equal, but are 2 and 6. Shapes are [?,2] and [?,6].
TLDR:是否存在通用功能/实用工具来动态更改Keras中任何模型架构的输入和输出形状?
PS:如果模型有多个输出,或者最后两层是keras.layers.Dense,后跟keras.layers.Activation
,那么更改最后一层的形状是否可行?< / p>
答案 0 :(得分:0)
我想出了这种实现方式,但它远非完美,无法在我目前拥有的所有模型中使用。我希望对其他模型进行进一步测试。我把它留在这里供参考。
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