我创建了一个名为 HousingData 的新结构,还定义了迭代和长度等函数。但是,当我为 HousingData 对象使用函数 collect 时,我遇到了以下错误。
TypeError: in typeassert, expected Integer, got a value of type Float64
import Base: length, size, iterate
struct HousingData
x
y
batchsize::Int
shuffle::Bool
num_instances::Int
function HousingData(
x, y; batchsize::Int=100, shuffle::Bool=false, dtype::Type=Array{Float64})
new(convert(dtype,x),convert(dtype,y),batchsize,shuffle,size(y)[end])
end
end
function length(d::HousingData)
return ceil(d.num_instances/d.batchsize)
end
function iterate(d::HousingData, state=ifelse(
d.shuffle, randperm(d.num_instances), collect(1:d.num_instances)))
if(length(state)==0)
return nothing
end
return ((d.x[:,state[1]],d.y[:,state[1]]),state[2:end])
end
x1 = randn(5, 100); y1 = rand(1, 100);
obj = HousingData(x1,y1; batchsize=20)
collect(obj)
最佳答案
您的代码中存在多个问题。第一个与 length
相关,不返回整数,而是返回 float 。 ceil
的行为解释了这一点:
julia> ceil(3.8)
4.0 # Notice: 4.0 (Float64) and not 4 (Int)
你可以很容易地解决这个问题:
function length(d::HousingData)
return Int(ceil(d.num_instances/d.batchsize))
end
还有一个问题是你迭代函数的逻辑,和标榜的长度不一致。举一个比你的小的例子:
julia> x1 = [i+j/10 for i in 1:2, j in 1:6]
2×6 Array{Float64,2}:
1.1 1.2 1.3 1.4 1.5 1.6
2.1 2.2 2.3 2.4 2.5 2.6
# As an aside, unless you really want to work with 1xN matrices
# it is more idiomatic in Julia to use 1D Vectors in such situations
julia> y1 = [Float64(j) for i in 1:1, j in 1:6]
1×6 Array{Float64,2}:
1.0 2.0 3.0 4.0 5.0 6.0
julia> obj = HousingData(x1,y1; batchsize=3)
HousingData([1.1 1.2 … 1.5 1.6; 2.1 2.2 … 2.5 2.6], [1.0 2.0 … 5.0 6.0], 3, false, 6)
julia> length(obj)
2
julia> for (i, e) in enumerate(obj)
println("$i -> $e")
end
1 -> ([1.1, 2.1], [1.0])
2 -> ([1.2, 2.2], [2.0])
3 -> ([1.3, 2.3], [3.0])
4 -> ([1.4, 2.4], [4.0])
5 -> ([1.5, 2.5], [5.0])
6 -> ([1.6, 2.6], [6.0])
迭代器产生 6 个元素,而此对象的 length
只有 2。这解释了为什么 collect
出错:
julia> collect(obj)
ERROR: ArgumentError: destination has fewer elements than required
了解您的代码,您可能是修复其逻辑的最佳人选。
关于julia - Julia 中的类型错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64716018/