zoukankan      html  css  js  c++  java
  • 深度学习与计算机视觉系列(1)_基础介绍

    深度学习与计算机视觉系列(1)_基础介绍

    作者:寒小阳 
    时间:2015年11月。 
    出处:http://blog.csdn.net/han_xiaoyang/article/details/49876119 
    声明:版权所有,转载请注明出处,谢谢。

    1.背景

    计算机视觉/computer vision是一个火了N年的topic。持续化升温的原因也非常简单:在搜索/影像内容理解/医学应用/地图识别等等领域应用太多,大家都有一个愿景『让计算机能够像人一样去”看”一张图片,甚至”读懂”一张图片』。

    有几个比较重要的计算机视觉任务,比如图片的分类,物体识别,物体定位于检测等等。而近年来的神经网络/深度学习使得上述任务的准确度有了非常大的提升。加之最近做了几个不大不小的计算机视觉上的项目,爱凑热闹的博主自然不打算放过此领域,也边学边做点笔记总结,写点东西,写的不正确的地方,欢迎大家提出和指正。

    2.基础知识

    为了简单易读易懂,这个课程笔记系列中绝大多数的代码都使用Python完成。这里稍微介绍一下python和Numpy/Scipy(python中的科学计算包)的一些基础。

    2.1 python基础

    python是一种长得像伪代码,具备高可读性的编程语言。 
    优点挺多:可读性相当好,写起来也简单,所想立马可以转为实现代码,且社区即为活跃,可用的package相当多;缺点:效率一般。

    2.1.1 基本数据类型

    最常用的有数值型(Numbers),布尔型(Booleans)和字符串(String)三种。

    • 数值型(Numbers)

    可进行简单的运算,如下:

    x = 5
    print type(x) # Prints "<type 'int'>"
    print x       # Prints "5"
    print x + 1   # 加; prints "6"
    print x - 1   # 减; prints "4"
    print x * 2   # 乘; prints "10"
    print x ** 2  # 幂; prints "25"
    x += 1  #自加
    print x  # Prints "6"
    x *= 2  #自乘
    print x  # Prints "12"
    y = 2.5
    print type(y) # Prints "<type 'float'>"
    print y, y + 1, y * 2, y ** 2 # Prints "2.5 3.5 5.0 6.25"
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    PS:python中没有x++ 和 x– 操作

    • 布尔型(Booleans)

    包含True False和常见的与或非操作

    t = True
    f = False
    print type(t) # Prints "<type 'bool'>"
    print t and f # 逻辑与; prints "False"
    print t or f  # 逻辑或; prints "True"
    print not t   # 逻辑非; prints "False"
    print t != f  # XOR; prints "True" 
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 字符串型(String)

    字符串可以用单引号/双引号/三引号声明

    hello = 'hello'   
    world = "world"   
    print hello       # Prints "hello"
    print len(hello)  # 字符串长度; prints "5"
    hw = hello + ' ' + world  # 字符串连接
    print hw  # prints "hello world"
    hw2015 = '%s %s %d' % (hello, world, 2015)  # 格式化字符串
    print hw2015  # prints "hello world 2015"
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    字符串对象有很有有用的函数:

    s = "hello"
    print s.capitalize()  # 首字母大写; prints "Hello"
    print s.upper()       # 全大写; prints "HELLO"
    print s.rjust(7)      # 以7为长度右对齐,左边补空格; prints "  hello"
    print s.center(7)     # 居中补空格; prints " hello "
    print s.replace('l', '(ell)')  # 字串替换;prints "he(ell)(ell)o"
    print '  world '.strip()  # 去首位空格; prints "world"
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    2.1.2 基本容器

    • 列表/List

    和数组类似的一个东东,不过可以包含不同类型的元素,同时大小也是可以调整的。

    xs = [3, 1, 2]   # 创建
    print xs, xs[2]  # Prints "[3, 1, 2] 2"
    print xs[-1]     # 第-1个元素,即最后一个
    xs[2] = 'foo'    # 下标从0开始,这是第3个元素
    print xs         # 可以有不同类型,Prints "[3, 1, 'foo']"
    xs.append('bar') # 尾部添加一个元素
    print xs         # Prints 
    x = xs.pop()     # 去掉尾部的元素
    print x, xs      # Prints "bar [3, 1, 'foo']"
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    列表最常用的操作有: 
    切片/slicing 
    即取子序列/一部分元素,如下:

    nums = range(5)    # 从1到5的序列
    print nums         # Prints "[0, 1, 2, 3, 4]"
    print nums[2:4]    # 下标从2到4-1的元素 prints "[2, 3]"
    print nums[2:]     # 下标从2到结尾的元素
    print nums[:2]     # 从开头到下标为2-1的元素  [0, 1]
    print nums[:]      # 恩,就是全取出来了
    print nums[:-1]    # 从开始到第-1个元素(最后的元素)
    nums[2:4] = [8, 9] # 对子序列赋值
    print nums         # Prints "[0, 1, 8, 8, 4]"
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    循环/loops 
    即遍历整个list,做一些操作,如下:

    animals = ['cat', 'dog', 'monkey']
    for animal in animals:
        print animal
    # 依次输出 "cat", "dog", "monkey",每个一行.
    • 1
    • 2
    • 3
    • 4
    • 1
    • 2
    • 3
    • 4

    可以用enumerate取出元素的同时带出下标

    animals = ['cat', 'dog', 'monkey']
    for idx, animal in enumerate(animals):
        print '#%d: %s' % (idx + 1, animal)
    # 输出 "#1: cat", "#2: dog", "#3: monkey",一个一行。
    • 1
    • 2
    • 3
    • 4
    • 1
    • 2
    • 3
    • 4

    List comprehension 
    这个相当相当相当有用,在很长的list生成过程中,效率完胜for循环:

    # for 循环
    nums = [0, 1, 2, 3, 4]
    squares = []
    for x in nums:
        squares.append(x ** 2)
    print squares   # Prints [0, 1, 4, 9, 16]
    
    # list comprehension
    nums = [0, 1, 2, 3, 4]
    squares = [x ** 2 for x in nums]
    print squares   # Prints [0, 1, 4, 9, 16]
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    你猜怎么着,list comprehension也是可以加多重条件的:

    nums = [0, 1, 2, 3, 4]
    even_squares = [x ** 2 for x in nums if x % 2 == 0]
    print even_squares  # Prints "[0, 4, 16]"
    • 1
    • 2
    • 3
    • 1
    • 2
    • 3
    • 字典/Dict 
      和Java中的Map一样的东东,用于存储key-value对:
    d = {'cat': 'cute', 'dog': 'furry'}  # 创建
    print d['cat']       # 根据key取出value
    print 'cat' in d     # 判断是否有'cat'这个key
    d['fish'] = 'wet'    # 添加元素
    print d['fish']      # Prints "wet"
    # print d['monkey']  # KeyError: 'monkey'非本字典的key
    print d.get('monkey', 'N/A')  # 有key返回value,无key返回"N/A"
    print d.get('fish', 'N/A')    # prints "wet"
    del d['fish']        # 删除某个key以及对应的value
    print d.get('fish', 'N/A') # prints "N/A"
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    对应list的那些操作,你在dict里面也能找得到:

    循环/loops

    # for循环
    d = {'person': 2, 'cat': 4, 'spider': 8}
    for animal in d:
        legs = d[animal]
        print 'A %s has %d legs' % (animal, legs)
    # Prints "A person has 2 legs", "A spider has 8 legs", "A cat has 4 legs"
    
    # 通过iteritems
    d = {'person': 2, 'cat': 4, 'spider': 8}
    for animal, legs in d.iteritems():
        print 'A %s has %d legs' % (animal, legs)
    # Prints "A person has 2 legs", "A spider has 8 legs", "A cat has 4 legs"
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    # Dictionary comprehension
    nums = [0, 1, 2, 3, 4]
    even_num_to_square = {x: x ** 2 for x in nums if x % 2 == 0}
    print even_num_to_square  # Prints "{0: 0, 2: 4, 4: 16}"
    • 1
    • 2
    • 3
    • 4
    • 1
    • 2
    • 3
    • 4
    • 元组/turple 
      本质上说,还是一个list,只不过里面的每个元素都是一个两元组对。
    d = {(x, x + 1): x for x in range(10)}  # 创建
    t = (5, 6)       # Create a tuple
    print type(t)    # Prints "<type 'tuple'>"
    print d[t]       # Prints "5"
    print d[(1, 2)]  # Prints "1"
    • 1
    • 2
    • 3
    • 4
    • 5
    • 1
    • 2
    • 3
    • 4
    • 5

    2.1.3 函数

    用def可以定义一个函数:

    def sign(x):
        if x > 0:
            return 'positive'
        elif x < 0:
            return 'negative'
        else:
            return 'zero'
    
    for x in [-1, 0, 1]:
        print sign(x)
    # Prints "negative", "zero", "positive"
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    def hello(name, loud=False):
        if loud:
            print 'HELLO, %s' % name.upper()
        else:
            print 'Hello, %s!' % name
    
    hello('Bob') # Prints "Hello, Bob"
    hello('Fred', loud=True)  # Prints "HELLO, FRED!"
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 类/Class

    python里面的类定义非常的直接和简洁:

    class Greeter:
    
        # Constructor
        def __init__(self, name):
            self.name = name  # Create an instance variable
    
        # Instance method
        def greet(self, loud=False):
            if loud:
                print 'HELLO, %s!' % self.name.upper()
            else:
                print 'Hello, %s' % self.name
    
    g = Greeter('Fred')  # Construct an instance of the Greeter class
    g.greet()            # Call an instance method; prints "Hello, Fred"
    g.greet(loud=True)   # Call an instance method; prints "HELLO, FRED!"
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    2.2.NumPy基础

    NumPy是Python的科学计算的一个核心库。它提供了一个高性能的多维数组(矩阵)对象,可以完成在其之上的很多操作。很多机器学习中的计算问题,把数据vectorize之后可以进行非常高效的运算。

    2.2.1 数组

    一个NumPy数组是一些类型相同的元素组成的类矩阵数据。用list或者层叠的list可以初始化:

    import numpy as np
    
    a = np.array([1, 2, 3])  # 一维Numpy数组
    print type(a)            # Prints "<type 'numpy.ndarray'>"
    print a.shape            # Prints "(3,)"
    print a[0], a[1], a[2]   # Prints "1 2 3"
    a[0] = 5                 # 重赋值
    print a                  # Prints "[5, 2, 3]"
    
    b = np.array([[1,2,3],[4,5,6]])   # 二维Numpy数组
    print b.shape                     # Prints "(2, 3)"
    print b[0, 0], b[0, 1], b[1, 0]   # Prints "1 2 4"
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    生成一些特殊的Numpy数组(矩阵)时,我们有特定的函数可以调用:

    import numpy as np
    
    a = np.zeros((2,2))  # 全0的2*2 Numpy数组
    print a              # Prints "[[ 0.  0.]
                         #          [ 0.  0.]]"
    
    b = np.ones((1,2))   # 全1 Numpy数组
    print b              # Prints "[[ 1.  1.]]"
    
    c = np.full((2,2), 7) # 固定值Numpy数组
    print c               # Prints "[[ 7.  7.]
                          #          [ 7.  7.]]"
    
    d = np.eye(2)        # 2*2 对角Numpy数组
    print d              # Prints "[[ 1.  0.]
                         #          [ 0.  1.]]"
    
    e = np.random.random((2,2)) # 2*2 的随机Numpy数组
    print e                     # 随机输出
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    2.2.2 Numpy数组索引与取值

    可以通过像list一样的分片/slicing操作取出需要的数值部分。

    import numpy as np
    
    # 创建如下的3*4 Numpy数组
    # [[ 1  2  3  4]
    #  [ 5  6  7  8]
    #  [ 9 10 11 12]]
    a = np.array([[1,2,3,4], [5,6,7,8], [9,10,11,12]])
    
    # 通过slicing取出前两行的2到3列:
    # [[2 3]
    #  [6 7]]
    b = a[:2, 1:3]
    
    # 需要注意的是取出的b中的数据实际上和a的这部分数据是同一份数据.
    print a[0, 1]   # Prints "2"
    b[0, 0] = 77    # b[0, 0] 和 a[0, 1] 是同一份数据
    print a[0, 1]   # a也被修改了,Prints "77"
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    import numpy as np
    
    a = np.array([[1,2,3,4], [5,6,7,8], [9,10,11,12]])
    
    row_r1 = a[1, :]    # a 的第二行  
    row_r2 = a[1:2, :]  # 同上
    print row_r1, row_r1.shape  # Prints "[5 6 7 8] (4,)"
    print row_r2, row_r2.shape  # Prints "[[5 6 7 8]] (1, 4)"
    
    col_r1 = a[:, 1]
    col_r2 = a[:, 1:2]
    print col_r1, col_r1.shape  # Prints "[ 2  6 10] (3,)"
    print col_r2, col_r2.shape  # Prints "[[ 2]
                                #          [ 6]
                                #          [10]] (3, 1)"
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    还可以这么着取:

    import numpy as np
    
    a = np.array([[1,2], [3, 4], [5, 6]])
    
    # 取出(0,0) (1,1) (2,0)三个位置的值
    print a[[0, 1, 2], [0, 1, 0]]  # Prints "[1 4 5]"
    
    # 和上面一样
    print np.array([a[0, 0], a[1, 1], a[2, 0]])  # Prints "[1 4 5]"
    
    # 取出(0,1) (0,1) 两个位置的值
    print a[[0, 0], [1, 1]]  # Prints "[2 2]"
    
    # 同上
    print np.array([a[0, 1], a[0, 1]])  # Prints "[2 2]"
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    我们还可以通过条件得到bool型的Numpy数组结果,再通过这个数组取出符合条件的值,如下:

    import numpy as np
    
    a = np.array([[1,2], [3, 4], [5, 6]])
    
    bool_idx = (a > 2)  # 判定a大于2的结果矩阵
    
    print bool_idx      # Prints "[[False False]
                        #          [ True  True]
                        #          [ True  True]]"
    
    # 再通过bool_idx取出我们要的值
    print a[bool_idx]  # Prints "[3 4 5 6]"
    
    # 放在一起我们可以这么写
    print a[a > 2]     # Prints "[3 4 5 6]"
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    Numpy数组的类型

    import numpy as np
    
    x = np.array([1, 2])  
    print x.dtype         # Prints "int64"
    
    x = np.array([1.0, 2.0]) 
    print x.dtype             # Prints "float64"
    
    x = np.array([1, 2], dtype=np.int64)  # 强制使用某个type
    print x.dtype                         # Prints "int64"
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    2.2.3 Numpy数组的运算

    矩阵的加减开方和(元素对元素)乘除如下:

    import numpy as np
    
    x = np.array([[1,2],[3,4]], dtype=np.float64)
    y = np.array([[5,6],[7,8]], dtype=np.float64)
    
    # [[ 6.0  8.0]
    #  [10.0 12.0]]
    print x + y
    print np.add(x, y)
    
    # [[-4.0 -4.0]
    #  [-4.0 -4.0]]
    print x - y
    print np.subtract(x, y)
    
    # 元素对元素,点对点的乘积
    # [[ 5.0 12.0]
    #  [21.0 32.0]]
    print x * y
    print np.multiply(x, y)
    
    # 元素对元素,点对点的除法
    # [[ 0.2         0.33333333]
    #  [ 0.42857143  0.5       ]]
    print x / y
    print np.divide(x, y)
    
    # 开方
    # [[ 1.          1.41421356]
    #  [ 1.73205081  2.        ]]
    print np.sqrt(x)
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    矩阵的内积是通过下列方法计算的:

    import numpy as np
    
    x = np.array([[1,2],[3,4]])
    y = np.array([[5,6],[7,8]])
    
    v = np.array([9,10])
    w = np.array([11, 12])
    
    # 向量内积,得到 219
    print v.dot(w)
    print np.dot(v, w)
    
    # 矩阵乘法,得到 [29 67]
    print x.dot(v)
    print np.dot(x, v)
    
    # 矩阵乘法
    # [[19 22]
    #  [43 50]]
    print x.dot(y)
    print np.dot(x, y)
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    特别特别有用的一个操作是,sum/求和(对某个维度):

    import numpy as np
    
    x = np.array([[1,2],[3,4]])
    
    print np.sum(x)  # 整个矩阵的和,得到 "10"
    print np.sum(x, axis=0)  # 每一列的和 得到 "[4 6]"
    print np.sum(x, axis=1)  # 每一行的和 得到 "[3 7]"
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    还有一个经常会用到操作是矩阵的转置,在Numpy数组里用.T实现:

    import numpy as np
    
    x = np.array([[1,2], [3,4]])
    print x    # Prints "[[1 2]
               #          [3 4]]"
    print x.T  # Prints "[[1 3]
               #          [2 4]]"
    
    # 1*n的Numpy数组,用.T之后其实啥也没做:
    v = np.array([1,2,3])
    print v    # Prints "[1 2 3]"
    print v.T  # Prints "[1 2 3]"
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    2.2.4 Broadcasting

    Numpy还有一个非常牛逼的机制,你想想,如果你现在有一大一小俩矩阵,你想使用小矩阵在大矩阵上做多次操作。额,举个例子好了,假如你想将一个1*n的矩阵,加到m*n的矩阵的每一行上:

    #你如果要用for循环实现是酱紫的(下面用y的原因是,你不想改变原来的x)
    import numpy as np
    
    x = np.array([[1,2,3], [4,5,6], [7,8,9], [10, 11, 12]])
    v = np.array([1, 0, 1])
    y = np.empty_like(x)   # 设置一个和x一样维度的Numpy数组y
    
    # 逐行相加
    for i in range(4):
        y[i, :] = x[i, :] + v
    
    # 恩,y就是你想要的了
    # [[ 2  2  4]
    #  [ 5  5  7]
    #  [ 8  8 10]
    #  [11 11 13]]
    print y
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    #上一种方法如果for的次数非常多,会很慢,于是我们改进了一下
    import numpy as np
    
    x = np.array([[1,2,3], [4,5,6], [7,8,9], [10, 11, 12]])
    v = np.array([1, 0, 1])
    vv = np.tile(v, (4, 1))  # 变形,重复然后叠起来
    print vv                 # Prints "[[1 0 1]
                             #          [1 0 1]
                             #          [1 0 1]
                             #          [1 0 1]]"
    y = x + vv  # 相加
    print y  # Prints "[[ 2  2  4
             #          [ 5  5  7]
             #          [ 8  8 10]
             #          [11 11 13]]"
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    #其实因为Numpy的Broadcasting,你可以直接酱紫操作
    import numpy as np
    
    x = np.array([[1,2,3], [4,5,6], [7,8,9], [10, 11, 12]])
    v = np.array([1, 0, 1])
    y = x + v  # 直接加!!!
    print y  # Prints "[[ 2  2  4]
             #          [ 5  5  7]
             #          [ 8  8 10]
             #          [11 11 13]]"
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    更多Broadcasting的例子请看下面:

    import numpy as np
    
    v = np.array([1,2,3])  # v has shape (3,)
    w = np.array([4,5])    # w has shape (2,)
    # 首先把v变成一个列向量
    # v现在的形状是(3, 1);
    # 作用在w上得到的结果形状是(3, 2),如下
    # [[ 4  5]
    #  [ 8 10]
    #  [12 15]]
    print np.reshape(v, (3, 1)) * w
    
    # 逐行相加
    x = np.array([[1,2,3], [4,5,6]])
    # 得到如下结果:
    # [[2 4 6]
    #  [5 7 9]]
    print x + v
    
    # 先逐行相加再转置,得到以下结果:
    # [[ 5  6  7]
    #  [ 9 10 11]]
    print (x.T + w).T
    # 恩,也可以这么做
    print x + np.reshape(w, (2, 1))
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    2.3 SciPy

    Numpy提供了一个非常方便操作和计算的高维向量对象,并提供基本的操作方法,而Scipy是在Numpy的基础上,提供很多很多的函数和方法去直接完成你需要的矩阵操作。有兴趣可以浏览Scipy方法索引查看具体的方法,函数略多,要都记下来有点困难,随用随查吧。

    向量距离计算

    需要特别拎出来说一下的是,向量之间的距离计算,这个Scipy提供了很好的接口scipy.spatial.distance.pdist

    import numpy as np
    from scipy.spatial.distance import pdist, squareform
    
    # [[0 1]
    #  [1 0]
    #  [2 0]]
    x = np.array([[0, 1], [1, 0], [2, 0]])
    print x
    
    # 计算矩阵每一行和每一行之间的欧氏距离
    # d[i, j] 是 x[i, :] 和 x[j, :] 之间的距离,
    # 结果如下:
    # [[ 0.          1.41421356  2.23606798]
    #  [ 1.41421356  0.          1.        ]
    #  [ 2.23606798  1.          0.        ]]
    d = squareform(pdist(x, 'euclidean'))
    print d
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    2.4 Matplotlib

    这是python中的一个作图工具包。如果你熟悉matlab的语法的话,应该会用得挺顺手。可以通过matplotlib.pyplot.plot了解更多绘图相关的设置和参数。

    import numpy as np
    import matplotlib.pyplot as plt
    
    # 计算x和对应的sin值作为y
    x = np.arange(0, 3 * np.pi, 0.1)
    y = np.sin(x)
    
    # 用matplotlib绘出点的变化曲线
    plt.plot(x, y)
    plt.show()  # 只有调用plt.show()之后才能显示
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    结果如下: 
    sin图像

    # 在一个图中画出2条曲线
    import numpy as np
    import matplotlib.pyplot as plt
    
    # 计算x对应的sin和cos值
    x = np.arange(0, 3 * np.pi, 0.1)
    y_sin = np.sin(x)
    y_cos = np.cos(x)
    
    # 用matplotlib作图
    plt.plot(x, y_sin)
    plt.plot(x, y_cos)
    plt.xlabel('x axis label')
    plt.ylabel('y axis label')
    plt.title('Sine and Cosine')
    plt.legend(['Sine', 'Cosine'])
    plt.show()
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    sin和cos

    # 用subplot分到子图里
    import numpy as np
    import matplotlib.pyplot as plt
    
    # 得到x对应的sin和cos值
    x = np.arange(0, 3 * np.pi, 0.1)
    y_sin = np.sin(x)
    y_cos = np.cos(x)
    
    # 2*1个子图,第一个位置.
    plt.subplot(2, 1, 1)
    
    # 画第一个子图
    plt.plot(x, y_sin)
    plt.title('Sine')
    
    # 画第2个子图
    plt.subplot(2, 1, 2)
    plt.plot(x, y_cos)
    plt.title('Cosine')
    
    plt.show()
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    subplot

    2.5 简单图片读写

    可以使用imshow来显示图片。

    import numpy as np
    from scipy.misc import imread, imresize
    import matplotlib.pyplot as plt
    
    img = imread('/Users/HanXiaoyang/Comuter_vision/computer_vision.jpg')
    img_tinted = img * [1, 0.95, 0.9]
    
    # 显示原始图片
    plt.subplot(1, 2, 1)
    plt.imshow(img)
    
    # 显示调色后的图片
    plt.subplot(1, 2, 2)
    plt.imshow(np.uint8(img_tinted))
    
    plt.show()
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    computer_vision

    参考资料与原文

    cs231n python/Numpy指南

  • 相关阅读:
    LeetCode 42. Trapping Rain Water
    LeetCode 209. Minimum Size Subarray Sum
    LeetCode 50. Pow(x, n)
    LeetCode 80. Remove Duplicates from Sorted Array II
    Window10 激活
    Premiere 关键帧缩放
    AE 「酷酷的藤」特效字幕制作方法
    51Talk第一天 培训系列1
    Premiere 视频转场
    Premiere 暴徒生活Thug Life
  • 原文地址:https://www.cnblogs.com/zhehan54/p/7150894.html
Copyright © 2011-2022 走看看