Keras中Kronecker产品的自定义Lambda图层 - 为batch_size保留的维度存在问题

时间:2018-05-14 12:52:51

标签: python tensorflow lambda keras keras-layer

我正在使用带有Tensorflow后端的Keras 2.1.5来创建图像分类模型。 在我的模型中,我想通过计算Kronecker product来组合卷积层的输入和输出。我已经使用Keras后端函数编写了计算两个3D张量的Kronecker积的函数。

def kronecker_product(mat1, mat2):
    #Computes the Kronecker product of two matrices.
    m1, n1 = mat1.get_shape().as_list()
    mat1_rsh = K.reshape(mat1, [m1, 1, n1, 1])
    m2, n2 = mat2.get_shape().as_list()
    mat2_rsh = K.reshape(mat2, [1, m2, 1, n2])
    return K.reshape(mat1_rsh * mat2_rsh, [m1 * m2, n1 * n2])

def kronecker_product3D(tensors):
    tensor1 = tensors[0]
    tensor2 = tensors[1]
    #Separete slices of tensor and computes appropriate matrice kronecker product
    m1, n1, o1 = tensor1.get_shape().as_list()
    m2, n2, o2 = tensor2.get_shape().as_list()
    x_list = []
    for ind1 in range(o1):
        for ind2 in range(o2):
            x_list.append(DenseNetKTC.kronecker_product(tensor1[:,:,ind1], tensor2[:,:,ind2]))
    return K.reshape(Concatenate()(x_list), [m1 * m2, n1 * n2, o1 * o2])

然后我尝试使用Lambda图层将操作包装到Keras图层中:

cb = Convolution2D(12, (3,3), padding='same')(x)
x = Lambda(kronecker_product3D)([x, cb])

但收到错误" ValueError:要解压的值太多(预计为3)"。我希望输入是3维的张量,但事实上,它有4个维度 - 为Keras中的batch_size保留的第一个维度。我不知道如何用动态尺寸来处理这个第四维度。

我已经搜索了很多,但是找不到任何可以批量处理批量维度的示例函数。

我很乐意提供任何提示或帮助。非常感谢你!

1 个答案:

答案 0 :(得分:0)

简易解决方案:

只需将批量维度添加到计算和重新整形

def kronecker_product(mat1, mat2):
    #Computes the Kronecker product of two matrices.
    batch, m1, n1 = mat1.get_shape().as_list()
    mat1_rsh = K.reshape(mat1, [-1, m1, 1, n1, 1])
    batch, m2, n2 = mat2.get_shape().as_list()
    mat2_rsh = K.reshape(mat2, [-1, 1, m2, 1, n2])
    return K.reshape(mat1_rsh * mat2_rsh, [-1, m1 * m2, n1 * n2])

def kronecker_product3D(tensors):
    tensor1 = tensors[0]
    tensor2 = tensors[1]
    #Separete slices of tensor and computes appropriate matrice kronecker product
    batch, m1, n1, o1 = tensor1.get_shape().as_list()
    batch, m2, n2, o2 = tensor2.get_shape().as_list()
    x_list = []
    for ind1 in range(o1):
        for ind2 in range(o2):
            x_list.append(kronecker_product(tensor1[:,:,:,ind1], tensor2[:,:,:,ind2]))
    return K.reshape(Concatenate()(x_list), [-1, m1 * m2, n1 * n2, o1 * o2])

对于硬解决方案,我会尝试找出避免迭代的方法,但这可能比我想象的更复杂....