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了