深度学习入门:《鱼书》笔记 U2-3

第二章 感知机

感知机:神经网络初步

学习是确定合适的参数的过程。

相同构造的感知机,仅需调整参数的值,就可以实现与非门和或非门。

w1、w2:控制输入信号的重要性的参数

b:调整神经元被激活的容易程度

为什么叫激活呢?因为感知机可以看成一个求和函数,当输入的加权和超过某一阈值时,阶跃函数才能有输出。

但是,感知机无法实现异或门。

局限性:单层感知机只能表示由一条直线分割的空间。

多层感知机

多层感知机可以表示非线性空间,可以实现异或门。

2层感知机(严格地说是激活函数使用了非线性的sigmod函数的感知机)可以表示任意函数

(不过设计两层感知机的权重是一件很累的事,一般都是通过设计门控电路组成逻辑单元,再组成CPU)

总结

单层感知机只能表示线性空间,多层感知机可以表示非线性空间。

第三章 神经网络

自动学习感知机中的参数,就是神经网络。

神经元=节点

激活函数:连接感知机和神经网络的桥梁

激活函数决定如何来激活输入信号的总和。

就是把感知机中的阶跃函数换成其他的非线性函数。

阶跃函数的实现

def step_fuction(x):
	y = x>0
	return y.astype(np.int)

上面这个函数可以输入NumPy数组。y是一个布尔值,然后用astype()转换数组类型为int

>>> import numpy as np
>>> x = np.array([-1.0, 1.0, 2.0])
>>> x
array([-1.,  1.,  2.])
>>> y = x>0
>>> y
array([False,  True,  True])

sigmod函数的实现

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

x为NumPy数组时也能用(广播功能)。

另:def回车之后还要输入tab才可以

>>> import numpy as np
>>> t = np.array([1.0, 2.0, 3.0])
>>> 1.0 + t
array([2., 3., 4.])
>>> 1.0/t
array([1.        , 0.5       , 0.33333333])

注意,第一步运算之后并没有给t重新赋值,所以第二步1/t,t还是原来那个数组。

画图:

>>> import matplotlib.pylab as plt
>>> x = np.arange(-5.0, 5.0, 0.1)
>>> y = sigmod(x)
>>> plt.plot(x,y)
[<matplotlib.lines.Line2D object at 0x00000228C1379340>]
>>> plt.ylim(-0.1,1.1)
(-0.1, 1.1)
>>> plt.show()

当输入信号为重要信息时,阶跃函数和sigmod函数都会输出较大的值;输入信号为不重要的信息时,两者都输出较小的值

ReLU函数的实现

