深度学习之二:神经网络的实践与优化

【AI概念】神经网络架构(NN Architecture)与深度学习模型(Deep Learning):核心原理、数学表达、工程实践与未来趋势|主流神经网络架构与深度学习模型、对比与应用场景、优化流程 大家好,我是爱酱。本篇将会系统梳理神经网络架构(NN Architecture)与深度学习模型(Deep Learning)的核心原理、主流方法、数学表达、工程实践与未来趋势,配合数学公式,帮助你全面理解这些概念。 注:本文章含大量数学算式、详细例子说明,建议先收藏再慢慢观看理解。你们的每个赞、收藏跟转发都是我继续分享的动力! 本文章为入门介绍,爱酱会在之后逐一出单独文章介绍不同主流神经网络架构,如CNN、RNN、LSTM、Transformer、GAN、Autoencoder、GNN等,敬请期待! 阅读详情

本文内容为Andrew ng深度学习课程的第二部分的笔记,本篇总结了如何神经网络的训练和学习过程的实践经验与优化方法。

1 深度学习的实践技巧

应用机器学习是一个需要不断迭代的过程,众多经验参数如层数,隐层单元数,学习率,激活函数,权重参数的初始化方法等等众多的参数需要不断尝试改进以最终的得到较高的准确率。在这个过程中,有着众多的实践技巧。

1.1 训练/开发/测试集

如果针对某一监督学习的任务,当前有一批标注数据集。数据的分类方法:

方法\划分数据集训练集开发集测试集
激进中小数据集70%0%30%
均衡中小数据集60%20%20%
现代大数据集98%1%1%

在深度学习中,通常需要的数据集都很大,如百万级别的,这样只需要拿出较小比例数据用来做测试集即可。

最重要的一点是,务必保证开发集/测试集数据为来自相同的分布。保持我们训练和应用的目标一致性。

有了数据集的划分,我们可以在相同的训练集上训练不同的模型,并通过测试集进行对比以选择合适的模型。

1.2 偏差与方差

我们用训练集与开发集上的误差来说明偏差与方差的不同情况。

误差\划分例1例2例3例4
训练集误差1%15%15%1%
开发集误差11%16%30%1.5%
结论高方差高偏差方差高/偏差高方差低/偏差低

优良的分类器,其偏差与方差均偏低。

下面我们来看下机器学习过程如何解决偏差与方差问题。
这里写图片描述

A{"训练结果"} -->
|"高偏差"|B["上更大网络/训练更久"]
D-->A
B-->D["训练"]
A-->|"高方差"|C["增加数据/正则化"]
C-->D

1.4 正则化

正则化可以用来解决神经过拟合的问题。

1.4.1 逻辑回归的正则化

L2正则化: J(w,b)=1m∑L(yˆ,y)+λ2m||w||22 J ( w , b ) = 1 m ∑ L ( y ^ , y ) + λ 2 m | | w | | 2 2

L1正则化: J(w,b)=1m∑L(yˆ,y)+λ2m||w||1 J ( w , b ) = 1 m ∑ L ( y ^ , y ) + λ 2 m | | w | | 1

1.4.2 神经网络的正则化

对于神经网络,由于神经网络有多层,因此需要计算所有层的正则化的和,这样损失函数将有两部分构成,一部分为预测的误差,一部分为所有层权重参数的范数。

J(w,b)=1m∑i=1mL(yˆ[i],y[i])+λ2m∑l=1n||wl||22 J ( w , b ) = 1 m ∑ i = 1 m L ( y ^ [ i ] , y [ i ] ) + λ 2 m ∑ l = 1 n | | w l | | 2 2

由于损失函数中增加了正则项,在各层的反向传播过程中需要加入考虑,因此在加入正则化后各层的反向传播计算公式如下:
dW[l]=1mdZ[l]A[l]+λmW[l] d W [ l ] = 1 m d Z [ l ] A [ l ] + λ m W [ l ]
W[l]=W[l]−αdW[l] W [ l ] = W [ l ] − α d W [ l ]

1.4.3 为什么正则化会有用

由于在误差中引入了新的项,当 λ λ 升高时, W W 会变小,这样会使得生成的Z变小。对于激活函数来说,自变量Z就会取在函数的中间近似于线性的部分,而无法利用非线性的部分。因此会使得参数的过拟合现象降低。

1.5 Dropout正则化

Droupout的作用是随机在神经网络中选择一些单元,使其在运算中不参与计算,这样神经网络的规模将变小,从而实现避免过拟合。同时为了避免不影响后续计算的数值,未被dropout的单元需要整体放大,以补充消除单元的数值。

keep-prob = 0.5
Dl = np.random.rand(Al.shape[0], Al.shape[0])<keep-prob
# 使得对应项置0
Al *= Dl 
Al /= keep-prob

