栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

读书笔记:深度学习入门-基于python的理论与实现(俗称鱼书)

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

读书笔记:深度学习入门-基于python的理论与实现(俗称鱼书)

文章目录
  • 前言
  • 三、神经网络
    • 3.2 激活函数
      • 3.2.1 阶跃函数
      • 3.2.2 sigmoid函数
      • 3.2.3 ReLU函数
    • 3.3 多维数组
      • 3.3.1 多维数组的维度和形状
      • 3.3.2 多维数组的点乘
    • 3.4 三层神经网络的实现
      • 3.4.1 一步一步进行
      • 3.4.2 合起来实现
    • 3.5 输出层的设计
      • 3.5.1 Softmax函数
      • 3.5.2 Softmax函数的特征:输出值求和为1,符合概率分布问题
  • 四、神经网络的学习
    • 4.2 损失函数
      • 4.2.1 均方误差MSE
      • 4.2.2 交叉熵误差CEE
      • 4.2.3 mini-batch上的交叉熵的实现
    • 4.3 数值微分
      • 4.3.1 导数
      • 4.3.2 偏导数
    • 4.4 梯度
      • 4.4.1 梯度法
      • 4.4.2 神经网络的梯度
    • 4.5 学习算法的实现
  • 五、误差反向传播法
    • 5.4 简单层的实现
    • 5.5 激活函数层的实现
      • 5.5.1 Relu层
      • 5.5.2 Sigmoid
    • 5.6 Affine/Softmax层的实现
      • 5.6.1 Affine层数
      • 5.6.2 Softmax-with-Loss层
  • 总结


前言

终于从头到尾把鱼书看完啦,真的是非常入门,非常查漏补缺,对新手很友好,对有一定基础的人也非常不错。看完不复习等于没看,所以今天开始复盘,顺便写这篇读书笔记。希望分享给没看过这本书或者看过这本书的同僚们参考,欢迎大家指教。我将从第三章神经网络开始复习,前两章内容书里已经非常基础and清楚了。(会持续更新滴)


三、神经网络 3.2 激活函数

这一小节学习的概念是神经网络学习中非常重要的激活函数,它们都是一些非线性函数,至于为何是非线性函数,因为非线性函数组合才能实现复杂网络的构建。以下将实现三个激活函数,它们分别是阶跃函数、sigmoid函数和relu函数

3.2.1 阶跃函数
def step_function(x):
#     if x > 0:
#         y = 1
#     else:
#         y = 0
    y = x > 0
    y = y.astype(np.int)
    return y

这就是阶跃函数的代码实现,可以了解到阶跃函数就是当自变量大于零的时候等于1,小于零的时候等于0的函数,注释上面的改写成下面的原因是,为了numpy数组更方便进行后续操作。

x = np.array([1.5,-2,5.0])
step_function(x)

输出为array([1, 0, 1])

x1 = np.arange(-6,7,1)
y1 = step_function(x1)
plt.plot(x1,y1)
plt.show()

输出的图像为

3.2.2 sigmoid函数
def sigmoid(x):
    y = 1/(1+np.exp(-x))
    return y

sigmoid函数是1/(+exp(-x))的形式,当输入是numpy数组的时候,用上面的代码就可实现了。

sigmoid(x):

输出为array([0.81757448, 0.11920292, 0.99330715])

x1 = np.arange(-6,7,1)
y2 = sigmoid(x1)
plt.plot(x1,y2)
plt.show()

输出的图像为

3.2.3 ReLU函数
def ReLU(x):
    y = np.maximum(0,x)
    return y

ReLU函数相当于在自变量小于0的时候为0,大于零的时候和自变量相等,也就是在自变量和0中取最大值,如上代码即可实现。

ReLU(x)

输出为array([1.5, 0. , 5. ])

x1 = np.arange(-6,7,1)
y3 = ReLU(x1)
plt.plot(x1,y3)
plt.show()

输出图像为
以上小节激活函数,为什么激活函数不能是线性函数呢?如果使用线性函数,加深神经网络的层数就没有意义了。

3.3 多维数组

numpy多维数组的相关运算对于神经网络的实现是基本操作。

3.3.1 多维数组的维度和形状
a = np.array([[2,4,5],[2,3,9]])
a.ndim #维度 将会输出2
a.shape #形状 将会输出(2,3)

b = np.array([[2,2,1],[2,2,4],[5,4,4]])
b.ndim #维度 将会输出2
b.shape #形状 将会输出(3,3)
3.3.2 多维数组的点乘
np.dot(a,b) #维度要符合矩阵乘法,左列等于右行;不然就要符合广播机制

输出为array([[37, 32, 38],
[55, 46, 50]])

3.4 三层神经网络的实现 3.4.1 一步一步进行

第一层,大概逻辑是输入×权重加偏置,然后激活函数

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

print(X.shape)
print(W1.shape)
print(B1.shape)

输出为(2,)
(2, 3)
(3,)

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

输出为[0.3 0.7 1.1]

Z1 = sigmoid(A1)
print(Z1)

输出为[0.57444252 0.66818777 0.75026011]
第二层,和第一层的逻辑

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(A1,W2) + B2

print(A2)

输出为[0.6 1.33]

Z2 = sigmoid(A2)
print(Z2)

输出为[0.64565631 0.79084063]
第三层,前面逻辑一样,激活函数那里用的恒等函数,回归用恒等,分类下一节介绍

W3 = np.array([[0.1,0.3],[0.2,0.4]])
B3 = np.array([0.1,0.2])
A3 = np.dot(A2,W3) + B3

print(A3)

输出为[0.426 0.912]

def identity_function(x):
    y = x
    return y

Z3=identity_function(A3)
print(Z3)

