1

我是 Julia 和 ML 的初学者。我正在尝试重新使用 Flux Model Zoo 中的代码,特别是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,32,1), nclasses=28)
    return Chain(
            Dense(prod(imgsize), 32, 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, y = device(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, model, device)
        test_loss, test_acc = loss_and_accuracy(test_loader, model, 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, ::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!), ::Matrix{Matrix{Float32}}, ::Char, ::Char, ::Matrix{Float32}, ::Matrix{Matrix{Int64}}, ::LinearAlgebra.MulAddMul{true, true, Bool, Bool})@interface2.jl:0
_pullback@matmul.jl:302[inlined]
_pullback@matmul.jl:275[inlined]
_pullback(::Zygote.Context, ::typeof(LinearAlgebra.mul!), ::Matrix{Matrix{Float32}}, ::Matrix{Float32}, ::Matrix{Matrix{Int64}})@interface2.jl:0
_pullback@matmul.jl:153[inlined]
_pullback(::Zygote.Context, ::typeof(*), ::Matrix{Float32}, ::Matrix{Matrix{Int64}})@interface2.jl:0
_pullback@basic.jl:147[inlined] ....
4

1 回答 1

0

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

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

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

    return mtrx'
end
于 2021-06-22T04:27:57.323 回答