需要注意的是,dropout只能用于训练神经网络,在做预测时不需要使用。

通常在神经网络的隐层的前面的层中使用较小的keep-prob,在后面的层中使用大的keep-prob,甚至不使用dropout。

1.6 正则化实现示例

下面的代码展示了在一个3层神经网络上增加L2正则与Dropout的功能的实现。大部分代码在第一课中都已经实现过,这里只是增加了正则项的计算修正。

import numpy as np


def sigmoid(x):
    return 1 / (1 + np.exp(-x))

def relu(x):
    return np.maximum(0, x)

def initialize_parameters(layer_dims):
    np.random.seed(3)
    parameters = {}
    layers = len(layer_dims)  

    for l in range(1, layers):
        parameters['W' + str(l)] = np.random.randn(layer_dims[l], layer_dims[l - 1]) / np.sqrt(layer_dims[l - 1])
        parameters['b' + str(l)] = np.zeros((layer_dims[l], 1))

    return parameters

def forward_propagation(X, parameters):

    W1 = parameters["W1"]
    b1 = parameters["b1"]
    W2 = parameters["W2"]
    b2 = parameters["b2"]
    W3 = parameters["W3"]
    b3 = parameters["b3"]

    # 前向传播
    Z1 = np.dot(W1, X) + b1
    A1 = relu(Z1)
    Z2 = np.dot(W2, A1) + b2
    A2 = relu(Z2)
    Z3 = np.dot(W3, A2) + b3
    A3 = sigmoid(Z3)

    # 缓存计算中间结果
    cache = (Z1, A1, W1, b1, Z2, A2, W2, b2, Z3, A3, W3, b3)

    return A3, cache

def forward_propagation_with_dropout(X, parameters, keep_prob=0.5):

    np.random.seed(1)

    W1 = parameters["W1"]
    b1 = parameters["b1"]
    W2 = parameters["W2"]
    b2 = parameters["b2"]
    W3 = parameters["W3"]
    b3 = parameters["b3"]

    # 第1层前向计算,Dropout部分节点,且增大未失活节点的权重
    Z1 = np.dot(W1, X) + b1
    A1 = relu(Z1)

    D1 = np.random.rand(A1.shape[0], A1.shape[1])  
    D1 = D1 < keep_prob  
    A1 = A1 * D1  
    A1 = A1 / keep_prob  

    # 第2层前向计算,处理Dropout
    Z2 = np.dot(W2, A1) + b2
    A2 = relu(Z2)

    D2 = np.random.rand(A2.shape[0], A2.shape[1])  
    D2 = D2 < keep_prob 
    A2 = A2 * D2
    A2 = A2 / keep_prob  

    # 输出层计算,无Dropout
    Z3 = np.dot(W3, A2) + b3
    A3 = sigmoid(Z3)

    cache = (Z1, D1, A1, W1, b1, Z2, D2, A2, W2, b2, Z3, A3, W3, b3)

    return A3, cache


def compute_cost(a3, Y):
    m = Y.shape[1]

    logprobs = np.multiply(-np.log(a3), Y) + np.multiply(-np.log(1 - a3), 1 - Y)
    cost = 1. / m * np.nansum(logprobs)

    return cost


def compute_cost_with_regularization(A3, Y, parameters, lambd):
    m = Y.shape[1]
    W1 = parameters["W1"]
    W2 = parameters["W2"]
    W3 = parameters["W3"]

    cross_entropy_cost = compute_cost(A3, Y)  

    L2_regularization_cost = lambd * (np.sum(np.square(W1)) + np.sum(np.square(W2)) + np.sum(np.square(W3))) / (2 * m)

    cost = cross_entropy_cost + L2_regularization_cost

    return cost

def backward_propagation(X, Y, cache):
    m = X.shape[1]
    (Z1, A1, W1, b1, Z2, A2, W2, b2, Z3, A3, W3, b3) = cache
    # 输出层梯度计算
    dZ3 = A3 - Y
    dW3 = 1. / m * np.dot(dZ3, A2.T)
    db3 = 1. / m * np.sum(dZ3, axis=1, keepdims=True)
    # 第二层梯度计算
    dA2 = np.dot(W3.T, dZ3)
    dZ2 = np.multiply(dA2, np.int64(A2 > 0))
    dW2 = 1. / m * np.dot(dZ2, A1.T)
    db2 = 1. / m * np.sum(dZ2, axis=1, keepdims=True)
    # 第一层梯度计算
    dA1 = np.dot(W2.T, dZ2)
    dZ1 = np.multiply(dA1, np.int64(A1 > 0))
    dW1 = 1. / m * np.dot(dZ1, X.T)
    db1 = 1. / m * np.sum(dZ1, axis=1, keepdims=True)

    gradients = {"dZ3": dZ3, "dW3": dW3, "db3": db3,
                 "dA2": dA2, "dZ2": dZ2, "dW2": dW2, "db2": db2,
                 "dA1": dA1, "dZ1": dZ1, "dW1": dW1, "db1": db1}

    return gradients


