首页 文章

如何改变Keras中任何模型架构的输入和输出形状?

提问于
浏览
0

我最近收集了几个使用 keras.Models.model_from_json 函数导入其架构的Keras模型(请注意,尚未进行任何培训) . 我的图像数据生成器可以定制,以 生产环境 不同尺寸和形状的批量样品(在同一流量发生器中变化) . 例如,我可以生成形状为 (*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: 是否有通用函数/ util来动态更改Keras中任何模型架构的输入和输出形状?

PS: 如果模型有几个输出或最后两层是,keras.layers.Dense后跟 keras.layers.Activation ,改变最后一层的形状是一个可行的解决方案吗?

1 回答

  • 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
    

相关问题