深度学习(六):正则化与批处理

1 神经网络中的过拟合问题

MNIST(Modified National Institute of Standards and Technology)是一个经典的手写数字分类数据集,广泛用于机器学习、深度学习以及图像处理的教学和研究。MNIST 数据集包含了大量的手写数字图像,常被用作入门级的分类任务。它的任务是从 28x28 像素的灰度图像中识别出数字(0-9)。MNIST 数据集组成: (1) 训练集:60,000张手写数字图像;测试集:10,000张手写数字图像。(2)图像:每张图片是一个28x28的灰度图像,像素值在[0, 255]之间,其中0表示白色,255表示黑色。

1、在 MNIST 数字分类上应用带有 relu 隐藏层的三层神经网络,在训练集上的Error和正确率:

import sys,numpy as np
from keras.datasets import mnist

(x_train,y_train),(x_test,y_test) = mnist.load_data()
#维度分别为(60000,28,28),((60000,)
x_train.shape,y_train.shape 

#维度分别为(1000,28*28),((1000,)
#功能:降维,进行标准化
images,labels = (x_train[0:1000].reshape(1000,28*28)/255,y_train[0:1000])

#维度是(1000,10)
one_hot_labels = np.zeros((len(labels),10))

#这个是结果的维度(1000,10),在0-9的的对应位置上标记为1,其余位置标记为0
for i,l in enumerate(labels):
    one_hot_labels[i][l] = 1

labels = one_hot_labels

test_images = x_test.reshape(len(x_test),28*28)/255
test_labels = np.zeros((len(y_test),10))

for i,l in enumerate(y_test):
    test_labels[i][l] = 1

np.random.seed(1)
relu = lambda x:(x>0) * x
relu2deriv = lambda x:x>0

#三层神经网络 layer0 为 784,layer1 隐藏层为 40,layer2 结果层为10
alpha,interations,hidden_size,pixels_per_image,num_labels = (0.005,350,40,784,10)

#初始化权重
weight_0_1 = 0.2*np.random.random((pixels_per_image,hidden_size)) - 0.1
weight_1_2 = 0.2*np.random.random((hidden_size,num_labels)) - 0.1

#迭代次数
for j in range(interations):
    error,correct_cnt = (0.0,0)
    #遍历整个test数据集
    for i in range(len(images)):
        #三层神经网络
        layer_0 = images[i:i+1]
        #relu实现非线性
        layer_1 = relu(np.dot(layer_0,weight_0_1))
        layer_2 = np.dot(layer_1,weight_1_2)
        #错误
        error += np.sum((labels[i:i+1] - layer_2)**2)
        #np.argmax返回最大值位置索引
        #计算预测分类正确的次数
        correct_cnt += int(np.argmax(layer_2) == np.argmax(labels[i:i+1]))

        layer_2_delta = (labels[i:i+1] - layer_2)
        #反向传播
        layer_1_delta = layer_2_delta.dot(weight_1_2.T)*relu2deriv(layer_1)
        #更该权重
        weight_1_2 += alpha * layer_1.T.dot(layer_2_delta)
        weight_0_1 += alpha * layer_0.T.dot(layer_1_delta)

    sys.stdout.write("\r" + \
                     " I:" + str(j) + \
                        " Error:" + str(error/float(len(images)))[0:5] +\
                        " Correct:" + str(correct_cnt/float(len(images)))
                        )

2、在测试集上的Error和正确率:

if(j % 10 == 0 or j == interations-1):
    error,correct_cnt = (0.0,0)
    for i in range(len(test_images)):
        layer_0 = test_images[i:i+1]
        layer_1 = relu(np.dot(layer_0,weight_0_1))
        layer_2 = np.dot(layer_1,weight_1_2)

        error += np.sum((test_labels[i:i+1]-layer_2)**2)
        correct_cnt += int(np.argmax(layer_2) == np.argmax(test_labels[i:i+1]))
    sys.stdout.write(" Test-Err:" + str(error/float(len(test_images)))[0:5] +\
                     " Test-Acc:" + str(correct_cnt/float(len(test_images))))
    print()

3、神经网络中的过拟合问题。如果你过度训练神经网络,它会变得更糟!神经网络过拟合现象的一个正式的定义是,这个神经网络学习到了数据集中的噪声,而不是仅基于真实的信号做出的决策

2 正则化

1、正则化是使模型泛化到新的数据点(而不仅是记忆训练数据)的方法的子领域。它是能够帮助神经网络学习信号并忽略噪声的一部分方法

2、正则化是用于在机器学习模型中鼓励泛化的方法的一个子集,通常通过提高模型学习训练数据的细粒度细节的难度来实现

3、dropout: 在训练过程中随机关闭神经元 (设置为0)。通过每次随机训练神经网络中的一小部分,dropout 能够让一张大网络像小网络一样进行学习——较小的神经网络不会发生过拟合

4、较小的神经网络没有太多的表达力。它们无法抓住那些可能导致过拟合的更细粒度的细节。它们只留下了捕捉那些更大、更明显、更高级特性的空间

