微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

无法理解 Julia 中的维度不匹配错误

如何解决无法理解 Julia 中的维度不匹配错误

我是 Julia 和 ML 的初学者。我正在尝试重用来自 Flux Model Zoo 的代码,特别是 this,以对来自 this dataset 的图像进行分类。下面是我的代码版本 - 我修改了 build_model 中的数据加载和参数,以说明图像大小和要分类的字符类型数量的差异。原版有 28x28 和 10 个数字,阿拉伯字符集有 32x32 图像和 28 个字符。

function getimages(filename)
    filepath = pwd() * "/images/" * filename

    mtrx = Matrix(DataFrame(CSV.File(filepath)))
    r,_ = size(mtrx)

    v = Vector{Matrix{Int64}}()

    for i = 1:r
        push!(v,reshape(m[i,:],32,32))
    end

    v
end

function getlabels(filename)
    filepath = pwd() * "/images/" * filename
    vec(Matrix(DataFrame(CSV.File(filepath))))
end

function load_data(args)
    train_data_file = "csvTrainImages.csv"
    test_data_file = "csvTestimages.csv"
    train_label_file = "csvTrainLabel.csv"
    test_label_file = "csvTestLabel.csv"

    train_data = getimages(train_data_file)
    test_data = getimages(test_data_file)
    train_labels = getlabels(train_label_file)
    test_labels = getlabels(test_label_file)

    xtrain = Flux.flatten(train_data)
    xtest = Flux.flatten(test_data)

    ytrain,ytest = onehotbatch(train_labels,1:28),onehotbatch(test_labels,1:28)

    train_loader = DataLoader((xtrain,ytrain),batchsize=args.batchsize,shuffle=true)
    test_loader = DataLoader((xtest,ytest),batchsize=args.batchsize)

    return train_loader,test_loader
end

function build_model(; imgsize=(32,1),nclasses=28)
    return Chain(
            Dense(prod(imgsize),relu),Dense(32,nclasses))
end

function loss_and_accuracy(data_loader,model,device)
    acc = 0
    ls = 0.0f0
    num = 0
    for (x,y) in data_loader
        x,y = device(x),device(y)
        ŷ = model(x)
        ls += logitcrossentropy(model(x),y,agg=sum)
        acc += sum(onecold(cpu(model(x))) .== onecold(cpu(y)))
        num +=  size(x,2)
    end
    return ls / num,acc / num
end

@kwdef mutable struct Args
    η::Float64 = 3e-4       # learning rate
    batchsize::Int = 256    # batch size
    epochs::Int = 10        # number of epochs
    use_cuda::Bool = true   # use gpu (if cuda available)
end

function train(; kws...)
    args = Args(; kws...) # collect options in a struct for convenience

    if CUDA.functional() && args.use_cuda
        @info "Training on CUDA GPU"
        CUDA.allowscalar(false)
        device = gpu
    else
        @info "Training on cpu"
        device = cpu
    end

    # Create test and train DataLoaders
    train_loader,test_loader = load_data(args)

    # Construct model
    model = build_model() |> device
    ps = Flux.params(model) # model's trainable parameters

    ## Optimizer
    opt = Adam(args.η)

    ## Training
    for epoch in 1:args.epochs
        for (x,y) in train_loader
            x,device(y) # transfer data to device
            gs = gradient(() -> logitcrossentropy(model(x),y),ps) # compute gradient
            Flux.Optimise.update!(opt,ps,gs) # update parameters
        end
    
        # Report on train and test
        train_loss,train_acc = loss_and_accuracy(train_loader,device)
        test_loss,test_acc = loss_and_accuracy(test_loader,device)
        println("Epoch=$epoch")
        println("  train_loss = $train_loss,train_accuracy = $train_acc")
        println("  test_loss = $test_loss,test_accuracy = $test_acc")
    end
end

我在训练模型时收到以下错误。具体来说,在梯度计算期间。你能帮我理解错误指的是哪两个矩阵并指出我的解决方案吗?我的猜测是它与 build_model 参数有关,但我不太确定需要更改什么以及如何更改。

DimensionMismatch("matrix A has dimensions (32,1024),matrix B has dimensions (1,256)")
macro expansion@interface2.jl:0[inlined]
_pullback(::Zygote.Context,::typeof(throw),::DimensionMismatch)@interface2.jl:9
_pullback@matmul.jl:814[inlined]
_pullback(::Zygote.Context,::typeof(Linearalgebra._generic_matmatmul!),::Matrix{Matrix{Float32}},::Char,::Matrix{Float32},::Matrix{Matrix{Int64}},::Linearalgebra.MulAddMul{true,true,Bool,Bool})@interface2.jl:0
_pullback@matmul.jl:802[inlined]
_pullback(::Zygote.Context,::typeof(Linearalgebra.generic_matmatmul!),Bool})@interface2.jl:0
_pullback@matmul.jl:302[inlined]
_pullback@matmul.jl:275[inlined]
_pullback(::Zygote.Context,::typeof(Linearalgebra.mul!),::Matrix{Matrix{Int64}})@interface2.jl:0
_pullback@matmul.jl:153[inlined]
_pullback(::Zygote.Context,::typeof(*),::Matrix{Matrix{Int64}})@interface2.jl:0
_pullback@basic.jl:147[inlined] ....

解决方法

通过修复如下获取图像方法解决。

function getimages(filename)
    filepath = pwd() * "/images/" * filename

    mtrx = Matrix(DataFrame(CSV.File(filepath)))

    return mtrx'
end

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。