通过K近邻算法探究numpy向量运算提速

茴香豆的“茴”字有... ...

使用三种计算图片距离的方式实现K近邻算法:

1.最为基础的双循环

2.利用numpy的broadca机制实现单循环

3.利用broadcast和矩阵的数学性质实现无循环

图片被拉伸为一维数组

X_train:(train_num, 一维数组)

X:(test_num, 一维数组)

方法验证

import numpy as np
a = np.array([[1,1,1],[2,2,2],[3,3,3]])
b = np.array([[4,4,4],[5,5,5],[6,6,6],[7,7,7]])

双循环:

dists = np.zeros((3,4))
for i in range(3):
for j in range(4):
dists[i][j] = np.sqrt(np.sum(np.square(a[i] - b[j])))
print(dists)

[[  5.19615242   6.92820323   8.66025404  10.39230485]
 [  3.46410162   5.19615242   6.92820323   8.66025404]
 [  1.73205081   3.46410162   5.19615242   6.92820323]]

单循环:

dists=np.zeros((3,4))
for i in range(3):
dists[i] = np.sqrt(np.sum(np.square(a[i] - b),axis=1))
print(dists)

[[  5.19615242   6.92820323   8.66025404  10.39230485]
 [  3.46410162   5.19615242   6.92820323   8.66025404]
 [  1.73205081   3.46410162   5.19615242   6.92820323]]

无循环:

r1=(np.sum(np.square(a),axis=1)*(np.ones((b.shape[0],1)))).T
r2=np.sum(np.square(b),axis=1)*(np.ones((a.shape[0],1)))
r3=-2*np.dot(a,b.T)
print(np.sqrt(r1+r2+r3))

[[  5.19615242   6.92820323   8.66025404  10.39230485]
 [  3.46410162   5.19615242   6.92820323   8.66025404]
 [  1.73205081   3.46410162   5.19615242   6.92820323]]

无循环算法原理:

(注意,原理图-验证代码-实现程序 的变量并不严格一一对应,均有调整)

全代码实现如下:

import numpy as np

class KNearsNeighbor():
def _init_(self):
pass def train(self, x, y):
self.X_train = x
self.y_train = y
  
# 选择使用几个循环体的方式来计算距离
def predict(self, X, k=1, num_loops=0):
if num_loops == 0:
dist = self.compute_distances_no_loops(X)
elif num_loops == 1:
dist = self.compute_distances_one_loops(X)
elif num_loops == 2:
dist = self.compute_distances_two_loops(X)
else:
raise ValueError('Invalid value %d' % num_loops)
return dist def compute_distances_two_loops(self, X):
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):
dists[i][j] = np.sqrt(np.sum(np.square(X[i] - self.X_train[j])))
return dists
def compute_distances_one_loops(self, X):
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):
dists[i] = np.sqrt(np.sum(np.square(X[i] - self.X_train), axis=1))
return dists def compute_distances_no_loops(self, X):
# num_test = X.shape[0]
# num_train = self.X_train.shape[0]
# dists = np.zeros((num_test,num_train))
dists = np.sqrt(-2*np.dot(X, self.X_train.T) +
np.sum(np.square(self.X_train), axis=1)*(np.ones((X.shape[0],1))) +
np.sum(np.square(X), axis=1)*(np.ones(X_train.shape[0],1)).T)
return dists    # 预测标签
def predict_labels(self, dists, k=1):
num_test = dists.shape[0]
y_pred = np.zeros(num_test)
for i in range(num_test):
closest_y = self.y_train[np.argsort(dists[i])[:k]] # 【【【按照距离给索引排序】取最近的k个索引】按照索引取训练标签】
y_pred[i] = np.argmax(np.bincount(closest_y)) # 投票,注意np.bincount()和np.argmax()在投票上的妙用
return y_pred

交叉验证选择超参数k的取值

We have implemented(实施) the k-Nearest Neighbor classifier(分类) but we set the value k = 5 arbitrarily(武断地). We will now determine the best value of this hyperparameter with cross-validation(交叉验证).

import numpy as np
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.split(X_train, num_folds)
y_train_folds = np.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:
k_to_accuracies[k]=np.zeros(num_folds)
for i in range(num_folds):
Xtr = np.concatenate(
(np.array(X_train_folds)[:i],np.array(X_train_folds)[(i+1):]),axis=0)
ytr = np.concatenate(
(np.array(y_train_folds)[:i],np.array(y_train_folds)[(i+1):]),axis=0)
Xte = np.array(X_train_folds)[i]
yte = np.array(y_train_folds)[i] # [num_of_folds, num_in_flods, feature_of_x] -> [num_of_pictures, feature_of_x]
Xtr = np.reshape(Xtr, (X_train.shape[0] * 4 / 5, -1))
ytr = np.reshape(ytr, (y_train.shape[0] * 4 / 5, -1))
Xte = np.reshape(Xte, (X_train.shape[0] / 5, -1))
yte = np.reshape(yte, (y_train.shape[0] / 5, -1)) classifier.train(Xtr, ytr)
yte_pred = classifier.predict(Xte, k)
yte_pred = np.reshape(yte_pred, (yte_pred.shape[0], -1)) accuracy = np.sum(yte_pred == yte, dtype=float)/len(yte) # bool to int,我们需要显示指定为float
k_to_accuracies[k][i] = accuracy
################################################################################
# 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)

SVM支持向量机