def backward_propagation_with_regularization(X, Y, cache, lambd):
    m = X.shape[1]
    (Z1, A1, W1, b1, Z2, A2, W2, b2, Z3, A3, W3, b3) = cache
    # 输出层梯度计算,增加了正则项的梯度
    dZ3 = A3 - Y
    dW3 = 1. / m * np.dot(dZ3, A2.T) + (lambd * W3) / m
    db3 = 1. / m * np.sum(dZ3, axis=1, keepdims=True)

    # 第二层梯度计算
    dA2 = np.dot(W3.T, dZ3)
    dZ2 = np.multiply(dA2, np.int64(A2 > 0))
    dW2 = 1. / m * np.dot(dZ2, A1.T) + (lambd * W2) / m
    db2 = 1. / m * np.sum(dZ2, axis=1, keepdims=True)

    # 第一层梯度计算
    dA1 = np.dot(W2.T, dZ2)
    dZ1 = np.multiply(dA1, np.int64(A1 > 0))
    dW1 = 1. / m * np.dot(dZ1, X.T) + (lambd * W1) / m
    db1 = 1. / m * np.sum(dZ1, axis=1, keepdims=True)

    gradients = {"dZ3": dZ3, "dW3": dW3, "db3": db3, "dA2": dA2,
                 "dZ2": dZ2, "dW2": dW2, "db2": db2, "dA1": dA1,
                 "dZ1": dZ1, "dW1": dW1, "db1": db1}

    return gradients


def backward_propagation_with_dropout(X, Y, cache, keep_prob):
    m = X.shape[1]
    (Z1, D1, A1, W1, b1, Z2, D2, A2, W2, b2, Z3, A3, W3, b3) = cache
    # 输出层梯度计算
    dZ3 = A3 - Y
    dW3 = 1. / m * np.dot(dZ3, A2.T)
    db3 = 1. / m * np.sum(dZ3, axis=1, keepdims=True)
    # 第二层梯度计算
    dA2 = np.dot(W3.T, dZ3)
    dA2 = dA2 * D2  
    dA2 = dA2 / keep_prob
    dZ2 = np.multiply(dA2, np.int64(A2 > 0))
    dW2 = 1. / m * np.dot(dZ2, A1.T)
    db2 = 1. / m * np.sum(dZ2, axis=1, keepdims=True)
    # 第一层梯度计算
    dA1 = np.dot(W2.T, dZ2)
    dA1 = dA1 * D1 
    dA1 = dA1 / keep_prob  
    dZ1 = np.multiply(dA1, np.int64(A1 > 0))
    dW1 = 1. / m * np.dot(dZ1, X.T)
    db1 = 1. / m * np.sum(dZ1, axis=1, keepdims=True)

    gradients = {"dZ3": dZ3, "dW3": dW3, "db3": db3, "dA2": dA2,
                 "dZ2": dZ2, "dW2": dW2, "db2": db2, "dA1": dA1,
                 "dZ1": dZ1, "dW1": dW1, "db1": db1}

    return gradients


def update_parameters(parameters, grads, learning_rate):
    n = len(parameters) // 2  # number of layers

    for k in range(n):
        parameters["W" + str(k + 1)] = parameters["W" + str(k + 1)] - learning_rate * grads["dW" + str(k + 1)]
        parameters["b" + str(k + 1)] = parameters["b" + str(k + 1)] - learning_rate * grads["db" + str(k + 1)]

    return parameters

def predict(X, y, parameters):
    m = X.shape[1]
    p = np.zeros((1, m), dtype=np.int)

    a3, caches = forward_propagation(X, parameters)

    for i in range(0, a3.shape[1]):
        if a3[0, i] > 0.5:
            p[0, i] = 1
        else:
            p[0, i] = 0

    # print ("predictions: " + str(p[0,:]))
    # print ("true labels: " + str(y[0,:]))
    print("Accuracy: " + str(np.mean((p[0, :] == y[0, :]))))

    return p


