算法目录


image.png


前言

数据结构基本概念

1. 数据

数据是信息的载体,是描述客观事物属性的数,字符以及所有能输入到计算机中被程序识别和处理的符号合集

2. 数据元素

数据元素是数据的基本单位,通常作为一个整体进行处理。一个数据元素可由若干数据组成,数据项是构成数据元素不可分割的最小单位。例如,学生档案是一个数据元素,它是由学号,性别,名字等数据项组成的。

3. 数据对象

数据对象是具有相同数据元素的合集。是一个数据的子集。例如, 整数的数据对象是N={0,±1,±2,。。。}

4. 数据类型

  1. 原子类型:其值不可再分的数据类型

  2. 结构类型: 其值可以在分解为若干分量

  3. 抽象数据类型:抽象数据与之相关的操作

5. 抽象数据结构

抽象数据类型(ADT)是指一个数学模型及其定义在该模型的一系列操作。通常用数据对象,数据关系,基本操作集三元组来表示抽象数据类型。

6. 数据结构

数据之间存在相互的关系,这种关系就称为数据结构。数据机构包括三方面:逻辑结构,储存结构,数据的运算


数据结构三要素

1. 数据的逻辑结构

image.png

2. 数据的储存结构

image.png

3. 数据的运算

image.png

算法基本概念与度量

1. 基本概念

算法(Algorithm)是对特定问题求最优解的一种描述,一个算法需要具备5个重要特征:

  1. )有穷性。对于任何合法的输入值必须在有穷步以后结束,且每一步再有穷时间内完成
  2. )确定性。 保证不会出现薛定谔的量子不确定状态,即同样条件下的同一输入值得出不同的结果
  3. )可行性。算法描述中的操作是可以做到的,可用induction归纳法证明出来
  4. )输入。一个算法有零个或者多个输入,来自于某个特定的对象的合集
  5. )输出。一个算法有一个或多个输出,输出与输入有特定关系的量。

2. 时间复杂度

一行指令被重复的频次就是频度。Σni=1频度=T(n)
算法中的基本运算频度是f(n),算法的时间复杂度记为T(n)=O(f(n)).

Asymptotic Analysis——渐近分析

