다중 입력 및 다중 출력을 갖는 Keras DQN 모델 [닫기]

Nov 15 2020

2 개의 입력이있는 DQN 에이전트를 만들려고합니다 : 에이전트의 위치와 0과 1의 행렬입니다. 출력은 에이전트가 새로 선택한 위치, 0과 1로 구성된 행렬 (입력 행렬과 다름), 값 벡터로 구성됩니다.

첫 번째 입력은 MLP 네트워크에 공급되고 두 번째 입력 (매트릭스)은 컨볼 루션 계층에 공급 된 다음 출력이 FC 네트워크에 공급되거나 적어도 아이디어입니다.

이것은이 튜토리얼 을 참조로하는 지금까지의 시도 입니다.

다음은 코드입니다.

먼저 MLP 네트워크를 만듭니다.

def create_mlp(self, arr, regress=False): # for the position input
        # define MLP network
        print("Array", arr)
        model = Sequential()
        model.add(Dense(env.rows * env.cols, input_shape=(len(arr)//2, len(arr)), activation="relu"))
        model.add(Dense((env.rows * env.cols)//2, activation="relu"))
        
        # check to see if the regression node should be added
        if regress:
            model.add(Dense(1, activation="linear"))
            
        # return our model
        return model

그런 다음 CNN

def create_cnn(self, width, height, depth=1, regress=False): # for the matrix
        # initialize the input shape and channel dimension
        inputShape = (height, width, depth)
        output_nodes = 6e2
        
        # define the model input
        inputs = Input(shape=inputShape)

        # if this is the first CONV layer then set the input
        # appropriately
        x = inputs
        
        input_layer = Input(shape=(width, height, depth))
        conv1 = Conv2D(100, 3, padding="same", activation="relu", input_shape=inputShape) (input_layer)
        pool1 = MaxPooling2D(pool_size=(2,2), padding="same")(conv1)
        flat = Flatten()(pool1)
        hidden1 = Dense(200, activation='softmax')(flat) #relu

        batchnorm1 = BatchNormalization()(hidden1) 
        output_layer = Dense(output_nodes, activation="softmax")(batchnorm1) 
        output_layer2 = Dense(output_nodes, activation="relu")(output_layer) 
        output_reshape = Reshape((int(output_nodes), 1))(output_layer2)
        model = Model(inputs=input_layer, outputs=output_reshape)

        # return the CNN
        return model

그런 다음 두

def _build_model(self):
        # create the MLP and CNN models
        mlp = self.create_mlp(env.stateSpacePos)
        cnn = self.create_cnn(3, len(env.UEs))
        
        # create the input to our final set of layers as the *output* of both
        # the MLP and CNN
        combinedInput = concatenate([mlp.output, cnn.output])
        
        # our final FC layer head will have two dense layers, the final one
        # being our regression head
        x = Dense(len(env.stateSpacePos), activation="relu")(combinedInput)
        x = Dense(1, activation="linear")(x)
        
        # our final model will accept categorical/numerical data on the MLP
        # input and images on the CNN input, outputting a single value
        model = Model(inputs=[mlp.input, cnn.input], outputs=x)
        
        opt = Adam(lr=self.learning_rate, decay=self.epsilon_decay)
        model.compile(loss="mean_absolute_percentage_error", optimizer=opt)
        
        print(model.summary())
        
        return model

오류가 있습니다.

A `Concatenate` layer requires inputs with matching shapes except for the concat axis. Got inputs shapes: [(None, 32, 50), (None, 600, 1)]

오류를 제공하는 코드 줄은 다음과 같습니다.

combinedInput = concatenate([mlp.output, cnn.output])

이것은 MLP 요약입니다

그리고 이것은 CNN 요약입니다

저는 초보자이고 실수가있는 곳이 아닙니다. 코드는 분명히 작동하지 않지만 수정하는 방법을 모릅니다.

답변

1 yang2x Nov 15 2020 at 20:57

첫째, concatenate는 축의 동일한 출력 모양에서만 작동합니다. 그렇지 않으면 기능이 작동하지 않습니다. 이제 함수 출력 크기는 (None, 32, 50) 및 (None, 600, 1)입니다. 여기서 '32'와 '600'은 연결하려는 경우 동일해야합니다.

귀하의 문제에 따라 몇 가지 조언을 제안하고 싶습니다. 둘 다 먼저 병합 한 다음 연결할 수 있습니다. 나중에 조밀 한 레이어를 사용하려면 피처를 병합해야하기 때문입니다.

def create_mlp(self, arr, regress=False): 
        # define MLP network
        print("Array", arr)
        model = Sequential()
        model.add(Dense(env.rows * env.cols, input_shape=(len(arr)//2, len(arr)), activation="relu"))
        model.add(Dense((env.rows * env.cols)//2, activation="relu"))
        **model.add.flatten() ### shape = (None, 1600)**
        # check to see if the regression node should be added
        if regress:
            model.add(Dense(1, activation="linear"))
        # return our model
        return model

그리고 create_cnn 함수 에서 reshape 레이어를 제거하십시오 . (출력 형태는 = (없음, 600)이어야합니다).

그런 다음 두 모델을 연결

combinedInput = concatenate([mlp.output, cnn.output]) ## output shape =(None, 2200)

나중에 Dense 레이어를 코드로 사용할 수 있습니다. create_mlp 함수 에서 기능을 평평하게하지 않고 조밀 한 (연결 레이어 옆에) 어떻게 사용할 수 있는지 모르겠습니다 .

코드는이 방식으로 작동해야합니다. 더 나은 이해를 위해이 간단한 것을 읽을 수 있습니다 .