第4章

4.1 从数据中学习

深度学习的特点是数据驱动,端到端,极力避免人为干预。

将数据分为两拨

【 训练数据 || 测试数据 】

  1. 确保神经网络具有泛化能力。
  2. 避免过拟合(只对训练时采用的数据集效果较好)。

4.2 单个损失函数

loss:度量神经网络性能有多差,所以损失函数越小越好

损失函数类型:

  1. 均方误差:
E = \frac{1}{2}\sum_k(y_k-t_k)^2
  1. 交叉熵误差:
E = -\sum_kt_klog(y_k)

k : 输出量个数

y :输出量

t : 正确解标签

对比两种误差

输入:

import numpy as np
from functions import cross_entropy_error,mean_squared_error

y=np.array([0.02,0.9,0.01,0.01,0.06])
t=np.array([0,1,0,0,0])

sum1=mean_squared_error(y,t)
sum2=cross_entropy_error(y,t)

print("mean_squared_error:"+str(sum1))
print("cross_entropy_error:"+str(sum2))

输出:

mean_squared_error:0.007099999999999997
cross_entropy_error:0.1053604045467214

均方误差涉及到所有的输出及其对应的正确解标签

但是在one hot表示方法下,非正确解对应的标签tk=0,只有正确解对应的标签tk=1,所以交叉熵误差只关注正确解标签对应的输出

4.3 mini-batch学习

神经网络的是从总数据集中,随机抽出一批(mini-batch)数据进行学习,每学习一次,计算一次损失函数,再随机抽出一批数据进行学习,再计算损失函数,循环,追求损失函数最小化。

随机抽出一批数据的代码:

batch_mask = np.random.choice(train_size,batch_size)    #从所有的索引中,随机抽出一批大小的索引
x_batch = x_train(batch_mask)   #根据索引抽出对应的训练数据
y_batch = y_train(batch_mask)   #根据索引抽出对应的正确解标签

计算每个mini-batch的交叉熵公式:

E = -\frac{1}{N}\sum_n\sum_kt_{nk}log(y_k)

N为每个mini-batch的数据个数,tnk为第n个数据对应标签(one hot类型)的第k个元素。

实现代码:

def cross_entropy_error(y, t):
    if y.ndim == 1:                  #用if分类,使得单个数据也可以计算交叉熵
        t = t.reshape(1, t.size)
        y = y.reshape(1, y.size)
        
    batch_size = y.shape[0]
    
    return -np.sum(t*np.log(y+ 1e-7)) / batch_size
    #log(0)为-∞,为防止溢出,y通常加上一个很小的数

4.4 为什么要设定损失函数

神经网络的学习主要是通过梯度下降法实现的,即当我们更改神经网络中的一些参数(权重,偏置),我们希望有一个量,能够反映出神经网络是变好了还是变差了。即使参数只是微调,也可以观察到这个量的变化。所以我们使用损失函数来度量。

作为对比,如果使用正确率作为度量的量,一个mini-batch有100个数据,假设正确分类32个数据,通过微调参数,正确率依旧是32%,参数的微调效果被正确率抹杀

使用阶跃函数作为激活函数同样会抹杀参数的微调效果。

而sigmoid函数连续,且任何点的导数不为0,所以它可以作为激活函数。并使用sigmoid函数的输出来计算损失函数。

image

总结:保留微调效果,实现可导

4.5 数值微分

4.5.1导数

原始的求导公式:

image

观察图像:


image

用这种方法求出来的导数所对应的切线,与真正的切线存在误差,所以将公式改良为:


image

因为左边的误差和右边的误差抵消了一部分,所以使用这个公式求出来的导数更为精确。

代码实现:

def numerical_diff(f, x):
    h = 1e-4 # 0.0001
    return (f(x+h) - f(x-h)) / (2*h)

4.5.2

你可能感兴趣的:(第4章)