机器学习入门之6- 深度学习之神经网络核心原理与算法-学习率
小标 2018-12-18 来源 : 阅读 1447 评论 0

摘要:本文主要向大家介绍了机器学习入门之6- 深度学习之神经网络核心原理与算法-学习率,通过具体的内容向大家展现,希望对大家学习机器学习入门有所帮助。

本文主要向大家介绍了机器学习入门之6- 深度学习之神经网络核心原理与算法-学习率,通过具体的内容向大家展现,希望对大家学习机器学习入门有所帮助。

学习率

学习率 一塔 就是每次挪动中的步长。一塔通常来说给一个比较小的值会更好一些。


mark

步子太大会导致迈过谷底。

其他超参数

而由于偏导数方向的改变。你再次挪动又会向着谷底的方向挪动。


mark

只是由于步子还是很大,还是会迈过谷底。这样就会像上图一样来回折返。

到底设置为多少,是要根据自己的项目进行判断的。但是小一点的值总是要好一点的。
收敛的比较慢,但是可以使loss的值下到谷底。

Dropout(克服过拟合)

每次训练随机丢弃一些神经元,就相当于整个网络结构发生变化

减少过拟合风险


mark

在某些层上临时关闭一些节点,让他们不输入也不输出。原则上选择关闭哪些节点都是随机性的。

在分类阶段,将所有的节点都置于有效的状态


mark

就可以把训练中得到的子网络并联起来使用。

交叉熵( Cross Entropy)

学习慢

有时候我们使用相同的学习率,初始化不同的w和b,开始学习的变化率会很慢。

网络在开始学习的时候,整个loss下降的很慢。

举例: 使用梯度下降法来计算w和b, 来看看它是如何学习的

w=0.6 b=0.9 x=1.0 y=0.82 学习率=0.15


mark

简化后的网络。


mark

我们的w和b在不断的变化,我们的cost在不断的下降。

举例: 一个不好的初始化

w=2.0 b=2.0 x=1.0 y=0.2 学习率=0.15


mark

可以看到网络的训练开始学习的很慢。w和b的变化很慢。

复杂的神经网络学习很慢。

原因: 其实就是因为偏导很小造成的。


mark


mark

也就是图中某一点的斜率几乎水平了。

为什么偏导很小,导致学习很慢。

回顾一下之前的网络更新方程。


mark

最后一层的偏loss/偏b 等于 预测出来的结果减去网络的标签。点乘于sigmoid的导数。

这里的y0 yi都是一个定值。sigmoid在Z 小于-4 或大于4.水平。斜率为0.


mark

想要让网络学习快一点,也就是偏导大一些。我们就要增大sigmoid函数的导数值。

定义


mark

之前我们都是使用二次cost来定义我们网络的损失函数。这里我们可以使用交叉熵来定义我们网络的损失函数。

我们可以重新推导一遍偏loss偏w和偏loss偏b的值。


mark

如果使用交叉熵函数,而不使用二次损失函数。


mark

可以看到最终的公式里就没有sigmoid的导数这一项了。同样的方法我们也可以推导出偏loss/偏b。(避免使用sigmoid的导数)


mark

这里的x,n,y都是定制。sigmoid(z)是网络的预测结果。如果网络的预测结果和真实结果接近的话,整个网络的loss值就会减小。

如果偏差比较大的话,loss的值也会因为偏导较大而减小。


mark

可以看到情况1中loss一直随着训练轮数增加而下降。


mark

情况2不再出现学习很慢的情况。

交叉熵编码实现

如何在代码里面添加交叉熵(Cross Entropy)

Network类的初始化时我们可以定义一个损失函数。

    def __init__(self, sizes, cost=CrossEntropyCost):
        # 损失函数
        self.cost = cost

增加一个cost参数。

定义一个二次cost的类

class QuadraticCost(object):    @staticmethod
    def fn(a, y):
       return 0.5 * np.linalg.norm(a -y) ** 2    @staticmethod
    def delta(z, a, y):
        return (a - y) * sigmoid_prime(z)

通过staticmethod装饰器,可以直接通过类名.方法名调用(不要实例化:QuadraticCost.fn)

fn里面a是网络预测结果,y是真实的标签。我们返回二次cost函数。

1/2 乘以 (预测值-真实值)的二范数 的平方。

np.linalg.norm

https://blog.csdn.net/lanchunhui/article/details/51004387

再定义另一个delta方法,输入参数为z,预测值a,真实值y

返回(误差) 乘以 sigmoid(z)

这时候再定义交叉熵的类。

class CrossEntropyCost(object):
    '''
    >>>import numpy as np
    >>> a = np.array([[np.nan,np.inf],\n    ...               [-np.nan,-np.inf]])
    >>> a
    array([[  nan,   inf],
           [  nan,  -inf]])
    >>> np.nan_to_num(a)
    array([[ 0.00000000e+000,  1.79769313e+308],
           [ 0.00000000e+000, -1.79769313e+308]])
    '''    @staticmethod
    def fn(a, y):
        return np.sum(np.nan_to_num(-y * np.log(a) - (1 - y) * np.log(1 - a)))    @staticmethod
    def delta(z, a, y):
        return (a - y)

交叉熵的方程:


mark

因为在计算出来的数中可能存在无限大和nan值。所以我们通过nan_to_num方法将其进行处理。

网络初始化时,我们可以默认使用CrossEntropyCost这个类

接着我们要将反向更新的代码进行修改:

        # 反向更新了
        # 计算最后一层的误差
        delta = (self.cost).delta(zs[-1], activations[-1], y)

使用self.cost函数来替换掉我们之前写死的二次损失函数。

本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标人工智能机器学习频道!

本文由 @小标 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式AI+学习就业服务平台 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved