Turi Create  4.0
compute_context.hpp
1 /* Copyright © 2018 Apple Inc. All rights reserved.
2  *
3  * Use of this source code is governed by a BSD-3-clause license that can
4  * be found in the LICENSE.txt file or at https://opensource.org/licenses/BSD-3-Clause
5  */
6 
7 #ifndef UNITY_TOOLKITS_NEURAL_NET_COMPUTE_CONTEXT_HPP_
8 #define UNITY_TOOLKITS_NEURAL_NET_COMPUTE_CONTEXT_HPP_
9 
10 #include <memory>
11 
12 #include <core/export.hpp>
13 #include <core/system/exceptions/TuriException.hpp>
14 #include <ml/neural_net/image_augmentation.hpp>
15 #include <ml/neural_net/model_backend.hpp>
16 
17 namespace turi {
18 namespace neural_net {
19 
20 /** A struct to define all the parameters used to create the activity classifier
21  * model backend
22  */
23 struct ac_parameters {
24  /** Defines the batch size */
26 
27  /** Defines the number of features in the data */
29 
30  /** Each group of this many consecutive samples from the same session are
31  * assumed to have the same class label.
32  */
34 
35  /** Defines the number of classes */
37 
38  /** Each session is segmented into chunks of this many prediction windows. */
40 
41  /** Setting random seed makes results reproducible. */
43 
44  /** Set to true, when the data is used for training. */
46 
47  /** Defines the weights of the network */
48  float_array_map weights;
49 };
50 /**
51  * Interface for factories that produce concrete data augmentation and neural
52  * network module instances, used to abstract across backend implementations and
53  * hardware resources.
54  */
55 class EXPORT compute_context {
56  public:
57  /** Function that yields a compute context. */
58  using factory = std::function<std::unique_ptr<compute_context>()>;
59 
60  /**
61  * To solve for layering/dependency issues, we allow compute_context::factory
62  * values to be defined at runtime. Instantiating this class, preferably at
63  * static init time, adjusts the behavior of the create() function below.
64  */
65  class registration {
66  public:
67  // Registers `factory_fn` at the given priority.
68  registration(int priority, factory factory_fn, factory tf_factory_fn_, factory mlc_factory_fn_);
69 
70  // Removes the registration. In practice, simplest just not to deallocate...
71  ~registration();
72 
73  int priority() const { return priority_; }
74  std::unique_ptr<compute_context> create_context() const {
75  return factory_fn_();
76  }
77 
78  std::unique_ptr<compute_context> create_tensorflow_context() const {
79  return tf_factory_fn_ ? tf_factory_fn_() : nullptr;
80  }
81 
82  std::unique_ptr<compute_context> create_mlc_context() const
83  {
84  return mlc_factory_fn_ ? mlc_factory_fn_() : nullptr;
85  }
86 
87  private:
88  int priority_;
89  factory factory_fn_;
90  factory tf_factory_fn_;
91  factory mlc_factory_fn_;
92  };
93 
94  /**
95  * Requests a compute_context from each registered compute_context::factory,
96  * in ascending order by "priority", until one returns non-nil. Factories
97  * should be registered so that this function yields a backend appropriate to
98  * the current platform and hardware.
99  */
100  static std::unique_ptr<compute_context> create();
101 
102  static std::unique_ptr<compute_context> create_tf();
103 
104  static std::unique_ptr<compute_context> create_mlc();
105 
106  virtual ~compute_context();
107 
108  /**
109  * Prints (human readable) device information.
110  */
111  virtual void print_training_device_info() const = 0;
112 
113  /**
114  * Provides a measure of the memory resources available.
115  *
116  * Returns the maximum memory size in bytes that neural networks should
117  * allocate, typically used to determine batch sizes (often heuristically).
118  */
119  virtual size_t memory_budget() const = 0;
120 
121  /**
122  * Creates an object detection network.
123  *
124  * \todo Define a object_detector_config struct to encapsulate these
125  * parameters in a more self-documenting and typesafe way.
126  * \todo Initialize the network directly from a model_spec, in lieu of passing
127  * weights as a float_array_map.
128  */
129  virtual std::unique_ptr<model_backend> create_object_detector(int n, int c_in, int h_in, int w_in,
130  int c_out, int h_out, int w_out,
131  const float_array_map& config,
132  const float_array_map& weights)
133  {
134  throw TuriException(TuriErrorCode::NotImplemented);
135  }
136 
137  /**
138  * Creates an activity classification network.
139  *
140  * \todo Define an activity_classifier_config struct to encapsulate these
141  * parameters in a more self-documenting and typesafe way.
142  * \todo Initialize the network directly from a model_spec, in lieu of passing
143  * weights as a float_array_map.
144  */
145  virtual std::unique_ptr<model_backend> create_activity_classifier(
146  const ac_parameters& ac_params) {
147  throw TuriException(TuriErrorCode::NotImplemented);
148  }
149 
150  /**
151  * Creates a style transfer network
152  *
153  * \todo Define an style_transfer_config struct to encapsulate these
154  * parameters in a more self-documenting and typesafe way.
155  * \todo Initialize the network directly from a model_spec, in lieu of passing
156  * weights as a float_array_map.
157  */
158  virtual std::unique_ptr<model_backend> create_style_transfer(const float_array_map& config,
159  const float_array_map& weights)
160  {
161  throw TuriException(TuriErrorCode::NotImplemented);
162  }
163 
164  /**
165  * Creates a drawing classification network.
166  *
167  * \todo Define a drawing_classifier_config struct to encapsulate these
168  * parameters in a more self-documenting and typesafe way.
169  * \todo Initialize the network directly from a model_spec, in lieu of passing
170  * weights as a float_array_map.
171  * \todo what args here?
172  */
173  virtual std::unique_ptr<model_backend> create_drawing_classifier(
174  /* TODO: const float_array_map& config if needed */
175  const float_array_map& weights, size_t batch_size, size_t num_classes) {
176  throw TuriException(TuriErrorCode::NotImplemented);
177  }
178 
179  /**
180  * Creates an image augmenter.
181  */
182  virtual std::unique_ptr<image_augmenter> create_image_augmenter(
183  const image_augmenter::options& opts)
184  {
185  throw TuriException(TuriErrorCode::NotImplemented);
186  }
187 
188  /**
189  * Creates a multilevel perceptron classifier.
190  */
191  virtual std::unique_ptr<turi::neural_net::model_backend> create_multilayer_perceptron_classifier(
192  int n, int c_in, int c_out, const std::vector<size_t>& layer_sizes,
193  const turi::neural_net::float_array_map& config)
194  {
195  throw TuriException(TuriErrorCode::NotImplemented);
196  }
197 };
198 
199 } // namespace neural_net
200 } // namespace turi
201 
202 #endif // UNITY_TOOLKITS_NEURAL_NET_COMPUTE_CONTEXT_HPP_
virtual std::unique_ptr< model_backend > create_activity_classifier(const ac_parameters &ac_params)
virtual std::unique_ptr< image_augmenter > create_image_augmenter(const image_augmenter::options &opts)
std::function< std::unique_ptr< compute_context >()> factory
virtual std::unique_ptr< model_backend > create_object_detector(int n, int c_in, int h_in, int w_in, int c_out, int h_out, int w_out, const float_array_map &config, const float_array_map &weights)
virtual std::unique_ptr< model_backend > create_style_transfer(const float_array_map &config, const float_array_map &weights)
virtual std::unique_ptr< turi::neural_net::model_backend > create_multilayer_perceptron_classifier(int n, int c_in, int c_out, const std::vector< size_t > &layer_sizes, const turi::neural_net::float_array_map &config)
virtual std::unique_ptr< model_backend > create_drawing_classifier(const float_array_map &weights, size_t batch_size, size_t num_classes)