5、神经网络总是随机初始化的。虽然大型非正则化的神经网络更可能对噪声过度拟合,但它们不太可能对相同的噪声过拟合

6、如果你训练 100 个神经网络,它们每个都倾向于捕捉不同的噪声和相似的信号。因此,当这些神经网络出错时,它们犯的错误往往不同。如果把它们整合到一起,让它们平等地投票,则它们的误差往往相互抵消,最终只展示它们学到的共同的东西:信号

7、dropout的真正含义:它是一种噪声。它使得神经网络在训练数据上的训练更加的复杂。它会减慢训练准确率上升的速度

添加 dropout 的实现

#迭代次数
for j in range(interations):
    error,correct_cnt = (0.0,0)
    #遍历整个test数据集
    for i in range(len(images)):
        #三层神经网络
        layer_0 = images[i:i+1]
        #relu实现非线性
        layer_1 = relu(np.dot(layer_0,weight_0_1))
        #dropout 增加1
        dropout_mask = np.random.randint(2,size=layer_1.shape)
        layer_1 *= dropout_mask*2

        layer_2 = np.dot(layer_1,weight_1_2)
        #错误
        error += np.sum((labels[i:i+1] - layer_2)**2)
        #np.argmax返回最大值位置索引
        #计算预测分类正确的次数
        correct_cnt += int(np.argmax(layer_2) == np.argmax(labels[i:i+1]))

        layer_2_delta = (labels[i:i+1] - layer_2)
        #反向传播
        layer_1_delta = layer_2_delta.dot(weight_1_2.T)*relu2deriv(layer_1)
        #dropout 增加2
        layer_1_delta *= dropout_mask

        #更该权重
        weight_1_2 += alpha * layer_1.T.dot(layer_2_delta)
        weight_0_1 += alpha * layer_0.T.dot(layer_1_delta)

    sys.stdout.write("\r" + \
                     " I:" + str(j) + \
                        " Error:" + str(error/float(len(images)))[0:5] +\
                        " Correct:" + str(correct_cnt/float(len(images)))
                        )

增加的三行代码:

#随机关闭50%的节点(生成与layer_1一样shape的矩阵,用0和1填充)
dropout_mask = np.random.randint(2,size=layer_1.shape)
#随机关闭50%的节点后,加权和没有太大的变化
layer_1 *= dropout_mask*2
#反向传播将将对应的delta设置为0
layer_1_delta *= dropout_mask

3 批量梯度下降

之前每次用一个训练样例进行训练,并在每次训练之后更新权重。现在,我们一次用100个训练样例进行训练,在更新权重时使用所有 100 个样例的权重增量的平均值。这样训练精度的上升趋势更平稳了。这种现象是因为单个样例进行训练,在生成权重更新增量时会有非常大的噪声。对这些权重增量更新进行平均可以使学习过程更加平滑

import numpy as np
np.random.seed(1)

def relu(x):
    return (x >=0)*x

def relu2deri(output):
    return output > 0

batch_size = 100
alpha,interations = (0.001,300)

hidden_size,pixels_per_image,num_labels = (100,784,10)

#初始化权重
weight_0_1 = 0.2*np.random.random((pixels_per_image,hidden_size)) - 0.1
weight_1_2 = 0.2*np.random.random((hidden_size,num_labels)) - 0.1

for j in range(interations):
    error,correct_cnt = (0.0,0)
    for i in range(int(len(images)/batch_size)):
        batch_start,batch_end = ((i*batch_size),((i+1)*batch_size))
        #维度(100,784)
        layer_0 = images[batch_start:batch_end]
        layer_1 = relu(np.dot(layer_0,weight_0_1))
        dropout_mask = np.random.randint(2,size=layer_1.shape)
        layer_1 *= dropout_mask * 2
        layer_2 = np.dot(layer_1,weight_1_2)

        error += np.sum((labels[batch_start:batch_end] - layer_2)**2)
        for k in range(batch_size):
            correct_cnt += int(np.argmax(layer_2[k:k+1]) == np.argmax(labels[batch_start+k:batch_start+k+1]))
            #取平均权重
            layer_2_delta = (labels[batch_start:batch_end] - layer_2)/batch_size
            print(layer_2_delta)
            layer_1_delta = layer_2_delta.dot(weight_1_2.T)*relu2deriv(layer_1)
            
            layer_1_delta *= dropout_mask

            weight_1_2 += alpha * layer_1.T.dot(layer_2_delta)
            weight_0_1 += alpha * layer_0.T.dot(layer_1_delta)

    if (j%10 == 0):
        test_eror,test_correct_cnt = (0.0,0)
        for i in range(len(test_images)):
            layer_0 = test_images[i:i+1]
            layer_1 = relu(np.dot(layer_0,weight_0_1))
            layer_2 = relu(np.dot(layer_1,weight_1_2))

4 参考资料

《深度学习图解》

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