def svm_loss_vectorized(W, X, y, reg):
"""
Structured SVM loss function, vectorized implementation. Inputs and outputs are the same as svm_loss_naive.
""" loss = 0.0
dW = np.zeros(W.shape) # initialize the gradient as zero # 向前传播
scores = X.dot(W)
scores_correct = scores[np.arange(y.shape[0]),y].reshape(y.shape[0],1)
margins = np.maximum(0., scores - scores_correct + 1) # 错误类加上阈值减去正确类得分,满足的置零,不满足的计算loss
margins[np.arange(y.shape[0]),y] = 0 # 把上一步正确类参与计算的部分置零
loss = np.sum(margins)/y.shape[0] + 0.5*reg*np.sum(W*W) # 反向传播
margins[margins>0] = 1 # 类relu反向传播
row_grad = np.sum(margins, axis=1)
margins[np.arange(y.shape[0]),y] - row_grad # 分类器反向都是这样,错误类不动,正确类减去上层梯度
dW = np.dot(X.T,margins)/y.shape[0] + reg*W return loss, dW

『cs231n』作业1选讲_通过代码理解KNN&交叉验证&SVM的更多相关文章

  1. 『cs231n』作业2选讲_通过代码理解Dropout

    Dropout def dropout_forward(x, dropout_param): p, mode = dropout_param['p'], dropout_param['mode'] i ...

  2. 『cs231n』作业2选讲_通过代码理解优化器

    1).Adagrad一种自适应学习率算法,实现代码如下: cache += dx**2 x += - learning_rate * dx / (np.sqrt(cache) + eps) 这种方法的 ...

  3. 『cs231n』作业3问题1选讲_通过代码理解RNN&图像标注训练

    一份不错的作业3资料(含答案) RNN神经元理解 单个RNN神经元行为 括号中表示的是维度 向前传播 def rnn_step_forward(x, prev_h, Wx, Wh, b): " ...

  4. 『cs231n』作业3问题3选讲_通过代码理解图像梯度

    Saliency Maps 这部分想探究一下 CNN 内部的原理,参考论文 Deep Inside Convolutional Networks: Visualising Image Classifi ...

  5. 『cs231n』作业3问题2选讲_通过代码理解LSTM网络

    LSTM神经元行为分析 LSTM 公式可以描述如下: itftotgtctht=sigmoid(Wixxt+Wihht−1+bi)=sigmoid(Wfxxt+Wfhht−1+bf)=sigmoid( ...

  6. 『cs231n』作业3问题4选讲_图像梯度应用强化

    [注],本节(上节也是)的model是一个已经训练完成的CNN分类网络. 随机数图片向前传播后对目标类优化,反向优化图片本体 def create_class_visualization(target ...

  7. 『cs231n』计算机视觉基础

    线性分类器损失函数明细: 『cs231n』线性分类器损失函数 最优化Optimiz部分代码: 1.随机搜索 bestloss = float('inf') # 无穷大 for num in range ...

  8. 『cs231n』通过代码理解风格迁移

    『cs231n』卷积神经网络的可视化应用 文件目录 vgg16.py import os import numpy as np import tensorflow as tf from downloa ...

  9. 『TensorFlow』SSD源码学习_其一:论文及开源项目文档介绍

    一.论文介绍 读论文系列:Object Detection ECCV2016 SSD 一句话概括:SSD就是关于类别的多尺度RPN网络 基本思路: 基础网络后接多层feature map 多层feat ...

随机推荐

  1. web前端----jQuery扩展(很重要!!)

    1.jQuery扩展语法 把扩展的内容就可以写到xxxx.js文件了,在主文件中直接导入就行了. 用法1.$.xxx() $.extend({ "GDP": function () ...

  2. ACM题目————A Knight's Journey

    Description BackgroundThe knight is getting bored of seeing the same black and white squares again a ...

  3. Win32建立右键弹出菜单(PopMenu)

    自定义右键菜单: #ifndef _CONTEXTMENU_H_ #define _CONTEXTMENU_H_ #include <windows.h> //动态菜单 #define I ...

  4. 将kali linux装入U盘 制作随身携带的kali linux

    一 准备工作 USB3.0 U盘 不小于32G USB2.0的U盘安装速度要比3.0的慢一倍以上,运行也会有明显差别,所以建议使用3.0U盘.安装好之后差不多就得占用十几G,所以16G的太小了,尽量用 ...

  5. apache2.4配置多个端口对应多个目录

    文件 /usr/local/apache/conf/extra/httpd-vhosts.conf 的内容如下: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 NameVir ...

  6. 【第六章】 springboot + 事务

    在实际开发中,其实很少会用到事务,一般情况下事务用的比较多的是在金钱计算方面. mybatis与spring集成后,其事务该怎么做?其实很简单,直接在上一节代码的基础上在相应的方法(通常是servic ...

  7. 实现分享功能插件2---jiathis分享插件应用

    博主原创:未经博主允许,不得转载 在上一篇的博文中分享了如何用百度分享插件实现分享功能,现在展示用jiathis进行实现分享功能: 主要代码如下: <body> <div class ...

  8. ajax实现highchart与数据库数据结合完整案例分析(三)---柱状折线图

    作者原创,未经博主允许,不可转载 在前面分析和讲解了用java代码分别实现饼状图和折线图,在工作当中,也会遇到很多用ajax进行异步请求 实现highchart. 先展示一下实现的效果图: 用ajax ...

  9. junit中test注解测试使用案列解析一

    本文原创,转载请注明出处 在写代码的过程中,只想测试部分代码,调试一小段功能有没有通的情况下,可以用该方法: 以下为在项目中测试一个小功能的案例,在此记录一下, /**     * <解析查询磁 ...

  10. 03_Flume多节点Failover实践

    1.实践场景 模拟上游Flume Agent在发送event时的故障切换 (failover) 1)初始:上游Agent向active的下游节点Collector1传递event 2)Collecto ...