内存错误Numpy / Python欧几里德距离

时间:2018-01-14 21:49:26

标签: python numpy memory-leaks k-means ram

我正在尝试使用numpy和python运行K-Means聚类算法,但如果我使用更大的K值(任何大于10的值似乎都会导致错误),则会继续遇到内存错误。我有两个大小为[42000,784](数据集)和[K,784](质心)的numpy数组。在计算每个质心和每个数据点之间的欧氏距离时发生存储器错误。这是我一直在使用的功能:

<?php

namespace Drupal\block_header\Plugin\Block;

use Drupal\Core\Block\BlockBase;
use Drupal\Core\Block\BlockPluginInterface;
use Drupal\Core\Form\FormStateInterface;

/**
 * Provides a 'Header' Block.
 *
 * @Block(
 *   id = "block_header",
 *   admin_label = @Translation("Block Header"),
 *   category = @Translation("Block Header"),
 * )
 */

class BlockHeader extends BlockBase implements BlockPluginInterface {

  /**
   * {@inheritdoc}
   */
  public function build() {
    $config = $this->getConfiguration();

    if (!empty($config['block_header_title']) && ($config['block_header_text'])) {
      $title = $config['block_header_title'];
      $descp = $config['block_header_text'];
    }
    else {
      $title = $this->t('<div>Atención! Titulo no configurado!</div> </p>');
      $descp = $this->t('<div>Atención! Descripción no configurada!</div>');
    }
    $block = array
        (
            'title' => array
            (
             '#prefix' => '<div class="title"><p>', /* HERE I ADD THE CSS TAGS */
             '#suffix' => '</p></div>',
             '#markup' => t('@title', array('@title' => $title,)),
            ),
            'description' => array
            (
             '#prefix' => '<div class="descp"><p>', /* HERE I ADD THE CSS TAGS */
             '#suffix' => '</p></div>',
             '#markup' => t('@descp', array('@descp' => $descp,))
            ),
        );
    return $block;  

  }


   /**
   * {@inheritdoc}
   */
  public function blockForm($form, FormStateInterface $form_state) {
    $form = parent::blockForm($form, $form_state);

    $config = $this->getConfiguration();

    $form['block_header_title'] = array(
      '#type' => 'textfield',
      '#title' => $this->t('Titulo del Bloque'),
      '#description' => $this->t('Titulo del Bloque'),
      '#default_value' => isset($config['block_header_title']) ? $config['block_header_title'] : '',
    );

    $form['block_header_text'] = array(
      '#type' => 'textarea',
      '#title' => $this->t('Descripción'),
      '#description' => $this->t('Descripción del bloque'),
      '#default_value' => isset($config['block_header_text']) ? $config['block_header_text'] : '',
    );

    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function blockSubmit($form, FormStateInterface $form_state) {
    parent::blockSubmit($form, $form_state);
    $values = $form_state->getValues();
    $this->configuration['block_header_title'] = $values['block_header_title'];
    $this->configuration['block_header_text'] = $values['block_header_text'];
    $this->configuration['block_header_title'] = $form_state->getValue('block_header_title');
    $this->configuration['block_header_text'] = $form_state->getValue('block_header_text');
  }
}

这是内存泄漏还是我没有足够的内存(我有8GB)?我该如何解决这个问题?

1 个答案:

答案 0 :(得分:1)

scipy has built-in functions for distance computations,与自制实施相比,闪电般快。

因此,第一个想法是用以下表达式替换整个distance函数:

from numpy.random import rand
from scipy.spatial import distance

# sample data
a = randn(42000, 784
b = randn(256, 784)

# distance computation
dist = distance.cdist(a, b, metric='euclidean')    # about 8.02 s on 
                                                   # my 8 GB RAM machine

请注意,此示例中的dist会根据您的示例进行转置。如果您想要示例的形状,请执行dist = distance.cdist(a, b).T

通过省略平方根运算,还可以稍微加速计算。您可以通过dist = distance.cdist(a, b, metric='sqeuclidean')完成此操作。

这整个方法并没有大大减少内存消耗,但它只占用内存几秒钟。

第二个想法是根本不使用自制的实现,而是使用一些可靠的第三方软件包,比如井[{1}}:

Scikit Learn

这种实现的几个优点之一是它会自动决定如何计算距离,这样就不会浪费你的记忆。