def model(X, Y, learning_rate=0.3, num_iterations=30000, print_cost=True, lambd=0, keep_prob=1):
    grads = {}
    costs = []  
    m = X.shape[1]  
    layers_dims = [X.shape[0], 20, 3, 1]

    parameters = initialize_parameters(layers_dims)

    for i in range(0, num_iterations):
        # Forward propagation
        if keep_prob == 1:
            a3, cache = forward_propagation(X, parameters)
        elif keep_prob < 1:
            a3, cache = forward_propagation_with_dropout(X, parameters, keep_prob)

        # Cost function
        if lambd == 0:
            cost = compute_cost(a3, Y)
        else:
            cost = compute_cost_with_regularization(a3, Y, parameters, lambd)

        # Backward propagation.
        if lambd == 0 and keep_prob == 1:
            grads = backward_propagation(X, Y, cache)
        elif lambd != 0:
            grads = backward_propagation_with_regularization(X, Y, cache, lambd)
        elif keep_prob < 1:
            grads = backward_propagation_with_dropout(X, Y, cache, keep_prob)

        # Update parameters.
        parameters = update_parameters(parameters, grads, learning_rate)

        if print_cost and i % 10000 == 0:
            print("Cost after iteration {}: {}".format(i, cost))
        if print_cost and i % 1000 == 0:
            costs.append(cost)

    return parameters

1.7 其他正则化方法

Data augmentation:对于图像输入尤其有用,通过将图像左右镜像,颜色变换,旋转角度等,可以将一张图片变成多张,从而增大输入数据集。

Early stoping:在训练过程中关注开发集上的误差,在开发集误差开始变差时,停止训练过程。

1.8 正则化输入

如果输入数据有多个维度,如果不同维度的取值类型不同,同时取值范围也大不相同,这将造成梯度下降在各个维度上是非对称的。在窄维度上需要一个很小的学习率才能找到极值,而在宽维度上将需要很多步骤。因而会造成训练时间过长。
解决这一问题的方法是对输入进行正则化,尽量使得各个维度的输入归一化,从而使得成本函数有更好的对称性。

一种正则化方法是如下公式所示:
x=x−μσ2+ϵ√ x = x − μ σ 2 + ϵ
不仅输入可以进行归一化,各个隐含层的输出在激活前也可以进行归一化。

1.9 梯度消失与梯度爆炸

当神经网络层数过多时,各层的权重参数w在运算过程中会出现指数级的累积效应。
以Relu激活函数为例,忽略参数b,将输出层的运算展开
z[l]=w[l]a[l−1]=w[l](w[l−1]a[l−2])=...=w[l](w[l−1](...w[2](w[1]x))) z [ l ] = w [ l ] a [ l − 1 ] = w [ l ] ( w [ l − 1 ] a [ l − 2 ] ) = . . . = w [ l ] ( w [ l − 1 ] ( . . . w [ 2 ] ( w [ 1 ] x ) ) )
当l较大时,比如大于100。若w在初始化小于1,则经过若干次乘积,最终z将十分接近于0。而w在初始化时大于1,则经过若干次乘积,最终z将十分巨大。而这种现象对我们训练权重参数十分不利。

1.10 参数初始化

可以通过合适的权重初始化方法来减轻此问题带来的影响,其方法是将权重参数设置为接近1。具体作法与使用的激活函数有关。

He初始化:当使用relu激活时适用。
w[l]=np.random.rand(shape)∗2n[l−1]‾‾‾‾√ w [ l ] = n p . r a n d o m . r a n d ( s h a p e ) ∗ 2 n [ l − 1 ]
Xavier初始化:当使用tanh激活时适用。
w[l]=np.random.rand(shape)∗1n[l−1]‾‾‾‾√ w [ l ] = n p . r a n d o m . r a n d ( s h a p e ) ∗ 1 n [ l − 1 ]

好的初始化可以加速训练过程的收敛,并可以使训练误差收敛在一个较小的水平上。

1.11 梯度逼近与检验

我们可以在运算时动态的检查梯度的计算结果,方法是我们手工计算某点梯度的近似值,并于神经网络反馈的梯度进行对比。
梯度的逼近值计算: f(θ+ϵ)−f(θ−ϵ)2ϵ f ( θ + ϵ ) − f ( θ − ϵ ) 2 ϵ

梯度检验需要检查每个参数,因而过程十分漫长,只能用于调试,不能用在训练过程中。

2 优化算法

2.1 Mini-batch梯度下降法

在之前实现的梯度下降算法中,我们将整个训练集作为X作为神经网络的输入进行计算。然而如果遇到训练集的规模很大,例如上百万的时候,数据无法全部装入内存,若数据不断在内存和外存之间切换,将十分影响计算效率。问题在于输入的矩阵过大。
Mini-batch梯度下降法的思想是将训练集划分为若干个固定大小(如batch_size=512)的小数据集(mini-batch),每次只运算batch_size个数据。

for i in range(epoches):
    num_batches = math.floor(m/batch_size)
    for t in range(num_batches):
        start,end = t*batch_size, (t+1)*batch_size

        A, caches = forward_propagation(X[:,start:end])
        cost = compute_cost(A, Y[:,start:end])
        grade = backward_propagation(A, caches, parameters)
        parameters = update_paramters(paramters, grade)

由于每次mini-batch都会计算损失函数,而mini-batch样本数明显较小,因此在训练过程中损失函数可能不会呈现出明显递减的趋势,而是呈现不断上下波动但整体降低的趋势。

当batch-size为整体样本数时,则mini-batch梯度下降就是原始的batch梯度下降算法,当batch-size为1时就是逐样本的梯度下降(或随机梯度下降)。batch-size越小,则损失函数的优化过程抖动越大,收敛过程越缓慢。一般的batch-size取值范围在64-512之间的2的指数值。当然不管batch-size多大,最好都保证每个mini-batch的数据能装入内存中。

mini-batch的一个变体是每个mini-batch为随机从总体中取batch_size个样本进行训练。

2.2 指数加权移动平均

对于时间序列的数据 θi θ i ,移动均线值 vt v t 的公式为
v0=0 v 0 = 0
vt=βvt−1+(1−β)θt v t = β v t − 1 + ( 1 − β ) θ t
我们通过下图可以看出指数加权移动平均的平滑作用。
此处输入图片的描述

2.3 动量梯度下降

动量(Momentum)梯度下降是基于指数加权移动平均的想法,对后向传播中计算的dw和db进行指数移动平均化,以平滑其抖动,这样可以加快训练的收敛速度。

下面列出了动量梯度下降中反向传播中w,b的更新计算公式
dW′=β1dW′+(1−β1)dW d W ′ = β 1 d W ′ + ( 1 − β 1 ) d W
db′=β1db′+(1−β1)db d b ′ = β 1 d b ′ + ( 1 − β 1 ) d b
W−=αdW′ W − = α d W ′
b−=αdb′ b − = α d b ′

通常将 β β 设置为0.9。

下面的代码可以插入到之前实现的神经网络中以实现动量梯度下降。

def initialize_velocity(parameters):
    layers = len(parameters) // 2 # number of layers in the neural networks
    v = {}
    for l in range(layers):
        v["dW" + str(l + 1)] = np.zeros_like(parameters["W" + str(l+1)])
        v["db" + str(l + 1)] = np.zeros_like(parameters["b" + str(l+1)])

    return v

def update_parameters_with_momentum(parameters, grads, v, beta, learning_rate):

    layers = len(parameters) // 2 

    for l in range(layers):
        v["dW" + str(l+1)] = beta * v["dW" + str(l)] + (1-beta) * grads['dW' + str(l+1)]
        v["db" + str(l+1)] = beta * v["db" + str(l)] + (1-beta) * grads['db' + str(l+1)]

        # update parameters
        parameters["W" + str(l + 1)] = parameters["W" + str(l + 1)] - learning_rate * v["dW" + str(l + 1)]
        parameters["b" + str(l + 1)] = parameters["b" + str(l + 1)] - learning_rate * v["db" + str(l + 1)]

    return parameters, v

2.4 RMSprop

RMSprop也是一种加速训练收敛的方法。
下面列出了RMSprop梯度下降中反向传播中w,b的更新计算公式
dW′=β2dW′+(1−β2)(dW)2 d W ′ = β 2 d W ′ + ( 1 − β 2 ) ( d W ) 2
db′=β2db′+(1−β2)(db)2 d b ′ = β 2 d b ′ + ( 1 − β 2 ) ( d b ) 2
W−=αdWdW′√ W − = α d W d W ′
b−=αdbdb′√ b − = α d b d b ′

2.5 Adam优化算法

Adam算法结合了动量梯度与RMSprop的思想。具体计算公式如下:
dW1=β1dW1+(1−β1)dW d W 1 = β 1 d W 1 + ( 1 − β 1 ) d W
db1=β1db1+(1−β1)db d b 1 = β 1 d b 1 + ( 1 − β 1 ) d b
dW2=β2dW2+(1−β2)(dW)2 d W 2 = β 2 d W 2 + ( 1 − β 2 ) ( d W ) 2
db2=β2db2+(1−β2)(db)2 d b 2 = β 2 d b 2 + ( 1 − β 2 ) ( d b ) 2
dWcorrect1=dW11−βt1 d W 1 c o r r e c t = d W 1 1 − β 1 t
dbcorrect1=db11−βt1 d b 1 c o r r e c t = d b 1 1 − β 1 t
dWcorrect2=dW21−βt2 d W 2 c o r r e c t = d W 2 1 − β 2 t
dbcorrect2=db21−βt2 d b 2 c o r r e c t = d b 2 1 − β 2 t
W−=αdWcorrect1dWcorrect2√+ϵ W − = α d W 1 c o r r e c t d W 2 c o r r e c t + ϵ
b−=αdbcorrect1dbcorrect2+ϵ√ b − = α d b 1 c o r r e c t d b 2 c o r r e c t + ϵ
推荐使用超参数如下表所示:

超参数 α α β1 β 1 β2 β 2 ϵ ϵ
推荐值待调优0.90.999 10−8 10 − 8

