Using TensorFlow Audio Recognition Model on iOS - ios

I'm trying to use the TensorFlow audio recognition model (my_frozen_graph.pb, generated here: https://www.tensorflow.org/tutorials/audio_recognition) on iOS.
But the iOS code NSString* network_path = FilePathForResourceName(#"my_frozen_graph", #"pb"); in the TensorFlow Mobile's tf_simple_example project outputs this error message: Could not create TensorFlow Graph: Not found: Op type not registered 'DecodeWav'.
Anyone knows how I can fix this? Thanks!

I believe you are using the pre-build Tensorflow from Cocapods? It probably does not have that op type, so you should build it yourself from latest source.
From documentation:
While Cocapods is the quickest and easiest way of getting started, you
sometimes need more flexibility to determine which parts of TensorFlow
your app should be shipped with. For such cases, you can build the iOS
libraries from the sources. This guide contains detailed instructions
on how to do that.
This might also be helpful: [iOS] Add optional Selective Registration of Ops #14421
Optimization
The build_all_ios.sh script can take optional
command-line arguments to selectively register only for the operators
used in your graph.
tensorflow/contrib/makefile/build_all_ios.sh -a arm64 -g $HOME/graphs/inception/tensorflow_inception_graph.pb
Please note this
is an aggresive optimization of the operators and the resulting
library may not work with other graphs but will reduce the size of the
final library.
After the build is done you can check /tensorflow/tensorflow/core/framework/ops_to_register.h for operations that were registered. (autogenerated during build with -g flag)

Some progress: having realized the unregistered DecodeWav error is similar to the old familiar DecodeJpeg issue (#2883), I ran strip_unused on the pb as follows:
bazel-bin/tensorflow/python/tools/strip_unused \
--input_graph=/tf_files/speech_commands_graph.pb \
--output_graph=/tf_files/stripped_speech_commands_graph.pb \
--input_node_names=wav_data,decoded_sample_data \
--output_node_names=labels_softmax \
--input_binary=true
It does get rid of the DecodeWav op in the resulting graph. But running the new stripped graph on iOS now gives me an Op type not registered 'AudioSpectrogram' error.
Also there's no object file audio*.o generated after build_all_ios.sh is done, although AudioSpectrogramOp is specified in tensorflow/core/framework/ops_to_register.h:
Jeffs-MacBook-Pro:tensorflow-1.4.0 zero2one$ find . -name decode*.o
./tensorflow/contrib/makefile/gen/obj/ios_ARM64/tensorflow/core/kernels/decode_bmp_op.o
./tensorflow/contrib/makefile/gen/obj/ios_ARM64/tensorflow/core/kernels/decode_wav_op.o
./tensorflow/contrib/makefile/gen/obj/ios_ARMV7/tensorflow/core/kernels/decode_bmp_op.o
./tensorflow/contrib/makefile/gen/obj/ios_ARMV7/tensorflow/core/kernels/decode_wav_op.o
./tensorflow/contrib/makefile/gen/obj/ios_ARMV7S/tensorflow/core/kernels/decode_bmp_op.o
./tensorflow/contrib/makefile/gen/obj/ios_ARMV7S/tensorflow/core/kernels/decode_wav_op.o
./tensorflow/contrib/makefile/gen/obj/ios_I386/tensorflow/core/kernels/decode_bmp_op.o
./tensorflow/contrib/makefile/gen/obj/ios_I386/tensorflow/core/kernels/decode_wav_op.o
./tensorflow/contrib/makefile/gen/obj/ios_X86_64/tensorflow/core/kernels/decode_bmp_op.o
./tensorflow/contrib/makefile/gen/obj/ios_X86_64/tensorflow/core/kernels/decode_wav_op.o
Jeffs-MacBook-Pro:tensorflow-1.4.0 zero2one$ find . -name audio*_op.o
Jeffs-MacBook-Pro:tensorflow-1.4.0 zero2one$

Just verified that Pete's fix (https://github.com/tensorflow/tensorflow/issues/15921) is good:
add this line tensorflow/core/ops/audio_ops.cc to the file tensorflow/contrib/makefile/tf_op_files.txt and run tensorflow/contrib/makefile/build_all_ios.sh again (compile_ios_tensorflow.sh "-O3" itself used to work for me after adding a line to the tf_op_files.txt, but not anymore with TF 1.4).
Also, use the original model file, don't use the stripped version. Some note was added in the link above.

Related

Ada + Machine Learning (Python Framework)

I'm trying to write a simple machine learning application in Ada, and also trying to find a good framework to use. My knowledge of one thing is extremely minimal, and of the other is somewhat minimal.
There are several nifty machine learning frameworks out there, and I'd like to leverage one for use with an Ada program, but I guess I'm just...at a loss. Can I use an existing framework written in Python, for instance and wrap (or I guess, bind?) the API calls in Ada? Should I just pass off the scripting capabilities? I'm trying to figure it out.
Case in point: Scikit (sklearn)
https://scikit-learn.org/stable/tutorial/text_analytics/working_with_text_data.html#
This does some neat stuff, and I'd like to be able to leverage this, but with an Ada program. Does anyone have advice from a similar experience?
I am just researching, so I have tried finding information.
http://www.inspirel.com/articles/Ada_Python_Binding.html
https://scikit-learn.org/stable/tutorial/text_analytics/working_with_text_data.html#
The inspirel solution is based on python2.7. If you're using anything from python3.5 onwards a few mods need to be made. On Linux, changing to say python 3.7, you'd just change
--for Default_Switches ("Ada") use ("-lpython2.7");
for Default_Switches ("Ada") use ("-lpython3.7");
but on windows, the libraries aren't dumped in a community lib so gnat doesn't know where to find them. All the packages are kept separately. The -L has to be added to tell the linker where to find the library. Alternatively, you can use for lib_dir. In my case, I did a non-admin install of python, so it looks something like
for Default_Switches ("Ada") use ("-L\Users\StdUser\AppData\Local\Programs\Python\Python37-32\libs", "-lpython37");
Note that on windows, the library is called python37: not python3.7. Use gprbuild instead of gnatmake -p, which has been deprecated. If you do all your mods correctly
gprbuild ada_main.gpr
should give you an executable in obj\ada_main.exe if it builds. If a later version of python is used, some edits need to be made
python_module.py
#print 'Hello from Python module'
print('Hello from Python module')
#print 'Python adding:', a, '+', b
print('Python adding:', a, '+', b)
ada_main.adb
-- Python.Execute_String("print 'Hello from Python!'");
Python.Execute_String("print('Hello from Python!')");
Some routines have been deprecated so the linkage has to change
python.adb
--pragma Import(C, PyInt_AsLong, "PyInt_AsLong");
pragma Import(C, PyInt_AsLong, "PyLong_AsLong");
--pragma Import(C, PyString_FromString, PyString_FromString");
pragma Import(C, PyString_FromString, "PyUnicode_FromString");
Running the build and executable should give
C:\Users\StdUser\My Documents\ada-python>gprbuild ada_main.gpr
Compile
[Ada] ada_main.adb
Bind
[gprbind] ada_main.bexch
[Ada] ada_main.ali
Link
[link] ada_main.adb
C:\Users\StdUser\My Documents\ada-python>obj\ada_main.exe
executing Python directly from Ada:
Hello from Python!
loading external Python module and calling functions from that module:
Hello from Python module!
asking Python to add two integers:
Python adding: 10 + 2
Ada got result from Python: 12
we can try other operations, too:
subtract: 8
multiply: 20
divide : 5
Remember to put the pythonxx.dll somewhere on your path otherwise it won't be able to find the library when it starts executing.

Using Mosek with Drake on Deepnote

ValueError: "MosekSolver cannot Solve because MosekSolver::available() is false, i.e., MosekSolver has not been compiled as part of this binary. Refer to the MosekSolver class overview documentation for how to compile it."
Hi, I got the above error when trying to use the Mosek solver in Drake. It is not clear to me how to enable Mosek in Deepnote with Drake. Do I need to include something in the Dockerfile or the init file? Any tips would be appreciated.
Links I looked at:
https://drake.mit.edu/pydrake/pydrake.solvers.mosek.html
https://drake.mit.edu/bazel.html#mosek
Mosek+Drake does work on Deepnote. The workflow is like this:
Obtain a Mosek license file (from the Mosek website), and upload it to Deepnote.
Set an environment variable to tell Drake where to find the license file. For instance, you can add the following at the top of your notebook:
import os
os["MOSEKLM_LICENSE_FILE"] = "mosek.lic"
Now MosekSolver.available() should be True, and Mosek will even be chosen as the default preferred solver for if you simply call Solve(prog).
Note: Please be very careful not to share the Deepnote notebook with your mosek.lic uploaded.

How to create a new demo in automotive?

I'm trying to separate out some code from drake/automotive/automotive_demo.cc. As a first step, I'm trying to copy automotive_demo.cc and automotive_demo.py into differently named files (test.cc and test.py) and then running bazel run automotive:test -- --num_simple_cars=1. I modified automotive/BUILD.bazel and test.py to take into account the new dependencies.
The problem is that after I bazel run, the simulator window opens but no car gets rendered. Eventually it just crashes with the following errors:
[lcm-spy] ClassDiscoverer: java.lang.NoClassDefFoundError: apple/laf/AquaPopupMenuUI
[lcm-spy] jar: ../com_jidesoft_jide_oss/jide-oss-2.9.7.jar
[lcm-spy] class: com/jidesoft/plaf/aqua/AquaJidePopupMenuUI.class
...
[drake_visualizer] Qt WebEngine seems to be initialized from a plugin. Please set Qt::AA_ShareOpenGLContexts using QCoreApplication::setAttribute before constructing QGuiApplication.
...
[lcm-spy] LCM: Disabling IPV6 support
[lcm-spy] LCM: TTL set to zero, traffic will not leave localhost.
[lcm-spy] java.net.SocketException: Can't assign requested address
Here is an (unresolved) Github issue that points to the problem being that test is a "custom plug-in". But if automotive_demo can work, surely there's a way to reproduce that behavior for test? I also tried grepping for QGuiApplication and only found a series of binary files, so I didn't know how to follow the error message's suggestion.
when trying out your steps on Mac I unfortunately cannot reproduce your specific errors. I do not think that having test as a target name should cause problems (at least I did not experience issues).
Could you please make sure:
You're able to run bazel run automotive:demo -- --num_simple_car=1?
After having renamed automotive_demo.* to test.*, in your BAZEL.build, test.py files the following are mapped correctly: demo -> test and automotive_demo -> test_cc (or whatever unique name you choose)?

Is it possible to keep my Nix packages in sync across machines not running NixOS?

I know with NixOS, you can simply copy over the configuration.nix file to sync your OS state including installed packages between machines.
Is it possible then, to do the same using Nix the package manager on a non-NixOS OS to sync only the installed packages?
Please note, that at least since 30.03.2017 (corresponding to 17.03 Nix/NixOS channel/release), as far as I understand the official, modern, supported and suggested solution is to use the so called overlays.
See the chapter titled "Overlays" in the nixpkgs manual for a nice guide on how to use the new approach.
As a short summary: you can put any number of files with .nix extension in $HOME/.config/nixpkgs/overlays/ directory. They will be processed in alphabetical order, and each one can modify the set of available Nix packages. Each of the files must be written as in the following pattern:
self: super:
{
boost = super.boost.override {
python = self.python3;
};
rr = super.callPackage ./pkgs/rr {
stdenv = self.stdenv_32bit;
};
}
The super set corresponds to the "old" set of packages (before the overlay was applied). If you want to refer to the old version of a package (as in boost above), or callPackage, you should reference it via super.
The self set corresponds to the eventual, "future" set of packages, representing the final result after all overlays are applied. (Note: don't be scared when sometimes using them might get rejected by Nix, as it would result in infinite recursion. Probably you should rather just use super in those cases instead.)
Note: with the above changes, the solution I mention below in the original answer seems "deprecated" now — I believe it should still work as of April 2017, but I have no idea for how long. It appears marked as "obsolete" in the nixpkgs repository.
Old answer, before 17.03:
Assuming you want to synchronize apps per-user (as non-NixOS Nix keeps apps visible on per-user basis, not system-wide, as far as I know), it is possible to do it declaratively. It's just not well advertised in the manual — though it seems quite popular among long-time Nixers!
You must create a text file at: $HOME/.nixpkgs/config.nix — e.g.:
$ mkdir -p ~/.nixpkgs
$ $EDITOR ~/.nixpkgs/config.nix
then enter the following contents:
{
packageOverrides = defaultPkgs: with defaultPkgs; {
home = with pkgs; buildEnv {
name = "home";
paths = [
nethack mc pstree #...your favourite pkgs here...
];
};
};
}
Then you should be able to install all listed packages with:
$ nix-env -i home
or:
$ nix-env -iA nixos.home # *much* faster than above
In paths you can put stuff in a similar way like in /etc/nixos/configuration.nix on NixOS. Also, home is actually a "fake package" here. You can add more custom package definitions beside it, and then include them your "paths".
(Side note: I'm hoping to write a blog post with what I learned on how exactly this works, and also showing how to extend it with more customizations. I'll try to remember to link it here if I succeed.)

how can i upgrade my caffe model so it doesn't 'upgrade' every time I use it

I am using caffe with python(pycaffe). I am using the prebuilt alexnet model from model zoo.
from this page:
https://github.com/BVLC/caffe/tree/master/models/bvlc_alexnet
Every time I use the model, with this code:
net = caffe.Classifier('deploy.prototxt','bvlc_alexnet.caffemodel',
channel_swap=(2,1,0),
raw_scale=255,
image_dims=(256, 256))
caffe tells me the file format is old and it needs to upgrade the file. Shouldn't this happen only once?
E0304 20:52:57.356480 12716 upgrade_proto.cpp:609] Attempting to upgrade input file specified using deprecated transformation parameters: /tmp/bvlc_alexnet.caffemodel
I0304 20:52:57.356554 12716 upgrade_proto.cpp:612] Successfully upgraded file specified using deprecated data transformation parameters. E0304 20:52:57.356564 12716 upgrade_proto.cpp:614] Note that future Caffe releases will only support transform_param messages for transformation fields.
E0304 20:52:57.356580 12716 upgrade_proto.cpp:618] Attempting to upgrade input file specified using deprecated V1LayerParameter: /tmp/bvlc_alexnet.caffemodel
I0304 20:52:59.307096 12716 upgrade_proto.cpp:626] Successfully upgraded file specified using deprecated V1LayerParameter
how can I properly upgrade the file so that this doesn't happen every single time.
When you load the model caffe upgrades your prototxt and binary proto, but does not override the original files you are using. This is why you keep getting this message.
Upgrading is very straight forward. In $CAFFE_ROOT/build/tools you'll find two binaries: upgrade_net_proto_binary and upgrade_net_proto_text. Simply apply them to your deploy.prototxt and bvlc_alexnet.caffemodel and save the results:
~$ mv deploy.prototxt deploy_old.prototxt
~$ mv bvlc_alexnet.caffemodel bvlc_alexnet_old.caffemodel
~$ $CAFFE_ROOT/build/tools/upgrade_net_proto_text deploy_old.prototx deploy.prototxt
~$ $CAFFE_ROOT/build/tools/upgrade_net_proto_binary bvlc_alexnet_old.caffemodel bvlc_alexnet.caffemodel
And that's it!
Thank you for Shai for your help.
However, if you are in Windows upgrade_net_proto_binary and upgrade_net_proto_text .exe files are in path-to-caffe-master/caffe/build/tools/Release.
Hope this will help Windows users

Resources