前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >cs231n assignment1 knn

cs231n assignment1 knn

作者头像
平凡的学生族
发布2019-05-25 09:41:45
7150
发布2019-05-25 09:41:45
举报
文章被收录于专栏:后端技术后端技术

实现compute_distances_two_loops

代码语言:javascript
复制
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 xrange(num_test):
      for j in xrange(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.sqrt(np.sum(np.square(X[i,:] - self.X_train[j,:])))
        #####################################################################
        #                       END OF YOUR CODE                            #
        #####################################################################
    return dists

实现predict_labels

代码语言:javascript
复制
 def predict_labels(self, dists, k=1):
    """
    Given a matrix of distances between test points and training points,
    predict a label for each test point.

    Inputs:
    - dists: A numpy array of shape (num_test, num_train) where dists[i, j]
      gives the distance betwen the ith test point and the jth training point.

    Returns:
    - y: A numpy array of shape (num_test,) containing predicted labels for the
      test data, where y[i] is the predicted label for the test point X[i].  
    """
    num_test = dists.shape[0]
    y_pred = np.zeros(num_test)
    for i in xrange(num_test):
      # A list of length k storing the labels of the k nearest neighbors to
      # the ith test point.
      closest_y = []
      #########################################################################
      # TODO:                                                                 #
      # Use the distance matrix to find the k nearest neighbors of the ith    #
      # testing point, and use self.y_train to find the labels of these       #
      # neighbors. Store these labels in closest_y.                           #
      # Hint: Look up the function numpy.argsort.                             #
      #########################################################################
      sorted_vector = np.argsort(dists[i,:])
      # print sorted_vector[:k]
      closest_y = []
      closest_y = self.y_train[sorted_vector[:k]]
      # print closest_y
      #########################################################################
      # TODO:                                                                 #
      # Now that you have found the labels of the k nearest neighbors, you    #
      # need to find the most common label in the list closest_y of labels.   #
      # Store this label in y_pred[i]. Break ties by choosing the smaller     #
      # label.                                                                #
      #########################################################################
 
      # appear_times:
      #   key: the label
      #   value: the appear times of the label
      appear_times = {}
      for label in closest_y:
        if label in appear_times:
          appear_times[label] += 1
        else:
          appear_times[label] = 0

      # find most commen label
      y_pred[i] = max(appear_times, key=lambda x: appear_times[x])

      #########################################################################
      #                           END OF YOUR CODE                            # 
      #########################################################################

    return y_pred

预测准确率

k=1时

代码语言:javascript
复制
# Now implement the function predict_labels and run the code below:
# We use k = 1 (which is Nearest Neighbor).
y_test_pred = classifier.predict_labels(dists, k=1)

# Compute and print the fraction of correctly predicted examples
num_correct = np.sum(y_test_pred == y_test)
accuracy = float(num_correct) / num_test
print 'Got %d / %d correct => accuracy: %f' % (num_correct, num_test, accuracy)

Got 137 / 500 correct => accuracy: 0.274000

k=5时

代码语言:javascript
复制
y_test_pred = classifier.predict_labels(dists, k=5)
num_correct = np.sum(y_test_pred == y_test)
accuracy = float(num_correct) / num_test
print 'Got %d / %d correct => accuracy: %f' % (num_correct, num_test, accuracy)

Got 142 / 500 correct => accuracy: 0.284000

compute_distances_one_loop

代码语言:javascript
复制
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 xrange(num_test):
      #######################################################################
      # TODO:                                                               #
      # Compute the l2 distance between the ith test point and all training #
      # points, and store the result in dists[i, :].                        #
      #######################################################################
      dists[i] = np.sqrt(np.sum(np.square(self.X_train - X[i]), axis=1))
      #######################################################################
      #                         END OF YOUR CODE                            #
      #######################################################################
    return dists

Difference was: 0.000000 Good! The distance matrices are the same

计算结果的速度更快了,而且结果一致

此处用到了numpy的二维数组减一维数组

代码语言:javascript
复制
# 二维数组减一维数组
a = np.array([1,2,3])
b = np.ones([2,3])
a - b

array([[ 0., 1., 2.], [ 0., 1., 2.]])

cross-validation

代码语言:javascript
复制
num_folds = 5
k_choices = [1, 3, 5, 8, 10, 12, 15, 20, 50, 100]

X_train_folds = []
y_train_folds = []
################################################################################
# TODO:                                                                        #
# Split up the training data into folds. After splitting, X_train_folds and    #
# y_train_folds should each be lists of length num_folds, where                #
# y_train_folds[i] is the label vector for the points in X_train_folds[i].     #
# Hint: Look up the numpy array_split function.                                #
################################################################################
X_train_folds = np.array_split(X_train, num_folds)
Y_train_folds = np.array_split(y_train, num_folds)
################################################################################
#                                 END OF YOUR CODE                             #
################################################################################

# A dictionary holding the accuracies for different values of k that we find
# when running cross-validation. After running cross-validation,
# k_to_accuracies[k] should be a list of length num_folds giving the different
# accuracy values that we found when using that value of k.
k_to_accuracies = {}


################################################################################
# TODO:                                                                        #
# Perform k-fold cross validation to find the best value of k. For each        #
# possible value of k, run the k-nearest-neighbor algorithm num_folds times,   #
# where in each case you use all but one of the folds as training data and the #
# last fold as a validation set. Store the accuracies for all fold and all     #
# values of k in the k_to_accuracies dictionary.                               #
################################################################################
for k in k_choices:
    accuracy_sum = 0
    k_to_accuracies[k] = []
    for f in xrange(num_folds):    
        x_trai = np.array(X_train_folds[:f] + X_train_folds[f+1:])
        y_trai = np.array(Y_train_folds[:f] + Y_train_folds[f+1:])
        
        x_trai = x_trai.reshape(-1, x_trai.shape[2])
        y_trai = y_trai.reshape(-1)
        
        x_vali = np.array(X_train_folds[f])
        y_vali = np.array(Y_train_folds[f])
        
        classifier.train(x_trai, y_trai)
        dists = classifier.compute_distances_no_loops(x_vali)
        y_vali_pred = classifier.predict_labels(dists, k=k)

        # Compute and print the fraction of correctly predicted examples
        num_correct = np.sum(y_vali_pred == y_vali)
        acc = float(num_correct) / y_vali.shape[0]
        k_to_accuracies[k].append(acc)
################################################################################
#                                 END OF YOUR CODE                             #
################################################################################

# Print out the computed accuracies
for k in sorted(k_to_accuracies):
    for accuracy in k_to_accuracies[k]:
        print 'k = %d, accuracy = %f' % (k, accuracy)

k = 1, accuracy = 0.263000 k = 1, accuracy = 0.257000 k = 1, accuracy = 0.264000 k = 1, accuracy = 0.278000 k = 1, accuracy = 0.266000 k = 3, accuracy = 0.241000 k = 3, accuracy = 0.249000 k = 3, accuracy = 0.243000 k = 3, accuracy = 0.273000 k = 3, accuracy = 0.264000 k = 5, accuracy = 0.258000 k = 5, accuracy = 0.273000 k = 5, accuracy = 0.281000 k = 5, accuracy = 0.290000 k = 5, accuracy = 0.272000 k = 8, accuracy = 0.263000 k = 8, accuracy = 0.288000 k = 8, accuracy = 0.278000 k = 8, accuracy = 0.285000 k = 8, accuracy = 0.277000 k = 10, accuracy = 0.265000 k = 10, accuracy = 0.296000 k = 10, accuracy = 0.278000 k = 10, accuracy = 0.284000 k = 10, accuracy = 0.286000 k = 12, accuracy = 0.260000 k = 12, accuracy = 0.294000 k = 12, accuracy = 0.281000 k = 12, accuracy = 0.282000 k = 12, accuracy = 0.281000 k = 15, accuracy = 0.255000 k = 15, accuracy = 0.290000 k = 15, accuracy = 0.281000 k = 15, accuracy = 0.281000 k = 15, accuracy = 0.276000 k = 20, accuracy = 0.270000 k = 20, accuracy = 0.281000 k = 20, accuracy = 0.280000 k = 20, accuracy = 0.282000 k = 20, accuracy = 0.284000 k = 50, accuracy = 0.271000 k = 50, accuracy = 0.288000 k = 50, accuracy = 0.278000 k = 50, accuracy = 0.269000 k = 50, accuracy = 0.266000 k = 100, accuracy = 0.256000 k = 100, accuracy = 0.270000 k = 100, accuracy = 0.263000 k = 100, accuracy = 0.256000 k = 100, accuracy = 0.263000

选取最佳的k

代码语言:javascript
复制
# Based on the cross-validation results above, choose the best value for k,   
# retrain the classifier using all the training data, and test it on the test
# data. You should be able to get above 28% accuracy on the test data.
best_k = 7

classifier = KNearestNeighbor()
classifier.train(X_train, y_train)
y_test_pred = classifier.predict(X_test, k=best_k)

# Compute and display the accuracy
num_correct = np.sum(y_test_pred == y_test)
accuracy = float(num_correct) / num_test
print 'Got %d / %d correct => accuracy: %f' % (num_correct, num_test, accuracy)

Got 141 / 500 correct => accuracy: 0.282000

可见,k = 7比较好

本文参与?腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018.01.28 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客?前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与?腾讯云自媒体分享计划? ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 实现compute_distances_two_loops
  • 实现predict_labels
  • 预测准确率
  • compute_distances_one_loop
  • cross-validation
  • 选取最佳的k
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
http://www.vxiaotou.com