输出为[0.426 0.912]
回归问题的输出层的激活函数为恒等函数,下一节详细介绍

3.4.2 合起来实现

先构建一个初始化参数的函数,如下:

def init_network():
    network = {}
    network['W1'] = np.array([[0.1,0.3,0.5],[0.2,0.4,0.6]])
    network['W2'] = np.array([[0.1,0.4],[0.2,0.5],[0.3,0.6]])
    network['W3'] = np.array([[0.1,0.3],[0.2,0.4]])
    network['B1'] = np.array([0.1,0.2,0.3])
    network['B2'] = np.array([0.1,0.2])
    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
    Z3 = identity_function(A3)
    return Z3

接着传入输入,观察参数通过网络的情况

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

输出为[0.31682708 0.69627909]

3.5 输出层的设计 3.5.1 Softmax函数

激活函数的使用,回归问题用恒等函数,分类问题用softmax函数

def softmax(x):
    exp_x = np.exp(x)
    sum_exp_x = np.sum(exp_x)
    y = exp_x / sum_exp_x
    return y

softmax函数的函数形式相当于是自然指数除以自然之数求和

x = np.array([0.3,2.9,4.0])
y = softmax(x)
print(y)

输出为[0.01821127 0.24519181 0.73659691]

x = np.array([1010,1000,990])
y = softmax(x)
print(y)

输出为[nan nan nan]
为了解决数组中的大数的输入无法处理的问题,将softmax函数优化为下面这样,在传入自然指数的时候减去数组中的最大值,得到的函数定义代码如下:

def softmax(x):
    c = np.max(x)
    exp_x = np.exp(x-c)
    sum_exp_x = np.sum(exp_x)
    y = exp_x / sum_exp_x
    return y
x = np.array([1010,1000,990])
y = softmax(x)
print(y)

输出为[9.99954600e-01 4.53978686e-05 2.06106005e-09],至此解决了softmax函数的大数输入问题

3.5.2 Softmax函数的特征:输出值求和为1,符合概率分布问题
sum_y = np.sum(y)
print(sum_y)

输出为1.0,因此对于分类问题的输出都是需要进行这样的softmax操作,规范输出的求和符合1.0

四、神经网络的学习 4.2 损失函数

这一小节中的y为输出的预测值,t为标签

4.2.1 均方误差MSE

均方误差的公式相当于相减的平方求和然后×0.5,如下:

def mean_standard_erro(y,t):
    return 0.5*np.sum((y-t)**2)   

t=[0,0,1,0,0,0,0,0,0,0]
y=[0.1,0.05,0.6,0.0,0.05,0.1,0.0,0.1,0.0,0.0]
mean_standard_erro(np.array(y),np.array(t))

输出为0.09750000000000003

y=[0.1,0.05,0.1,0.0,0.05,0.1,0.0,0.6,0.0,0.0]
mean_standard_erro(np.array(y),np.array(t))

输出为0.5975
一般回归问题使用的损失函数是方均误差这种形式的

4.2.2 交叉熵误差CEE

交叉熵误差相当于计算一个和另一个的lg相乘的相反数,其中lg里需要加上一个小数,避免定义域出现0的问题,这是一种保护机制,交叉熵误差的值是由正确解标签所对应的输出结果决定的,代码如下:

def cross_entropy_error(y,t):
    delta=1e-7
    return -np.sum(t*np.log(y+delta))

t=[0,0,1,0,0,0,0,0,0,0]
y=[0.1,0.05,0.6,0.0,0.05,0.1,0.0,0.1,0.0,0.0]
cross_entropy_error(np.array(y),np.array(t))

输出为0.510825457099338

y=[0.1,0.05,0.1,0.0,0.05,0.1,0.0,0.6,0.0,0.0]
cross_entropy_error(np.array(y),np.array(t))

输出为2.302584092994546
一般分类问题使用的损失函数是交叉熵误差这种形式的

4.2.3 mini-batch上的交叉熵的实现

mini-batch用的是部分计算计算近似整体的一个思路,类似于电视台求收视率,mini-batch上的交叉熵求解的代码如下:

def cross_entropy_error(y,t):
    if y.ndim==1:
        t=t.reshape(1,t.size)
        y=y.reshape(1,y.size)
    batch_size=y.shape[0]
    return -np.sum(np.log(y[np.arange(batch_size),t]+1e-7))/batch_size

np.arange(batch_size)会生成一个从0到batch_size-1的numpy数组,y[np.arange(batch_size),t]能抽出各个数据的正确解标签对应的神经网络输出
关于为何设定损失函数,不直接把精度作为标准,原因是以精度为标准的话会使得绝大多数地方的导数为0,连续、平滑才能使导数不为0,才能继续更新神经网络参数,这也是激活函数不能选择阶跃函数这样不连续光滑的函数,而是选择了sigmoid这样的函数的原因

4.3 数值微分 4.3.1 导数
 
4.3.2 偏导数 
 
4.4 梯度 
 
4.4.1 梯度法 
 
4.4.2 神经网络的梯度 
 
4.5 学习算法的实现 
 
五、误差反向传播法 
5.4 简单层的实现 
5.5 激活函数层的实现 
5.5.1 Relu层 
 
5.5.2 Sigmoid 
 
5.6 Affine/Softmax层的实现 
5.6.1 Affine层数 
 
5.6.2 Softmax-with-Loss层 
 

总结

第三章到第七章将会以书上的基础内容总结为主,第八章争取找一些新东西(那些没有代码示例,但似乎很有趣的概念和算法)加进读书笔记里。
希望这一次的读书笔记不要半途而废,每天总结一小部分,积少成多,希望早日完结撒花~

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/925700.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号