Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

238
Visualizações
cómo realizar la agrupación máxima / media en una matriz 2d usando numpy

Dada una matriz 2D (M x N) y un kernel 2D (K x L), ¿cómo devuelvo una matriz que es el resultado de la agrupación máxima o media usando el kernel dado sobre la imagen?

Me gustaría usar numpy si es posible.

Nota: M, N, K, L pueden ser pares o impares y no es necesario que sean perfectamente divisibles entre sí, por ejemplo: matriz 7x5 y núcleo 2x2.

por ejemplo, de agrupación máxima:

 matrix: array([[ 20, 200, -5, 23], [ -13, 134, 119, 100], [ 120, 32, 49, 25], [-120, 12, 09, 23]]) kernel: 2 x 2 soln: array([[ 200, 119], [ 120, 49]])
over 4 years ago · Santiago Trujillo
3 Respostas
Responde à pergunta

0

Podrías usar scikit-image block_reduce :

 import numpy as np import skimage.measure a = np.array([ [ 20, 200, -5, 23], [ -13, 134, 119, 100], [ 120, 32, 49, 25], [-120, 12, 9, 23] ]) skimage.measure.block_reduce(a, (2,2), np.max)

Da:

 array([[200, 119], [120, 49]])
over 4 years ago · Santiago Trujillo Relatório

0

Si el tamaño de la imagen es divisible uniformemente por el tamaño del kernel, puede remodelar la matriz y usar el max o mean como mejor le parezca.

 import numpy as np mat = np.array([[ 20, 200, -5, 23], [ -13, 134, 119, 100], [ 120, 32, 49, 25], [-120, 12, 9, 23]]) M, N = mat.shape K = 2 L = 2 MK = M // K NL = N // L print(mat[:MK*K, :NL*L].reshape(MK, K, NL, L).max(axis=(1, 3))) # [[200, 119], [120, 49]]

Si no tiene un número par de kernels, tendrá que manejar los límites por separado. (Como se señaló en los comentarios, esto da como resultado que se copie la matriz, lo que afectará el rendimiento).

 mat = np.array([[20, 200, -5, 23, 7], [-13, 134, 119, 100, 8], [120, 32, 49, 25, 12], [-120, 12, 9, 23, 15], [-57, 84, 19, 17, 82], ]) # soln # [200, 119, 8] # [120, 49, 15] # [84, 19, 82] M, N = mat.shape K = 2 L = 2 MK = M // K NL = N // L # split the matrix into 'quadrants' Q1 = mat[:MK * K, :NL * L].reshape(MK, K, NL, L).max(axis=(1, 3)) Q2 = mat[MK * K:, :NL * L].reshape(-1, NL, L).max(axis=2) Q3 = mat[:MK * K, NL * L:].reshape(MK, K, -1).max(axis=1) Q4 = mat[MK * K:, NL * L:].max() # compose the individual quadrants into one new matrix soln = np.vstack([np.c_[Q1, Q3], np.c_[Q2, Q4]]) print(soln) # [[200 119 8] # [120 49 15] # [ 84 19 82]]
over 4 years ago · Santiago Trujillo Relatório

0

En lugar de hacer "cuadrantes" como se muestra en la respuesta de Elliot, podríamos rellenarlo para que sea divisible de manera uniforme y luego realizar una agrupación máxima o media.

Como la agrupación se usa a menudo en CNN, la matriz de entrada suele ser 3D. Así que hice una función que funciona en matrices 2D o 3D.

 def pooling(mat,ksize,method='max',pad=False): '''Non-overlapping pooling on 2D or 3D data. <mat>: ndarray, input array to pool. <ksize>: tuple of 2, kernel size in (ky, kx). <method>: str, 'max for max-pooling, 'mean' for mean-pooling. <pad>: bool, pad <mat> or not. If no pad, output has size n//f, n being <mat> size, f being kernel size. if pad, output has size ceil(n/f). Return <result>: pooled matrix. ''' m, n = mat.shape[:2] ky,kx=ksize _ceil=lambda x,y: int(numpy.ceil(x/float(y))) if pad: ny=_ceil(m,ky) nx=_ceil(n,kx) size=(ny*ky, nx*kx)+mat.shape[2:] mat_pad=numpy.full(size,numpy.nan) mat_pad[:m,:n,...]=mat else: ny=m//ky nx=n//kx mat_pad=mat[:ny*ky, :nx*kx, ...] new_shape=(ny,ky,nx,kx)+mat.shape[2:] if method=='max': result=numpy.nanmax(mat_pad.reshape(new_shape),axis=(1,3)) else: result=numpy.nanmean(mat_pad.reshape(new_shape),axis=(1,3)) return result

A veces, es posible que desee realizar una agrupación superpuesta, a un ritmo que no es igual al tamaño del núcleo. Aquí hay una función que hace eso, con o sin relleno:

 def asStride(arr,sub_shape,stride): '''Get a strided sub-matrices view of an ndarray. See also skimage.util.shape.view_as_windows() ''' s0,s1=arr.strides[:2] m1,n1=arr.shape[:2] m2,n2=sub_shape view_shape=(1+(m1-m2)//stride[0],1+(n1-n2)//stride[1],m2,n2)+arr.shape[2:] strides=(stride[0]*s0,stride[1]*s1,s0,s1)+arr.strides[2:] subs=numpy.lib.stride_tricks.as_strided(arr,view_shape,strides=strides) return subs def poolingOverlap(mat,ksize,stride=None,method='max',pad=False): '''Overlapping pooling on 2D or 3D data. <mat>: ndarray, input array to pool. <ksize>: tuple of 2, kernel size in (ky, kx). <stride>: tuple of 2 or None, stride of pooling window. If None, same as <ksize> (non-overlapping pooling). <method>: str, 'max for max-pooling, 'mean' for mean-pooling. <pad>: bool, pad <mat> or not. If no pad, output has size (nf)//s+1, n being <mat> size, f being kernel size, s stride. if pad, output has size ceil(n/s). Return <result>: pooled matrix. ''' m, n = mat.shape[:2] ky,kx=ksize if stride is None: stride=(ky,kx) sy,sx=stride _ceil=lambda x,y: int(numpy.ceil(x/float(y))) if pad: ny=_ceil(m,sy) nx=_ceil(n,sx) size=((ny-1)*sy+ky, (nx-1)*sx+kx) + mat.shape[2:] mat_pad=numpy.full(size,numpy.nan) mat_pad[:m,:n,...]=mat else: mat_pad=mat[:(m-ky)//sy*sy+ky, :(n-kx)//sx*sx+kx, ...] view=asStride(mat_pad,ksize,stride) if method=='max': result=numpy.nanmax(view,axis=(2,3)) else: result=numpy.nanmean(view,axis=(2,3)) return result
over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda