python一些入门

Numpy

导入:import numpy as np,将numpy作为np导入

生成Numpy数组(numpy.ndarray):使用np.array(ython)方法。np.array()以列表为参数。它和一维数组是不同的

>>>x = np.array([1.0,2.0,3.0])
>>>print(x)
[ 1. 2. 3.]
>>> type(x)
<class 'numpy.ndarray'>

Numpy数组的算术运算:对应位置的运算,数组元素个数要相同。

Numpy生成二维数组:

>>> A = np.array([[1, 2], [3, 4]])
>>> print(A)
[[1 2]
[3 4]]
>>> A.shape # 查看矩阵A的形状
(2, 2)
>>> A.dtype # 查看矩阵元素的类型
dtype('int64')

数学上将一维数组称为向量,将二维数组称为矩阵。可以将一般化之后的向量或矩阵等统称为张量(tensor)。本书基本上将二维数组称为“矩阵”,将三维数组及三维以上的数组称为“张量”或“多维数组”。

NumPy 有广播功能,所以不同形状的数组之间也可以顺利地进行运算。

>>> A = np.array([[1, 2], [3, 4]])
>>> B = np.array([10, 20])
>>> A * B
array([[ 10, 40],
[ 30, 80]])

flatten()函数,可以将Numpy数组转化为一维数组

>>> X = np.array([[51, 55], [14, 19], [0, 4]])
>>> X = X.flatten() # 将 X 转换为一维数组
>>> print(X)
[51 55 14 19 0 4]
>>> X[np.array([0, 2, 4])] # 获取索引为 0、2、4 的元素
array([51, 14, 0])

运用这个标记法,可以获取满足一定条件的元素。例如,要从 X 中抽出大于 15 的元素,可以写成如下形式:

>>> X > 15
array([ True, True, False, True, False, False], dtype=bool)
>>> X[X>15]
array([51, 55, 19])

对 NumPy 数组使用不等号运算符等(上例中是 X > 15), 结果会得到一个布尔型的数组。上例中就是使用这个布尔型数组取出了数组的各个元素(取出 True 对应的元素)。

Matplotlib

用于绘制图形和实现数据的可视化。可以使用 matplotlib 的 pyplot 模块绘制图形。

例如:

import numpy as np
import matplotlib.pyplot as plt
# 生成数据
x = np.arange(0, 6, 0.1) # 以 0.1 为单位,生成 0 到 6 的数据
y = np.sin(x)
# 绘制图形
plt.plot(x, y)
plt.show()

这里使用 NumPy 的 arange 方法生成了 [0, 0.1, 0.2, …, 5.8, 5.9]的数据,将其设为 x。对 x 的各个元素,应用 NumPy 的 sin 函数 np.sin(),将 x、y 的数据传给 plt.plot 方法,然后绘制图形。最后,通过 plt.show() 显示图形。显示结果如下

Figure_1

pyplot的功能:

在刚才的 sin 函数的图形中,我们尝试追加 cos 函数的图形,并尝试使用
pyplot 的添加标题和 x 轴标签名等其他功能。

import numpy as np
import matplotlib.pyplot as plt
# 生成数据
x = np.arange(0, 6, 0.1) # 以 0.1 为单位,生成 0 到 6 的数据
y1 = np.sin(x)
y2 = np.cos(x)
# 绘制图形
plt.plot(x, y1, label="sin")
plt.plot(x, y2, linestyle = "--", label="cos") # 用虚线绘制
plt.xlabel("x") # x 轴标签
plt.ylabel("y") # y 轴标签
plt.title('sin & cos') # 标题
plt.legend() # 图例
plt.show() #显示

结果如下:

Figure_2

显示图像:

pyplot中还提供了用于显示图像的方法imshow(),另外可以使用matplotlib.image模块的imread()方法读入图像。

import matplotlib.pyplot as plt
from matplotlib.image import imread

img = imread('./img/dog.jpg') # 读入图像(设定合适的路径!)
plt.imshow(img)
plt.show()

结果如下:Figure_3

感知机

感知机是什么?

感知机接收多个输入信号,输出一个信号

像电流流过导线,向前方输送电子一样,感知机的信号也会形成流,向前方输送信息

感知机的信号只有“流/不流”(1/0)两种取值。在本书中,0对应“不传递信号”,1对应“传递信号”。Figure_4

感知机运行原理的数学公式

上图是一个接收两个输入信号的感知机的例子。x1、x2是输入信号y是输出信号w1、w2是权重(w是weight的首字母)。图中的⚪称为“神经元”或者“节点”。输入信号被送往神经元时,会被分别乘以固定的权重(w1x1、w2x2)。神经元会计算传送过来的信号的总和,只有当这个总和超过了某个界限值时,才会输出1。这也称为“神经元被激活”。这里将这个界限值称为阈值,用符号θ表示。感知机的多个输入信号都有各自固有的权重,这些权重发挥着控制各个信号的重要性的作用。也就是说,权重越大,对应该权重的信号的重要性就越高。

简单逻辑电路