2.6 学习率衰减

在神经网络训练的初期往往需要较大的学习率,使得梯度下降可以快速到达某个极值区域。随后则需要较小的学习率,使用逐步逼近极值点。

学习率衰减是一种随着训练轮数增加减小学习率的算法。decay_rate为衰减因子,只需要在每次epoch时更新学习率参数即可,更新公式如下:
α=11+decay_rate∗epoch_num α = 1 1 + d e c a y _ r a t e ∗ e p o c h _ n u m

2.7 局部最优化问题

由于神经网络中参数巨大,因此局部很小问题并不像人们原始认为那样严重。在高维空间中,更多的是要解决如何快速到达的鞍点。

对于属于不同维度的超参数,可以使用组合遍历的方法来寻找最优的参数组合。由于效率的原因,只建议从组合中随机的抽取一部分组合来训练模型,然后在效果好的点附近区域寻找更多的参数组合再进行尝试。概括的说,就是先在参数空间中进行粗略的搜索,然后再进入精细的搜索模式。

3 超参数调试

3.1 调试处理

在第2节中,我们引入了众多的超参数,诸如 α α , β β ,至今为止,最为重要的超参数是学习率。

其次隐层单元数,batch_size参数也较为重要。

最后是层数,移动平均的权重参数,学习率衰减因子等。

3.2 超参数的随机选择

以选择学习率为例,如果希望在[0.0001,1]之间随机选择4个值,如果使用均匀分布的方式随机取值,则90%的值都在[0.1,1]的区间上,只有10%的值在[0.0001, 0.1]区间内,这样显然不太合理。
解决这一问题的方法是使用对数坐标区间,区间转换为[-4, 0],在对数区间内随机取值,再通过指数函数,将随机值转换为原始区间内。

3.3 超参数训练的实践

如果没有大量的资源,训练模型只能一个一个进行,每隔一段时间观察一下模型的效果,然后调整一些参数,继续对模型进行训练。
如果有大量的计算资源,则可以同时训练多个模型,每个模型使用不同的超参数,达到并行的效果。

3.4 Batch Norm拟合进神经网络

3.5 Softmax回归

Softmax回归可以认为是Logistic回归的泛化,它可以输出多个分类时的每个类的归一化概率向量。
Softmax层通常用在神经网络的输出层,其作用可以通过下面的公式说明:
Z[l]=W[l]A[l−1]+b[l] Z [ l ] = W [ l ] A [ l − 1 ] + b [ l ]
E=eZ[l] E = e Z [ l ]
A[l]=E∑Ei,Ei为E的各维度分量 A [ l ] = E ∑ E i , E i 为 E 的 各 维 度 分 量

3.6 神经网络框架

在如今的深度学习中,深度学习的框架占据着重要的地位,它可以让学术界和业界以统一的标准,快速实现各种想法并进行传播。本节简单介绍当下比较流行框架。

名称框架语言API支持来源
CaffeC++Python/MatlabPersonal
CNTKC++PythonMicrosoft
DL4JJava
KerasPython
mxnetC++Python/Go/R…
PaddlePythonBaidu
TensorflowC++PythonGoogle
TheanoPythonMontreal University
TorchLuaFacebook

框架的选择要考虑下面的一些因素:

  1. 易于学习和使用
  2. 运行速度
  3. 社区支持情况和活跃度
  4. 框架提供的特性

3.7 Tensorflow

可参考Tensorflow的官方教程.

深度学习基础:从神经网络架构到训练优化实践 神经网络作为深度学习的核心架构,通过多层非线性变换实现复杂函数拟合。其核心在于前向传播的矩阵运算与激活函数(如ReLU)引入的非线性特性,配合反向传播算法实现参数优化。在实际工程中,梯度消失/爆炸问题常通过批归一化、残差连接等技术解决,而优化器(如Adam)的选择直接影响模型收敛效率。正则化技术如Dropout和数据增强能有效提升模型泛化能力,合理的参数初始化(如Kaiming初始化)则是训练成功的前提。这些技术在计算机视觉、自然语言处理等领域有广泛应用,是构建高效AI系统的基础。 阅读详情

相关推荐

Python深度学习实践:优化神经网络的权重初始化策略

Python深度学习实践:优化神经网络的权重初始化策略 1. 背景介绍 1.1 深度学习的兴起 深度学习作为人工智能的一个重要分支,在近年来取得了突飞猛进的发展。从计算机视觉到自然语言处理,深度学习技术已经广泛应用于各

AI天才研究院 1347

[python]中 np.int64解释

Numpy的int64是一个64位整数,这意味着它由64个0或1的位置组成。因此,最小的表示值是-2 **63,最大的表示值是2 **63 - 1 Python的int本质上是无限长的,因此它可以表示任何值。它相当于Java中的BigInteger。它存储为int64的列表,本质上被认为是一个大数

