深度学习(四):反向传播

1 梯度下降分类

1、本章描述的交通信号灯问题是一个多个输入一个输出的神经网络

2、随机梯度下降:它分别为每个训练样例执行预测和权重更新。它先拿到第一条信号灯的数据,尝试基于它进行预测,计算权重增量 weight_delta,并更新权重。然后继续读取第二条信号灯数据,以此类推。它循环遍历整个数据集多次,直到找到适合所有训练用例的权重配置

3、完全梯度下降:它每次为整个数据集更新权重。在训练示例中,网络针对整个数据集计算 weight_delta 的平均值,并在均值计算完成之后更新权重,而非对每个训练用例更新权重

4、批量梯度下降:它每次针对每 n 个样例更新权重。选择确定批次大小(通常在8到256之间)的样例子,然后更新权重

5、下面的结果中,中间信号灯的 weight 非常接近 1 ,而最左边和最右边的权重非常接近 0 。整个神经网络的训练学习过程,完成了相当简单的事情:让神经网络确认了中间的输入和输出的相关性。任何权重数值高的位置都具有高相关性

6、深度学习的最大弱点是过拟合。所有的权值都有误差。如果某个特定的权重配置意外地在预测数据集和输出数据集之间创建了完美的吻合(error=0),而此时并没有给真正最重要的输入赋予最大权重,那么神经网络将停止学习

7、正则化的目的是使得只有真正强相关性的权重才能保持不变,其他的一切都会被压制,因为它们会产生噪声

#交通信号灯实例,训练全部数据
import numpy as np
weights = np.array([0.5,0.48,-0.7])
alpha = 0.1

streetlights = np.array([[1,0,1],
                         [0,1,1],
                         [0,0,1],
                         [1,1,1],
                         [0,1,1],
                         [1,0,1]
                         ])

walk_vs_stop = np.array([0,1,0,1,1,0])

input = streetlights[0]
goal_prediction = walk_vs_stop[0]

#随机梯度下降
for iteration in range(40):#训练40轮
    error_for_all_lights = 0
    for row_index in range(len(walk_vs_stop)):#一次性训练所有数据
        input = streetlights[row_index]
        goal_prediction = walk_vs_stop[row_index]
        prediction = input.dot(weights)
        error = (prediction - goal_prediction)**2
        error_for_all_lights += error
        delta = prediction - goal_prediction
        weights = weights - (input * delta) * alpha
        print('Weights: ' + str(weights))
        print("Prediction: " + str(prediction))
    print("Error: " + str(error_for_all_lights))

2 堆叠神经网络

1、如果数据没有相关性,那么创建具有相关性的中间数据。在现实中,神经网络搜索它们的输入层和输出层之间的相关性

2、如果输入数据集和输出数据集不相关,所以你可以使用输入数据集创建一个与输出相关的中间数据集。如下图所示,目标是训练这个网络使得即使在输入数据集和输出数据集(layer_0 和 layer_2)之间没有相关性的情况下,用 layer_0 创建的数据集 layer_1 仍与 layer_2 相关

3、下面这个 “堆叠神经网络” ,第一个神经网络的输出是第二个神经网络的输入。神经网络的上半层 (layer_1 到 layer_2 层)与前一章训练的网络没有什么区别。这章新的部分是layer_0 到 layer_1 之间的权重

3 反向传播

1、如果 layer_2 以 x(+0.25)的误差偏高,layer_1 中权重较高的值(weights_1_2)会贡献更多的误差,权重较低的值会贡献较少的误差。取一个极端的例子,最左边节点的权重是0,该节点对误差的贡献就是 0。从 layer_1 到 layer_2 的权重准确描述了 layer_1 节点对 layer_2 预测的贡献,这些权重也能准确的描述 layer_1 节点对 layer_2 的误差的贡献

2、layer_2 的 delta 乘以 layer_1 的各个权重,就可以获得layer_1 的 delta。 这就像反向的预测逻辑。这种反向传递增量信号的过程叫做 反向传播