relu:
h(x)={xif x>00if x≤0 h(x) = \begin{cases} x & \text{if } x > 0 \\ 0 & \text{if } x \leq 0 \end{cases} h(x)={x0if x>0if x0

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

多维数组

多维数组

>>> import numpy as np
>>> A = np.array([1,2,3,4])
>>> np.ndim(A) #数组维数
1
>>> A.shape #数组形状(返回一个元组tuple)
(4,)
>>> A.shape[0] 
4 

>>> B = np.array([[1,2],[3,4],[5,6]]) #注意中括号数量
>>> np.ndim(B)
2
>>> B.shape
(3, 2) #3*2数组,第一个维度有三个元素,第二个维度有两个元素。(第一个维度是0维,第二个是1维)

缩进:[1,2]里不能有缩进,外面可以

矩阵乘法

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

注意:np.dot(A, B)$ \neq \$np.dot(B,A)

请添加图片描述

请添加图片描述

神经网络的实现

请添加图片描述

>>> X = np.array([1, 2])
>>> W = np.array([[1,3,5],[2,4,6]])
>>> Y = np.dot(X,W)
>>> print(Y)
[ 5 11 17]

请添加图片描述

第一层

请添加图片描述

X = np.array([1.0, 0.5]) 
W1 = np.array([[0.1, 0.3, 0.5], [0.2, 0.4, 0.6]]) 
B1 = np.array([0.1, 0.2, 0.3]) 

A1 = np.dot(X, W1) + B1

Z1 = sigmoid(A1)

请添加图片描述

第二层

W2 = np.array([[0.1, 0.4], [0.2, 0.5], [0.3, 0.6]]) 
B2 = np.array([0.1, 0.2])  

A2 = np.dot(Z1, W2) + B2 

Z2 = sigmoid(A2)

第三层

def identity_function(x): 
	return x  
	
W3 = np.array([[0.1, 0.3], [0.2, 0.4]]) 
B3 = np.array([0.1, 0.2])  
A3 = np.dot(Z2, W3) + B3 
Y = identity_function(A3) # 或者 Y = A3,输出层的激活函数。这个函数没必要设,只是为了和前面的流程保持统一

输出层的激活函数用 σ() 表示,隐 藏层的激活函数 h()

σ() 要根据求解问题的性质决定。

总结

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) # [ 0.31682708 0.69627909]

输出层处理

一般而言,回归问题用恒等函数,分类问题用 softmax 函数。

恒等函数

请添加图片描述

softmax 函数

分类问题中,用于输出层的激活函数(输出是“概率”,数值在0-1之间)

yk=exp⁡(ak)∑i=1nexp⁡(ai) y_k = \frac{\exp(a_k)}{\sum_{i=1}^{n} \exp(a_i)} yk=i=1nexp(ai)exp(ak)

输出层共有 n 个神经元,计算第 k 个神经元的输出 yk

请添加图片描述

>>> a = np.array([0.3, 2.9, 4.0]) 
>>> exp_a = np.exp(a) # 指数函数 [ 1.34985881 18.17414537 54.59815003]
>>> sum_exp_a = np.sum(exp_a) # 指数函数的和  74.1221542102
>>> y = exp_a / sum_exp_a 
>>> print(y)  #[ 0.01821127 0.24519181 0.73659691]

def softmax(a): 
    exp_a = np.exp(a) 
    sum_exp_a = np.sum(exp_a) 
    y = exp_a / sum_exp_a 

    return y

softmax 函数溢出问题

指数就会容易数据过大而导致溢出。

这里的 C’可以使用任何值,但是为了防止溢出,一般会使用输入信号中的最大值。
yk=exp⁡(ak)∑i=1nexp⁡(ai)=Cexp⁡(ak)C∑i=1nexp⁡(ai)=exp⁡(ak+log⁡C)∑i=1nexp⁡(ai+log⁡C)=exp⁡(ak+C′)∑i=1nexp⁡(ai+C′) \begin{align*} y_k &= \frac{\exp(a_k)}{\sum_{i=1}^{n} \exp(a_i)} = \frac{C \exp(a_k)}{C \sum_{i=1}^{n} \exp(a_i)} \\ &= \frac{\exp(a_k + \log C)}{\sum_{i=1}^{n} \exp(a_i + \log C)} \\ &= \frac{\exp(a_k + C')}{\sum_{i=1}^{n} \exp(a_i + C')} \end{align*} yk=i=1nexp(ai)exp(ak)=Ci=1nexp(ai)Cexp(ak)=i=1nexp(ai+logC)exp(ak+logC)=i=1nexp(ai+C)exp(ak+C)

>>> a = np.array([1010, 1000, 990]) 
>>> np.exp(a) / np.sum(np.exp(a)) # softmax 函数的运算 
array([ nan, nan, nan]) # 没有被正确计算 

>>> c = np.max(a) # 1010 
>>> a - c array([ 0, -10, -20]) 

>>> np.exp(a - c) / np.sum(np.exp(a - c))  
array([ 9.99954600e-01, 4.53978686e-05, 2.06106005e-09])

softmax 函数特征

softmax 函数的输出是 0.0 到 1.0 之间的实数。并且,softmax 函数的输出值的总和是 1

正 因为有了这个性质,我们才可以把 softmax 函数的输出解释为“概率”

最终的输出y可以解释成

y[0] 的概率是 0.018(1.8 %),y[1] 的概率 是 0.245(24.5 %),y[2] 的概率是 0.737(73.7 %)。

从概率的结果来看,可以 说“因为第 2 个元素的概率最高,所以答案是第 2 个类别”

不过,实际上, a 的各元素的大小关系和 y 的各元素的大小关系并没有改变。所以在实际的问题中的推理阶段, 输出层的 softmax 函数 一般会被省略。

请添加图片描述

手写数字识别——推理

数据集:MNIST 手写数字图像集

图像数据:28 像素 × 28 像素的灰度图像,取值0-255,每个都有标签

正规化:在提高学习性能方面很有效

batch :图像打包一起输入的方式,就如同纸币一样扎成一捆。批处理一次性计算大型数组要比分开逐步计算 各个小型数组速度更快

x, t = get_data() network = init_network()  
batch_size = 100 # 批数量 
accuracy_cnt = 0  

for i in range(0, len(x), batch_size): 
    x_batch = x[i:i+batch_size] 
    y_batch = predict(network, x_batch) 
    p = np.argmax(y_batch, axis=1) 
    accuracy_cnt += np.sum(p == t[i:i+batch_size])  

print("Accuracy:" + str(float(accuracy_cnt) / len(x)))

range(start, end, step) 这样指定 3 个整数,则生成的列表中的 下一个元素会增加 step 指定的值。

>>> list( range(0, 10, 3) ) 
[0, 3, 6, 9]

tch_size):
x_batch = x[i:i+batch_size]
y_batch = predict(network, x_batch)
p = np.argmax(y_batch, axis=1)
accuracy_cnt += np.sum(p == t[i:i+batch_size])

print(“Accuracy:” + str(float(accuracy_cnt) / len(x)))


range(start, end, step) 这样指定 3 个整数,则生成的列表中的  下一个元素会增加 step 指定的值。

list( range(0, 10, 3) )
[0, 3, 6, 9]
``

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值