SJZSZYH的博客 6600

60、数据科学与深度学习:优化问题与神经网络实践

本文深入探讨了数据科学与深度学习中的核心主题,涵盖优化问题的多种求解方法,包括目标函数最小化、Booth函数极值求解以及概率分布分位数函数的估计。结合R语言实践,展示了Google Trends数据分析与可视化流程。文章进一步介绍了深度学习基础,比较了传统神经网络与深度学习的差异,解析了感知机、前馈网络、多层感知机的结构与生物神经元的类比,并通过XOR与NAND逻辑运算示例说明神经网络的计算能力。最后,以Keras框架为基础,详细演示了使用R进行泰坦尼克号乘客生存预测的完整建模流程,从数据预处理到模型训练与

peace的博客 80

TypeError:“numpy.int64“类型的对象没有 len()

例如,我们可以使用这个数字作为特征的一部分,进行文本的分类任务。在训练过程中,我们可能需要将这个数字转换为一个固定长度的特征向量,以便于模型处理。在这个示例中,我们首先导入了numpy库,并创建了一个numpy.int64类型的变量。函数,但是这个函数对于非序列对象(如列表、元组等)是必需的,而对于整数这种不可变数据类型(长度固定),它是无效的。函数计算字符串的长度,最后打印出这个长度的值。输出:整数的长度: 5(因为负号不计数)输出:整数的长度: 5。输出:整数的长度: 1。输出:整数的长度: 8。

476

深度学习进阶实践:构建和优化神经网络

本文基于提供的书籍章节内容,深入探讨了使用Python和Keras框架构建和优化神经网络的实践。通过具体的代码示例和运行结果,展示了如何处理数据、构建模型、应用不同的优化技术,并利用回调函数监控训练过程,最终提高模型的准确性和性能。

weixin_33816734的博客 378

吴恩达深度学习编程实践:深层神经网络优化技术及作业解析

损失函数,也称为代价函数或成本函数,是用于评估模型预测值与真实值之间差异的数学函数。在监督学习中,对于每个训练样本,损失函数会计算出一个非负实数值,表示模型预测的误差。误差越大,损失函数的值就越大。常见的损失函数包括均方误差(MSE)和交叉熵损失等。损失函数的数学表达通常如下所示:其中,( y ) 是真实值,( \hat{y} ) 是模型预测值,( f ) 是损失函数。对于回归问题,常用损失函数是均方误差(MSE),而对于分类问题,则常使用交叉熵损失。

weixin_35734408的博客 975

【深度学习基础4】深度神经网络的优化与调参(1)

     转载请注明出处。谢谢。      本博文根据 coursera 吴恩达 Improving Deep Neural Networks: Hyperparameter tuning, Regularization and Optimization整理。作为深度学习网络优化的记录,将三章内容均以要点的形式记录,并结合实例说明。 Q1. 数据设计(数据集该怎么分割)      常规来说,...

Biyoner的博客 1133

告别蓝牙音质妥协:用ESP32和PCM5102搭建WiFi无损音频播放器(附完整代码)

本文详细介绍了如何利用ESP32微控制器和PCM5102 DAC芯片构建一套完整的WiFi无损音频流媒体系统,彻底摆脱蓝牙协议的音质束缚。从硬件原理到软件实现,包括核心器件选型、电路设计、I2S音频驱动实现以及系统优化方案,帮助音频发烧友实现高保真无线音频传输。

weixin_30733003的博客 542

深度学习-深度学习的实用层面 吴恩达第二课第一周作业1答案(Gradient Checking)

# Packages import numpy as np from testCases import * from gc_utils import sigmoid, relu, dictionary_to_vector, vector_to_dictionary, gradients_to_vector # GRADED FUNCTION: forward_propagatio...

Brianone的博客 826

RK3588交叉编译实战:从环境搭建到程序部署

本文详细介绍了在X86主机上为RK3588开发板搭建交叉编译环境的完整流程。从获取ARM工具链、配置sysroot,到实战编译Hello World和Qt应用程序,并提供了部署方法和常见问题解决方案。通过交叉编译,开发者可以在高性能PC上高效开发,并在ARM架构的RK3588上运行程序,大幅提升嵌入式开发效率。

weixin_29191669的博客 274

自动驾驶关键技术(一):时间敏感网络TSN

时间敏感网络TSN的基本概念、协议族介绍和开发流程。

3080

深度学习与神经网络:从算法设计到实践

1.背景介绍 深度学习(Deep Learning)是人工智能(Artificial Intelligence)的一个分支,它主要通过模拟人类大脑的结构和工作原理来进行机器学习。深度学习的核心技术是神经网络(Neural Networks),它们由多层感知器(Perceptrons)组成,这些感知器可以通过训练学习从大量数据中提取出复杂的特征和模式。 深度学习的发展历程可以分为以下几个阶段: ...