image.png
big 0 notation 三个rules

  1. ignore constant factor
  2. Combine fixed number of terms with same complexity(special case: n terms)
  3. consider only the most higher dimension power

    3. 空间复杂度

    一个算法所耗费的储存空间。
    记为S(n)=O(g(n))

  4. 空间复杂度 O(1)

    1. int i = 1;
    2. int j = 2;
    3. i++ ;
    4. ++j;
    5. //代码中的 i、j 所分配的空间都不随着处理数据量变化,因此它的空间复杂度 S(n) = O(1)
  5. 空间复杂度 O(n) ```python a = n x = [None]*a print(x)

    [None, None, None, None, None, None, None, None, None, None,。。。。]

    创建了n个空间,所以占用了这么多的空间,即 S(n) = O(n)

  1. 常见的复杂度不多,从低到高排列就这么几个: O(1) O(log(n)) O(n) O(n2)
  2. ---
  3. <a name="L1QLs"></a>
  4. # 线性表
  5. <a name="KKc2E"></a>
  6. ## 数组
  7. <a name="k42Tp"></a>
  8. ## 链表
  9. ---
  10. <a name="x2QQ4"></a>
  11. # 散列表
  12. ---
  13. <a name="C8hUj"></a>
  14. # 树
  15. ---
  16. <a name="EMw87"></a>
  17. # 图
  18. ---
  19. <a name="VjIC4"></a>
  20. # 复杂度分析
  21. ---
  22. <a name="y8JxZ"></a>
  23. # 基本算法思路
  24. ---
  25. <a name="YMbqw"></a>
  26. # 排序
  27. ---
  28. <a name="Sy28m"></a>
  29. # 搜索
  30. ---
  31. <a name="gbybK"></a>
  32. # 查找
  33. ---
  34. <a name="E1FG1"></a>
  35. # 字符串匹配
  36. ---
  37. <a name="w0ByP"></a>
  38. # 不精确一维搜索-Armijo-Goldstein准则与Wolfe-Powell准则(ama505)
  39. 不精确一维搜索就是在区间【0,∞)上求近似最小值,用一个可以接受的参数来表示这个近似值,使用条件是函数 f ( 0 ) < 0。<br />主要有两种方法:Armijo-Goldstein法和Wolfe-Powell
  40. **Armijo-Goldstein准则:**<br />两个核心思想,1. 目标函数有足够的下降 2. 一维搜索的步长λ不应该太小。<br />每一次下降的步长够小才能保证近似值的精准度,就像牛顿法那样分的步骤越多越精准,但是步长太小也会导致你的机器学习一直在在地停留没有进步。
  41. 数学表达式:<br />![](https://cdn.nlark.com/yuque/__latex/103629657e6e572e26a5b583692bc98c.svg#card=math&code=%5C%5C%5C%5C%5C%0Af%28x%20%0Ak%0A%20%2B%CE%BB%20%0Ak%0A%E2%80%8B%0A%20d%20%0Ak%0A%20%29%E2%88%92f%28x%20%0Ak%0A%20%29%E2%89%A4%CE%BB%20%0Ak%0A%E2%80%8B%0A%20%CF%81g%20%0Ak%0AT%0A%E2%80%8B%0A%20d%20%0Ak%0A%20%0A%E2%80%8B%0A%EF%BC%881%EF%BC%89%0A&id=Rd0OH)
  42. ![](https://cdn.nlark.com/yuque/__latex/f729467b3eb6ab46333969fa75487180.svg#card=math&code=f%28x%20%0Ak%0A%20%2B%CE%BB%20%0Ak%0A%E2%80%8B%0A%20d%20%0Ak%0A%20%29%E2%88%92f%28x%20%0Ak%0A%20%29%E2%89%A5%CE%BB%20%0Ak%0A%E2%80%8B%0A%20%281%E2%88%92%CF%81%29g%20%0Ak%0AT%0A%E2%80%8B%0A%20d%20%0Ak%0A%5C%20%20%20%0A%E2%80%8B%282%29%0A%5C%5C%0A%0A%E5%85%B6%E4%B8%AD%EF%BC%8C0%20%3C%20%CF%81%20%3C%20%0A1%2F2&id=lUL98)
  43. ![image.png](https://cdn.nlark.com/yuque/0/2021/png/22418899/1632496722557-da9b7450-1d14-4934-b2c7-dbeee50ee184.png#clientId=u1f4171d7-899e-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=378&id=u1576a0af&margin=%5Bobject%20Object%5D&name=image.png&originHeight=484&originWidth=939&originalType=binary&ratio=1&rotation=0&showTitle=false&size=109787&status=done&style=none&taskId=u32f7ba21-3445-401b-ad70-fc5820dce4b&title=&width=733.5)<br />Matlab实现
  44. ```matlab
  45. function mk=armijo(xk,dk )
  46. beta=0.5; sigma=0.2;
  47. m=0; mmax=20;
  48. while (m<=mmax)
  49. if(fun(xk+beta^m*dk)<=fun(xk)+sigma*beta^m*gfun(xk)'*dk)
  50. mk=m; break;
  51. end
  52. m=m+1;
  53. end
  54. alpha=beta^mk
  55. newxk=xk+alpha*dk
  56. fk=fun(xk)
  57. newfk=fun(newxk)
  58. ————————————————
  59. 版权声明:本文为CSDN博主「斑马L*」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
  60. 原文链接:https://blog.csdn.net/qq_47326711/article/details/118075514

python实现

  1. def armijo_goldstein(f,df,d,x,lambda_max,p,t):
  2. '''
  3. f=函数
  4. df=导数
  5. d= 矢量方向
  6. x=当前点
  7. lambda_max=最大步长
  8. p= 公示里面的p用来调整步长的
  9. t= 上一步的时间相当于游戏存档
  10. '''
  11. true_false = 0
  12. a= 0
  13. b = lambda_max
  14. fx = f(x)
  15. df = df(x)
  16. last_step = fx
  17. next_step = np.dot(df,d) '用numpy朝着d方向精确求导一个梯度'
  18. lambda0 = b*random.unifrom(0,1)
  19. while(true_false==0):
  20. new_fx = f(x+lambda0 * d)
  21. curr_step = new_fx
  22. if (curr_step-last_step) <= (p * lambda0 * next_step): '如果近似步长小于最大上界'
  23. if (curr_step - last_step) >= ((1-p) * lambda0 * next_step): '近似步长大于最小下界'
  24. true_false = 1
  25. else:
  26. '步长太小,使用binary提高a来寻找更适中的lambda'
  27. a = lambda0
  28. b = b
  29. if (b < lambda_max):
  30. lambda0 = (a+b)/2
  31. else: '梯度爆炸问题,回到上一步存档'
  32. lambda0 = t* lambd0
  33. else:'过大了,减少上界重新选步长'
  34. a = a
  35. b = lambda0
  36. lambda0 = (a+b) /2
  37. return lambda0
  38. '''
  39. 版权声明:蒙特卡洛树正在找图灵的猫
  40. '''

Wolfe-Powell准则(ama505)

Armijo-Goldstein准则可能会把极小值点(可接受的区间)判断在外,因此使用wolfe-powell准则
wolfe-powell准则也有两个数学表达式,第一个和armijo-goldstein一样,第二个是:
image.png
这个是一个关于梯度的式子。

算法:
【1】筛选数据
在搜索区间[0,_λ_max] 上选定初始探测点λ0,代入计算好的 f ( 0 ) , f ′ ( 0 ) ,给出可接受系数
算法 - 图7
【2】检查步长lambda合格否
如果算法 - 图8,成功,取下一步,否则缩小上界重新选择下探点
【3】检查下探点是否过小
步骤类似于python实现
[

](https://blog.csdn.net/qq_43940950/article/details/117566544)


拟牛顿法BFGS(ama505)

  1. 什么是拟牛顿法

牛顿法可以快速收敛,迭代次数少但是每一次都需要计算矩阵的逆导致计算量很大。因此拟牛顿法就是引入了Hessian矩阵的近似矩阵可以避免每次迭代都计算矩阵的逆。它的收敛速度介于梯度下降法和牛顿法之间。

  1. 原理

在机器学习中经常碰到非线性优化问题,一些算法试图求解一个非线性极小点,最常用的就是BFGS和L-BFGS算法。
image.png
image.png
image.png
image.png
image.png

  1. 实现

其实现在python里面有scipy包里面的optimizer内置函数可以直接用,已经有更好的optimizer了,比如SGD/BGD

  1. #coding:UTF-8
  2. from numpy import *
  3. from function import *
  4. def bfgs(fun, gfun, x0):
  5. result = []
  6. maxk = 500
  7. rho = 0.55
  8. sigma = 0.4
  9. m = shape(x0)[0]
  10. Bk = eye(m)
  11. k = 0
  12. while (k < maxk):
  13. gk = mat(gfun(x0))#计算梯度
  14. dk = mat(-linalg.solve(Bk, gk))
  15. m = 0
  16. mk = 0
  17. while (m < 20):
  18. newf = fun(x0 + rho ** m * dk)
  19. oldf = fun(x0)
  20. if (newf < oldf + sigma * (rho ** m) * (gk.T * dk)[0,0]):
  21. mk = m
  22. break
  23. m = m + 1
  24. #BFGS校正
  25. x = x0 + rho ** mk * dk
  26. sk = x - x0
  27. yk = gfun(x) - gk
  28. if (yk.T * sk > 0):
  29. Bk = Bk - (Bk * sk * sk.T * Bk) / (sk.T * Bk * sk) + (yk * yk.T) / (yk.T * sk)
  30. k = k + 1
  31. x0 = x
  32. result.append(fun(x0))
  33. return result
  34. '''
  35. 代码来源:https://blog.csdn.net/xiaopihaierletian/article/details/73950484
  36. '''

共轭梯度法(Conjugate Gradient Method)(ama505)

  1. 介绍

共轭梯度法(Conjugate Gradient)是介于最速下降法牛顿法之间的一个方法,它仅需利用一阶导数信息,但克服了最速下降法收敛慢的缺点,又避免了牛顿法需要存储和计算Hesse矩阵并求逆的缺点,共轭梯度法不仅是解决大型线性方程组最有用的方法之一,也是解大型非线性最优化最有效的算法之一。 在各种优化算法中,共轭梯度法是非常重要的一种。其优点是所需存储量小,具有步收敛性,稳定性高,而且不需要任何外来参数。
共轭梯度法最初由Hesteness和Stiefel于1952年为求解线性方程组而提出的。后来,人们把这种方法用于求解无约束最优化问题,使之成为一种重要的最优化方法。
共轭梯度法的基本思想是把共轭性与最速下降方法相结合,利用已知点处的梯度构造一组共轭方向,并沿这组方向进行搜素,求出目标函数的极小点。根据共轭方向基本性质,这种方法具有二次终止性。

  1. 原理与数学推理

https://www.cnblogs.com/walccott/p/4956966.html
https://blog.csdn.net/Liang_Ling/article/details/78552788

  1. 实现

共轭梯度法。一种求解数学特定线性方程组Ax=b的数值解的迭代方法。
要求矩阵A对称(symmetric)且正定(positive definite)。

  1. def Conjugate_Gradient(e=1e-1, lambda0=0.01,x_init):
  2. x = x_init
  3. df = grad(x)'grad求导‘
  4. p = -df
  5. costs = [cost(x)]
  6. while abs(df[0]) > e or abs(df[1]) > e:
  7. x1 = armijo_goldstein(x,df,p,lamda0) '一维搜索都可以用‘
  8. df1 = grad(x1)
  9. alpha_t = alpha(df1, df) '计算两次求导梯度差‘
  10. p1 = -df1 + alpha_t*p
  11. current_cost = cost(x1) '用新的x1算出新的cost
  12. costs.append(current_cost)
  13. '更新参数‘
  14. x = x1
  15. df = df1
  16. p = p1
  17. return costs, x
  18. '''
  19. 蒙特卡洛树正在找图灵的猫
  20. ‘’‘

深度学习入门

环境安装

  1. #环境安装
  2. #python
  3. #https://www.python.org/downloads/
  4. GPU>= 1080ti
  5. RAM >= 64gb
  6. 方法二:
  7. 使用google colaboratory
  8. 方法三:
  9. 使用Jupyter Notebook
  10. 下载CUDA/Anaconda
  11. https://oreil.ly/9hAxg
  12. 安装pytorch
  13. conda install pytorch torchvision -c pytorch
  14. jupyter notebook
  15. import torch
  16. print(torch.cuda.is_available())
  1. #导入numpy
  2. import numpy as np
  3. x = np.array([1,2,3])
  4. y = np.array([2,4,6])
  5. # >>>x + y = ([3,6,9])
  6. #matrix muultiplication
  7. x = ([[1,2],[3,4]])
  8. y = ([10,20])
  9. # >>>x*y = ([[10,40],[30,80]])
  10. #转化为一维数组
  11. x = x.flatten()
  12. import matplotlib.pyplot as plt
  13. #draw graph
  14. plt.plot(x,y1, label = "sales")
  15. plt.plot(x,y2,linestyle='--',label = "cost")
  16. plt.xlabel("x")
  17. plt.ylabel("y")
  18. plt.title("sales & cost")
  19. img = imread('../Destop/lena.png')
  20. plt.show()
  21. #与门
  22. def and_door(x1,x2):
  23. x = np.array([x1,x2])
  24. w = np.array([0.5,0.5])
  25. theta = -0.8
  26. tmp = np.sum(w*x)+theta
  27. if tmp <= 0 :
  28. return 0
  29. else:
  30. return 1
  31. #与非门
  32. def NAND(x1,x2):
  33. x = np.array([x1,x2])
  34. w = np.array([-0.5,-0.5])
  35. theta = 0.8
  36. tmp = np.sum(w*x)+theta
  37. if tmp <= 0 :
  38. return 0
  39. else:
  40. return 1
  41. #或门
  42. def or_door(x1,x2):
  43. x = np.array([x1,x2])
  44. w = np.array([0.5,0.5])
  45. theta = -0.3
  46. tmp = np.sum(w*x)+theta
  47. if tmp <= 0 :
  48. return 0
  49. else:
  50. return 1
  51. #异或门
  52. def XOR(x1,x2):
  53. s1 = NAND(x1,x2)
  54. s2 = or_door(x1,x2)
  55. y = and_door(s1,s2)
  56. return y

非线性函数activation function

  1. #activation function
  2. #非线性函数
  3. #sigmoid fun
  4. #h(x) = 1/(1+exp(-x))
  5. def sigmoid(x):
  6. return 1/(1 + np.exp(-x))
  7. #step function
  8. def step_fun(x):
  9. y = x >0
  10. return y.astype(np.int)

线性函数

算法 - 图14

  1. #ReLU
  2. def relu(x):
  3. return np.maximum(0,x)

多维数组

  1. A= np.array([1,2,3,4])
  2. B = np.array([[1,2],[3,4],[5,6]])
  3. np.ndim(A) = 1
  4. np.ndim(B) = 2
  5. A.shape = (4,)
  6. B.shape = (3,2)
  7. A.shape[0] = 4
  8. #shape is tuple
  9. #mult
  10. np.dot(A,B)

基本三元神经实现

  1. def network():
  2. net = {}
  3. net['w1'] = np.array([ [x1,x2,x3],[y1,y2,y3] ])
  4. net['w2'] = np.array([ [x1,x2],[y1,y2],[z1,z2] ])
  5. net['w3'] = np.array([ [x1,x2,x3],[y1,y2,y3] ])
  6. net['b1'] = np.array([ [t1,t2,t3] ])
  7. net['b2'] = np.array([ [t1,t2] ])
  8. net['b3'] = np.array([ [t1,t2] ])
  9. return net
  10. def forward(net,x):
  11. w1,w2,w3 = net['w1'], net['w2'], net['w3']
  12. b1,b2,b3 = net['b1'], net['b2'], net['b3']
  13. a1 = np.dot(x,w1) +b1
  14. z1 = sigmoid(a1)
  15. a2 = np.dot(z1,w2) +b2
  16. z2 = sigmoid(a2)
  17. a3 = np.dot(z2,w3) + b3
  18. res = identity_function(a3) #let output.shape = input.shape
  19. return res
  20. net = network()
  21. x = np.array([1,0.5])
  22. y = forward(net,x)

很多事情,尽量更新


softmax函数

softmax是一个总是输出0到1之间的实数的一个函数,其实可以理解把每一个结果变成一个可能发生的概率。因为即使使用了softmax各个元素之间的大小关系也不会发生变化。
算法 - 图15

  1. def softmax(a):
  2. exp_a = np.exp(a)
  3. sum_exp_a = np.sum(exp_a)
  4. res = exp_a / sum_exp_a
  5. return res
  6. #因为计算机的运算存在缺陷会导致指数函数的值变得非常大没办法计算因此直接使用:
  7. def softmax(x):
  8. if x.ndim == 2:
  9. x = x.T
  10. x = x - np.max(x, axis=1) #稳定概率,剪掉最大的元素,axis=0是列,axis=1是行
  11. y = np.exp(x) / np.sum(np.exp(x), axis=0)
  12. return y.T
  13. x = x - np.max(x) # 溢出对策
  14. return np.exp(x) / np.sum(np.exp(x))

MNIST 数据集

mnist数据集就是一堆从0到9的手写数字图像集:
image.png
使用这个mnist.py可以将数据集下载并转化成Numpy数组来处理

  1. # coding: utf-8
  2. try:
  3. import urllib.request
  4. except ImportError:
  5. raise ImportError('You should use Python3')
  6. import os.path
  7. import gzip
  8. import pickle
  9. import os
  10. import numpy as np
  11. url_base = 'http://yann.lecun.com/exdb/mnist/'
  12. key_file = {
  13. 'train_img':'train-images-idx3-ubyte.gz',
  14. 'train_label':'train-labels-idx1-ubyte.gz',
  15. 'test_img':'t10k-images-idx3-ubyte.gz',
  16. 'test_label':'t10k-labels-idx1-ubyte.gz'
  17. }
  18. dataset_dir = os.path.dirname(os.path.abspath(__file__))
  19. save_file = dataset_dir + "/mnist.pkl"
  20. train_num = 60000
  21. test_num = 10000
  22. img_dim = (1, 28, 28)
  23. img_size = 784
  24. def _download(file_name):
  25. file_path = dataset_dir + "/" + file_name
  26. if os.path.exists(file_path):
  27. return
  28. print("Downloading " + file_name + " ... ")
  29. urllib.request.urlretrieve(url_base + file_name, file_path)
  30. print("Done")
  31. def download_mnist():
  32. for v in key_file.values():
  33. _download(v)
  34. def _load_label(file_name):
  35. file_path = dataset_dir + "/" + file_name
  36. print("Converting " + file_name + " to NumPy Array ...")
  37. with gzip.open(file_path, 'rb') as f:
  38. labels = np.frombuffer(f.read(), np.uint8, offset=8)
  39. print("Done")
  40. return labels
  41. def _load_img(file_name):
  42. file_path = dataset_dir + "/" + file_name
  43. print("Converting " + file_name + " to NumPy Array ...")
  44. with gzip.open(file_path, 'rb') as f:
  45. data = np.frombuffer(f.read(), np.uint8, offset=16)
  46. data = data.reshape(-1, img_size)
  47. print("Done")
  48. return data
  49. def _convert_numpy():
  50. dataset = {}
  51. dataset['train_img'] = _load_img(key_file['train_img'])
  52. dataset['train_label'] = _load_label(key_file['train_label'])
  53. dataset['test_img'] = _load_img(key_file['test_img'])
  54. dataset['test_label'] = _load_label(key_file['test_label'])
  55. return dataset
  56. def init_mnist():
  57. download_mnist()
  58. dataset = _convert_numpy()
  59. print("Creating pickle file ...")
  60. with open(save_file, 'wb') as f:
  61. pickle.dump(dataset, f, -1)
  62. print("Done!")
  63. def _change_one_hot_label(X):
  64. T = np.zeros((X.size, 10))
  65. for idx, row in enumerate(T):
  66. row[X[idx]] = 1
  67. return T
  68. def load_mnist(normalize=True, flatten=True, one_hot_label=False):
  69. """读入MNIST数据集
  70. Parameters
  71. ----------
  72. normalize : 将图像的像素值正规化为0.0~1.0
  73. one_hot_label :
  74. one_hot_label为True的情况下,标签作为one-hot数组返回
  75. one-hot数组是指[0,0,1,0,0,0,0,0,0,0]这样的数组
  76. flatten : 是否将图像展开为一维数组
  77. Returns
  78. -------
  79. (训练图像, 训练标签), (测试图像, 测试标签)
  80. """
  81. if not os.path.exists(save_file):
  82. init_mnist()
  83. with open(save_file, 'rb') as f:
  84. dataset = pickle.load(f)
  85. if normalize:
  86. for key in ('train_img', 'test_img'):
  87. dataset[key] = dataset[key].astype(np.float32)
  88. dataset[key] /= 255.0
  89. if one_hot_label:
  90. dataset['train_label'] = _change_one_hot_label(dataset['train_label'])
  91. dataset['test_label'] = _change_one_hot_label(dataset['test_label'])
  92. if not flatten:
  93. for key in ('train_img', 'test_img'):
  94. dataset[key] = dataset[key].reshape(-1, 1, 28, 28)
  95. return (dataset['train_img'], dataset['train_label']), (dataset['test_img'], dataset['test_label'])
  96. if __name__ == '__main__':
  97. init_mnist()
  1. #接着可以使用load_mnist()读入mnist数据
  2. #normalize设置是否将图像正规化为0~1的实数,否则像素保持0~255
  3. #flatten设置是否展开图像为一维,否则保持1*28*28
  4. #one-hot表示仅仅正确的解的标签为1其余标签为0
  5. # coding: utf-8
  6. import sys, os
  7. sys.path.append(os.pardir) # 为了导入父目录的文件而进行的设定
  8. import numpy as np
  9. from dataset.mnist import load_mnist
  10. from PIL import Image
  11. def img_show(img):
  12. pil_img = Image.fromarray(np.uint8(img))
  13. pil_img.show()
  14. (x_train, t_train), (x_test, t_test) = load_mnist(flatten=True, normalize=False)
  15. img = x_train[0]
  16. label = t_train[0]
  17. print(x_train.shape) #60000,784
  18. print(t_train.shape) #60000
  19. print(x_test.shape) #10000,784
  20. print(t_test.shape) #10000
  21. print(label) # 5
  22. print(img.shape) # (784,)
  23. img = img.reshape(28, 28) # 把图像的形状变为原来的尺寸
  24. print(img.shape) # (28, 28)
  25. img_show(img)
  1. #接着使用之前的sigmoid,softmax和forward来进行基本的机器学习
  2. # coding: utf-8
  3. import sys, os
  4. sys.path.append(os.pardir) # 为了导入父目录的文件而进行的设定
  5. import numpy as np
  6. import pickle
  7. from dataset.mnist import load_mnist
  8. def softmax(x):
  9. if x.ndim == 2:
  10. x = x.T
  11. x = x - np.max(x, axis=0)
  12. y = np.exp(x) / np.sum(np.exp(x), axis=1)
  13. return y.T
  14. x = x - np.max(x) # 溢出对策
  15. return np.exp(x) / np.sum(np.exp(x))
  16. def sigmoid(x):
  17. return 1 / (1 + np.exp(-x))
  18. def get_data():
  19. (x_train, t_train), (x_test, t_test) = load_mnist(normalize=True, flatten=True, one_hot_label=False)
  20. return x_test, t_test
  21. def init_network():
  22. with open("sample_weight.pkl", 'rb') as f:
  23. network = pickle.load(f)
  24. return network
  25. def predict(network, x):
  26. W1, W2, W3 = network['W1'], network['W2'], network['W3']
  27. b1, b2, b3 = network['b1'], network['b2'], network['b3']
  28. a1 = np.dot(x, W1) + b1
  29. z1 = sigmoid(a1)
  30. a2 = np.dot(z1, W2) + b2
  31. z2 = sigmoid(a2)
  32. a3 = np.dot(z2, W3) + b3
  33. y = softmax(a3)
  34. return y
  35. x, t = get_data()
  36. network = init_network()
  37. accuracy_cnt = 0
  38. for i in range(len(x)):
  39. y = predict(network, x[i])
  40. p= np.argmax(y) # 获取概率最高的元素的索引
  41. if p == t[i]:
  42. accuracy_cnt += 1
  43. print("Accuracy:" + str(float(accuracy_cnt) / len(x)))
  44. ##Accuracy:0.9352

批处理batch

例如输入数据是100x784,然后输出数据是100x10.这种打包数据是batch,批处理可以缩短每张图像处理的时间

  1. #批处理的实现·
  2. x, t = get_data()
  3. network = init_network()
  4. batch_size = 100
  5. acc = 0
  6. for i in range(0,len(x),batch_size):
  7. x_batch = x[i:i+batch_size]
  8. y_batch = predict(network,x_batch)
  9. p = np.argmax(y_batch,axis = 1)
  10. #p == t[i:i+batch_size] 是布尔值,将np.sum会将所有的TRUE加起来
  11. acc += np.sum(p == t[i:i+batch_size])
  12. print("Accuracy:" + str(float(acc)/len(x)))
  1. #argmax
  2. a = array([[10, 11, 12],
  3. [13, 14, 15]])
  4. np.argmax(a)
  5. >>5
  6. np.argmax(a, axis=0)#axis=0 从列出发
  7. >>array([1, 1, 1])
  8. np.argmax(a, axis=1)#从行出发
  9. >>array([2, 2])

训练与测试数据

在计算机视觉领域中,常用的特征量为SIFT,SURF,HOG,然后使用这个特征量将图像数据转化为向量。
对转化后的向量使用机器学习的SVM,KNN等分类器进行学习。
在机器学习中,一般将数据分为训练数据和测试数据。有训练数据的机器学习也称为监督学习,反之为无监督学习。某个数据过度拟合就是过拟合over fitting


损失函数