1 # TensorFlow iOS Examples
2
3 This folder contains examples of how to build applications for iOS devices using TensorFlow.
4
5 ## Running the Samples using CocoaPod
6 - You'll need Xcode 7.3 or later.
7
8 - There are currently three examples: simple, benchmark, and camera. For now,
9 you can download the sample code by cloning the main tensorflow repository
10 (we are planning to make the samples available as a separate repository
11 later).
12
13 - From the root of the tensorflow folder, download
14 [Inception v1](https://storage.googleapis.com/download.tensorflow.org/models/inception5h.zip),
15 and extract the label and graph files into the data folders inside both the
16 simple and camera examples:
17
18 ```bash
19 mkdir -p ~/graphs
20 curl -o ~/graphs/inception5h.zip \
21 https://storage.googleapis.com/download.tensorflow.org/models/inception5h.zip \
22 && unzip ~/graphs/inception5h.zip -d ~/graphs/inception5h
23 cp ~/graphs/inception5h/* tensorflow/examples/ios/benchmark/data/
24 cp ~/graphs/inception5h/* tensorflow/examples/ios/camera/data/
25 cp ~/graphs/inception5h/* tensorflow/examples/ios/simple/data/
26 ```
27
28 - Change directory to one of the samples, download the TensorFlow-experimental
29 pod, and open the Xcode workspace. Observe: installing the pod can take a
30 long time since it is big (~450MB). For example, if you want to run the
31 simple example, then:
32 ```bash
33 cd tensorflow/examples/ios/simple
34 pod install
35 open tf_simple_example.xcworkspace # obs, not the .xcodeproj directory
36 ```
37
38 - Run the simple app in the simulator. You should see a single-screen app with
39 a "Run Model" button. Tap that, and you should see some debug output appear
40 below indicating that the example Grace Hopper image in directory data has
41 been analyzed, with a military uniform recognized.
42
43 - Run the other samples using the same process. The camera example requires a
44 real device connected. Once you build and run that, you should get a live
45 camera view that you can point at objects to get real-time recognition
46 results.
47
48 ### Troubleshooting
49
50 - Make sure you use the TensorFlow-experimental pod (and not TensorFlow).
51
52 - The TensorFlow-experimental pod is current about ~450MB. The reason it is
53 so big is because we are bundling multiple platforms, and the pod includes
54 all TensorFlow functionality (e.g. operations). The final app size after
55 build is substantially smaller though (~25MB). Working with the complete
56 pod is convenient during development, but see below section on how you can
57 build your own custom TensorFlow library to reduce the size.
58
59 ### Creating Your own App
60
61 - Create your own app using Xcode then add a file named Podfile at the project
62 root directory with the following content:
63 ```bash
64 target 'YourProjectName'
65 pod 'TensorFlow-experimental'
66 ```
67
68 - Then you run ```pod install``` to download and install the
69 TensorFlow-experimental pod, and finally perform
70 ```open YourProjectName.xcworkspace``` and add your code.
71
72 - In your apps "Build Settings", make sure to add $(inherited) to sections
73 "Other Linker Flags", and "Header Search Paths".
74
75 - That's it. If you want to create your custom TensorFlow iOS library, for
76 example to reduce binary footprint, see below section.
77
78 ## Building the TensorFlow iOS libraries from source
79
80 - You'll need Xcode 7.3 or later, with the command-line tools installed.
81
82 - Follow the instructions at
83 [tensorflow/contrib/makefile](https://github.com/tensorflow/tensorflow/tree/master/tensorflow/contrib/makefile)
84 under "iOS" to compile a static library containing the core TensorFlow code.
85
86 - You should see a single-screen app with a "Run Model" button. Tap that, and
87 you should see some debug output appear below indicating that the example
88 Grace Hopper image has been analyzed, with a military uniform recognized.
89
90 - Once you have success there, make sure you have a real device connected and
91 open up the Xcode project in the `camera` subfolder. Once you build and run
92 that, you should get a live camera view that you can point at objects to get
93 real-time recognition results.
94
95 ### Troubleshooting
96
97 If you're hitting problems, here's a checklist of common things to investigate:
98
99 - Make sure that you've run the `build_all_ios.sh` script.
100 This will run `download_dependencies.sh`,`compile_ios_protobuf.sh` and `compile_ios_tensorflow.sh`.
101 (check each one if they have run successful.)
102
103 - Check that you have version 7.3 of Xcode.
104
105 - If there's a complaint about no Sessions registered, that means that the C++
106 global constructors that TensorFlow relies on for registration haven't been
107 linked in properly. You'll have to make sure your project uses force_load, as
108 described below.
109
110 ### Creating your Own App from your source libraries
111
112 You'll need to update various settings in your app to link against
113 TensorFlow. You can view them in the example projects, but here's a full
114 rundown:
115
116 - The `compile_ios_tensorflow.sh` script builds a universal static library in
117 `tensorflow/contrib/makefile/gen/lib/libtensorflow-core.a`. You'll need to add
118 this to your linking build stage, and in Search Paths add
119 `tensorflow/contrib/makefile/gen/lib` to the Library Search Paths setting.
120
121 - You'll also need to add `libprotobuf.a` and `libprotobuf-lite.a` from
122 `tensorflow/contrib/makefile/gen/protobuf_ios/lib` to your _Build Stages_ and
123 _Library Search Paths_.
124
125 - The _Header Search_ paths needs to contain:
126 - the root folder of tensorflow,
127 - `tensorflow/contrib/makefile/downloads/protobuf/src`
128 - `tensorflow/contrib/makefile/downloads`,
129 - `tensorflow/contrib/makefile/downloads/eigen`, and
130 - `tensorflow/contrib/makefile/gen/proto`.
131
132 - In the Linking section, you need to add `-force_load` followed by the path to
133 the TensorFlow static library in the _Other Linker_ Flags section. This ensures
134 that the global C++ objects that are used to register important classes
135 inside the library are not stripped out. To the linker, they can appear
136 unused because no other code references the variables, but in fact their
137 constructors have the important side effect of registering the class.
138
139 - You'll need to include the Accelerate framework in the "Link Binary with
140 Libraries" build phase of your project.
141
142 - C++11 support (or later) should be enabled by setting `C++ Language Dialect` to
143 `GNU++11` (or `GNU++14`), and `C++ Standard Library` to `libc++`.
144
145 - The library doesn't currently support bitcode, so you'll need to disable that
146 in your project settings.
147
148 - Remove any use of the `-all_load` flag in your project. The protocol buffers
149 libraries (full and lite versions) contain duplicate symbols, and the
150 `-all_load` flag will cause these duplicates to become link errors. If you
151 were using `-all_load` to avoid issues with Objective-C categories in static
152 libraries, you may be able to replace it with the `-ObjC` flag.
153
154 ### Reducing the binary size
155
156 TensorFlow is a comparatively large library for a mobile device, so it will
157 increase the size of your app. Currently on iOS we see around a 11 MB binary
158 footprint per CPU architecture, though we're actively working on reducing that.
159 It can be tricky to set up the right configuration in your own app to keep the
160 size minimized, so if you do run into this issue we recommend you start by
161 looking at the simple example to examine its size. Here's how you do that:
162
163 - Open the Xcode project in tensorflow/examples/ios/simple.
164
165 - Make sure you've followed the steps above to get the data files.
166
167 - Choose "Generic iOS Device" as the build configuration.
168
169 - Select Product->Build.
170
171 - Once the build's complete, open the Report Navigator and select the logs.
172
173 - Near the bottom, you'll see a line saying "Touch tf_simple_example.app".
174
175 - Expand that line using the icon on the right, and copy the first argument to
176 the Touch command.
177
178 - Go to the terminal, type `ls -lah ` and then paste the path you copied.
179
180 - For example it might look like `ls -lah /Users/petewarden/Library/Developer/Xcode/DerivedData/tf_simple_example-etdbksqytcnzeyfgdwiihzkqpxwr/Build/Products/Debug-iphoneos/tf_simple_example.app`
181
182 - Running this command will show the size of the executable as the
183 `tf_simple_example` line.
184
185 Right now you'll see a size of around 25 MB, since it's including two
186 architectures (armv7 and arm64). As a first step, you should make sure the size
187 increase you see in your own app is similar, and if it's larger, look at the
188 "Other Linker Flags" used in the Simple Xcode project settings to strip the
189 executable.
190
191 After that, you can manually look at modifying the list of kernels
192 included in tensorflow/contrib/makefile/tf_op_files.txt to reduce the number of
193 implementations to the ones you're actually using in your own model. We're
194 hoping to automate this step in the future, but for now manually removing them
195 is the best approach.
196