我试图了解 Go 泛型(v1.18)中类型联合约束的用法。这是我尝试过的代码:
type A struct {
}
type B struct {
}
type AB interface {
*A | *B
}
func (a *A) some() bool {
return true
}
func (b *B) some() bool {
return false
}
func some[T AB](x T) bool {
return x.some() // <- error
}
Run Code Online (Sandbox Code Playgroud)
编译器抱怨:
x.some
未定义(类型T
没有字段或方法)
这是为什么?*A
如果我不能使用and类型的共享方法*B
,那么定义类型 union 的意义何在*A | *B
?
(显然我可以使用共享方法定义一个接口并直接使用它。但在我的特定用例中,我想明确限制为某些类型。)
在 tensorflow 中调用 get_variable() 函数时,“reuse”标志的行为在tensorflow api doc 中定义为 AUTO_REUSE:
重用:True、None 或 tf.AUTO_REUSE;...当启用急切执行时,此参数始终强制为 tf.AUTO_REUSE。
但是,当我真正按照网页中的建议运行演示代码时:
tf.enable_eager_execution()
def foo():
with tf.variable_scope("foo", reuse=tf.AUTO_REUSE):
v = tf.get_variable("v", [1])
return v
v1 = foo() # Creates v.
v2 = foo() # Gets the same, existing v.
assert v1 == v2
Run Code Online (Sandbox Code Playgroud)
它失败。(如果第一行被删除,它就会通过,正如预期的那样。)
那么如何在 Eager 模式下重用变量呢?这是一个错误还是我遗漏了什么?
如果我有一个 keras 层 L,并且我想在 keras 模型中堆叠该层的 N 个版本(具有不同的权重),那么最好的方法是什么?请注意,这里的 N 很大并且由超参数控制。如果 N 很小,那么这不是问题(我们可以手动重复一行 N 次)。例如,我们假设 N > 10。
如果该层只有一个输入和一个输出,我可以这样做:
m = Sequential()
for i in range(N):
m.add(L)
Run Code Online (Sandbox Code Playgroud)
但如果我的层实际上接受多个输入,则这不起作用。例如,如果我的层具有 z = L(x, y) 的形式,并且我希望我的模型执行以下操作:
x_1 = L(x_0, y)
x_2 = L(x_1, y)
...
x_N = L(x_N-1, y)
Run Code Online (Sandbox Code Playgroud)
那么 Sequential 就无法完成这项工作。我认为我可以对 keras 模型进行子类化,但我不知道将 N 层放入类中的最简洁方法是什么。我可以使用一个列表,例如:
class MyModel(Model):
def __init__(self):
super(MyModel, self).__init__()
self.layers = []
for i in range(N):
self.layers.append(L)
def call(self, inputs):
x = inputs[0]
y = inputs[1]
for i in range(N):
x …
Run Code Online (Sandbox Code Playgroud) 让我们说在第三方库中我们有一个接口和一个实现这个接口的结构.我们还假设有一个函数将ParentInterface作为参数,它对不同类型具有不同的行为.
type ParentInterface interface {
SomeMethod()
}
type ParentStruct struct {
...
}
func SomeFunction(p ParentInterface) {
switch x := p.Type {
case ParentStruct:
return 1
}
return 0
}
Run Code Online (Sandbox Code Playgroud)
在我们的代码中,我们想要使用这个接口,但是使用我们的增强行为,所以我们将它嵌入到我们自己的结构中.编译器实际上允许我们ParentInterface
直接在我的struct上调用函数:
type MyStruct struct {
ParentInterface
}
parentStruct := ParentStruct{...}
myStruct := MyStruct{parentStruct}
parentStruct.SomeMethod() // Compiler OK.
myStruct.SomeMethod() // Compiler OK. Result is same. Great.
SomeFunction(parentStruct) // Compiler OK. Result is 1.
SomeFunction(myStruct.ParentInterface) // Compiler OK. Result is 1.
SomeFunction(myStruct) // Compiler OK. Result is 0. (!)
Run Code Online (Sandbox Code Playgroud)
最后一例不是问题吗?我不止一次遇到过这种错误.因为我愉快地使用 …