u-ryo's blog

various information for coding...

Category: Machine Learning

Python Basic Web Server for Applying Keras Model

| Comments

VGG16をfine tuningしたmodelを簡単にapply(predict)するsystemが NotePC程度で動くことを証明したく、 PythonのBaseHTTPServerで1日でちゃちゃっと作りました。

といっても「PythonのBaseHTTPServer」なんて触るの初めてです。 bradmontgomery/dummy-web-server.pyを参考にしました。 なるほど、classを定義して、BaseHTTPRequestHandlerを引数にして、 do_GETdo_POSTを書くわけですね。 routingは自分でやれと。面倒なのでmethodで分けました。 このsystem自体をone fileで済ませたかったので、 GETindex.htmlを返したいと思い、 そのためにはhere documentを書きたいな、 と思ったので、 Pythonのヒアドキュメントを参考に、 あぁ、普通に'''(single quote 3つ)でいいのね、とわかりました。 single quoteでも中で変数展開されるんですね。へー。 PythonでJSONを受けて処理をするを参考に、 POST時のparameter(=request body)の受け取り方を。 HTTP Request HeaderのContent-Lengthintとして記憶し、 self.rfile.read()でそのbyte分読んで、 decode()でstringにすると。 parameterizedされるわけではなく、bodyがまるっと読まれるので、 parameterで分けるのは自分でやれということですね。

あと、base64として来た文字列をdecodeしてImage化するには、 先頭のimage/jpeg;base64,を除去し(replace())て純粋にBase64文字列だけにし、 base64.b64decode(content)したものをio.BytesIO()し、 それをImage.open()すると。

predict()したものは2次元配列になっているので、 0番目のargmax()したものが答えの添字、なのですね。

ともあれ、このpython predict server script 1つと keras model fileの2 filesだけでサクッと動くものを、 githubに置きました。

DeepLearning for Java DL4J

| Comments

会社はケチな(本気でMLやる気はない)のでマシンもGPUもなく、 やむなくGoogle Colaboratory上でkerasでVGG16 with ImageNetをfine tuningしたmodelを、 GPUのないNotePCでpredictしようとしました。 NotePCはDisk/Memory容量が小さいためpythonも本気では入れてないので、 Groovy+DeepLearning4Jで何とかならないかなー、 とあがきました。 単純にGrapeでの指定だけだと失敗するんです。

1
2
3
4
5
6
7
8
9
$ groovy dl4j.groovy
Caught: java.lang.NoClassDefFoundError: org/bytedeco/javacpp/hdf5$Group
java.lang.NoClassDefFoundError: org/bytedeco/javacpp/hdf5$Group
        at org.deeplearning4j.nn.modelimport.keras.utils.KerasModelBuilder.modelHdf5Filename(KerasModelBuilder.java:226)
        at org.deeplearning4j.nn.modelimport.keras.KerasModelImport.importKerasSequentialModelAndWeights(KerasModelImport.java:194)
        at org.deeplearning4j.nn.modelimport.keras.KerasModelImport$importKerasSequentialModelAndWeights.call(Unknown Source)
        at dl4j.run(dl4j.groovy:17)
Caused by: java.lang.ClassNotFoundException: org.bytedeco.javacpp.hdf5$Group
        ... 4 more

これは、何も指定しないと~/.groovy/grapes/org.bytedeco.javacpp-presets/hdf5/jars/hdf5-1.10.2-1.4.2-windows-x86_64.jarが落ちてきて、Windows用native libraryで動こうとするからっぽい?んですね。 なので、hdf5-1.10.2-1.4.2-linux-x86_64.jarを落としてきて、-cpで明示的に指定しないとダメでした。

1
2
3
4
5
6
7
8
9
10
$ groovy -cp ~/.groovy/grapes/org.bytedeco.javacpp-presets/hdf5/jars/hdf5-1.10.2-1.4.2-linux-x86_64.jar dl4j.groovy
[main] INFO org.deeplearning4j.nn.modelimport.keras.Hdf5Archive - Unexpected end-of-input: was expecting closing quote for a string value at [Source: {"config": {"name": "model_1", "input_layers": ......, "name; line: 1, column: 20001]
Caught: org.deeplearning4j.nn.modelimport.keras.exceptions.InvalidKerasConfigurationException: Model class name must be Sequential (found Model). For more information, see http://deeplearning4j.org/model-import-keras.
org.deeplearning4j.nn.modelimport.keras.exceptions.InvalidKerasConfigurationException: Model class name must be Sequential (found Model). For more information, see http://deeplearning4j.org/model-import-keras.
        at org.deeplearning4j.nn.modelimport.keras.KerasSequentialModel.<init>(KerasSequentialModel.java:94)
        at org.deeplearning4j.nn.modelimport.keras.KerasSequentialModel.<init>(KerasSequentialModel.java:61)
        at org.deeplearning4j.nn.modelimport.keras.utils.KerasModelBuilder.buildSequential(KerasModelBuilder.java:320)
        at org.deeplearning4j.nn.modelimport.keras.KerasModelImport.importKerasSequentialModelAndWeights(KerasModelImport.java:195)
        at org.deeplearning4j.nn.modelimport.keras.KerasModelImport$importKerasSequentialModelAndWeights.call(Unknown Source)
        at dl4j.run(dl4j.groovy:18)

VGG16はSequential Modelじゃないからダメでした。 ...ってこれ、importKerasSequentialModelAndWeightsでやってるからですよね。 そりゃそうですか。importKerasModelAndWeightsに変えて試してみます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
$ groovy -cp ~/.groovy/grapes/org.bytedeco.javacpp-presets/hdf5/jars/hdf5-1.10.2-1.4.2-linux-x86_64.jar dl4j.groovy
[main] INFO org.deeplearning4j.nn.modelimport.keras.Hdf5Archive - Unexpected end-of-input: was expecting closing quote for a string value at [Source: {"config": {"name": "model_1", ......, "name; line: 1, column: 20001]
Caught: java.lang.ExceptionInInitializerError
java.lang.ExceptionInInitializerError
        at org.deeplearning4j.nn.conf.dropout.Dropout.initializeHelper(Dropout.java:107)
        at org.deeplearning4j.nn.conf.dropout.Dropout.<init>(Dropout.java:100)
        at org.deeplearning4j.nn.conf.dropout.Dropout.<init>(Dropout.java:80)
        at org.deeplearning4j.nn.conf.layers.Layer$Builder.dropOut(Layer.java:257)
        at org.deeplearning4j.nn.modelimport.keras.layers.convolutional.KerasConvolution2D.<init>(KerasConvolution2D.java:101)
        at org.deeplearning4j.nn.modelimport.keras.utils.KerasLayerUtils.getKerasLayerFromConfig(KerasLayerUtils.java:226)
        at org.deeplearning4j.nn.modelimport.keras.KerasModel.prepareLayers(KerasModel.java:220)
        at org.deeplearning4j.nn.modelimport.keras.KerasModel.<init>(KerasModel.java:166)
        at org.deeplearning4j.nn.modelimport.keras.KerasModel.<init>(KerasModel.java:98)
        at org.deeplearning4j.nn.modelimport.keras.utils.KerasModelBuilder.buildModel(KerasModelBuilder.java:305)
        at org.deeplearning4j.nn.modelimport.keras.KerasModelImport.importKerasModelAndWeights(KerasModelImport.java:144)
        at org.deeplearning4j.nn.modelimport.keras.KerasModelImport$importKerasModelAndWeights.call(Unknown Source)
        at dl4j.run(dl4j.groovy:18)
Caused by: java.lang.RuntimeException: org.nd4j.linalg.factory.Nd4jBackend$NoAvailableBackendException: Please ensure that you have an nd4j backend on your classpath. Please see: http://nd4j.org/getstarted.html
        at org.nd4j.linalg.factory.Nd4j.initContext(Nd4j.java:5449)
        at org.nd4j.linalg.factory.Nd4j.<clinit>(Nd4j.java:213)
        ... 13 more
Caused by: org.nd4j.linalg.factory.Nd4jBackend$NoAvailableBackendException: Please ensure that you have an nd4j backend on your classpath. Please see: http://nd4j.org/getstarted.html
        at org.nd4j.linalg.factory.Nd4jBackend.load(Nd4jBackend.java:213)
        at org.nd4j.linalg.factory.Nd4j.initContext(Nd4j.java:5446)
        ... 14 more

何でしょう。今度はNd4jのようなので、同じように~/.groovy/grapes/org.nd4j/nd4j-native/jars/nd4j-native-1.0.0-beta2-linux-x86_64.jarを落としてきて入れて明示的に指定して試してみても同じだったので、色々試行錯誤の結果、Grapeで指定するのはnd4j-native-platformではなくnd4j-nativeの方だった、ということで一歩進みました。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
$ groovy -cp ~/.groovy/grapes/org.bytedeco.javacpp-presets/hdf5/jars/hdf5-1.10.2-1.4.2-linux-x86_64.jar:/home/u-ryo/.groovy/grapes/org.nd4j/nd4j-native/jars/nd4j-native-1.0.0-beta2-linux-x86_64.jar dl4j.groovy
[main] INFO org.deeplearning4j.nn.modelimport.keras.Hdf5Archive - Unexpected end-of-input: was expecting closing quote for a string value at [Source: {"config": {"name": "model_1", ......, "name; line: 1, column: 20001]
[main] INFO org.nd4j.linalg.factory.Nd4jBackend - Loaded [CpuBackend] backend
[main] INFO org.nd4j.nativeblas.NativeOpsHolder - Number of threads used for NativeOps: 2
Caught: java.lang.UnsatisfiedLinkError: no jniopenblas_nolapack in java.library.path
java.lang.UnsatisfiedLinkError: no jniopenblas_nolapack in java.library.path
        at org.bytedeco.javacpp.Loader.loadLibrary(Loader.java:1225)
        at org.bytedeco.javacpp.Loader.load(Loader.java:983)
        at org.bytedeco.javacpp.Loader.load(Loader.java:882)
        at org.bytedeco.javacpp.openblas_nolapack.<clinit>(openblas_nolapack.java:10)
        at org.bytedeco.javacpp.Loader.load(Loader.java:941)
        at org.bytedeco.javacpp.Loader.load(Loader.java:898)
        at org.bytedeco.javacpp.presets.openblas_nolapack.blas_set_num_threads(openblas_nolapack.java:189)
        at org.nd4j.linalg.cpu.nativecpu.blas.CpuBlas.setMaxThreads(CpuBlas.java:136)
        at org.nd4j.nativeblas.Nd4jBlas.<init>(Nd4jBlas.java:52)
        at org.nd4j.linalg.cpu.nativecpu.blas.CpuBlas.<init>(CpuBlas.java:31)
        at org.nd4j.linalg.cpu.nativecpu.CpuNDArrayFactory.createBlas(CpuNDArrayFactory.java:91)
        at org.nd4j.linalg.factory.BaseNDArrayFactory.blas(BaseNDArrayFactory.java:72)
        at org.nd4j.linalg.cpu.nativecpu.ops.NativeOpExecutioner.getEnvironmentInformation(NativeOpExecutioner.java:1236)
        at org.nd4j.linalg.api.ops.executioner.DefaultOpExecutioner.printEnvironmentInformation(DefaultOpExecutioner.java:649)
        at org.nd4j.linalg.factory.Nd4j.initWithBackend(Nd4j.java:5575)
        at org.nd4j.linalg.factory.Nd4j.initContext(Nd4j.java:5447)
        at org.nd4j.linalg.factory.Nd4j.<clinit>(Nd4j.java:213)
        at org.deeplearning4j.nn.conf.dropout.Dropout.initializeHelper(Dropout.java:107)
        at org.deeplearning4j.nn.conf.dropout.Dropout.<init>(Dropout.java:100)
        at org.deeplearning4j.nn.conf.dropout.Dropout.<init>(Dropout.java:80)
        at org.deeplearning4j.nn.conf.layers.Layer$Builder.dropOut(Layer.java:257)
        at org.deeplearning4j.nn.modelimport.keras.layers.convolutional.KerasConvolution2D.<init>(KerasConvolution2D.java:101)
        at org.deeplearning4j.nn.modelimport.keras.utils.KerasLayerUtils.getKerasLayerFromConfig(KerasLayerUtils.java:226)
        at org.deeplearning4j.nn.modelimport.keras.KerasModel.prepareLayers(KerasModel.java:220)
        at org.deeplearning4j.nn.modelimport.keras.KerasModel.<init>(KerasModel.java:166)
        at org.deeplearning4j.nn.modelimport.keras.KerasModel.<init>(KerasModel.java:98)
        at org.deeplearning4j.nn.modelimport.keras.utils.KerasModelBuilder.buildModel(KerasModelBuilder.java:305)
        at org.deeplearning4j.nn.modelimport.keras.KerasModelImport.importKerasModelAndWeights(KerasModelImport.java:144)
        at org.deeplearning4j.nn.modelimport.keras.KerasModelImport$importKerasModelAndWeights.call(Unknown Source)
        at dl4j.run(dl4j.groovy:19)
Caused by: java.lang.UnsatisfiedLinkError: no openblas_nolapack in java.library.path
        at org.bytedeco.javacpp.Loader.loadLibrary(Loader.java:1225)
        at org.bytedeco.javacpp.Loader.load(Loader.java:968)
        ... 28 more

openblasがない? sudo apt install libopenblas-base libopenblas-devしても変わりません。 うーん。 色々探すと、libopenblas_nolapack.so.0: cannot open shared object file: No such file or directory #6132という記事があり、 「nd4j-backends」から「mkl-dnn」をexcludeしろ、とあります。 えー! nd4j-backendsはpomだけでjarないんですけど。 org.bytedeco.javacpp-presets:mkl-dnnを見てみると、 windowsのjarmkl-dnn-0.15-1.4.2-windows-x86_64.jarが落ちてきていました。 それならっていうんで、linux-x86 64版を持ってきて-cpで指定します。 ついでに、org.bytedeco.javacpp-presets:openblasというのもあって こっちにもwindows-x86 64版のjarだったので、これについてもlinux-x86 64版を 持ってきてClassPathに入れます。 するとどうでしょう、漸く動き出しました。 けれども、ヌルポで落ちます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$ groovy -cp ~/.groovy/grapes/org.bytedeco.javacpp-presets/hdf5/jars/hdf5-1.10.2-1.4.2-linux-x86_64.jar:/home/u-ryo/.groovy/grapes/org.nd4j/nd4j-native/jars/nd4j-native-1.0.0-beta2-linux-x86_64.jar:/home/u-ryo/.groovy/grapes/org.bytedeco.javacpp-presets/mkl-dnn/jars/mkl-dnn-0.15-1.4.2-linux-x86_64.jar:/home/u-ryo/.groovy/grapes/org.bytedeco.javacpp-presets/openblas/jars/openblas-0.3.0-1.4.2-linux-x86_64.jar dl4j.groovy
[main] INFO org.deeplearning4j.nn.modelimport.keras.Hdf5Archive - Unexpected end-of-input: was expecting closing quote for a string value at [Source: {"config": {"name": "model_1",......, "name; line: 1, column: 20001]
[main] INFO org.nd4j.linalg.factory.Nd4jBackend - Loaded [CpuBackend] backend
[main] INFO org.nd4j.nativeblas.NativeOpsHolder - Number of threads used for NativeOps: 2
[main] INFO org.nd4j.nativeblas.Nd4jBlas - Number of threads used for BLAS: 2
[main] INFO org.nd4j.linalg.api.ops.executioner.DefaultOpExecutioner - Backend used: [CPU]; OS: [Linux]
[main] INFO org.nd4j.linalg.api.ops.executioner.DefaultOpExecutioner - Cores: [4]; Memory: [4.3GB];
[main] INFO org.nd4j.linalg.api.ops.executioner.DefaultOpExecutioner - Blas vendor: [MKL]
{config={lr=9.999999747378752E-5, decay=0.0, momentum=0.8999999761581421, nesterov=false}, class_name=SGD}
Caught: java.lang.NullPointerException
java.lang.NullPointerException
        at org.deeplearning4j.nn.modelimport.keras.utils.KerasOptimizerUtils.mapOptimizer(KerasOptimizerUtils.java:119)
        at org.deeplearning4j.nn.modelimport.keras.KerasModel.importTrainingConfiguration(KerasModel.java:253)
        at org.deeplearning4j.nn.modelimport.keras.KerasModel.<init>(KerasModel.java:173)
        at org.deeplearning4j.nn.modelimport.keras.KerasModel.<init>(KerasModel.java:98)
        at org.deeplearning4j.nn.modelimport.keras.utils.KerasModelBuilder.buildModel(KerasModelBuilder.java:305)
        at org.deeplearning4j.nn.modelimport.keras.KerasModelImport.importKerasModelAndWeights(KerasModelImport.java:144)
        at org.deeplearning4j.nn.modelimport.keras.KerasModelImport$importKerasModelAndWeights.call(Unknown Source)
        at dl4j.run(dl4j.groovy:19)

これ、119行目って、KerasOptimizerUtils.javaこの修正の前のこれですね。

1
119: double momentum = (double) optimizerParameters.get("epsilon");

epsilonじゃねーよmomentumだよー今は。 ここは8.17.2018にtry-catchで囲まれて、現在のversionには反映されてないので、 うー、commentしました。 でもまー、keras変わっちゃうと、DL4Jがついていくのも大変なのかもですね。 けどこれで現状、kerasのmodelのimportは、 optimizerにSGDを使ったものについては全滅です。 実に下らない理由(=parameter nameの間違い)で。

あまりにも悔しいので、Java Bytecode Editor: JByteModを使ってbytecodeを書き換えてみました(正確にはCol-E/RecafJBE - Java Bytecode Editorと3つ試してみて、JByteModだけでうまく書き換えられました)。 deeplearning4j-modelimport-1.0.0-beta2.jarをjarごと読み込めて、 org.deeplearning4j.nn.modelimport.keras.utils.KerasOptimizerUtilsに 降りていって、 EditorのDecompilerで見事にsource codeが出て来ます。 こちらで変えたくなりますが、ここはview onlyの模様。 EditorのCodeで見られるbytecodeならいじれるので、 line 119近辺のldc String "epsilon"に当たりをつけ、 それをmomentumに変えて保存すると... うまく行きました!→次のエラーに進みました。orz

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
[main] INFO org.nd4j.linalg.factory.Nd4jBackend - Loaded [CpuBackend] backend
[main] INFO org.nd4j.nativeblas.NativeOpsHolder - Number of threads used for NativeOps: 2
[main] INFO org.nd4j.nativeblas.Nd4jBlas - Number of threads used for BLAS: 2
[main] INFO org.nd4j.linalg.api.ops.executioner.DefaultOpExecutioner - Backend used: [CPU]; OS: [Linux]
[main] INFO org.nd4j.linalg.api.ops.executioner.DefaultOpExecutioner - Cores: [4]; Memory: [4.3GB];
[main] INFO org.nd4j.linalg.api.ops.executioner.DefaultOpExecutioner - Blas vendor: [MKL]
{config={lr=9.999999747378752E-5, decay=0.0, momentum=0.8999999761581421, nesterov=false}, class_name=SGD}
Caught: org.deeplearning4j.exception.DL4JInvalidConfigException: Invalid configuration for layer (idx=-1, name=block2_conv1, type=ConvolutionLayer) for width dimension:  Invalid input configuration for kernel width. Require 0 < kW <= inWidth + 2*padW; got (kW=3, inWidth=1, padW=0)
Input type = InputTypeConvolutional(h=112,w=1,c=64), kernel = [3, 3], strides = [1, 1], padding = [0, 0], layer size (output channels) = 128, convolution mode = Same
org.deeplearning4j.exception.DL4JInvalidConfigException: Invalid configuration for layer (idx=-1, name=block2_conv1, type=ConvolutionLayer) for width dimension:  Invalid input configuration for kernel width. Require 0 < kW <= inWidth + 2*padW; got (kW=3, inWidth=1, padW=0)
Input type = InputTypeConvolutional(h=112,w=1,c=64), kernel = [3, 3], strides = [1, 1], padding = [0, 0], layer size (output channels) = 128, convolution mode = Same
        at org.deeplearning4j.nn.conf.layers.InputTypeUtil.getOutputTypeCnnLayers(InputTypeUtil.java:349)
        at org.deeplearning4j.nn.conf.layers.ConvolutionLayer.getOutputType(ConvolutionLayer.java:181)
        at org.deeplearning4j.nn.modelimport.keras.layers.convolutional.KerasConvolution2D.getOutputType(KerasConvolution2D.java:150)
        at org.deeplearning4j.nn.modelimport.keras.KerasModel.inferOutputTypes(KerasModel.java:306)
        at org.deeplearning4j.nn.modelimport.keras.KerasModel.<init>(KerasModel.java:181)
        at org.deeplearning4j.nn.modelimport.keras.KerasModel.<init>(KerasModel.java:98)
        at org.deeplearning4j.nn.modelimport.keras.utils.KerasModelBuilder.buildModel(KerasModelBuilder.java:305)
        at org.deeplearning4j.nn.modelimport.keras.KerasModelImport.importKerasModelAndWeights(KerasModelImport.java:144)
        at org.deeplearning4j.nn.modelimport.keras.KerasModelImport$importKerasModelAndWeights.call(Unknown Source)
        at tt.run(tt.groovy:19)

Require 0 < kW <= inWidth + 2*padW; got (kW=3, inWidth=1, padW=0)ということからすると、多分keras modelの方のblock2_conv1padWが1でないとダメ? 何をどうすればいいんでしょう?

心が折れそうになりましたが、もう少し頑張ってみます。

まずVGG16のblock2_conv1のpadding(padWって恐らくこれでしょう?)は"same"のようです(VGG16をkerasで実装した)。 実際、途中のlogでは下のように"padding": "same"とあります。

1
{"name": "block2_conv1", "config": {"kernel_regularizer": null, "activation": "relu", "dilation_rate": [1, 1], "name": "block2_conv1", "data_format": "channels_last", "kernel_size": [3, 3], "bias_constraint": null, "filters": 128, "kernel_initializer": {"config": {"scale": 1.0, "mode": "fan_avg", "distribution": "uniform", "seed": null}, "class_name": "VarianceScaling"}, "use_bias": true, "kernel_constraint": null, "activity_regularizer": null, "trainable": false, "padding": "same", ...

色々見ると、VGG16ではpadding=[1,1]みたいです(事前学習済み VGG-16 畳み込みニューラル ネットワーク) (Build VGG16 from scratch : part II) (Reading the VGG Network Paper and Implementing It From Scratch with Keras)。 "same"が0と解釈された?? いやいや、DL4Jのsourceを見ると、"same"はきちんと扱っているようです。 あー、SAMEってこういう意味だったんですね(【Python】 KerasのConv2Dの引数paddingについて)。 今回のExceptionは、具体的には deeplearning4j/deeplearning4j/deeplearning4j-nn/src/main/java/org/deeplearning4j/nn/conf/layers/InputTypeUtil.javaの以下で出ていることがわかりました。

1
2
3
4
5
6
if (kW <= 0 || kW > inWidth + 2 * padW) {
    throw new DL4JInvalidConfigException(getConfigErrorCommonLine(layerIdx, layerName, layerClass, false)
                    + " Invalid input configuration for kernel width. Require 0 < kW <= inWidth + 2*padW; got (kW="
                    + kW + ", inWidth=" + inWidth + ", padW=" + padW + ")\n" + getConfigErrorCommonLastLine(
                                    inputType, kernelSize, stride, padding, outputDepth, convolutionMode));
}

padWって何?

1
2
int padH = (padding == null ? 0 : padding[0]); //May be null for ConvolutionMode.Same
int padW = (padding == null ? 0 : padding[1]);

paddinggetOutputTypeCnnLayersの引数です。 その元はdeeplearning4j/deeplearning4j/deeplearning4j-nn/src/main/java/org/deeplearning4j/nn/conf/layers/ConvolutionLayer.javaの↓から来ていて、

1
2
3
4
5
6
7
8
9
10
@Override
public InputType getOutputType(int layerIndex, InputType inputType) {
    if (inputType == null || inputType.getType() != InputType.Type.CNN) {
        throw new IllegalStateException("Invalid input for Convolution layer (layer name=\"" + getLayerName()
                + "\"): Expected CNN input, got " + inputType);
    }

    return InputTypeUtil.getOutputTypeCnnLayers(inputType, kernelSize, stride, padding, dilation,
            convolutionMode, nOut, layerIndex, getLayerName(), ConvolutionLayer.class);
}

このpaddingはconstructorから来ていて。

1
this.padding = builder.padding;

builderはinner classでそのpaddingは外から来ているか 又はdefaultならnew int[]{0, 0}と。 うーーー。 似ているissueもありましたが、input shapeの明示的指定では解決しなかったので、 もうissue上げました。

試すのは、Groovyだと↓で済むんですけど、

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ cat dl4j.groovy
@Grab('org.deeplearning4j:deeplearning4j-core:1.0.0-beta2')
@Grab('org.deeplearning4j:deeplearning4j-modelimport:1.0.0-beta2')
@Grab('org.nd4j:nd4j-native:1.0.0-beta2')
@Grab('org.slf4j:slf4j-simple')
@Grab('org.bytedeco.javacpp-presets:hdf5:1.10.2-1.4.2')
@Grab('org.bytedeco:javacpp:1.4.2')

import org.deeplearning4j.nn.modelimport.keras.KerasModelImport

// model = KerasModelImport.importKerasModelAndWeights('my_model.hdf5', [224, 224, 3] as int[], false)
model = KerasModelImport.importKerasModelAndWeights('my_model.hdf5')

$ groovy -cp ~/.groovy/grapes/org.bytedeco.javacpp-presets/hdf5/jars/hdf5-1.10.2-1.4.2-linux-x86_64.jar:/home/u-ryo/.groovy/grapes/org.nd4j/nd4j-native/jars/nd4j-native-1.0.0-beta2-linux-x86_64.jar:/home/u-ryo/.groovy/grapes/org.bytedeco.javacpp-presets/mkl-dnn/jars/mkl-dnn-0.15-1.4.2-linux-x86_64.jar:/home/u-ryo/.groovy/grapes/org.bytedeco.javacpp-presets/openblas/jars/openblas-0.3.2-1.4.2-linux-x86_64.jar dl4j.groovy

本家のissueで聞くからには、 Groovyだからダメなんじゃないの? とか言われそうだったので、 Javaにしました。 classpathの指定が大変でした。 不要なjarも入っているかもです。

1
2
3
4
5
6
7
8
9
10
11
$ cat DL4J.java
class DL4J {
    public static void main(String... args) throws Exception {
        org.deeplearning4j.nn.modelimport.keras.KerasModelImport
            .importKerasModelAndWeights("my_model.hdf5",
                                        new int[]{224, 224, 3}, false);
            // .importKerasModelAndWeights("my_model.hdf5"); // failed too
    }
}
$ javac -cp ~/.groovy/grapes/org.deeplearning4j/deeplearning4j-modelimport/jars/deeplearning4j-modelimport-1.0.0-beta2.jar:/usr/share/java/slf4j-simple.jar:/home/u-ryo/.groovy/grapes/org.deeplearning4j/deeplearning4j-nn/jars/deeplearning4j-nn-1.0.0-beta2.jar DL4J.java
$ java -cp ~/.groovy/grapes/org.deeplearning4j/deeplearning4j-modelimport/jars/deeplearning4j-modelimport-1.0.0-beta2.jar:/usr/share/java/slf4j-simple.jar:/home/u-ryo/.groovy/grapes/org.deeplearning4j/deeplearning4j-nn/jars/deeplearning4j-nn-1.0.0-beta2.jar:/usr/share/java/slf4j-api.jar:.:/home/u-ryo/.groovy/grapes/org.bytedeco.javacpp-presets/hdf5/jars/hdf5-1.10.2-1.4.2.jar:/home/u-ryo/.groovy/grapes/org.bytedeco/javacpp/jars/javacpp-1.4.2.jar:/home/u-ryo/.groovy/grapes/org.bytedeco.javacpp-presets/hdf5/jars/hdf5-1.10.2-1.4.2-linux-x86_64.jar:/home/u-ryo/.groovy/grapes/org.nd4j/nd4j-jackson/jars/nd4j-jackson-1.0.0-beta2.jar:/home/u-ryo/.groovy/grapes/org.nd4j/jackson/jars/jackson-1.0.0-beta2.jar:/home/u-ryo/.groovy/grapes/org.nd4j/nd4j-common/jars/nd4j-common-1.0.0-beta2.jar:/home/u-ryo/.groovy/grapes/org.nd4j/nd4j-api/jars/nd4j-api-1.0.0-beta2.jar:/home/u-ryo/.groovy/grapes/org.nd4j/nd4j-context/jars/nd4j-context-1.0.0-beta2.jar:/home/u-ryo/.groovy/grapes/org.nd4j/nd4j-buffer/jars/nd4j-buffer-1.0.0-beta2.jar:/home/u-ryo/.groovy/grapes/org.nd4j/nd4j-native/jars/nd4j-native-1.0.0-beta2-linux-x86_64.jar:/home/u-ryo/.groovy/grapes/org.nd4j/nd4j-native-platform/jars/nd4j-native-platform-1.0.0-beta2.jar:/home/u-ryo/.groovy/grapes/org.nd4j/nd4j-native/jars/nd4j-native-1.0.0-beta2.jar:/home/u-ryo/.groovy/grapes/org.nd4j/nd4j-native-api/jars/nd4j-native-api-1.0.0-beta2.jar:/home/u-ryo/.groovy/grapes/org.apache.commons/commons-math3/jars/commons-math3-3.5.jar:/home/u-ryo/.groovy/grapes/org.bytedeco.javacpp-presets/openblas/jars/openblas-0.3.0-1.4.2-linux-x86_64.jar:/home/u-ryo/.groovy/grapes/org.bytedeco/javacpp/jars/javacpp-1.4.2.jar:/home/u-ryo/.groovy/grapes/org.bytedeco.javacpp-presets/hdf5/jars/hdf5-1.10.2-1.4.2.jar:/home/u-ryo/.groovy/grapes/org.bytedeco.javacpp-presets/openblas/jars/openblas-0.3.0-1.4.2.jar DL4J