【问题标题】:Replacing a nested loop替换嵌套循环
【发布时间】:2019-01-24 21:17:44
【问题描述】:

我刚刚开始使用 Python,但我无法理解我应该如何实现以下目标(我是一名 Java 程序员)。

这里是初始代码:

  def compute_distances_two_loops(self, X):
    """
    Compute the distance between each test point in X and each training point
    in self.X_train using a nested loop over both the training data and the 
    test data.

    Inputs:
    - X: A numpy array of shape (num_test, D) containing test data.

    Returns:
    - dists: A numpy array of shape (num_test, num_train) where dists[i, j]
      is the Euclidean distance between the ith test point and the jth training
      point.
    """

    num_test = X.shape[0]
    num_train = self.X_train.shape[0]
    dists = np.zeros((num_test, num_train))

    for i in range(num_test):
      for j in range(num_train):
        #####################################################################
        # TODO:                                                             #
        # Compute the l2 distance between the ith test point and the jth    #
        # training point, and store the result in dists[i, j]. You should   #
        # not use a loop over dimension.                                    #
        #####################################################################
        dists[i, j] = np.sum(np.square(X[i] - self.X_train[j]))
        #####################################################################
        #                       END OF YOUR CODE                            #
        #####################################################################
    return dists

这是一段代码,它应该减少一个嵌套循环,同时仍然输出相同的数组:

  def compute_distances_one_loop(self, X):
    """
    Compute the distance between each test point in X and each training point
    in self.X_train using a single loop over the test data.

    Input / Output: Same as compute_distances_two_loops
    """
    num_test = X.shape[0]
    num_train = self.X_train.shape[0]
    dists = np.zeros((num_test, num_train))

    for i in range(num_test):
      tmp = '%s %d' % ("\nfor i:", i)
      print(tmp)

      print(X[i])
      print("end of X[i]")
      print(self.X_train[:]) # all the thing [[ ... ... ]]
      print(": before, i after")
      print(self.X_train[i]) # just a row
      print(self.X_train[i, :])

      #######################################################################
      # TODO:                                                               #
      # Compute the l2 distance between the ith test point and all training #
      # points, and store the result in dists[i, :].                        #
      #######################################################################
      dists[i, :] = np.sum(np.square(X[i] - self.X_train[i, :]))
      print(dists[i])
      #######################################################################
      #                         END OF YOUR CODE                            #
      #######################################################################
    return dists

看来this应该对我有所帮助,但我还是想不通。

您可以看到,我的缺陷之一是我对“:”的确切工作原理缺乏了解。

我花了好几个小时试图弄清楚这件事,但似乎我真的缺乏一些核心知识。任何人都可以帮助我吗?这个练习是为斯坦福的视觉识别课程准备的:这是第一个作业,但这不是我真正的家庭作业,因为我自己做这门课只是为了娱乐。

目前,我的一段代码输出two_loops 的对角线的正确值,但适用于整行。我不明白我应该如何将来自dists[i, :]:- self.X_train[i, :] 部分同步。如何计算 X[i] 减去遍历整个 self.X_train 的迭代?

注意num_test 是 500x3072,num_train 是 5000x3072。 3072 来自 32x32x3,它们是 32x32 图片的 RGB 值。 dists[i,j] 是一个 500x5000 矩阵,映射了num_test 的第 i 个元素和num_train 的第 j 个元素之间的 L2 距离。

【问题讨论】:

    标签: python python-3.x numpy machine-learning


    【解决方案1】:
    def compute_distances_one_loop(self, X):
        """
        Compute the distance between each test point in X and each training point
        in self.X_train using a single loop over the test data.
    
        Input / Output: Same as compute_distances_two_loops
        """
        num_test = X.shape[0]
        num_train = self.X_train.shape[0]
        dists = np.zeros((num_test, num_train))
    
        for i in range(num_test):
          tmp = '%s %d' % ("\nfor i:", i)
          print(tmp)
    
          #######################################################################
          # TODO:                                                               #
          # Compute the l2 distance between the ith test point and all training #
          # points, and store the result in dists[i, :].                        #
          #######################################################################
          dists[i] = np.sum(np.square(X[i] - self.X_train), axis=1)
          print(dists[i])
          #######################################################################
          #                         END OF YOUR CODE                            #
          #######################################################################
        return dists
    

    在循环中删除带有 self.X_train 的打印,因为长度不同。 (IndexOutOfRangeException) 我不确定这是否会删除第二个循环,但是否是一个可行的解决方案。

    另一个评论,我认为你对欧几里得距离公式有误。 您最后缺少 sqrt。

    【讨论】:

    • 这绝对看起来只是另一个for循环,以其他方式。我不相信这是解决方案。关于您对sqrt 的评论:“在实际的最近邻应用程序中,我们可以省略平方根运算,因为平方根是一个单调函数。也就是说,它缩放距离的绝对大小,但它保留了排序,所以有或没有它的最近邻居是相同的。” (来自课程)
    • 我想这就是你要找的。我修复了代码。
    • 确实!你介意在你的答案中解释它为什么/如何工作吗?
    • X[i] - self.X_train 返回一个数组,该数组是 self.X_train 中每两个组件点(与 self.X_train[:] 相同)减去两个组件的结果X[i] 中的数组(实际点与 X[i, :] 相同)并保留每个结果点,在 np.square 计算每个数字的平方之后,并且在 np.sum 的轴参数告诉 numpy对数组中的每一行求和(仅行中的组件,详细解释在here 中),返回dist中组件我们需要的数组。
    • 对于非常笼统的解释和我的英语感到抱歉。
    猜你喜欢
    • 2016-07-14
    • 1970-01-01
    • 2019-06-06
    • 2021-09-05
    • 2018-08-06
    • 1970-01-01
    • 2021-08-09
    • 2020-06-03
    • 2017-04-02
    相关资源
    最近更新 更多