Drop 简介

<!-- /* default css */ table { font-size: 1em; line-height: inherit; border-collapse: collapse; } tr { text-align: left; } div, address, ol, ul, li, option, select { margin-top: 0px; margin-bottom: 0px; } p { margin: 0px; } pre { font-family: Courier New; white-space: pre-wrap; margin:0; } body { margin: 6px; padding: 0px; font-family: Verdana, sans-serif; font-size: 10pt; background-color: #ffffff; } img { -moz-force-broken-image-icon: 1; } @media screen { html.pageview { background-color: #f3f3f3 !important; overflow-x: hidden; overflow-y: scroll; } body { min-height: 1100px; counter-reset: __goog_page__; } * html body { height: 1100px; } .pageview body { border-top: 1px solid #ccc; border-left: 1px solid #ccc; border-right: 2px solid #bbb; border-bottom: 2px solid #bbb; width: 648px !important; margin: 15px auto 25px; padding: 40px 50px; } /* IE6 */ * html { overflow-y: scroll; } * html.pageview body { overflow-x: auto; } /* Prevent repaint errors when scrolling in Safari. This "Star-7" css hack targets Safari 3.1, but not WebKit nightlies and presumably Safari 4. That's OK because this bug is fixed in WebKit nightlies/Safari 4 :-). */ html*#wys_frame::before { content: '/A0'; position: fixed; overflow: hidden; width: 0; height: 0; top: 0; left: 0; } .writely-callout-data { display: none; } .writely-footnote-marker { background-image: url('MISSING'); background-color: transparent; background-repeat: no-repeat; width: 7px; overflow: hidden; height: 16px; vertical-align: top; -moz-user-select: none; } .editor .writely-footnote-marker { cursor: move; } .writely-footnote-marker-highlight { background-position: -15px 0; -moz-user-select: text; } .writely-footnote-hide-selection ::-moz-selection, .writely-footnote-hide-selection::-moz-selection { background: transparent; } .writely-footnote-hide-selection ::selection, .writely-footnote-hide-selection::selection { background: transparent; } .writely-footnote-hide-selection { cursor: move; } /* Comments */ .writely-comment-yellow { background-color: #ffffd7; } .writely-comment-orange { background-color: #ffe3c0; } .writely-comment-pink { background-color: #ffd7ff; } .writely-comment-green { background-color: #d7ffd7; } .writely-comment-blue { background-color: #d7ffff; } .writely-comment-purple { background-color: #eed7ff; } .br_fix span+br:not(:-moz-last-node) { position:relative; left: -1ex } #cb-p-tgt { font-size: 8pt; padding: .4em; background-color: #ddd; color: #333; } #cb-p-tgt-can { text-decoration: underline; color: #36c; font-weight: bold; margin-left: 2em; } #cb-p-tgt .spin { width: 16px; height: 16px; background: url(//ssl.gstatic.com/docs/clipboard/spin_16o.gif) no-repeat; } } h6 { font-size: 8pt } h5 { font-size: 8pt } h4 { font-size: 10pt } h3 { font-size: 12pt } h2 { font-size: 14pt } h1 { font-size: 18pt } blockquote {padding: 10px; border: 1px #DDD dashed } .webkit-indent-blockquote { border: none; } a img {border: 0} .pb { border-width: 0; page-break-after: always; /* We don't want this to be resizeable, so enforce a width and height using !important */ height: 1px !important; width: 100% !important; } .editor .pb { border-top: 1px dashed #C0C0C0; border-bottom: 1px dashed #C0C0C0; } div.google_header, div.google_footer { position: relative; margin-top: 1em; margin-bottom: 1em; } /* Table of contents */ .editor div.writely-toc { background-color: #f3f3f3; border: 1px solid #ccc; } .writely-toc > ol { padding-left: 3em; font-weight: bold; } ol.writely-toc-subheading { padding-left: 1em; font-weight: normal; } /* IE6 only */ * html writely-toc ol { list-style-position: inside; } .writely-toc-none { list-style-type: none; } .writely-toc-decimal { list-style-type: decimal; } .writely-toc-upper-alpha { list-style-type: upper-alpha; } .writely-toc-lower-alpha { list-style-type: lower-alpha; } .writely-toc-upper-roman { list-style-type: upper-roman; } .writely-toc-lower-roman { list-style-type: lower-roman; } .writely-toc-disc { list-style-type: disc; } /* Ordered lists converted to numbered lists can preserve ordered types, and vice versa. This is confusing, so disallow it */ ul[type="i"], ul[type="I"], ul[type="1"], ul[type="a"], ul[type="A"] { list-style-type: disc; } ol[type="disc"], ol[type="circle"], ol[type="square"] { list-style-type: decimal; } /* end default css */ /* default print css */ @media print { body { padding: 0; margin: 0; } div.google_header, div.google_footer { display: block; min-height: 0; border: none; } div.google_header { flow: static(header); } /* used to insert page numbers */ div.google_header::before, div.google_footer::before { position: absolute; top: 0; } div.google_footer { flow: static(footer); } /* always consider this element at the start of the doc */ div#google_footer { flow: static(footer, start); } span.google_pagenumber { content: counter(page); } span.google_pagecount { content: counter(pages); } .endnotes { page: endnote; } /* MLA specifies that endnotes title should be 1" margin from the top of the page. */ @page endnote { margin-top: 1in; } callout.google_footnote { display: prince-footnote; footnote-style-position: inside; /* These styles keep the footnote from taking on the style of the text surrounding the footnote marker. They can be overridden in the document CSS. */ color: #000; font-family: Verdana; font-size: 10.0pt; font-weight: normal; } /* Table of contents */ #WritelyTableOfContents a::after { content: leader('.') target-counter(attr(href), page); } #WritelyTableOfContents a { text-decoration: none; color: black; } /* Comments */ .writely-comment-yellow { background-color: #ffffd7; } .writely-comment-orange { background-color: #ffe3c0; } .writely-comment-pink { background-color: #ffd7ff; } .writely-comment-green { background-color: #d7ffd7; } .writely-comment-blue { background-color: #d7ffff; } .writely-comment-purple { background-color: #eed7ff; } } @page { @top { content: flow(header); } @bottom { content: flow(footer); } @footnotes { border-top: solid black thin; padding-top: 8pt; } } /* end default print css */ /* custom css */ /* end custom css */ /* ui edited css */ body { font-family: Verdana; font-size: 10.0pt; line-height: normal; background-color: #ffffff; } /* end ui edited css */ /* editor CSS */ .editor a:visited {color: #551A8B} .editor table.zeroBorder {border: 1px dotted gray} .editor table.zeroBorder td {border: 1px dotted gray} .editor table.zeroBorder th {border: 1px dotted gray} .editor div.google_header, .editor div.google_footer { border: 2px #DDDDDD dashed; position: static; width: 100%; min-height: 2em; } .editor .misspell {background-color: yellow} .editor .writely-comment { font-size: 9pt; line-height: 1.4; padding: 1px; border: 1px dashed #C0C0C0 } /* end editor CSS */ -->

Drop 简介

Drop 简介

转载请保留作者信息:

作者:88250

时间:2009 年 11 月 30 日

Drop 是一个开源的 JSR-330(Dependency Injection for Java)参考实现,已通过 JSR-330 TCK 测试。该项目旨在构建一个符合 JSR-330 的最小化实现,使得新手能够更快了解 Java 依赖注入实现原理以及了解 Java 依赖注入标准规范。Drop 使用的是 Java 反射来进行依赖注入,没有使用代码生成来实现依赖注入。


Drop 注入器配置

Drop 提供两种方式配置组件(Bean):
  1. Java 注解
    例如:

    @Named("helloSpeaker")
    @Hello // 限定器
    @SessionScoped // 作用域
    public class HelloSpeaker {
    public String say() {
    return "Hello!";
    }
    }
  2. Builder-style APIs
    Configurer.createBean(concreteClass<T>) : Bean<T>
    Bean.<T>named(stringName) : Bean<T>
    Bean.<T>scoped(scopeAnnotation) : Bean<T>
    Bean.<T>qualified(qualifierAnnotation, qualifierAnnotation...) : Bean<T>

例如:

final Configurer configurer = injector.getConfigurer();
configurer.createBean(HelloSpeaker.class).
named("helloSpeaker").
scoped(new DefaultScopedLiteral()).
qualified(new HelloLiteral());

在 JSR-330 中,Named 也是一种 Qualifier,所以上述例子也可以这样写:

configurer.createBean(HelloSpeaker.class).
named("helloSpeaker").
scoped(new DefaultScopedLiteral()).
qualified (new NamedLiteral("helloSpeaker"), new HelloLiteral());

注入点检查

Drop 使用类型安全的依赖解析算法,类型安全指的就是:
    1. 不使用文本内容进行组件依赖配置
    2. 依赖类型 + 限定器 = 类型安全
在所有组件配置完成后,Drop 将对其进行注入点检查。

  1. 注入点
    注入点描述了需要进行依赖注入(标注了 @Inject)的元素信息。依赖注入有三个方法:字段注入,构造器注入,方法注入。据此,注入点可以分为两类,字段注入点,参数注入点。
  2. 需要的类型
    需要的类型指的是被注入实例的的类型。该信息包含在注入点描述中。
  3. 需要的限定器
    需要的限定器指的是注入点中描述的限定器。当注入点同时存在需要的限定器与需要的类型时,依赖注入容器可以进行类型安全的依赖查找与注入。
  4. 依赖不满足
    该情况指的是依赖注入容器在进行注入点依赖查找时未从容器中找到满足注入点条件的情况。
  5. 依赖混淆
    该情况指的是依赖注入容器在进行注入点依赖查找时从容器中查找到多于一个满足注入点条件的情况。
  6. 依赖检查
    依赖检查指的就是检查依赖注入器中的所有注入点是否合法以及是被否满足,发生在容器配置后。如果满足,则注入器可以进行依赖注入,如果不满足,则抛出检查异常。
例如,形如 @Inject Speaker nightSpeaker 的注入点,其需要的类型为:Speaker;需要的限定器为空集。形如 @Inject @Night Speaker nightSpeaker 的注入点,其需要的类型为:Speaker;需要的限定器为 @Night。该注入点为合法注入点,但是否能满足依赖还需要根据注入器的配置进行检查。

注入点合法性检查

一个合法可注入的构造器:
  1. 被 @Inject 标注。
  2. 接受 0 个或多个参数,所有参数都作为参数注入点。
  3. 在同一个类上只能存在一个可注入的构造器(只能有一个构造器被 @Inject 标注),如果一个类有且仅有一个默认构造器(public 修饰,无参数),不管是否标注 @Inject,注入器都将调用该默认构造器。
  4. 不能是带类型参数的构造器。例如:<T> TypeName(T t) 不能进行注入。

一个合法可注入的字段:
  1. 被 @Inject 标注。
  2. 不能是 final 的。
  3. 不能是类型变量。例如 T field 不能进行注入。

一个合法可注入的方法:
  1. 被 @Inject 标注。
  2. 不能是 abstract 的。
  3. 接受 0 个或多个参数,所有参数都作为参数注入点。
  4. 不能是带类型参数的方法。例如:<T> void method(T t) 不能进行注入。

Drop 目前还没有全部实现所有上述条件的检查。

注入点依赖满足检查

JSR-330 规范将 @Named 定义为了一个限定器,并且有一个 String 类型的属性。这样,除了使用类型安全的依赖解析算法,也可以使用命名解析算法。下面,我们通过一个具体的例子来看看如何对注入点进行依赖满足检查。
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.FIELD})
@Qualifier
public @interface Night {}
public interface Speaker {
String say();
}
public interface DarkernessSpeaker extends Speaker {}
@Named("nightSpeaker")
@Night
public class NightSpeaker implements DarknessSpeaker {
@Override
public String say() {
return "Night!";
}
}
public class SpeakerService {
@Inject
private Speaker nightSpeaker1;
@Inject
private DarknessSpeaker nightSpeaker2;
@Inject
private NightSpeaker nightSpeaker3;
@Inject
@Night
private Speaker nightSpeaker4;
@Inject
@Named("nightSpeaker")
private Speaker nightSpeaker5;
@Inject
@Named("nightSpeaker")
@Night
private Speaker nightSpeaker6;
}

