《鱼书》笔记

kkyljr 发布于 6 天前 21 次阅读


《鱼书》笔记

1. python基础

1.1 Numpy

Np的广播:


>>> x = np.array([1.0, 2.0, 3.0])
>>> x / 2.0
array([ 0.5,  1. ,  1.5])

多维数组:


>>> A = np.array([[1, 2], [3, 4]])
>>> print(A)
[[1 2]
[3 4]]
>>> A.shape  #多维数组每项长度一样否则报错
(2, 2)
>>> A.dtype  #矩阵元素的数据类型
dtype('int64')

>>> B = np.array([[3, 0],[0, 6]])
>>> A + B
array([[ 4,  2],
      [ 3, 10]])
>>> A * B # *号为直接数组对应元素乘积
array([[ 3,  0],
      [ 0, 24]])

访问操作:

>>> 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])

矩阵乘积(点乘):

>>> A = np.array([[1,2], [3,4]])
>>> A.shape
(2, 2)
>>> B = np.array([[5,6], [7,8]])
>>> B.shape
(2, 2)
>>> np.dot(A, B)
array([[19, 22],
      [43, 50]])

1.2 Matplotlib

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()
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() #图例显示, 收集plot()中的label
plt.show()

显示图像:

import matplotlib.pyplot as plt
from matplotlib.image import imread
img = imread('lena.png') # 读入图像(设定合适的路径!)
plt.imshow(img)
plt.show()

2. 感知机

2.1 什么是感知机

感知机算法是美国学者Frank Rosenblatt在1957年提出来的, 是神经网络的起源算法.

感知机接收多个输入信号, 输出一个信号. 在感知机中, 输出信号只有 0/1 两种取值. 为方便理解, 0对应"不传递信号", 1对应"传递信号".

其中x1, x2为输入信号, w1, w2为权重. 图中圆圈称为"神经元"或者"节点". 输入信号被送往神经元时, 会分别乘以固定的权重. 这些信号的总和超过阈值 θ 时, 才会输出1, 称之为"神经元被激活". 即:

令θ = -b, 则有

把b成为偏置, 把w1, w2称为权重

w1, w2为控制输入信号重要性的参数, 偏置是调整神经元被激活的容易程度的参数.

2.2 感知机的局限性

用上文中的感知机模型无法实现异或门, (w1, w2 + b> 0, 与w1 + w2 + b< 0矛盾)

2.2.1 线性与非线性

2.3 多层感知机 (异或门实现)

感知机的叠加, 使得感知机能够实现更多的功能, 如下图:

3.神经网络

神经网络的出线, 可以自动地从数据中学习到合适的权重参数.

3.1 神经网络的结构

输入层 ---- 隐藏层(中间层) ---- 输出层

3.2 激活函数

激活函数: 将输入信号总和转化为输出信号的函数. 即下图中h(x):

3.2.1 阶跃函数

前文中的激活函数称为阶跃函数, 一旦输入超过阈值, 就切换输出.

3.2.2 sigmoid函数

激活函数必须使用非线性函数, 因为如果使用线性函数的话, 那么叠加层就没有意义了

3.2.3 ReLU(Rectified Linear Unit)函数

ReLU函数, 输入大于0, 直接输出该值; 输入小于等于0时, 输出0.

3.3 3层神经网络的实现

第一层的加权和可以表示为:

上述操作计算出了加权信号与偏置之和, 然后还要通过之前学习的激活函数转换为输出信号.

代码实现如下:

def step_function(x):
   return np.array(x > 0, dtype=int)

def sigmoid(x):
   return 1 / (1 + np.exp(-x))

def relu(x):
   return np.maximum(0, x)

def identity_function(x):   #恒等函数
   return x


def init_network():     #三层神经网络
       network = {}
       network['W1'] = np.array([[0.1,0.3,0.5], [0.2, 0.4, 0.6]])
       network['b1'] = np.array([0.1, 0.2, 0.3])
       network['W2'] = np.array([[0.1,0.4], [0.2, 0.5], [0.3, 0.6]])
       network['b2'] = np.array([0.1, 0.2])
       network['W3'] = np.array([[0.1,0.3], [0.2, 0.4]])
       network['b3'] = np.array([0.1, 0.2])

       return network

def forward(network, x):
   W1, W2, W3 = network['W1'], network['W2'], network['W3']
   b1, b2, b3 = network['b1'], network['b2'], network['b3']

   a1 = np.dot(x, W1) + b1
   z1 = sigmoid(a1)
   a2 = np.dot(z1, W2) + b2
   z2 = sigmoid(a2)
   a3 = np.dot(z2, W3) + b3
   y = identity_function(a3)
   return y

network = init_network()
x = np.array([1.0, 0.5])
y = forward(network, x)
print(y)

3.4 输出层设计

一般来说, 回归问题用恒等函数, 分类问题用softmax函数

3.4.1 softmax函数

由于在计算机中, exp容易溢出, 所以需要对softmax函数进行改进

可以观察到, yk的和为1, 我们可以把softmax的输出解释为概率, 所以一般用于分类模型中, 一般而言, 神经网络只把输出值最大的神经元对应的类别作为识别结果. 且exp为递增函数, 故在进行推理阶段时, softmax函数可以省略.

3.5 MNIST数字识别