Stochastic Depth 原理与代码解析

paper:Deep Networks with Stochastic Depth

official implementation:https://github.com/yueatsprograms/Stochastic_Depth

third-party implementation:https://github.com/open-mmlab/mmcv/blob/main/mmcv/cnn/bricks/drop.py

存在的问题

网络深度是模型表达能力的决定性因素,但是非常深的网络也带来了新的挑战:反向传播中的梯度消失、前向传播中特征重用变少、更长的训练时间。 

本文的创新点

本文提出了一种新的训练深度网络的方法,随机深度stochastic depth,在训练阶段随机删除某些层使得网络的总层数变少,既缓解了梯度消失和特征重用减少的问题,又缩短了训练时间。此外和Dropout类似,stochastic depth还起到了正则化的作用,即使在有BN的情况下。用随机深度训练的网络还可以看作不同深度网络的隐式集和ensemble。

方法介绍

Stochastic depth的目的是在训练过程中减小网络的深度,同时在测试过程中保持其不变。\(b_{\ell}\in\{0,1\}\) 是一个伯努利随机变量,表示第 \(\ell^{th}\) ResBlock是active(\(b_{\ell}=1\))还是inactive(\(b_{\ell}=0\)),更进一步,将ResBlock \(\ell\) 的“存活”概率表示为 \(p_{\ell}=Pr(b_{\ell}=1)\)。\(p_{\ell}\) 是唯一的超参,关于 \(p_{\ell}\) 的设置有两种方式,一种是对所有层 \(\ell\) 设置同一 \(p_{\ell}\)。另一种是采用线性递减的方式,对于输入 \(p_{0}=1\) 线性递减到最后一个ResBlock的 \(p_{L}\),如下

作者通过实验得出结论第二种设置方式效果更好。

代码解析

这里的代码来自MMCV,和论文中的实现有出入,其中shape只保留batch_size的值,其它所有维度的值都为1。torch.rand从均匀分布[0, 1]中采样,与keep_prob相加得到random_tensor后最后再向下取整.floor(),假设drop_prob=0.2即有0.2的概率丢弃该层,则有keep_prob=1-drop_prob=0.8的概率保留该层,与[0, 1]均匀分布相加后有0.8的概率大于1向下取整后为1,0.2的概率小于1向下取整后为0。x.div(keep_prob)和dropout中的操作一样,因为训练时随机丢弃部分连接或层,推理时不丢弃,除以keep_prob是为了保持总体期望不变。

def drop_path(x: torch.Tensor,
              drop_prob: float = 0.,
              training: bool = False) -> torch.Tensor:
    """Drop paths (Stochastic Depth) per sample (when applied in main path of
    residual blocks).

    We follow the implementation
    https://github.com/rwightman/pytorch-image-models/blob/a2727c1bf78ba0d7b5727f5f95e37fb7f8866b1f/timm/models/layers/drop.py  # noqa: E501
    """
    if drop_prob == 0. or not training:
        return x
    keep_prob = 1 - drop_prob
    # handle tensors with different dimensions, not just 4D tensors.
    shape = (x.shape[0], ) + (1, ) * (x.ndim - 1)
    random_tensor = keep_prob + torch.rand(
        shape, dtype=x.dtype, device=x.device)
    output = x.div(keep_prob) * random_tensor.floor()
    return output

实验结果

如图所示,在CIFAR-10和CIFAR-100上,使用stochastic depth在测试机上的误差都更小。

  • 13
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
T-SNE(t-Distributed Stochastic Neighbor Embedding)是一种非线性降维技术,可以将高维数据映射到低维空间中,并保留数据之间的相似性关系。T-SNE主要应用于数据可视化和聚类分析。 下面是一个T-SNE的Python代码示例,代码中使用了Scikit-learn库中的TSNE类: ```python from sklearn.manifold import TSNE import matplotlib.pyplot as plt import seaborn as sns import pandas as pd # 读取数据 data = pd.read_csv('data.csv') # 将数据特征列和标签列分开 X = data.iloc[:, :-1].values y = data.iloc[:, -1].values # 创建TSNE对象,设置参数 tsne = TSNE(n_components=2, perplexity=30, early_exaggeration=12, learning_rate=200) # 调用fit_transform()方法对数据进行降维 X_tsne = tsne.fit_transform(X) # 创建散点图,可视化降维后的数据 sns.scatterplot(x=X_tsne[:, 0], y=X_tsne[:, 1], hue=y) plt.show() ``` 在代码中,首先读取了一个数据集,然后将特征列和标签列分开。接着创建了一个TSNE对象,并设置了一些参数,如n_components表示降维后的维度数,perplexity表示困惑度,early_exaggeration表示早期聚焦程度,learning_rate表示学习率等。最后调用fit_transform()方法对数据进行降维,并使用sns库和matplotlib库创建散点图,可视化降维后的数据。 需要注意的是,T-SNE是一种计算密集型算法,对于大规模数据集可能会比较耗时。因此,在使用T-SNE进行降维时,需要在选择参数和数据量上进行权衡。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

00000cj

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值