深度学习入门笔记


该篇文章为本人学习笔记的一部分。笔记基于《深度学习入门 基于python理论实践》这本书学习,尽可能简单的分享吧。

感知机

接收多个信号,输出一个信号。
感知机示意图
x1,x2是输入信号,w1,w2是权重,y是输出信号。信号送往神经元时,都会乘以相对应的权重(x1w1, x2w2)。神经元计算传来的信号总和,当总和超过一定阈值则输出1,否则输出0。
y = { 0 , ( w 1 x 1 + w 2 x 2 ≤ θ ) 1 , ( w 1 x 1 + w 2 x 2 > θ ) y = \begin{cases} 0, & {(w_1x_1 + w_2x_2 \leq \theta)}\\\\ 1, & {(w_1x_1 + w_2x_2 \gt \theta)} \end{cases} y= 0,1,(w1x1+w2x2θ)(w1x1+w2x2>θ)

逻辑与门

通过感知机来表示 逻辑与门。也就是说需要找到(w1,w2,θ) 相应的权重和偏置,满足条件。如:(0.5,0.5,0.7)满足条件,即 (0.5 * x1 + 0.5 * x2 <= 0.7 时为0, > 0.7时为1)当然(0.5,0.5,0.8)也可以。

import numpy as np
def AND(x1,x2):
    w = np.array([0.5,0.5,-0.7])
    x = np.array([x1,x2,1])
    temp = np.sum(w*x)
    if temp <= 0:
        return 0
    else:
        return 1

与非门

和与门相反

import numpy as np
def NAND(x1,x2):
    w = np.array([-0.5,-0.5,0.7])
    x = np.array([x1,x2,1])
    temp = np.sum(w*x)
    if temp <= 0:
        return 0
    else:
        return 1

或门

import numpy as np
#或门
def OR(x1,x2):
    w = np.array([1.0,1.0,-0.5])
    x = np.array([x1,x2,1])
    temp = np.sum(w*x)
    if temp <= 0:
        return 0
    else:
        return 1

或门
将x1,x2,作为横竖坐标,并将(0,0),(1,0),(0,1),(1,1)点画到坐标中,每个点Y如果是0,画○,如果是1,画×. 不难得出权重。

多层感知机

异或门

那么异或门如何表示。
仅当x1,x2当中的一方为1时才会输出1。
在这里插入图片描述
可以通过或门,与非门加上与门去完成。

def XOR(x1,x2):
    s1 = NAND(x1,x2)
    s2 = OR(x1,x2)
    y = AND(s1,s2)
    return y

在这里插入图片描述

神经网络

神经网络和感知机相似,最大区别就在于激活函数。
在这里插入图片描述

激活函数

常见激活函数有Sigmoid,ReLu,LeakyRelu等等。
感知机函数形式
h ( x ) = { 0 , ( w 1 x 1 + w 2 x 2 ≤ θ ) 1 , ( w 1 x 1 + w 2 x 2 > θ ) h(x) = \begin {cases} 0, &{(w_1x_1 + w_2x_2 \leq \theta)} \\\\ 1, &{(w_1x_1 + w_2x_2 \gt \theta)} \end {cases} h(x)= 0,1,(w1x1+w2x2θ)(w1x1+w2x2>θ)
变形
h ( x ) = { 0 , ( w 1 x 1 + w 2 x 2 + b ≤ 0 ) 1 , ( w 1 x 1 + w 2 x 2 + b > 0 ) h(x) = \begin {cases} 0, &{(w_1x_1 + w_2x_2 + b \leq 0)} \\\\ 1, &{(w_1x_1 + w_2x_2 + b \gt 0)} \end {cases} h(x)= 0,1,(w1x1+w2x2+b0)(w1x1+w2x2+b>0)
激活函数就是前面的感知机的简化变形
h ( x ) = { 0 , ( x ≤ 0 ) 1 , ( x > 0 ) h(x) = \begin {cases} 0, &{(x \leq 0)} \\\\ 1, &{(x\gt0)} \end {cases} h(x)= 0,1,(x0)(x>0)
此处h(x)就是激活函数。
sigmoid
h ( x ) = 1 1 + e ( − x ) h(x) = \frac {1}{1 + e^{(-x)}} h(x)=1+e(x)1
阶跃函数
就是一个阈值,超过就是1,没超过就是0
ReLu
h ( x ) = { x , ( x > 0 ) 0 , ( x ≤ 0 ) h(x) = \begin {cases}x, &{(x \gt 0)}\\\\ 0, &{(x \leq 0)} \end{cases} h(x)= x,0,(x>0)(x0)
在这里插入图片描述
为什么要有激活函数:激活函数都是非线性的,如果是线性函数,h(x) = c * x,叠加三层就成了c * c * c * x 相当于 a * x将毫无意义。

输出层设计

神经网络可分为两类问题:分类问题,回归问题
分类问题:属于哪一类
回归问题:预测数值
恒等函数:数值原样输出,用于回归问题。
Softmax函数:用于分类问题
y k = e a k ∑ i = 1 n e ( a i ) y_k = \frac {e^{a_k}}{\sum_{i=1}^{n}e^{(a_i)}} yk=i=1ne(ai)eak
softmax可以让输出的值总和为1,可以理解为softmax的输出解释为“概率”

输出神经元数量: 按照类别数量设定。

损失函数

表示神经网络性能的“恶劣程度”的指标,当前神经网络对监督数据在大多程度上不拟合,大多程度不一致。

均方误差 MSE

E = 1 2 ∑ k ( y k − t k ) 2 E = \frac {1}{2} \sum_k (y_k - t_k)^2 E=21k(yktk)2
yk : 神经网络的输出

tk : 监督数据

k : 数据维数

交叉熵误差

E = − ∑ k t k l o g ( y k ) E = -\sum_k t_klog(y_k) E=ktklog(yk)
小例子,MNIST手写数据集训练图像识别,MNIST数据集6w训练样本,1w测试样本,每张图28 x 28像素。标签为one_hot_label (一个大小为10的数组,图像的数字对应数组位置上的元素为1,其余为0)。训练中采用的交叉熵误差。详细代码见我博客地址

反向传播算法

这部分算是比较重要的,权重的更新依靠这个方法。
书上的例题:太郎在超市买了2个100日元一个的苹果,消费税是10%,请计算支付金额。
在这里插入图片描述
很简单的计算:100 * 2 * 1.1即可。
将x2和x1.1节点中的数字取出,符号单独放在○当中。
在这里插入图片描述
从左往右为正向传播
从右往左是反向传播

计算图

计算图:就是将计算过程用图的方式存下来。

局部计算

简单来说就是只用关注当前的简单计算部分,其他复杂的部分不需要管。意思就是计算偏导的那种感觉。

计算图反向传播

在这里插入图片描述
假设y = f(x)就是将信号E乘以节点的局部导数,然后传递到下一个节点。如果假设y = x^2 那么导数为2x,那么向下传播的值就是 E*2x,这里的x是正向传递时记录的。
链式法则
f ( x , y ) = ( x + y ) 2 令 u = ( x + y ) ∂ f ∂ x = ∂ f ∂ u ∂ u ∂ x = 2 ( x + y ) ∂ f ∂ y = ∂ f ∂ u ∂ u ∂ y = 2 ( x + y ) f(x,y) = (x + y)^2 \\ 令u = (x + y) \\ \frac{\partial f}{\partial x} = \frac{\partial f}{\partial u} \frac{\partial u}{\partial x} = 2(x + y) \\ \\ \frac{\partial f}{\partial y} = \frac{\partial f}{\partial u} \frac{\partial u}{\partial y} = 2(x + y) \\ f(x,y)=(x+y)2u=(x+y)xf=ufxu=2(x+y)yf=ufyu=2(x+y)
在这里插入图片描述

反向传播

对于每个层,都有forward方法和backward方法,对应正向反向传播。在训练时创建网络时,将每一层存在一个列表当中,顺序正向传播。当需要计算梯度时,将列表翻转,依次执行backward方法进行反向传播,求得梯度。
在这里插入图片描述在这里插入图片描述
加法正向和反向示意图
在这里插入图片描述在这里插入图片描述
乘法示意图
在这里插入图片描述
回到苹果的问题,计算过程反向传播过程。

参数更新

SGD随机梯度下降算法举例。其他更新的算法有很多Adam,Momentum,AdaGrad等等。
W ′ = W − η ∇ f ( W ) W' = W - \eta \nabla f(W) W=Wηf(W)
W W W为旧的权重, W ′ W' W更新的权重, η \eta η学习率, ∇ f ( W ) \nabla f(W) f(W)为损失函数在W权重上的导数。

训练过程

以MNIST数据集为例,简单写个训练过程伪代码。用pytorch或TensorFlow会更方便些。

# 加载数据集
(x_train,t_train),(x_test,t_test) = load_mnist(normalize=True)
# 创建网络
network = MultiLayerNet(input_size=784,hidden_size_list=[100,100,100,100,100,100],output_size=10)
# 优化器
optimizer = SGD(network.parameters(), lr = 0.01)
# 损失函数
loss_func = MSE()
# 参数设置
max_epochs = 201
train_size = x_train.shape[0]
batch_size = 100
# 训练轮数
for i in range(max_epochs):
	# 随机选择训练样本
    batch_mask = np.random.choice(train_size,batch_size)
    x_batch = x_train[batch_mask]
    t_batch = t_train[batch_mask]
    optimizer.zero_grad() # 梯度参数归零
	out = network(x_batch) # 正向传播
	loss = loss_fun(out, t_batch) # 计算损失
	loss.backward() # 反向传播
	optimizer.step() # 梯度参数更新
	if(best > loss.item()):
		best = loss.item()
		save_network(network) # 指标更好,保存当前网络

本文章只是简单介绍一些基础学习笔记,一些优化的trick并没有讲。比如BatchNormization,dropout,过拟合的处理等等。

总结

    个人感觉其实神经网络其实就是一个万能的拟合器,训练神经网络的过程,就是让计算机自己从大量的数据中寻找一条公式。这些数据有输入,输出结果,就是中间的函数映射是未知的,寻找的就是这些未知的映射。我们创建的神经网络,就是假定了函数的很多参数,通过损失函数,丈量与实际真实结果之间的距离。目标就是缩小之间的距离,而这个过程就相当于寻求一个函数的最低点,最低点的特征是导数为0,因此反向传播求导是获取了探寻最低点的方向,学习率就是前进的步长。然而最低点其实也是局部最优,为了更好的找到全局最优,也有很多的优化策略,比如余弦退火。
    这里只介绍了一些基础算法过程,到后面的卷积神经网络原理也是一样的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值