我们逐个分析 SpeakerService 类的字段注入点依赖检查。注意,在整个依赖注入容器中,目前有且仅有一个 Speaker 接口的实现,即 NightSpeaker。因此,对于:
  1. @Inject private Speaker nightSpeaker1;
    该字段是可依赖解析的,不存在依赖不满足或依赖混淆情况。注入器可以根据接口 Speaker 查找到其唯一的实现 NightSpeaker。
  2. @Inject private DarknessSpeaker nightSpeaker2;
    该字段是可以依赖解析的,不存在依赖不满足或依赖混淆情况。注入器可以根据抽象类 DarknessSpeaker 查找到其唯一的实现 NightSpeaker。
  3. @Inject private NightSpeaker nightSpeaker3;
    该字段是可以依赖解析的,不存在依赖不满足或依赖混淆情况。注入器可以根据具体类 DarknessSpeaker 查找到其唯一的实现 NightSpeaker。
  4. @Inject @Night private Speaker nightSpeaker4;
    该字段是可以依赖解析的,不存在依赖不满足或依赖混淆情况。注入器可以根据接口 Speaker 与限定器 @Night 查找到其唯一的实现 NightSpeaker。
  5. @Inject @Named("nightSpeaker") private Speaker nightSpeaker4;
    该字段是可以依赖解析的,不存在依赖不满足或依赖混淆情况。注入器可以根据接口 Speaker 与限定器 @Named("nightSpeaker") 查找到其唯一的实现 NightSpeaker。
  6. @Inject @Named("nightSpeaker") @Night private Speaker nightSpeaker4;
    该字段是可以依赖解析的,不存在依赖不满足或依赖混淆情况。注入器可以根据接口 Speaker 与限定器集 {@Named("nightSpeaker"), @Night} 查找到其唯一的实现 NightSpeaker。

