【发布时间】:2018-09-13 00:09:54
【问题描述】:
我正在使用JSON type provider 加载我创建的 JSON 文件。类型提供程序的最小输入如下所示:
{
"conv1": {
"weight": {
"shape": [ 64, 3, 7, 7 ],
"data": [ 1e-30, -0.01077061053365469 ]
}
},
"bn1": {
"eps": 1e-05,
"weight": {
"shape": [ 64 ],
"data": [ 1e-30, 0.2651672959327698 ]
},
"bias": {
"shape": [ 64 ],
"data": [ 1e-30, 0.24643374979496002 ]
}
}
}
虽然weight 的两个部分具有相同的形状和类型,但类型提供程序为我提供了两种不同但等效的类型:
type Weight =
inherit IJsonDocument
new : shape: int [] * data: float [] -> Weight
member Data : float []
member JsonValue: JsonValue
member Shape: int []
和
type Weight2 =
inherit IJsonDocument
new : shape: int [] * data: float [] -> Weight2
member Data : float []
member JsonValue: JsonValue
member Shape: int []
首先,这并不好,但也许它无法弄清楚它们的意思是一样的。所以我坐下来尝试编写一个函数来统一两者,这样我就可以从那里继续——我失败了。
我的第一个方法是使用重载:
type Tensor = {
Data:single[]
Shape:int list
} with
static member Unify1 (w:NN.Weight) = { Data = w.Data |> Array.map single; Shape = w.Shape |> Array.toList }
static member Unify1 (w:NN.Weight2) = { Data = w.Data |> Array.map single; Shape = w.Shape |> Array.toList }
错误 FS0438 重复方法。删除元组、函数、度量单位和/或提供的类型后,方法
Unify1与Tensor类型中的另一个方法具有相同的名称和签名。
然后我尝试了这样的手动类型测试:
let unify2 (o:obj) =
match o with
| :? NN.Weight as w -> { Data = w.Data |> Array.map single; Shape = w.Shape |> Array.toList }
| :? NN.Weight2 as w -> { Data = w.Data |> Array.map single; Shape = w.Shape |> Array.toList }
| _ -> failwith "pattern oops"
此变体无法编译,因为
错误 FS3062 不允许使用提供的类型
JsonProvider<...>.Weight进行此类型测试,因为此提供的类型将在运行时擦除为Runtime.BaseTypes.IJsonDocument。
如何让类型提供者生成统一类型?或者,我将如何在使编译器满意的同时自己统一它们?
【问题讨论】: