Keras dividida tensor / rebanada tensor / 分割 tensor

¿Cómo dividir un tensor en Keras

introducción

Ejecute el código siguiente:

# coding=utf-8
from keras.layers import *

if __name__ == '__main__':
    import numpy as np
    inp1 = Input(batch_shape=(None, 12, 30, 40))
    inp2 = Input(batch_shape=(None, 12, 30, 40))

    # 分割&Concat
    concat = merge([inp1[:, 0:6, ...], inp2], mode='concat', concat_axis=-1)
    conv = Convolution2D(32, 3, 3, name='conv1')(concat)

Se reportó el siguiente error:

Exception: You tried to call layer "conv1". This layer has no information about its expected input shape, and thus cannot be built. You can build it manually via: `layer.build(batch_input_shape)`

De hecho, mis necesidades son simples, el medio ent1 de nuestro canal, y de combinación ING2, y luego la convolución, y una operación más sencilla, Keras también informó de un error. El error que es muy fan, trato de buscar la tarde, conseguir que funcione. . .

Noche eureka momento, no está obligado a personalizar una capa Keras, se da input_shapese da en el caso de output_shapeque? Tal capa de una parte posterior fueron capaces de deducir la forma.

Dividir una capa personalizada

diferentes versiones Keras lograr autodefinida interfaces de capa para lograr ligeramente diferente, Keras versión 1.1.0 uso I, así que Referencia: http://faroit.com/keras-docs/1.1.0/layers/writing- -propio-Keras-Capas / . 1.1.0 Keras en una capa personalizada es el siguiente:

from keras import backend as K
from keras.engine.topology import Layer
import numpy as np

class MyLayer(Layer):
    def __init__(self, output_dim, **kwargs):
        self.output_dim = output_dim
        super(MyLayer, self).__init__(**kwargs)

    def build(self, input_shape):
        input_dim = input_shape[1]
        initial_weight_value = np.random.random((input_dim, output_dim))
        self.W = K.variable(initial_weight_value)
        self.trainable_weights = [self.W]

    def call(self, x, mask=None):
        return K.dot(x, self.W)

    def get_output_shape_for(self, input_shape):
        return (input_shape[0], self.output_dim)

La necesidad de lograr __init__, build, cally get_output_shape_forotras interfaces. Si una fracción de tensor, necesita dar salida a una pluralidad de tensor, por lo que necesita para lograr compute_mask, para devolver una lista de forma.

En resumen, para lograr una capa de Split de la siguiente manera:

# coding=utf-8
from keras.layers import *


class Split(Layer):
    def __init__(self, **kwargs):
        super(Split, self).__init__(**kwargs)

    def build(self, input_shape):
        # 调用父类的build函数,build本层
        super(Split, self).build(input_shape)
        # 存一下shape,其他函数要用
        self.shape = input_shape

    def call(self, x, mask=None):
        # 将x分割为两个tensor
        seq = [x[:, 0:self.shape[1] // 2, ...],
               x[:, self.shape[1] // 2:, ...]]
        return seq

    def compute_mask(self, inputs, input_mask=None):
        # 本层输出两个tensor,需要返回多个mask,mask可以为None
        return [None, None]

    def get_output_shape_for(self, input_shape):
        # 本层返回两个tensor,就要返回两个tensor的shape
        shape0 = list(self.shape)
        shape1 = list(self.shape)
        shape0[1] = self.shape[1] // 2
        shape1[1] = self.shape[1] - self.shape[1] // 2
        # print [shape0, shape1]
        return [shape0, shape1]

capa derramado con lo anterior:

if __name__ == '__main__':
    import numpy as np
    inp1 = Input(batch_shape=(None, 17, 30, 40))
    inp2 = Input(batch_shape=(None, 12, 30, 40))
    sp = Split()(inp1)
    # 分割&Concat
    concat = merge([sp[0], inp2], mode='concat', concat_axis=1)
    conv = Convolution2D(32, 3, 3, name='conv1')(concat)

    data = {inp1: np.random.rand(12, 17, 30, 40).astype(np.float32),
            inp2: np.random.rand(12, 12, 30, 40).astype(np.float32)}
    print sp[0].eval({inp1: np.random.rand(12, 17, 30, 40).astype(np.float32)}).shape
    print sp[1].eval({inp1: np.random.rand(12, 17, 30, 40).astype(np.float32)}).shape
    print concat.eval(data).shape
    print conv.eval(data).shape

Ejecutar el programa anterior, salida:

(12L, 8L, 30L, 40L)
(12L, 9L, 30L, 40L)
(12L, 20L, 30L, 40L)
(12L, 32L, 28L, 38L)

Satisfacer las necesidades sin error.

Publicado 88 artículos originales · ganado elogios 132 · vistas 180 000 +

Supongo que te gusta

Origin blog.csdn.net/DumpDoctorWang/article/details/104977299
Recomendado
Clasificación