Как я могу создать функциональный API Keras из нескольких входов и выходов? - PullRequest
1 голос
/ 16 января 2020

Сеть состоит из кодера, lstm и декодера. Кодер берет входную последовательность изображений (TimeDistribution) и извлекает 2 выходных сигнала различной формы. одно используют для lstm и передают его декодеру, а другое используют непосредственно для декодера. Декодер принимает два входа и выводит одно среднее изображение одинаковой формы с входной последовательностью. Как я могу написать функциональный API Keras для этой структуры?

enter image description here

Это мой пример кода, который я пробовал:

class CustomEncoder(Architecture):
def __init__(self, inputShape=(128, 128, 1), batchSize=None,
             latentSize=1000,  training=None):

     self.training=training
    super().__init__(inputShape, batchSize )

def Build(self):
    inLayer = Input(self.inputShape, self.batchSize)

    net = Conv2D(64, kernelSize=15, strides=4)(inLayer, training=self.training) # 

    net = Conv2D(64, kernelSize=11, strides=2)(net, training=self.training)    
    net = Conv2D(128, kernelSize=7, strides=2)(net, training=self.training) 

    ...

    sample = ...

    return Model(inputs=inLayer, outputs=[sample, net])



class CustomDecoder(Architecture):
def __init__(self, inputShape=(128, 128, 1), batchSize=None, latentSize=1000, training=None):
    self.training=training
    super().__init__(inputShape, batchSize, latentSize)

def Build(self):
    # input layer is from GlobalAveragePooling:
    inLayerA = Input([self.latentSize], self.batchSize)
    inLayerB = Input([8, 8, 64], self.batchSize)

    neta = Reshape((1, 1, self.latentSize))(inLayerA)

    neta = UpSampling2D((self.inputShape[0]//16, self.inputShape[1]//16))(neta)

    neta = DeconvBeta(128, kernelSize=7)(neta, training=self.training) 

    neta = DeconvBeta(64, kernelSize=11)(neta, training=self.training) 

    neta = DeconvBeta(64, kernelSize=15, strides=4)(neta, training=self.training) 

    netb = DeconvBeta(128, kernelSize=7)(inLayerB, training=self.training) 

    netb = DeconvBeta(64, kernelSize=11)(netb, training=self.training) 

    netb = DeconvBeta(64, kernelSize=15, strides=4)(netb, training=self.training) 


    neta = Conv2DTranspose(filters=1, kernel_size=15,
                  padding='same', activation="tanh")(neta)
    netb = Conv2DTranspose(filters=1, kernel_size=15,
                  padding='same', activation="tanh")(netb)
    net = Average([neta, netb])
    return Model([inLayerA, inLayerB], net)

class ConvLSTMBeta(Architecture):

def __init__(self, inputShape=(None, 8, 8, 64), batchSize=None, latentSize=1000, training=None):

    self.training=training
    super().__init__(inputShape, batchSize, latentSize)

def Build(self):
    # create the input layer for feeding the netowrk
    inLayer = Input(self.inputShape, self.batchSize)
    net = (ConvLSTM2D(64, (3, 3), padding="same",dropout=0.2, recurrent_dropout=0.2, return_sequences=True))(inLayer) # 1

    return Model(inputs=inLayer, outputs=net)
...