现在,我们添加一个 Speaker 实现类:

public class HelloSpeaker implements Speaker {
@Override
public String say() {
return "Night!";
}
}

此时,对于 SpeakerService 类的字段注入点 @Inject private Speaker nightSpeaker1; 来说,该注入点是不可依赖解析的,存在依赖混淆情况。注入器在根据接口 Speaker 查找时,将找到两个实现:NightSpeaker 与 HelloSpeaker。注入器无法判别该用哪一个类的实例进行依赖注入。

依赖注入

注入顺序

JSR-330 规定了依赖注入的顺序,如下(忽略了静态成员注入):
  1. 构造器注入
  2. 父类字段注入
  3. 父类方法注入
  4. 子类字段注入
  5. 子类方法注入

注入实现

算法实现了遵循 JSR-330 的依赖注入顺序:
SimpleBean.java:

@Override
protected void resolveDependencies(final Object reference)
throws Exception {
final Class<?> superclass = reference.getClass().getSuperclass();
resolveSuperclassFieldDependencies(reference, superclass);
resolveSuperclassMethodDependencies(reference, superclass);
resolveCurrentclassFieldDependencies(reference);
resolveCurrentclassMethodDependencies(reference);
}

具体实现为 Java 类层次递归实现,请参考 源码

中英术语对照表

