IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 人工智能 -> 《深度学习实战》第1章 深度学习的发展介绍 -> 正文阅读

[人工智能]《深度学习实战》第1章 深度学习的发展介绍

参考书籍《深度学习实战》杨云、杜飞著

第1章 深度学习的发展介绍

介绍

python是一种非常简单易学的解释性语言。由于强大的开源库支持(numpy,scipy,matplotlib),其广泛应用于科学计算中。如果你励志成为一名数据科学家或数据“攻城狮”,那python就是你必须学会的工具之一。接下来我们将简短的介绍下python, numpy, matplotlib的使用。本章教程内容主要参考于斯坦福大学cs228课程的python教程,详情可使用该网址查看 https://github.com/kuleshov/cs228-material/blob/master/tutorials/python/cs228-python-tutorial.ipynb

在本章中,你将逐步学习以下内容:

  • Python基本使用: 基本数据类型(Containers, Lists, Dictionaries, Sets, Tuples), 函数, 类
  • Numpy: 数组, 数组索引, 数据类型,数组运算, 广播
  • Matplotlib: Plotting, Subplots, Images

Python基本用法

Python是一种面向对象的解释型高级编程语言。很多时候,由于其代码具有高可读性,且只需要数行代码就可以表达复杂的功能,Python看起来简直和伪代码一样。如下所示,为Python实现经典的快速排序算法例子:

def quicksort(arr):
    if len(arr) <= 1:
        return arr
    pivot = arr[int(len(arr) / 2)]
    left = [x for x in arr if x < pivot]
    middle = [x for x in arr if x == pivot]
    right = [x for x in arr if x > pivot]
    return quicksort(left) + middle + quicksort(right)

print(quicksort([3,6,8,10,1,2,1]))
[1, 1, 2, 3, 6, 8, 10]

Python 版本

Python有两个差异较大的版本,分别是2.7+和3.4+。由于在3.0版本和2.7版本语言不兼容,因此2.7下的代码有时候在3.4下是行不通的。本教程中,我们使用的是3.8版本。你可以使用python --version命令。查看你所下载的python版本,确保你的python版本符合我们的教程需求。

基本数据类型

和大多数编程语言一样,Python拥有一系列的基本数据类型,比如整型、浮点型、布尔型和字符串等。这些基本数据类型的使用方式和其他语言的使用方式类似。

整型和浮点型

x = 3
print(x, type(x))
3 <class 'int'>
print(x + 1)   # 加;
print(x - 1)   # 减;
print(x * 2)   # 乘;
print(x ** 2)  # 幂乘;
4
2
6
9
x += 1
print(x)  # 打印 "4"
x *= 2
print(x)  # 打印 "8"
4
8
y = 2.5
print(type(y)) # 打印 "<type 'float'>"
print(y, y + 1, y * 2, y ** 2) # 打印 "2.5 3.5 5.0 6.25"
<class 'float'>
2.5 3.5 5.0 6.25
#python不支持(x++) 或(x--) 运算.
print(y++)
  File "C:\Users\23820\AppData\Local\Temp/ipykernel_11896/3264599002.py", line 2
    print(y++)
             ^
SyntaxError: invalid syntax

布尔型

Python实现了所有的布尔逻辑,但使用的是英语单词(“and”,“or”,“not”)等,而不是我们习惯的操作符("&&","||"等)。

t, f = True, False
print(type(t)) # 打印 "<type 'bool'>"
<class 'bool'>

逻辑运算:

print(t and f) # 逻辑 AND;
print(t or f)  # 逻辑 OR;
print(not t)  # 逻辑 NOT;
print(t != f)  # 逻辑 XOR;
False
True
False
True

字符串

hello = 'hello'   # 字符串可以使用单引号
world = "world"   # 也可以使用双引号
print(hello, len(hello),world)
hello 5 world
hw = hello + ' ' + world  # 字符串拼接
print(hw)  # 打印 "hello world"
hello world
hw12 = '%s %s %d' %(hello, world, 12)  # 按格式输出
print(hw12)  # 打印 "hello world 12"
hello world 12

你也可以将字符串当作是一个对象,其有大量的方法。例如:

s = "hello"
print(s.capitalize())  # 将字符串首字母大写; 打印 "Hello"
print(s.upper())       # 将字符串转换成大写; 打印 "HELLO"
print(s.rjust(7))      # 字符串向右对齐, 使用空格进行站位; 打印 "  hello"
print(s.center(7))     # 字符串居中, 使用空格对左右进行站位; 打印 " hello "
print(s.replace('l', '(ell)'))  # 使用子串代替规定处字符
                               # 打印 "he(ell)(ell)o"
print('   wo  rld '.strip())  # 删除空白字符(开头或结尾); 打印 "wor  ld"
Hello
HELLO
  hello
 hello 
he(ell)(ell)o
wo  rld

更多字符串操作请参考以下网址(https://docs.python.org/2/library/stdtypes.html#string-methods).

容器

Python有以下几种容器类型:列表(lists)、字典(dictionaries)、集合(sets)和元组(tuples)。

列表(Lists)

在Python中,列表相当于数组,但是列表长度可变,且能包含不同类型元素。

xs = [3, 1, 2]   # 创建列表
print(xs, xs[2])
print(xs[-1])     #负值索引相当于从列表的末端进行反向索引; 打印 "2"
[3, 1, 2] 2
2
xs[2] = 'foo'    # 列表可以包含不同的元素
print(xs)
[3, 1, 'foo']
xs.append('bar') # 添加新元素到列表末端
print(xs) 
[3, 1, 'foo', 'bar']
x = xs.pop()     # 移除列表末端元素
print(x, xs) 
bar [3, 1, 'foo']

更多列表操作请参考以下网址(https://docs.python.org/2/tutorial/datastructures.html#more-on-lists).

切片(Slicing)

为了同时获取列表中的多个元素,Python提供了一种简洁的语法去访问子列表,这就是切片。

nums = list(range(5))    # range是内置的创建整型列表函数
print(nums)         # 打印 "[0, 1, 2, 3, 4]"
print(nums[2:4])    # 获取索引2-4(排除)的子列表; 打印 "[2, 3]"
print(nums[2:])     # 获取索引2到末的子列表; 打印 "[2, 3, 4]"
print(nums[:2])    # 获取索引开始到2(排除)的子列表; 打印 "[0, 1]"
print(nums[:])     # 获取整个列表; 打印 ["0, 1, 2, 3, 4]"
print(nums[:-1])   # 切片也可以使用负号索引; 打印 ["0, 1, 2, 3]"
nums[2:4] = ['s','we'] # 用新子列表替换指定索引列表中的子列表
print(nums)         # 打印 "[0, 1, s, we, 4]"
[0, 1, 2, 3, 4]
[2, 3]
[2, 3, 4]
[0, 1]
[0, 1, 2, 3, 4]
[0, 1, 2, 3]
[0, 1, 's', 'we', 4]

循环(Loops)

我们可以这样遍历列表中的每一个元素:

animals = ['cat', 'dog', 'monkey']
for animal in animals:
    print(animal)
cat
dog
monkey

如果想要在循环体内访问每个元素的指针,可以使用内置的枚举(enumerate)函数。注意:起始号0

animals = ['cat', 'dog', 'monkey']
for idx, animal in enumerate(animals):
    print('#%d: %s' %(idx + 1, animal))
#1: cat
#2: dog
#3: monkey

列表解析(List comprehensions):

在编程的时候,我们常常想要将列表中的每一元素使用特定的表达式进行转换。下面是一个简单例子,将列表中的每个元素转换成它的平方。

nums = [0, 1, 2, 3, 4]
squares = []
for x in nums:
    squares.append(x ** 2)
print(squares)
[0, 1, 4, 9, 16]

你可以使用更简单的列表解析(list comprehension):

nums = [0, 1, 2, 3, 4]
squares = [x ** 2 for x in nums]
print(squares)
[0, 1, 4, 9, 16]

列表解析也可以包含条件语句:

nums = [0, 1, 2, 3, 4]
even_squares = [x ** 2 for x in nums if x % 2 == 0]
print(even_squares)
[0, 4, 16]

字典(Dictionaries)

字典用来储存(键, 值)对,这和Java中的Map差不多。你可以这样使用它:

d = {'cat': 'cute', 'dog': 'furry'}  # 为数据创建字典
print(d['cat'])       # 从字典中获取词条(entry); 打印 "cute"
print('cat' in d)     # 检查字典中是否有给定键值(key); 打印 "True"
cute
True
d['fish'] = 'wet'    # 给定键值,创建词条
print(d['fish'])      # 打印 "wet"
wet
print(d['monkey'])  # KeyError: 'monkey' 键值没有在字典中
---------------------------------------------------------------------------

KeyError                                  Traceback (most recent call last)

~\AppData\Local\Temp/ipykernel_11896/3201959582.py in <module>
----> 1 print(d['monkey'])  # KeyError: 'monkey' 键值没有在字典中


KeyError: 'monkey'
print(d.get('monkey', 'N/A'))  # 获取字典中元素默认值; 打印 "N/A"
print(d.get('fish', 'N/A'))    # 获取字典中元素默认值; 打印 "wet"
N/A
wet
del d['fish']        # 从字典中移除元素
print(d.get('fish', 'N/A')) # "fish" 不在是字典中的键值; 打印 "N/A"
N/A

字典的详细用法请参考以下网址:(https://docs.python.org/2/library/stdtypes.html#dict).

迭代字典:

d = {'人': 2, '猫': 4, '蜘蛛': 8}
for animal in d:
    legs = d[animal]
    print(' %s 有 %d 腿' %(animal, legs))
 人 有 2 腿
 猫 有 4 腿
 蜘蛛 有 8 腿

你也可以使用iteritems方法进行迭代:

d = {'人': 2, '猫': 4, '蜘蛛': 8}
for animal, legs in d.items():
    print(' %s 有 %d 腿' %(animal, legs))
 人 有 2 腿
 猫 有 4 腿
 蜘蛛 有 8 腿

字典解析(Dictionary comprehensions): 和列表解析类似,字典解析允许你轻松的构造字典,例如:

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)
{0: 0, 2: 4, 4: 16}

集合(Sets)

集合存放着无序的不同元素,在python中,集合使用花括号表示,如果将一个序列转换为集合,那该序列的重复元素将会被剔除,并且原有的顺序也将被打散。例如:

animals = {'cat', 'dog'}
print('cat' in animals)   # 检查是否元素在集合中; 打印 "True"
print('fish' in animals)  # 打印 "False"
True
False
animals.add('fish')      # 向集合中添加元素
print('fish' in animals)
print(len(animals) )      # 集合中的元素个数;
True
3
animals.add('cat')       # 添加一个存在的元素进集合中,其没有变化。
print(len(animals) )      
animals.remove('cat')    # 从集合中移除一个元素
print(len(animals) )      
3
2

集合循环:虽然集合中的循环语法和列表中的一样,但由于集合是无序的,因此访问集合元素的时候,不能做关于顺序的假设:

animals = {'cat', 'dog', 'fish'}
for idx, animal in enumerate(animals):
    print('#%d: %s' %(idx + 1, animal))
# 打印 "#1: fish", "#2: dog", "#3: cat"
#1: dog
#2: fish
#3: cat

集合解析(Set comprehensions):和字典,列表一样,你可以很方便地使用集合解析构建集合:

from math import sqrt
print({int(sqrt(x)) for x in range(30)})
{0, 1, 2, 3, 4, 5}

元组(Tuples)

元组是一个(不可改变)有序列表。元组和列表在很多方面都很相似,最大的不同在于,元组可以像字典一样使用键/值对,并且还可以作为集合的元素,而列表不行。例如:

d = {(x, x + 1): x for x in range(10)}  # 通过元组键值创建字典
t =(5, 6)       # 创建元组 
print(type(t))
print(d[t])      
print(d[(1, 2)])
<class 'tuple'>
5
1
t[0] = 1 # TypeError: 'tuple' object does not support item assignment
---------------------------------------------------------------------------

TypeError                                 Traceback (most recent call last)

~\AppData\Local\Temp/ipykernel_11896/2642684736.py in <module>
----> 1 t[0] = 1 # TypeError: 'tuple' object does not support item assignment


TypeError: 'tuple' object does not support item assignment

Functions

Python使用关键词def来定义函数,例如:

def sign(x):
    if x > 0:
        return '正'
    elif x < 0:
        return '负'
    else:
        return '零'

for x in [-1, 0, 1]:
    print(sign(x))
负
零
正

我们也经常使用可选参数来定义函数,例如:

def hello(name, loud=False):
    if loud:
        print('HELLO, %s' % name.upper())
    else:
        print('Hello, %s!' % name)

hello('Bob')
hello('Fred', loud=True)
Hello, Bob!
HELLO, FRED

类(Classes)

在python中,定义类的语法很直接:

class Greeter:

    # 构造函数
    def __init__(self, name):
        self.name = name  # 创建一个变量实例

    # 实例方法 
    def greet(self, loud=False):
        if loud:
            print('HELLO, %s!' % self.name.upper())
        else:
            print('Hello, %s' % self.name)

g = Greeter('Fred')  # 创建一个Greeter类实例 
g.greet()            # 调用实例方法; 打印 "Hello, Fred"
g.greet(loud=True)   # 调用实例方法; 打印 "HELLO, FRED!"
Hello, Fred
HELLO, FRED!

Numpy

Numpy是Python中用于科学计算的核心库。其提供了高性能的多维数组对象,以及相关工具。其用法和MATLAB相似,详情请参考如下网址:(http://wiki.scipy.org/NumPy_for_Matlab_Users)

要使用Numpy,首先要导入numpy包:

import numpy as np

数组(Arrays)

numpy数组是由相同数据类型组成的网格,其可以通过非负整型的元组访问。数组维度数量也被称为数组的秩或阶(rank),数组的形状是一个由整型数构成的元组,描述数组不同维度上的大小。我们可以从python内嵌的列表中创建数组,然后利用方括号访问其中的元素:

a = np.array([1, 2, 3])  # 创建秩为1的数组
print(type(a), a.shape, a[0], a[1], a[2])
a[0] = 5                 # 改变数组元素
print(a)                 
<class 'numpy.ndarray'> (3,) 1 2 3
[5 2 3]
b = np.array([[1,2,3],[4,5,6]])   # 创建秩为2的数组
print(b)
[[1 2 3]
 [4 5 6]]
print(b.shape)   # 查看b的维度                
print(b[0, 0], b[0, 1], b[1, 0])
(2, 3)
1 2 4

Numpy同样提供了大量的方法创建数组:

a = np.zeros((2,2))  # 创建2*2的零矩阵
print(a)
[[0. 0.]
 [0. 0.]]
b = np.ones((1,2))   # 创建各元素值为1的1*2矩阵
print(b)
[[1. 1.]]
c = np.full((2,2), 7,) # 创建各元素值为7的2*2矩阵
print(c) 
[[7 7]
 [7 7]]
d = np.eye(3)        # 创建3*3的单位矩阵
print(d)
[[1. 0. 0.]
 [0. 1. 0.]
 [0. 0. 1.]]
e = np.random.random((3,3)) # 创建3*3的矩阵,使用随机数填充值
print(e)
[[0.9626719  0.66113208 0.71213143]
 [0.04312188 0.54593384 0.61953381]
 [0.03517364 0.11899646 0.29335206]]

数组索引

切片:和Python列表类似,numpy数组可以使用切片语法。因为数组可以是多维的,所以你必须为每个维度指定好切片:

import numpy as np
# 创建秩为2,形状为(3,4)的数组
a = np.array([[1,2,3,4], [5,6,7,8], [9,10,11,12]])
print(a)
#取出第1行,2列开始的,形状为(2,2)的子数组
# [[2 3]
#  [6 7]]
b = a[:2, 1:3]
print(b)
[[ 1  2  3  4]
 [ 5  6  7  8]
 [ 9 10 11 12]]
[[2 3]
 [6 7]]

切取的子数组实际上是原数组的一份浅备份,因此修改子数组,原始数组也将受到修改,例如:

print('原始a:',a[0, 1]  )
b[0, 0] = 77    # b[0, 0] 和a[0, 1]共享同一内存
print('修改b后的a:',a[0, 1] )
原始a: 2
修改b后的a: 77

你也可以混合整数索引以及切片索引访问数组,但是,这会生成一个秩少于原始数组的子数组。注意:这和MATLAB处理的数组切片有些不同。

# 创建形状(3,4)秩为2的numpy数组
a = np.array([[1,2,3,4], [5,6,7,8], [9,10,11,12]])
print(a)
[[ 1  2  3  4]
 [ 5  6  7  8]
 [ 9 10 11 12]]

Numpy有两种数组切片方式:1.混合整数索引和切片,生成低秩子数组;2.仅使用切片,生成原始数组同秩的子数组。

row_r1 = a[1, :]    # 秩为1,数组a的第二行子数组 
row_r2 = a[1:2, :]  # 秩为2,数组a的第二行子数组 
row_r3 = a[[1], :]  # 秩为2,数组a的第二行子数组
print('秩为1:',row_r1, row_r1.shape )
print('秩为2:',row_r2, row_r2.shape)
print('秩为2:',row_r3, row_r3.shape)
秩为1: [5 6 7 8] (4,)
秩为2: [[5 6 7 8]] (1, 4)
秩为2: [[5 6 7 8]] (1, 4)
# 作用在列上同样适用:
col_r1 = a[:, 1] # 秩为1,数组a的第二列子数组
col_r2 = a[:, 1:2] # 秩为2,数组a的第二列子数组
print('秩为1:',col_r1, col_r1.shape)
print('秩为2:')
print(col_r2, col_r2.shape)
秩为1: [ 2  6 10] (3,)
秩为2:
[[ 2]
 [ 6]
 [10]] (3, 1)

整型数组索引:当我们使用切片索引数组时,得到的总是原数组的子数组。整型数组索引允许我们利用其它数组中的数据构建一个新的数组。例如:

a = np.array([[1,2], [3, 4], [5, 6]])

# 整型数组索引示例。
# 返回的数组形状为(3,)
print(a[[0, 1, 2], [0, 1, 0]])

# 上述整型数组索引相等于下列索引:
print(np.array([a[0, 0], a[1, 1], a[2, 0]]))
[1 4 5]
[1 4 5]
#当使用整型数组索引时,你可以重复索引同一个数组元素:
print(a[[0, 0], [1, 1]])

# 上述整型数组索引相等于下列索引:
print(np.array([a[0, 1], a[0, 1]]))
[2 2]
[2 2]

整型数组索引的一个小技巧是从矩阵的每一行中选择或改变元素:

# 创建新数组用于选择元素
a = np.array([[1,2,3], [4,5,6], [7,8,9], [10, 11, 12]])
print(a)
# 创建数组索引。
b = np.array([0, 2, 0, 1])
print('使用数组[0, 2, 0, 1]索引矩阵a中的每一行')
# 使用数组b中的索引选择矩阵a每一行中的特定元素。
print(a[np.arange(4), b])  # 打印 "[ 1  6  7 11]"

#使用数组b中的索引改变矩阵a每一行中的特定元素。
print('使用数组[0, 2, 0, 1]索引矩阵a中的每一行,将其加10')
a[np.arange(4), b] += 10
print(a)
[[ 1  2  3]
 [ 4  5  6]
 [ 7  8  9]
 [10 11 12]]
使用数组[0, 2, 0, 1]索引矩阵a中的每一行
[ 1  6  7 11]
使用数组[0, 2, 0, 1]索引矩阵a中的每一行,将其加10
[[11  2  3]
 [ 4  5 16]
 [17  8  9]
 [10 21 12]]

布尔型数组索引:布尔型索引让你任意挑选数组中的元素,这种类型索引频繁的用于条件语句下的元素选取。例如:

import numpy as np
a = np.array([[1,2], [3, 4], [5, 1]])
print(a)
bool_idx =(a > 2)  
# 寻找大于2的数组元素,返回相同形状的布尔型数组,其每个元素为a > 2的布尔值
print(bool_idx)
[[1 2]
 [3 4]
 [5 1]]
[[False False]
 [ True  True]
 [ True False]]
# 我们可以使用布尔数组索引去构造一个秩为1的数组,其元素与布尔数组的真值相对应。
print(a[bool_idx])

# 我们也可以将上述内容简洁的用一行语句表达:
print(a[a > 2])
[3 4 5]
[3 4 5]

数据类型(Datatypes)

Numpy提供了大量的数据类型去构造数组,Numpy会尝试猜测你创建的数组的数据类型,但构造函数的数组通常也会可选择的显式指明其数据类型。例如:

x = np.array([1, 2])  # 让numpy自己选择数据类型
y = np.array([1.0, 2.0])  # 让numpy自己选择数据类型
z = np.array([1, 2], dtype=np.int64)  # 显式的规定数据类型

print(x.dtype, y.dtype, z.dtype)
int32 float64 int64

详细的数据类型说明,可参考如下网址:(http://docs.scipy.org/doc/numpy/reference/arrays.dtypes.html).

数组数学运算

数组中基本的数学运算操作是按数组元素进行的,并且重载操作以及函数都可以使用:

x = np.array([[1,2],[3,4]], dtype=np.float64)
y = np.array([[5,6],[7,8]], dtype=np.float64)

# 按元素求和;两种方式都可以使用;
print(x + y)
print(np.add(x, y))
[[ 6.  8.]
 [10. 12.]]
[[ 6.  8.]
 [10. 12.]]
# 按元素相减;
print(x - y)
print(np.subtract(x, y))
[[-4. -4.]
 [-4. -4.]]
[[-4. -4.]
 [-4. -4.]]
# 按元素乘;
print(x * y)
print(np.multiply(x, y))
[[ 5. 12.]
 [21. 32.]]
[[ 5. 12.]
 [21. 32.]]
# 按元素除
# [[ 0.2         0.33333333]
#  [ 0.42857143  0.5       ]]
print(x / y)
print(np.divide(x, y))
[[0.2        0.33333333]
 [0.42857143 0.5       ]]
[[0.2        0.33333333]
 [0.42857143 0.5       ]]
# 按元素取平方根;
# [[ 1.          1.41421356]
#  [ 1.73205081  2.        ]]
print(np.sqrt(x))
[[1.         1.41421356]
 [1.73205081 2.        ]]

注意:和MATLAB不同,*在numpy中是按元素乘,而在MATLAB中是矩阵乘。在numpy中我们使用dot函数计算向量内积(点积),矩阵乘矩阵,以及矩阵乘向量等操作。dot可以当作函数在numpy中使用,也可作为数组对象的实例方法:

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))
219
219
# 矩阵 / 向量乘积; 都将生成秩为1的数组[29 67]。
print(x.dot(v))
print(np.dot(x, v))
[29 67]
[29 67]
# 矩阵 / 矩阵乘积;都将生成秩为2的数组
# [[19 22]
#  [43 50]]
print(x.dot(y))
print(np.dot(x, y))
[[19 22]
 [43 50]]
[[19 22]
 [43 50]]

Numpy还提供了许多有用的数组计算函数;其中最常用的是 sum 函数:

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]"
10
[4 6]
[3 7]

更多numpy的数学函数参见如下网址:(http://docs.scipy.org/doc/numpy/reference/routines.math.html).

除了使用数组进行数学计算,我们还频繁的使用reshape或者其他方法操纵数组数据。例如:要转置一个矩阵,简单的使用数组对象的T属性即可:

print(x)
print(x.T)
[[1 2]
 [3 4]]
[[1 3]
 [2 4]]
v = np.array([[1,2,3]])
print(v) 
print(v.T)
[[1 2 3]]
[[1]
 [2]
 [3]]

广播(Broadcasting)

广播提供了强大的机制允许numpy在不同形状的数组中执行数学操作。我们经常会遇到小数组和大数组相乘的情况,比如图片数据矩阵与权重矩阵。使用广播机制将提高你的代码质量以及运算效率。

例如,假设我们想在矩阵的每一行中都加上一个常数向量。我们可以这样做:

# 矩阵x的每一行加上向量v,将结果储存在矩阵y中。
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形状相同的空矩阵。

# 使用显式循环完成上述操作。
for i in range(4):
    y[i, :] = x[i, :] + v

print(y)
[[ 2  2  4]
 [ 5  5  7]
 [ 8  8 10]
 [11 11 13]]

这样做是有效的,但当矩阵x特别大时,在Python中计算显式循环就将变得非常缓慢。其实将向量v加到矩阵x的每一行相当于将向量v拷贝多次垂直堆叠成矩阵vv,然后对矩阵x与矩阵vv进行按元素求和。我们也可以这样实现该方法:

vv = np.tile(v,(4, 1))  # 拷贝4次向量v,然后将其堆叠起来。
print(vv)                 # 打印   "[[1 0 1]
                         #          [1 0 1]
                         #          [1 0 1]
                         #          [1 0 1]]"
[[1 0 1]
 [1 0 1]
 [1 0 1]
 [1 0 1]]
y = x + vv  # 矩阵x和矩阵vv按元素相加
print(y)
[[ 2  2  4]
 [ 5  5  7]
 [ 8  8 10]
 [11 11 13]]

Numpy广播机制允许我们不创建多次向量v备份的情况下执行该计算:

import numpy as np

# 矩阵x的每一行加上向量v,将结果储存在矩阵y中。
x = np.array([[1,2,3], [4,5,6], [7,8,9], [10, 11, 12]])
v = np.array([1, 0, 1])
y = x + v  # 使用广播将v加到矩阵的每一行上。
print(y)
[[ 2  2  4]
 [ 5  5  7]
 [ 8  8 10]
 [11 11 13]]

由于广播机制的原因,即使x的形状为(4, 3)v 的形状为(3,),表达式y = x + v依然可以执行;这就好像将v拷贝重塑为(4, 3)的矩阵,然后进行按元素相加。
对两个数组使用广播机制要遵守下列规则:

  1. 如果数组的秩不同,将秩较小的数组进行扩展,直到两个数组的尺寸长度都一样。
  2. 如果两个数组在某个维度上的长度是一样的,或者其中一个数组在该维度上长度为1,那么我们就说这两个数组在该维度上是相容的。
  3. 如果两个数组在所有维度上都是相容的,他们就能使用广播。
  4. 广播之后,两个数组的尺寸将和较大的数组尺寸一样。
  5. 在任何一个维度上,如果一个数组的长度为1,另一个数组长度大于1,那么在该维度上,就好像是对第一个数组进行了复制。

如果感觉没有解释清楚,详细文档请参考以下网址:(http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html) 或者更具体的解释(http://wiki.scipy.org/EricsBroadcastingDoc).

支持广播机制的函数也被称为通用函数(universal functions)。你可以更具以下网址查看所有的通用函数(http://docs.scipy.org/doc/numpy/reference/ufuncs.html#available-ufuncs).

以下是广播一些应用:

#计算向量外积 
v = np.array([1,2,3])  # v 形状(3,)
w = np.array([4,5])    # w 形状(2,)
# 要计算外积,我们首先要重塑v为一列(3, 1),
# 然后将其与w(2,)相乘,输出一个形状为(3,2)的矩阵,其就是v与w的外积。
print(np.reshape(v,(3, 1)) * w)
[[ 4  5]
 [ 8 10]
 [12 15]]
# 将向量加到矩阵中的每一行
x = np.array([[1,2,3], [4,5,6]])
# x 形状(2, 3) ,v 形状(3,) ,广播之后的形状(2, 3),
print(x + v)
[[2 4 6]
 [5 7 9]]
# 将向量加到矩阵的每一列
# x 形状(2, 3),w 形状(2,).如果我们将x进行转置,那其形状就被重塑为(3, 2),
# 然后将其与w进行广播,就可以生成形状为(3,2)的矩阵;
# 我们最后再将结果进行转置,就可以得到形状为(2,3)的矩阵;
# 其结果就是将向量w加到矩阵x的每一列
print((x.T + w).T)
[[ 5  6  7]
 [ 9 10 11]]
#另一种更简单的方法是将w重塑为形状为(2,1)的行向量;
#然后直接与x进行广播就可产生相同的结果
#注意(2,)表示的是秩为1的向量,(2,1)表示的是秩为2的矩阵
print(x + np.reshape(w,(2, 1)))
[[ 5  6  7]
 [ 9 10 11]]
# 矩阵各元素乘以一个常数:
# x 形状(2, 3). Numpy 将标量作为数组();
print(x * 2)
[[ 2  4  6]
 [ 8 10 12]]

广播使你的代码简洁而高效,因此你应该尽可能的使用广播操作。

以上仅仅是一些numpy的重要用法,但其功能远不止这些。详细的文档请参考如下网址:(http://docs.scipy.org/doc/numpy/reference/)

Matplotlib

Matplotlib是一个绘图工具库。下面我们简短的介绍下matplotlib.pyplot 模块,其用法和MATLAB相似。

import matplotlib.pyplot as plt
#使用以下IPython命令行,可以使得绘图结果嵌入到notebook中
%matplotlib inline

绘制(Plotting)

matplotlib最重要的函数就是绘制函数plot,其允许你绘制2D数据。例如:

# 使用sin三角函数计算x与y的坐标点
x = np.arange(0, 3 * np.pi, 0.1)
y = np.sin(x)
# 使用matplotlib绘制坐标点
plt.plot(x, y)
[<matplotlib.lines.Line2D at 0x20d10089b00>]

?
png
?

添加标题,说明,坐标轴标记到图表中:

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'])
<matplotlib.legend.Legend at 0x20d13595978>

?
png
?

子图(Subplots)

你可以使用subplot函数在一副图中绘制不同的子图。例如:

# 使用sin以及cos函数计算x与y的坐标点
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')
# 设置使用第二张子图,并绘制。
plt.subplot(2, 1, 2)
plt.plot(x, y_cos)
plt.title('Cosine')
# 显示图表.
plt.show()

?
png
?

更多内容你可以参考如下网址:(http://matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.subplot).

import numpy as np
from scipy.misc import imresize
from imageio import imread
import matplotlib.pyplot as plt

img = imread('kitten.jpg')
img_tinted = img * [1, 0.95, 0.6]

# 显示原始图片
plt.subplot(1, 2, 1)
plt.imshow(img)

# 显示着色后的图片
plt.subplot(1, 2, 2)

plt.imshow(np.uint8(img_tinted))
plt.show()

png

  人工智能 最新文章
2022吴恩达机器学习课程——第二课(神经网
第十五章 规则学习
FixMatch: Simplifying Semi-Supervised Le
数据挖掘Java——Kmeans算法的实现
大脑皮层的分割方法
【翻译】GPT-3是如何工作的
论文笔记:TEACHTEXT: CrossModal Generaliz
python从零学(六)
详解Python 3.x 导入(import)
【答读者问27】backtrader不支持最新版本的
上一篇文章      下一篇文章      查看所有文章
加:2021-10-23 12:29:25  更:2021-10-23 12:33:41 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/27 8:27:18-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码