Skip to content
This repository has been archived by the owner on Nov 17, 2023. It is now read-only.

Port of scala infer package to clojure #13595

Merged
merged 8 commits into from
Dec 27, 2018
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Add inference examples
  • Loading branch information
Kedar Bellare committed Dec 22, 2018
commit df2771e055dcae035ca4f1f576d48fc076534d67
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/target
/classes
/checkouts
/images
pom.xml
pom.xml.asc
*.jar
*.class
/.lein-*
/.nrepl-port
.hgignore
.hg/
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# imageclassifier

Run image classification using clojure infer package.

## Installation

kedarbellare marked this conversation as resolved.
Show resolved Hide resolved
`lein install`

## Usage

```
$ chmod +x scripts/get_resnet_18_data.sh
kedarbellare marked this conversation as resolved.
Show resolved Hide resolved
$ ./scripts/get_resnet_18_data.sh
$ lein uberjar
kedarbellare marked this conversation as resolved.
Show resolved Hide resolved
$ java -jar target/imageclassifier-0.1.0-SNAPSHOT-standalone.jar --help
$ java -jar target/imageclassifier-0.1.0-SNAPSHOT-standalone.jar \
-m models/resnet-18/resnet-18 -i images/kitten.jpg -d images/
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
;;
;; Licensed to the Apache Software Foundation (ASF) under one or more
;; contributor license agreements. See the NOTICE file distributed with
;; this work for additional information regarding copyright ownership.
;; The ASF licenses this file to You under the Apache License, Version 2.0
;; (the "License"); you may not use this file except in compliance with
;; the License. You may obtain a copy of the License at
;;
;; https://www.apache.org/licenses/LICENSE-2.0
;;
;; Unless required by applicable law or agreed to in writing, software
;; distributed under the License is distributed on an "AS IS" BASIS,
;; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
;; See the License for the specific language governing permissions and
;; limitations under the License.
;;

(defproject imageclassifier "0.1.0-SNAPSHOT"
:description "Image classification using infer with MXNet"
:plugins [[lein-cljfmt "0.5.7"]]
:dependencies [[org.clojure/clojure "1.9.0"]
[org.clojure/tools.cli "0.4.1"]
[org.apache.mxnet.contrib.clojure/clojure-mxnet "1.5.0-SNAPSHOT"]]
:main ^:skip-aot infer.imageclassifier-example
:profiles {:uberjar {:aot :all}})
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@

set -e

MXNET_ROOT=$(cd "$(dirname $0)/../../.."; pwd)
MXNET_ROOT=$(cd "$(dirname $0)/.."; pwd)

data_path=$MXNET_ROOT/scripts/infer/models/resnet-18/
data_path=$MXNET_ROOT/models/resnet-18/

image_path=$MXNET_ROOT/scripts/infer/images/
image_path=$MXNET_ROOT/images/

if [ ! -d "$data_path" ]; then
mkdir -p "$data_path"
Expand All @@ -33,9 +33,12 @@ if [ ! -d "$image_path" ]; then
mkdir -p "$image_path"
fi

if [ ! -f "$data_path" ]; then
if [ ! -f "$data_path/resnet-18-0000.params" ]; then
wget https://s3.us-east-2.amazonaws.com/scala-infer-models/resnet-18/resnet-18-symbol.json -P $data_path
wget https://s3.us-east-2.amazonaws.com/scala-infer-models/resnet-18/resnet-18-0000.params -P $data_path
wget https://s3.us-east-2.amazonaws.com/scala-infer-models/resnet-18/synset.txt -P $data_path
fi

if [ ! -f "$image_path/kitten.jpg" ]; then
wget https://s3.us-east-2.amazonaws.com/mxnet-scala/scala-example-ci/resnet152/kitten.jpg -P $image_path
fi
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@

set -e

MXNET_ROOT=$(cd "$(dirname $0)/../../.."; pwd)
MXNET_ROOT=$(cd "$(dirname $0)/.."; pwd)

data_path=$MXNET_ROOT/scripts/infer/models/resnet-152/
data_path=$MXNET_ROOT/models/resnet-152/

image_path=$MXNET_ROOT/scripts/infer/images/
image_path=$MXNET_ROOT/images/

if [ ! -d "$data_path" ]; then
mkdir -p "$data_path"
Expand All @@ -33,9 +33,12 @@ if [ ! -d "$image_path" ]; then
mkdir -p "$image_path"
fi

if [ ! -f "$data_path" ]; then
if [ ! -f "$data_path/resnet-152-0000.params" ]; then
wget https://s3.us-east-2.amazonaws.com/mxnet-scala/scala-example-ci/resnet152/resnet-152-0000.params -P $data_path
wget https://s3.us-east-2.amazonaws.com/mxnet-scala/scala-example-ci/resnet152/resnet-152-symbol.json -P $data_path
wget https://s3.us-east-2.amazonaws.com/mxnet-scala/scala-example-ci/resnet152/synset.txt -P $data_path
fi

if [ ! -f "$image_path/kitten.jpg" ]; then
wget https://s3.us-east-2.amazonaws.com/mxnet-scala/scala-example-ci/resnet152/kitten.jpg -P $image_path
fi
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
(ns infer.imageclassifier-example
(:require [org.apache.clojure-mxnet.context :as context]
[org.apache.clojure-mxnet.dtype :as dtype]
[org.apache.clojure-mxnet.infer :as infer]
[org.apache.clojure-mxnet.io :as mx-io]
[org.apache.clojure-mxnet.layout :as layout]
[clojure.java.io :as io]
[clojure.string :refer [join]]
[clojure.tools.cli :refer [parse-opts]])
(:gen-class))

(defn check-valid-dir
"Check that the input directory exists"
[input-dir]
(let [dir (io/file input-dir)]
(and
(.exists dir)
(.isDirectory dir))))

(defn check-valid-file
"Check that the file exists"
[input-file]
(let [file (io/file input-file)]
(.exists file)))

(def cli-options
kedarbellare marked this conversation as resolved.
Show resolved Hide resolved
[["-m" "--model-path-prefix PREFIX" "Model path prefix"
:default "models/resnet-152/resnet-152"
:validate [#(check-valid-file (str % "-symbol.json"))
"Model path prefix is invalid"]]
["-i" "--input-image IMAGE" "Input image"
:default "images/kitten.jpg"
:validate [check-valid-file "Input file not found"]]
["-d" "--input-dir IMAGE_DIR" "Input directory"
:default "images/"
:validate [check-valid-dir "Input directory not found"]]
[nil "--device [cpu|gpu]" "Device"
:default "cpu"
:validate [#(#{"cpu" "gpu"} %) "Device must be one of cpu or gpu"]]
[nil "--device-id INT" "Device ID"
:default 0]
["-h" "--help"]])

(defn print-predictions
"Print image classifier predictions for the given input file"
[input-file predictions]
(println (apply str (repeat 80 "=")))
(println "Input file:" input-file)
(doseq [[label probability] predictions]
(println (format "Class: %s Probability=%.8f" label probability)))
(println (apply str (repeat 80 "="))))

(defn classify-single-image
"Classify a single image and print top-5 predictions"
[classifier input-image]
(let [image (infer/load-image-from-file input-image)
topk 5
[predictions] (infer/classify-image classifier image topk)]
(print-predictions input-image predictions)))

(defn classify-images-in-dir
"Classify all jpg images in the directory"
[classifier input-dir]
(let [batch-size 20
image-file-batches (->> input-dir
io/file
file-seq
(filter #(.isFile %))
(filter #(re-matches #".*\.jpg$" (.getPath %)))
(mapv #(.getPath %))
(partition-all batch-size))]
(doseq [image-files image-file-batches]
(let [image-batch (infer/load-image-paths image-files)
topk 5]
(doseq [[input-image preds]
(map list
image-files
(infer/classify-image-batch classifier image-batch topk))]
(print-predictions input-image preds))))))

(defn run-classifier
"Runs an image classifier based on options provided"
[options]
(let [{:keys [model-path-prefix input-image input-dir
device device-id]} options
ctx (if (= device "cpu")
(context/cpu device-id)
(context/gpu device-id))
descriptors [(mx-io/data-desc {:name "data"
:shape [1 3 224 224]
:layout layout/NCHW
:dtype dtype/FLOAT32})]
factory (infer/model-factory model-path-prefix descriptors)
classifier (infer/create-image-classifier
factory {:contexts [ctx]})]
(classify-single-image classifier input-image)
(classify-images-in-dir classifier input-dir)))

(defn -main
[& args]
(let [{:keys [options summary errors] :as opts}
(parse-opts args cli-options)]
(cond
(:help options) (println summary)
(some? errors) (println (join "\n" errors))
:else (run-classifier options))))
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/target
/classes
/checkouts
/images
pom.xml
pom.xml.asc
*.jar
*.class
/.lein-*
/.nrepl-port
.hgignore
.hg/
18 changes: 18 additions & 0 deletions contrib/clojure-package/examples/infer/objectdetector/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# objectdetector

Run object detection on images using clojure infer package.

## Installation

`lein install`

## Usage

```
$ chmod +x scripts/get_ssd_data.sh
$ ./scripts/get_ssd_data.sh
$ lein uberjar
kedarbellare marked this conversation as resolved.
Show resolved Hide resolved
$ java -jar target/objectdetector-0.1.0-SNAPSHOT-standalone.jar --help
$ java -jar target/objectdetector-0.1.0-SNAPSHOT-standalone.jar \
-m models/resnet50_ssd/resnet50_ssd_model -i images/kitten.jpg -d images/
kedarbellare marked this conversation as resolved.
Show resolved Hide resolved
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
;;
;; Licensed to the Apache Software Foundation (ASF) under one or more
;; contributor license agreements. See the NOTICE file distributed with
;; this work for additional information regarding copyright ownership.
;; The ASF licenses this file to You under the Apache License, Version 2.0
;; (the "License"); you may not use this file except in compliance with
;; the License. You may obtain a copy of the License at
;;
;; https://www.apache.org/licenses/LICENSE-2.0
;;
;; Unless required by applicable law or agreed to in writing, software
;; distributed under the License is distributed on an "AS IS" BASIS,
;; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
;; See the License for the specific language governing permissions and
;; limitations under the License.
;;

(defproject objectdetector "0.1.0-SNAPSHOT"
:description "Object detection using infer with MXNet"
:plugins [[lein-cljfmt "0.5.7"]]
:dependencies [[org.clojure/clojure "1.9.0"]
[org.clojure/tools.cli "0.4.1"]
[org.apache.mxnet.contrib.clojure/clojure-mxnet "1.5.0-SNAPSHOT"]]
:main ^:skip-aot infer.objectdetector-example
:profiles {:uberjar {:aot :all}})
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@

set -e

MXNET_ROOT=$(cd "$(dirname $0)/../../../.."; pwd)
MXNET_ROOT=$(cd "$(dirname $0)/.."; pwd)

data_path=$MXNET_ROOT/examples/scripts/infer/models/resnet50_ssd
data_path=$MXNET_ROOT/models/resnet50_ssd

image_path=$MXNET_ROOT/examples/scripts/infer/images
image_path=$MXNET_ROOT/images

if [ ! -d "$data_path" ]; then
mkdir -p "$data_path"
Expand All @@ -34,10 +34,13 @@ if [ ! -d "$image_path" ]; then
mkdir -p "$image_path"
fi

if [ ! -f "$data_path" ]; then
wget https://s3.amazonaws.com/model-server/models/resnet50_ssd/resnet50_ssd_model-symbol.json -P $data_path
wget https://s3.amazonaws.com/model-server/models/resnet50_ssd/resnet50_ssd_model-0000.params -P $data_path
wget https://s3.amazonaws.com/model-server/models/resnet50_ssd/synset.txt -P $data_path
if [ ! -f "$data_path/resnet50_ssd_model-0000.params" ]; then
wget https://s3.amazonaws.com/model-server/models/resnet50_ssd/resnet50_ssd_model-symbol.json -P $data_path
wget https://s3.amazonaws.com/model-server/models/resnet50_ssd/resnet50_ssd_model-0000.params -P $data_path
wget https://s3.amazonaws.com/model-server/models/resnet50_ssd/synset.txt -P $data_path
fi

if [ ! -f "$image_path/000001.jpg" ]; then
cd $image_path
wget https://cloud.githubusercontent.com/assets/3307514/20012566/cbb53c76-a27d-11e6-9aaa-91939c9a1cd5.jpg -O 000001.jpg
wget https://cloud.githubusercontent.com/assets/3307514/20012567/cbb60336-a27d-11e6-93ff-cbc3f09f5c9e.jpg -O dog.jpg
Expand Down
Loading