机器学习的课题就是将这个决定参数值的工作交由计算机自动进行。学习是确定合适的参数的过程,而人要做的是思考感知机的构造模型,并把训练数据交给计算机。

与门

与门仅在两个输入均为1时输出1,其他时候输出0。

例如,当 (w1, w2, θ) = (0.5, 0.5, 0.7) 时,可以满足感知机的条件,设定这样的参数后,仅当x1和x2同时为1时,信号的加权总和才会超过给定的阈值θ。

与非门和或门

与非门

与非门仅当x1和x2同时为1时输出0,其他时候则输出1。要表示与非门,可以用(w1, w2, θ) = (−0.5, −0.5, −0.7)这样的组合,实际上,只要把实现与门的参数值的符号取反,就可以实现与非门。

或门

或门是“只要有一个输入信号是1,输出就为1”的逻辑电路。

与门、与非门、或门的感知机构造是一样的。实际上,3个门电路只有参数的值(权重和阈值)不同。也就是说,相同构造的感知机,只需通过适当地调整参数的值,就可以像“变色龙演员”表演不同的角色一样,变身为与门、与非门、或门。

感知机实现

导入权重和偏置

首先把上式的θ换成−b,于 是就可以用下式来表示感知机的行为,我们将感知机运行原理以下图重新描绘:

感知机运行数学原理

两式虽然有一个符号不同,但表达内容相同。此处,b称为偏置w1和w2称为权重

感知机会计算输入信号和权重的乘积,然后加上偏置,如果这个值大于0则输出1否则输出0

实现感知机:

>>> import numpy as np
>>> x = np.array([0, 1]) # 输入
>>> w = np.array([0.5, 0.5]) # 权重
>>> b = -0.7 # 偏置
>>> w*x
array([ 0. , 0.5])
>>> np.sum(w*x)
0.5
>>> np.sum(w*x) + b
-0.19999999999999996 # 大约为-0.2(由浮点小数造成的运算误差)

在NumPy数组的乘法运算中,当两个数组的元素个数相同时,各个元素分别相乘,因此wx的结果就是它们的各个元素分别相乘([0, 1] * [0.5, 0.5] => [0, 0.5])。之后,np.sum(wx)再计算相乘后的各个元素的总和。最后再把偏置加到这个加权总和上。

使用权重和偏置的实现

实现与门如下:

def AND(x1, x2):
x = np.array([x1, x2])
w = np.array([0.5, 0.5])
b = -0.7
tmp = np.sum(w*x) + b
if tmp <= 0:
return 0
else:
return 1

把−θ命名为偏置b,但是偏置和权重w1、w2的作用是不 一样的。具体地说,w1和w2是控制输入信号的重要性的参数,而偏置是调整神经元被激活的容易程度(输出信号为1的程度)的参数。

若b为 −0.1,则只要输入信号的加权总和超过0.1,神经元就会被激活。但是如果b为−20.0,则输入信号的加权总和必须超过20.0,神经元才会被激活。

感知机的局限性

异或门

仅当x1或x2中的一方为 1时,才会输出1。用感知机是无法实现这个异或门的

线性与非线性

感知机的局限性就在于它只能表示由一条直线分割的空间,弯曲的曲线无法用感知机表示。由曲线分割而成的空间称为非线性空间,由直线分割而成的空间称为线性空间

多层感知机

感知机的绝妙之处在于它可以“叠加层”(通过叠加层来表示异或门是本节的要点)。

已有门电路的组合

严格地讲,应该是“单层感知机无法表示异或门”或者“单层感知机无法分离非线性空间”。

异或门是一种多层结构的神经网络。

神经网络

神经网络的一个重要性质是它可以自动地从数据中学习到合适的权重参数。

从感知机到神经网络

神经网络的例子

神经网络例子

把最左边的一列称为输入层,最右边的一列称为输出层,中间的一列称为中间层。中间层有时也称为隐藏层,“隐藏”一词的意思是,隐藏层的神经元(和输入层、输出层不同)肉眼看不见。本书中把输入层到输出层依次称为第0层、第1层、第2层,第0层对应输入层,第1层对应中间层,第2层对应输出层。

激活函数

一个函数将输入信号的综合转换为输出信号,这种函数一般称作激活函数。如激活一词所示,激活函数的作用在于决定如何来激活输入信号的总和。

“多层感知机”是指神经网络,即使用 sigmoid 函数等平滑的激活函数的多层网络。

激活函数

前面的h(x)表示的激活函数以阈值为界,一旦输入超过阈值,就切换输出,这样的函数称为“阶跃函数”。因此,可以说感知机中使用了阶跃函数作为激活函数。

如果将激活函数从阶跃函数换成其他函数,就可以进入神经网络的世界了。

sigmoid函数

sigmoid函数

神经网络中用sigmoid函数作为激活函数,进行信号的转换,转换后的信号被传送给下一个神经元。

感知机和神经网络的主要区别就在于这个激活函数。

机器学习的问题大致可以分为分类问题和回归问题,一般而言,回归预测问题用恒等函数,多元分类问题用softmax函数,二元分类问题使用sigmoid函数。