3、对于每一个权重,将它的输出增量乘以它自身layer_1_delta=layer_2_delta.dot(weights_1_2.T)*relu2deriv(layer_1),然后将权重调整这么多

4、由于输入和输出之间不存在相关性,中间层只是把一些已经没用的相关性混合在一起,真正需要的是使中间层能够选择性地与输入节点相关联。 中间层的作用是只在想要和某个输入节点产生 x% 的关联的时候,才关联到它,而其他时候根本不关联。这称为条件相关,或者选择相关

5、如果中间层节点的值低于 0 ,这个节点与输入具有一定的相关性,只是这个相关性是负的而已。如果将其设置为 0 ,那么它与任何输入的相关性都会为 0 。这意味着节点可以在它想要的时候选择性地关联相应的对象,这就解决了第 4 点的问题

6、神经网络中间层节点的值如果是负的设置为 0,这实际上就是 ReLU(Rectified Linear Unit 修正线性单元)激活函数的操作。它的目的是引入非线性,并且改善网络的训练效率。f(x)=max(0,x)

7、layer_1_delta=layer_2_delta.dot(weights_1_2.T)*relu2deriv(layer_1) ; 如果 layer_1 的数值因为 Relu 设置为 0 ,则不会对误差产生任何影响,在这个前提下需要将这个节点的 delta 设置为 0 。将 layer_1 节点乘以 relu2deriv 函数就能做到这点。relu2deriv 的返回值是 1 还是 0 ,取决于 layer_1 的值是否大于0.

import numpy as np

np.random.seed(1)


streetlights = np.array([[1,0,1],
                         [0,1,1],
                         [0,0,1],
                         [1,1,1]
                         ])

walk_vs_stop = np.array([[1,1,0,0]]).T

def relu(x):
    return (x>0) * x
#当输入大于0时,返回1;当输入小于0时,返回0
#relu2deriv 是relu函数的导数(斜率)
def relu2deriv(output):
    return output>0

alpha = 0.2
hidden_size = 4

#两组权重经过随机初始化之后,将三层网络连接在一起
weights_0_1 = 2*np.random.random((3,hidden_size)) -1
weights_1_2 = 2*np.random.random((hidden_size,1)) -1

for iteration in range(60):
    layer_2_error = 0
    for i in range(len(streetlights)):
        layer_0 = streetlights[i:i+1]
        #relu 函数实现非线性
        layer_1 = relu(np.dot(layer_0,weights_0_1))
        layer_2 = np.dot(layer_1,weights_1_2)

        layer_2_error += np.sum((layer_2 - walk_vs_stop[i:i+1])**2)
        #之前的向前传播 delta 是prediction - goal_prediction
        #目前的 delta 是goal_prediction - prediction
        layer_2_delta = walk_vs_stop[i:i+1] - layer_2
        #反向传播
        layer_1_delta = layer_2_delta.dot(weights_1_2.T)*relu2deriv(layer_1)
        #更改权重
        weights_1_2 += alpha * layer_1.T.dot(layer_2_delta)
        weights_0_1 += alpha * layer_0.T.dot(layer_1_delta)

    if (iteration % 10 == 9):
        print("Error: " + str(layer_2_error))

8、附一张numpy 中 1D、2D、3D数组的区别


9、深度学习就是创建从数据集到预测结果的中间层,中间层中的每个节点表示输入数据中不同类型的组合模式是否存在。对于猫的图形数据集,没有任何一个单独的像素与照片中是否有猫有相关性。相反,中间层将尝试识别不同的像素组合模式,这些像素组合在一起可能与猫相关(比如猫的耳朵、眼睛),也可能与猫无关

4 参考资料

《深度学习图解》

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,098评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,213评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,960评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,519评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,512评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,533评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,914评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,804评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,563评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,644评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,350评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,933评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,908评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,146评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,847评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,361评论 2 342

推荐阅读更多精彩内容