Как использовать nupmy.as_strided - PullRequest
0 голосов
/ 29 мая 2020

Я создаю свою собственную библиотеку нейронной сети, и сейчас я создаю алгоритм свертки. Я пытаюсь разделить ввод на локальные восприимчивые поля, а затем умножить его на соответствующие веса, суммировать умноженные восприимчивые поля, добавить смещения и вернуть результат. Я использую функцию 'numpy .lib.stride_tricks.as_strided', и я не уверен, как установить шаги. Буду очень признателен за вашу помощь. Вот код:

"""
the matrix shape is: 
mini_batch_size X
numberOfFilters X
numberOfInputFeatureMaps X
sizeOfInputImage[0] X 
sizeOfInputImage[1]  

the kernel shape is:
mini_batch_size X 
numberOfFilters X 
sizeOfLocalReceptiveField[0] X  
sizeOfLocalReceptiveField[1]
"""

    s1, s2, s3, s4, s5 =  matrix.strides
    imageWidth, imageHeight = matrix.shape[-2:]
    localReceptiveFieldWidth, localReceptiveFieldHeight = kernel.shape[-2:]
    matrix_shape = matrix.shape
    numberOfLocalReceptiveFields =  
    (1 + (imageWidth - localReceptiveFieldWidth) // stride) * 
    (1 + (imageHeight - localReceptiveFieldHeight) // stride) * 
    matrix_shape[1]

    view_shape = (
        matrix_shape[0], # mini batch size
        matrix_shape[1], # number of filters
        numberOfLocalReceptiveFields,
        localReceptiveFieldWidth,
        localReceptiveFieldHeight
    )

    strides = () # don't know what to put here
    subs = numpy.lib.stride_tricks.as_strided(matrix, view_shape, strides=strides)

1 Ответ

0 голосов
/ 29 мая 2020

Привет, если кому интересно, мне удалось создать алгоритм таким образом:

    @staticmethod
    def getOutputImageDims(imageWidth, imageHeight, lrfWidth, lrfHeight, stride):
        return [
            (1 + (imageWidth - lrfWidth) // stride),
            (1 + (imageHeight - lrfHeight) // stride)
        ]

    @staticmethod
    def getNumberOfLocalReceptiveFields(imageWidth, imageHeight, lrfWidth, lrfHeight, stride,
                                        numberOfInputFeatureMaps, numberOfFilters):
        return _MathHelper.getOutputImageDims(imageWidth, imageHeight, lrfWidth, lrfHeight, stride) * \
            numberOfFilters * numberOfInputFeatureMaps

    @staticmethod
    def getLocalReceptiveFields(
            matrix,
            stride,
            outputImageWidth,
            outputImageHeight,
            lrfWidth,
            lrfHeight
    ):
        s0, s1 = matrix.strides[-2:]
        matrix_dims = np.ndim(matrix)
        view_shape = matrix.shape[:2-matrix_dims] + (outputImageWidth, outputImageHeight, lrfWidth, lrfHeight)
        strides = matrix.strides[:2-matrix_dims] + (stride * s0, stride * s1, s0, s1)
        return np.lib.stride_tricks.as_strided(matrix, view_shape, strides=strides)

    @staticmethod
    def conv5D(matrix, kernel, stride=1):
        # needed variables
        imageWidth, imageHeight = matrix.shape[-2:]
        localReceptiveFieldWidth, localReceptiveFieldHeight = kernel.shape[-2:]
        x, y = _MathHelper.getOutputImageDims(imageWidth, imageHeight,
                                              localReceptiveFieldWidth, localReceptiveFieldHeight,
                                              stride)

        # wraps the kernel in a [] and then duplicates the array
        kernel = np.repeat(kernel[:, :, None, :, :], x, axis=2)
        kernel = np.repeat(kernel[:, :, :, None, :, :], y, axis=3)
        subs = _MathHelper.getLocalReceptiveFields(matrix, stride, x, y,
                                            localReceptiveFieldWidth, localReceptiveFieldHeight)

        # multipling the kernel in the local receptive fields and summing up
        arr = subs * kernel
        conv = np.sum(subs * kernel, axis=(4, 5))

        return conv
...