- This repo provides train/inference procedure of MNIST model known as Hello World of Deep Learning on Julia runtime. These techniques are based on Chainer and PyCall.jl.
- NEW: Add feature to convert ResNet50/Chainer -> ResNet50/Flux.jl
- This package is not registered as official julia package, so called 野良(nora), which means we should specify repository url:
- Note that Package
Gomah.jl
depends onPyCall.jl
. So before installing, We recommend set environment variable in Julia.
$ julia
julia> ENV["PYTHON"] = Sys.which("python3")
pkg> add https://github.com/terasakisatoshi/Gomah.jl.git
julia> using Gomah
PyCall.jl
provides interface between Python and Julia.- This means you can construct training script of Chainer on Julia environment.
- If you are familiar with some Deep learnig framework, checkout our
src/mnist.jl
. - We provide an example of training MNIST classifier.
$ julia
julia> using Gomah
julia> train()
epoch main/loss main/accuracy validation/main/loss validation/main/accuracy elapsed_time
1 0.56446 0.840621 0.28946 0.914727 3.49408
2 0.248238 0.927429 0.212789 0.937381 5.90154
3 0.189395 0.945183 0.175694 0.948423 8.43833
4 0.152917 0.95592 0.145494 0.957898 10.832
5 0.128008 0.963307 0.128785 0.962386 13.2714
6 0.108765 0.968306 0.121768 0.961222 15.6906
7 0.0948146 0.97286 0.103434 0.969201 18.361
8 0.0854993 0.974762 0.10229 0.96818 20.7444
9 0.0746463 0.977655 0.0916977 0.972739 23.1146
10 0.0663983 0.980598 0.0889726 0.972573 25.5239
julia> predict()
accuracy for test set = 97.31 [%]
- We found the structure (shape) of parameter i.e. weight of Chainer is similar that of Flux.
- The structure of weight of Convolution of Chainer is
NCHW
. On the other hand, Conv of Flux.jl has weight its shape isWHCN
, whereN
is batchsize,H
(resp.W
) is height (resp. width) of kernel andC
is num of channel. - We provided script to convert ResNet50 of Chainer to that of Flux.jl
- Here is a example of How to use converted model. What you have to do is ...
- Install chainer and chainercv
- Install Flux.jl, PyCall, Gomah.jl
- Prepare sample RGB image. e.g.
pineapple.png
- Run the following the script.
using Gomah
using Gomah: L, np, reversedims
using Flux
using PyCall
using Test
using BenchmarkTools
py"""
import chainer
import chainercv
import numpy as np
num = 50
PyResNet = chainercv.links.model.resnet.ResNet
resnet = PyResNet(num, pretrained_model = "imagenet")
img=chainercv.utils.read_image("pineapple.png",dtype=np.float32,alpha="ignore")
img=chainercv.transforms.resize(img,(224,224))
_imagenet_mean = np.array(
[123.15163084, 115.90288257, 103.0626238],
dtype=np.float32
)[:, np.newaxis, np.newaxis]
img=img-_imagenet_mean
img=np.expand_dims(img,axis=0)
resnet.pick=resnet.layer_names
with chainer.using_config('train', False):
pyret=resnet(img)
result=np.squeeze(pyret[-1].array)
chidx=int(np.argmax(result))
chprob=100*float(result[chidx])
print(chidx)
print(chprob)
"""
@testset "regression" begin
num = 50
myres = ResNet(num)
Flux.testmode!.(myres.layers)
img = reversedims(py"img")
@show size(img), typeof(img)
ret, name2data = myres(img)
for (i,name) in enumerate(myres.layer_names)
pyr = reversedims(py"pyret[$i-1].array")
flr = name2data[name]
@show name, size(flr)
@test size(pyr) == size(flr)
@show maximum(abs.(pyr .- flr))
end
flidx = argmax(ret)
flprob = 100ret[argmax(ret)]
@show flidx,flprob
@test Int(py"chidx") == flidx[1]-1
@show Float32(py"chprob") - flprob
end
@testset "benchmark" begin
num=50
img = reversedims(py"img")
myres = ResNet(num)
chainmodel = Chain(myres.layers...)
Flux.testmode!(chainmodel)
@time chainmodel(img)
@time chainmodel(img)
@time chainmodel(img)
@time chainmodel(img)
@time chainmodel(img)
@time chainmodel(img)
end
- My favorite thing ごまちゃん
- Inspired by Menoh
- Gomah.jl will be promoted as DNN inference library (in the future)
- Script for training MNIST is based on this notebook.
- See also Julia で Chainer を動かすぞ💪
- Construct Chain is based on Flux.jl
- Basic implementation of ResNet is taken from ChainerCV project.