AI天才研究院 588

MMCV安装后报错‘from mmcv import Config’?别慌,这是MMCV 2.0的锅!快速降级回退MMCV 1.x全指南

本文详细解析了MMCV 2.0版本升级导致的‘from mmcv import Config’报错问题,提供了从诊断到降级回退MMCV 1.x的完整解决方案。通过pip和OpenMIM工具链的实操指南,帮助开发者快速解决版本冲突,确保项目稳定运行。

weixin_29102619的博客 263

深度学习基础:神经网络数学原理与优化实践

神经网络作为深度学习的核心组件,其数学原理是理解现代AI模型的基础。前向传播通过权重矩阵和激活函数实现特征变换,而反向传播则利用链式法则计算梯度,这是训练模型的关键机制。激活函数如ReLU和Sigmoid引入非线性,直接影响模型的学习能力。在实际工程中,参数初始化和优化算法(如Adam、SGD)的选择对训练效果至关重要。这些技术在计算机视觉、自然语言处理等领域有广泛应用,掌握它们可以帮助开发者构建更高效的深度学习系统。本文通过具体示例解析神经网络的基础数学原理,并分享工程实践中的优化经验。

weixin_34067102的博客 470

2024.6.15丨基于VFDB数据库的致病菌毒力因子注释实战指南

本文提供了一份基于VFDB数据库进行致病菌毒力因子本地化注释的实战指南。详细介绍了从环境准备、DIAMOND工具安装、VFDB数据库选择与构建,到核心比对操作及结果解读与过滤的全流程。重点阐述了本地化分析相较于在线工具在速度、稳定性和批量处理上的优势,旨在帮助微生物基因组研究人员高效、精准地识别致病菌的关键毒力因子。

weixin_29220405的博客 272

【OpenBMC 系列】4.启动流程 使用qume模拟ast2600-evb

1.安装openbmc适配的qume 2.启动bmc 3.使用bmc web

AiFool的博客 4459

深度学习推理优化:神经网络算子性能提升实践

矩阵乘法(GEMM)作为深度学习推理的核心算子,其性能优化直接影响模型推理效率。通过算子融合、内存布局优化和指令级并行等技术手段,可以显著提升计算密集型任务的执行速度。在硬件适配方面,针对x86/ARM/GPU等不同架构的SIMD指令集优化尤为关键,例如利用AVX-512指令集实现向量化计算。工程实践中,缓存行对齐、线程绑定和混合精度计算等优化策略,能够有效解决内存带宽瓶颈和NUMA架构下的性能问题。这些优化技术在ResNet、Transformer等典型模型中已验证可获得30%以上的加速效果,特别适合对延

weixin_34335458的博客 377

基于浏览器插件的拼多多买家订单导出方法

基于浏览器插件的拼多多买家订单导出方法

2501_93542170的博客 1725

AI技术栈解析:从机器学习到神经网络的核心概念与学习路径

机器学习作为人工智能的核心实现路径,其核心原理是让计算机通过数据和经验自动改进性能,而非依赖显式编程。这一技术范式通过监督学习、无监督学习和强化学习等方法,赋予机器从数据中学习规律的能力,在计算机视觉、自然语言处理等领域展现出巨大价值。深度学习作为机器学习的重要分支,通过构建多层神经网络实现自动特征工程,尤其擅长处理图像、语音等非结构化数据。神经网络作为深度学习的核心架构,其卷积神经网络(CNN)和循环神经网络(RNN)等变体已成为计算机视觉和自然语言处理的基础模型。理解这些概念的层次关系,有助于开发者构建

weixin_34389926的博客 394

海思3516DV300智能算法实现

海思3516DV300智能算法实现

xiaoning132的专栏 936

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

深度学习与机器学习如何选择?

人工智能领域包含机器学习(ML)和深度学习(DL)两个重要分支,其中DL是ML的子领域。核心区别在于特征提取方式:ML依赖人工特征工程,DL通过神经网络自动学习特征。选择原则:小数据+强特征用ML(可解释性强),大数据+复杂数据用DL(精度高)。实际应用中建议先尝试ML模型作为基线,再考虑DL提升性能,最终根据数据和任务需求权衡选择最优方案。

2403_84639931的博客 123

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

【第20期】实践深度学习?先接住这三板斧再说

作者:木羊同学来源:华章计算机(hzbook_jsj)深度学习发展到现在,已经不是红不红的问题,真的是那种谈项目做课题不扯两句深度学习,别人就要来怀疑你用的技术是不是落后于时代。可是,深...

华章IT官方博客 661

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

上一篇: 深度学习之一:神经网络与深度学习
下一篇: 深度学习之三:机器学习的策略
zzulp
博客等级 码龄19年 464粉丝 176原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值