【Julia Deep Learning CV】 第二篇 MNIST扩展

julia的深度学习工具包有,(1)、Merlin.jl   源码网址:https://github.com/hshindo/Merlin.jl

                                          (2)、MXNet.jl   大牛老沫、陈老怪他们搞的,很好用   源码网址  https://github.com/dmlc/MXNet.jl

                                          (3)、TensorFlow.jl   不多说了,列位自己看名称  源码网址 https://github.com/malmaud/TensorFlow.jl

                                          (4)、Flux.jl   源码网址  https://github.com/FluxML/Flux.jl

                                          (5)、Knet.jl   大名鼎鼎  源码网址  https://github.com/denizyuret/Knet.jl

还有超多的机器学习库。唉!记得有位高人说过python的包多如屎,Julia现在也是一样的。

闲话到此,开始上代码:

using Printf

using Flux, Flux.Data.MNIST, Statistics
using Flux: onehotbatch, onecold, crossentropy, @epochs
using Base.Iterators: partition
using BSON: @load, @save
using CuArrays
using Random

function prepare_dataset(;train=true)
    train_or_test = ifelse(train,:train,:test)
    imgs = MNIST.images(train_or_test)
    X = hcat(float.(vec.(imgs))...)
    labels = MNIST.labels(train_or_test)
    Y = onehotbatch(labels,0:9)
    return X, Y
end


function define_model(;hidden)
    mlp = Chain(Dense(28^2,hidden,relu), #此处用的是relu,不是默认的Sigmoid,激活函数说明:详见 
                                         #https://blog.csdn.net/edogawachia/article/details/80043673
                Dense(hidden,hidden,relu),
                Dense(hidden,10),
                softmax)
    return mlp
end

function split_dataset_random(X, Y)
    divide_ratio=0.9
    shuffled_indices = shuffle(1:size(Y)[2])
    divide_idx = round(Int,0.9*length(shuffled_indices))
    train_indices = shuffled_indices[1:divide_idx]
    val_indices = shuffled_indices[divide_idx:end]
    train_X = X[:,train_indices]
    train_Y = Y[:,train_indices]
    val_X = X[:,val_indices]
    val_Y = Y[:,val_indices]
    return train_X, train_Y, val_X, val_Y
end

function train()
    println("Start to train")
    epochs = 10
    X, Y = prepare_dataset(train=true)
    train_X, train_Y, val_X,val_Y = split_dataset_random(X, Y)
    model = define_model(hidden=100) |> gpu #如果没有gpu,只有cpu,此处可以写成 |> cpu。本代码中是一样的。
    loss(x,y)= crossentropy(model(x),y)
    accuracy(x, y) = mean(onecold(model(x)) .== onecold(y))
    batchsize = 64
    train_dataset = gpu.([(train_X[:,batch] ,train_Y[:,batch]) for batch in partition(1:size(train_Y)[2],batchsize)])
    val_dataset = gpu.([(val_X[:,batch] ,val_Y[:,batch]) for batch in partition(1:size(val_Y)[2],batchsize)])

    callback_count = 0
    eval_callback = function callback()
        callback_count += 1
        if callback_count == length(train_dataset)
            println("action for each epoch")
            total_loss = 0
            total_acc = 0
            for (vx, vy) in val_dataset
                total_loss += loss(vx, vy)
                total_acc += accuracy(vx, vy)
            end
            total_loss /= length(val_dataset)
            total_acc /= length(val_dataset)
            @show total_loss, total_acc #跟python中的装饰器类似,代码中他处类似
            callback_count = 0
            pretrained = model |> cpu
            @save "pretrained.bson" pretrained
            callback_count = 0
        end
        if callback_count % 50 == 0
            progress = callback_count / length(train_dataset)
           @printf("%.3f\n", progress)
        end
    end
    optimizer = ADAM(params(model))

    @epochs epochs Flux.train!(loss, train_dataset, optimizer, cb = eval_callback)

    pretrained = model |> cpu
    weights = Tracker.data.(params(pretrained))
    @save "pretrained.bson" pretrained
    @save "weights.bson" weights
    println("Finished to train")
end

function predict()
    println("Start to evaluate testset")
    println("loading pretrained model")
    @load "pretrained.bson" pretrained
    model = pretrained |> gpu
    accuracy(x, y) = mean(onecold(model(x)) .== onecold(y))
    println("prepare dataset")
    X, Y = prepare_dataset(train=false)
    X = X |> gpu
    Y = Y |> gpu
    @show accuracy(X, Y)
    println("Done")
end

function predict2()
    println("Start to evaluate testset")
    println("loading pretrained model")
    @load "weights.bson" weights
    model = define_model(hidden=100)
    Flux.loadparams!(model, weights)
    model = model |> gpu
    accuracy(x, y) = mean(onecold(model(x)) .== onecold(y))
    println("prepare dataset")
    X, Y = prepare_dataset(train=false)
    X = X |> gpu
    Y = Y |> gpu
    @show accuracy(X, Y)
    println("Done")
end

function main()
    train()
    predict()
    predict2()
end
main()

代码中注意的地方:使用GPU,请 Pkg.add("CuArrays") 

调用代码的方式:

imgs = MNIST.images(:train)
X = hcat(float.(vec.(imgs))...)
labels = MNIST.labels(:train)
Y = onehotbatch(labels,0:9)
 @show size(X)  size(Y);
size(X) = (784, 10000)
size(Y) = (10, 60000)
train_dataset = gpu.([(train_X[:,batch] ,train_Y[:,batch]) for batch in partition(1:size(train_Y)[2],batchsize)])
val_dataset = gpu.([(val_X[:,batch] ,val_Y[:,batch]) for batch in partition(1:size(val_Y)[2],batchsize)])
loss(x,y)= crossentropy(model(x),y) # 损失函数原理及说明详见:https://www.cnblogs.com/guoyaohua/p/9217206.html
accuracy(x, y) = mean(onecold(model(x)) .== onecold(y))
epochs 10
@epochs epochs Flux.train!(loss, train_dataset, optimizer, cb = eval_callback)

结果保存:

pretrained = model |> cpu
weights = Tracker.data.(params(pretrained))
@save "pretrained.bson" pretrained
@save "weights.bson" weights
println("Finished to train")

保存的结果加载:

@load "pretrained.bson" pretrained
@load "weights.bson" weights 
model = define_model(hidden=100)
Flux.loadparams!(model, weights)

代码比较简单,下一篇开始CNN了

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值