英文
中文
Annotation 注解
Qulifier 限定器
Scope
作用域
Bean
组件
Injection Point
注入点
Required Type
需要的类型
Required Qualifiers
需要的限定器


well-formed

### Drop Path 技术简介 Drop Path 是一种正则化技术,广泛应用于深度学习框架中,尤其是在神经网络架构的训练阶段。它通过在训练过程中随机丢弃网络中的某些路径来减少模型的过拟合风险[^1]。这种方法与 Dropout 类似,但作用于整个路径而非单个神经元。Drop Path 的核心思想在于,通过引入随机性,使模型更加鲁棒,并增强其泛化能力。 在深度学习框架中,Drop Path 技术通常被用来训练复杂的神经网络架构,例如卷积神经网络(CNN)和图神经网络(GNN)。例如,在一些现代架构如 EfficientNet 和 Vision Transformers 中,Drop Path 被用作一种有效的正则化手段以提升模型性能[^2]。 以下是一个使用 PyTorch 实现 Drop Path 的代码示例: ```python import torch import torch.nn as nn class DropPath(nn.Module): def __init__(self, drop_prob=None): super(DropPath, self).__init__() self.drop_prob = drop_prob def forward(self, x): if self.drop_prob == 0. or not self.training: return x keep_prob = 1 - self.drop_prob shape = (x.shape[0],) + (1,) * (x.ndim - 1) # work with diff dim tensors, not just 2D ConvNets random_tensor = keep_prob + torch.rand(shape, dtype=x.dtype, device=x.device) random_tensor.floor_() # binarize output = x.div(keep_prob) * random_tensor return output ``` ### Drop Path 的应用场景 Drop Path 技术不仅适用于图像分类任务,还可以扩展到其他领域,例如自然语言处理(NLP)和时间序列预测。在这些任务中,Drop Path 可以帮助模型更好地处理复杂的数据结构,同时避免过拟合[^3]。此外,Drop Path 还可以与其他正则化技术结合使用,进一步提高模型的稳定性和准确性。 ### 注意事项 尽管 Drop Path 是一种强大的正则化工具,但在实际应用中需要注意以下几点: - **调整参数**:Drop Path 的效果很大程度上取决于其概率参数的选择。建议根据具体任务调整该参数。 - **数据规模**:对于小规模数据集,Drop Path 可能会导致欠拟合问题。因此,在使用前需要充分评估数据量是否足够支持该技术。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值