見出し画像

Core ML 3の詳細

以下の記事が面白かったので、ざっくり訳してみました。

An in-depth look at Core ML 3

0. はじめに

WWDC 2019のビデオでお気づきかもしれませんが、「Core ML 3」はiOSの機械学習に多くの新しい機能を追加します。新しいキラー機能は、モデルのオンデバイストレーニングですが、多くの高度なモデルアーキテクチャを実行できるようになりました。多くの新しいレイヤータイプの追加により、まだ発明されていない新しいアーキテクチャも実行できるはずです。

これは、2017年の最初のリリース以来、Core MLの圧倒的な最大のアップデートです。

「Core ML」は完璧ではありませんが、これらの新しい追加機能とA12チップの「Neural Engine」によって、Appleはモバイルでの機械学習に関して他の誰よりも確実に先んじています。

このブログ投稿では、「Core ML 3」の新機能が何であるかを個々のレイヤータイプまで詳細に説明します。ここでは、「CoreML.framework」からのAPIではなく、「mlmodel形式」を主に見ていきます(訓練機能の追加を除いて、実際にはあまり変化しませんでした)。

既存のモデルを変換してアプリで使用するだけの場合は、このことを知る必要はないでしょう。ただし、「Core ML 3」で使用する予定の独自の機械学習モデルを設計するとき、または既存のモデルを変換できるかどうかわからないときは、参考になるでしょう。

1. すべてはprotoファイルにある

何が新しいのか、「CoreML.framework」のAPIドキュメントで調べるのは、それほど賢くありません。重要な点は、APIドキュメントではなく、「Core ML形式仕様」にあります。

この仕様は、protobufメッセージ定義を含む多数の「protoファイル」で構成されています。Protobuf、または「Protocol Buffers」は、Core MLのmlmodelファイルで使用されるシリアル化形式です。これは、TensorFlowとONNXでも使用される一般的なシリアル化技術です。protoファイルは、mlmodelファイルにあるさまざまなオブジェクトを記述しています。

「Core ML」モデルの仕様はこちらで確認できますが、このWebサイトは常に最新とは限りません。protoファイルを直接確認することをお勧めします。これらはcoremltoolsリポジトリ内にあります。これらは通常のテキストファイルなので、任意のエディターで開くことができます。

形式仕様のメインファイルは「Model.proto」です。これは、モデルとは何か、モデルが持つことができる入力と出力の種類、および存在するさまざまなタイプのモデルを定義します。

Model定義の重要なプロパティは、仕様バージョンです。このバージョン番号は、mlmodelファイルで使用可能な機能、およびモデルを実行できるオペレーティングシステムを決定します。

新しい仕様バージョンは、予想どおり3ではなく4です。「Core ML」には3つのメジャーリリースがありますが、バージョン番号を上げたiOS 11.2の小さなアップデートもありました。

仕様バージョン4の「Core ML」モデルは、iOS 13およびmacOS 10.15(Catalina)以上でのみ実行できます。iOS 12または11をターゲットにしている場合は、このブログ投稿に示されている新機能の使用を忘れてください。

2. 新しいモデルの種類

◎仕様v1
Core MLは、常に「仕様v1」をサポートしています。

・アイデンティティ
これは何もせず、入力データを単に出力に渡します。テストにのみ役立ちます。

・GLM回帰および分類子
線形およびロジスティック回帰用です。

・回帰および分類のためのサポートベクターマシン

・ツリーアンサンブルの回帰分析と分類器
XGBoostモデル用です。

・ニューラルネットワーク
回帰、分類、または汎用ニューラルネットワーク用です。

・パイプラインモデル
複数のモデルを1つの大きなモデルに結合できます。

・フィーチャエンジニアリングのモデルタイプ
ワンホットエンコード、欠損値の代入、入力ベクトル化などです。これらは主にscikit-learnモデルをCore MLに変換するのに役立ちます。モデルは、これらの機能エンジニアリングモデルのいくつかを連続して持つパイプラインに変わります。

◎仕様v2
「仕様v2」は、16ビット浮動小数点の重みのサポートを追加した小さな更新でした。これを有効にすると、mlmodelファイルが約2倍小さくなりますが、一部の人が予想するものとは異なり、モデルの実行速度が上がりません。

◎仕様v3
「仕様v3」(Core ML 2)では、次のモデルタイプが追加されました。

・ベイジアンプロビット回帰
ロジスティック回帰のより派手なバージョンです。

・非最大抑制
通常、パイプラインの最後のモデルとして使用される、オブジェクト検出結果の後処理に役立ちます。
詳細については、Core MLのSSDLiteに関する私のブログ投稿を参照してください。

・VisionFeaturePrint
これは、画像から特徴を抽出するための畳み込みニューラルネットワークです。出力は、2048要素の特徴ベクトルです。「Create ML」は、これを画像分類器の訓練時の転移学習に使用しますが、独自のモデルで使用することもできます(画像の類似性など)。

・Create MLの他のモデル
テキスト分類子、ワードタガー。

・カスタムモデル
場合によっては、Core MLが理解できないモデルタイプがありますが、それでも他のモデルと一緒にパイプラインに配置したいことがあります。
カスタムモデルを使用すると、学習したパラメーター(およびその他のデータ)をmlmodelファイル内に配置し、カスタムロジックの実際の実装をアプリ内に配置できます。

v3で追加されたその他の機能は、さらに小さなmlmodelファイルの重みの量子化(ただし、推論速度は変わらない)と柔軟な入力サイズです。
APIは、バッチ予測を追加し、シーケンシャルデータを処理するためのサポートを改善しました。

◎仕様v4
仕様v3(Core ML 3)以降、mlmodelファイルでは次のモデルタイプも記述できます。

・k-Nearest Neighbors分類器(またはk-NN)

・ItemSimilarityRecommender
これを使用して、「Create ML」に付属しているような推奨モデルを作成できます。

・SoundAnalysisPreprocessing
これは、「Create ML」の新しいサウンド分類モデル用です。オーディオサンプルを受け取り、それらをメルスペクトログラムに変換します。これは、パイプラインでオーディオフィーチャ抽出モデル(通常はニューラルネットワーク)への入力として使用できます。

・Gazetteer
これは、自然言語フレームワークMLGazetteerで使用される「Create ML」の新しいモデルNLTaggerです。地名辞典は、単語や語句の豪華なルックアップテーブルです。

・WordEmbedding
MLWordEmbedding単語とその埋め込みベクトルの辞書であるCreate MLの新しいモデルです。自然言語フレームワークでも使用されます。

・リンクモデル
リンクモデルは、アプリバンドル内の別のmlmodelファイル(実際には、コンパイルされたバージョンmlmodelc)への単なる参照です。これにより、高価な特徴抽出機能を複数の分類子で再利用できます。2つの異なるパイプラインが同じリンクモデルを使用する場合、一度だけ読み込まれます。

ModelオブジェクトにisUpdatableプロパティが追加されました。これが当てはまる場合、新しいデータを使用してモデルをオンラインデバイストレーニングできます。これは現在、ニューラルネットワークとk-Nearest Neighborでのみ動作します(スタンドアロンモデルまたはパイプライン内で)。

k-Nearest Neighborsは単純なアルゴリズムにすぎませんが、オンデバイストレーニングに非常に適しています。一般的な方法は、VisionFeaturePrintなどの固定ニューラルネットワークを使用し、入力データから特徴を抽出し、k-NNを使用してそれらの特徴ベクトルを分類することです。このようなモデルは、訓練するのが非常に高速です。k-NNは、与えられた例を記憶するだけで、実際の学習は行わないからです。

k-NNの欠点の1つは、多くの例が記憶されていると予測が遅くなることですが、「Core ML」は非常に効率的なK-Dツリーバリアントをサポートします。

3. ニューラルネットワークの新機能

「Core ML 3」の変更の大部分はニューラルネットワークに関連しています。

「Core ML 2」は約40の異なるレイヤータイプを「のみ」サポートしていましたが、「Core ML 3」は100を超える新しいレイヤータイプを追加しています。しかし、これらの新しいレイヤーのいくつかは、柔軟なテンソル形状の処理に適した古いレイヤータイプの単なる改良です。

「Core ML 2」以前の場合、ニューラルネットワークを流れるデータは常にランク5のテンソルでした。つまり、各テンソルは次の5つの次元でこの順序で構成されていました。

(sequence length, batch size, channels, height, width)

ニューラルネットワークへの入力の大部分が画像である場合、この選択は非常に理にかなっていますが、他の種類のデータにはあまり適応しません。

1次元ベクトルを処理するニューラルネットワークでは、「チャネル」次元を使用してベクトルのサイズを記述し、他の次元をサイズ1に設定することになっています。その場合、入力テンソルの形状 (1, batch size, number of elements, 1, 1)になります。

「Core ML 3」に追加された新しいレイヤーの多くは、任意のランクと形状のテンソルをサポートしているため、「Core ML」は画像以外のデータにより適しています。

全てのニューラルネットワークは、「NeuralNetwork.proto」で説明されています。約5000行の大きなファイルです。


主なオブジェクトは「NeuralNetwork」ですが、他にも2つのバリエーションがあります。「NeuralNetworkClassifier」と「NeuralNetworkRegressor」です。違いは、プレーンニューラルネットワークはMultiArrayオブジェクトまたはイメージを出力し、分類子バリアントはクラスとその予測確率を含む辞書を出力し、回帰分析は単に数値を出力することです。出力の解釈方法のわずかな違いを除けば、これら3つのモデルタイプはすべて同じように機能します。

NeuralNetworkオブジェクトには、レイヤーのリストと、画像入力の前処理オプションのリストがあります。「Core ML 3」では、以下を説明する新しいプロパティがいくつか追加されています。

・MultiArrayの入力がテンソルに変換される方法
前に示したランク5テンソルを作成する古い方法と、入力テンソルを変更せずに単に渡す新しい方法のどちらかを選択できます。画像ではないほとんどのタイプのデータでは、この新しい方法を使用するのが理にかなっています。

・画像入力がテンソルに変換される方法
古いランク5テンソルの代わりに、ランク4テンソルを使用することを選択できます。これはちょうど(batch size, channels, height, width)です。これにより、「シーケンスの長さ」ディメンションが削除されます。これは通常、画像には必要ありません(もちろん、それらのシーケンスがある場合を除きます)。

・このモデルを訓練するためのハイパーパラメータ
これはNetworkUpdateParametersオブジェクトです(以下で説明)。

すぐにオンデバイストレーニングに関する詳細なブログ記事を書く予定ですが、何が関係しているのかをお伝えします。

・ModelのisUpdatableプロパティにtrueを設定

・訓練するレイヤーのisUpdatableプロパティをtrueに設定
これにより、訓練を特定のレイヤーのみに制限できます。現在、訓練は畳み込み層と完全に接続された層でのみサポートされています。

・訓練するレイヤーの学習可能なパラメータを保持
WeightParamsオブジェクトには、isUpdatableプロパティも設定する必要があります。

・モデルに追加の「training inputs」を定義して、損失関数にground-truth labelsを提供


さらに、NetworkUpdateParametersオブジェクトは以下について説明します。

・使用する損失関数
サポートされている損失関数は、カテゴリクロスエントロピーとMSEです。
mlmodelファイル内では、損失関数は単なる別のレイヤーです。2つのプロパティのみがあります。1つのモデルの出力レイヤーの名前と、ターゲットラベ
クロスエントロピーの場合、入力をsoftmaxレイヤーの出力に接続する必要があります。

・使用するオプティマイザ
現在、SGDとAdamのみがサポートされています。

・訓練するエポックの数


エポック数、学習率などのハイパーパラメーターは、アプリ内でオーバーライドできることに注意してください。mlmodel内の値は適切なデフォルト値に設定する必要がありますが、気に入らなくてもそれらにこだわることはありません

4. Core ML 2のニューラルネットワーク層

◎仕様v1
「仕様v1」は、次のレイヤータイプのみをサポートしていました。

・畳み込み層
2Dのみです。ただし、カーネルの幅または高さを1に設定することにより、1Dの畳み込みを偽造できます。また、拡張畳み込みまたは畳み込み畳み込み、グループ化(深さ)畳み込み、および畳み込みをサポートします。

・プーリング層
max、average、L2、グローバルプーリングをサポートします。

・全結合層
「inner product」や「dense」レイヤーとしても知られます。

・アクティベーション関数
linear、ReLU、leaky ReLU、thresholded ReLU、PReLU、tanh、scaled tanh、sigmoid、hard sigmoid、ELU、softsign、softplus、parametric soft plus。アクティベーション関数はすべて、単一のレイヤータイプActivationParamsによって処理されます。活性化が畳み込み層のプロパティになることがあるKerasとは異なり、「Core ML」では常に独自の層であることに注意してください。速度を上げるために、可能であれば、「Core ML」ランタイムはアクティベーション機能を前のレイヤーと「融合」します。

・バッチ正規化

・他の正規化
mean & variance、L2 norm、local response normalization (LRN)。

・ソフトマックス
通常、NeuralNetworkClassifierオブジェクトの最後のレイヤーです。

・パディング
イメージテンソルのエッジにゼロパディングを追加します。畳み込み層とプーリング層はすでにパディング自体を処理できますが、この層を使用すると、リフレクションまたはレプリケーションパディングなどを実行できます。

・クロッピング
テンソルのエッジの周りのピクセルを削除します。

・アップサンプリング
最近接または整数スケーリング係数による双線形アップサンプリングです。

・単項演算
sqrt、1/sqrt、1/x、x^power、exp、log、abs、thresholding。

・2つ以上のテンソル間の要素単位の操作
add、multiply、average、maximum、minimum。これらはある程度ブロードキャストをサポートします。

・単一のテンソルでの要素ごとの操作
scale factor、add bias。これらはブロードキャストをサポートします。

・単一のテンソルの縮約操作
sum、sum of natural logarithm、sum of squares、average、product、L1 norm、L2 norm、maximum、minimum、argmax。2つのベクトル間のドット積も、コサイン類似度を計算できます。

・テンソルのコンテンツを再編成するレイヤー
reshape、flatten、permute、space-to-depth、depth-to-space.

・連結、分割、スライス
これらは、テンソルを結合または引き離します。

・リカレントニューラルネットワーク層
基本的なRNN、単方向および双方向のLSTM、GRU(単方向のみ)です。

・シーケンスの繰り返し
指定された入力シーケンスを何度も複製します。

・埋め込み

・負荷定数
オブジェクト検出モデルのアンカーボックスなど、他のいくつかのレイヤーにデータを提供するために使用できます。

◎仕様v2
「仕様v2」では、ニューラルネットワークのカスタムレイヤーのサポートが追加されました。より多くのモデルを変換できるようになったため、これは非常に歓迎すべき追加でした。

mlmodelファイル内では、カスタムレイヤーは単なるプレースホルダーであり、おそらく訓練された重みと構成パラメーターを持ちます。アプリでは、レイヤーの機能のSwiftまたはObjective-C実装を提供することになっています。また、GPUで実行するために、おそらくMetalバージョンも提供することになっています。(残念ながら、現在、ニューラルエンジンはカスタムレイヤーのオプションではありません。)

たとえば、モデルに上記のリストにないアクティベーション関数が必要な場合、カスタムレイヤーとして実装できます。ただし、他のレイヤータイプのいくつかを巧みに組み合わせることでこれを行うこともできます。たとえば、ReLU6は、最初に通常のReLUを実行し、次にデータに-1を乗算して、しきい値を-6にし、最後に再び-1を乗算することによって作成できます。これには4つの異なる層が必要ですが、理論上、Core MLフレームワークは実行時にこれを最適化できます。

◎仕様v3
「仕様v3」(Core ML 2)では、次のレイヤータイプが追加されました。

・バイリニアのサイズ変更
整数のスケーリング係数のみを受け入れるアップサンプリングレイヤーとは異なり、これにより、任意の画像サイズにバイリニアのサイズ変更を実行できます。

・クロップサイズ変更
テンソルから関心領域を抽出します。 これを使用して、Mask R-CNNで使用されているRoI Alignレイヤーを実装できます。

ベクトルまたはシーケンスデータを処理するレイヤータイプはありますが、
ほとんどのレイヤーは画像を処理するための畳み込みニューラルネットワークに非常に焦点を当てています。「Core ML 2」では、データが1次元のみの場合でも、すべてのレイヤーが形状のテンソル(sequence length, batch size, channels, height, width) を想定しています。

◎仕様v4
「仕様v4」(Core ML 3)は、これらの既存のレイヤータイプの要件を少し緩和します。たとえば、内部製品レイヤーは、ランク1からランク5の入力テンソルで動作するようになりました。したがって、「Core ML 3」は、新しいレイヤーを追加するだけでなく、既存のレイヤータイプをより柔軟にしました。最後に、新しいものを見てみましょう。

5. 新しいニューラルネットワーク層

新しいニューラルネットワーク層は100を超えるほどたくさんありますが、すべてをリストします。

以前のバージョンの仕様では、特定の操作が単一のレイヤーに結合されていたことに留意してください。たとえば、すべての単項テンソル操作は、レイヤータイプUnaryFunctionLayerの一部でした。しかし、「Core ML 3」では、多数の新しい単項演算が追加され、それらにはすべて独自のレイヤータイプがあり、明らかに合計数が増えます。

「Core ML 3」は、要素単位の単項演算のために次のレイヤーを追加します。

・ClipLayer
入力を最小値と最大値の間でクランプします。

・CeilLayerとFloorLayer
テンソル全体に一度に適用される通常のCeilLayer関数とFloor関数です。

・SignLayer
数値が正、ゼロ、または負かどうかを示します

・RoundLayer
テンソルの値を整数に丸めます。

・Exp2Layer
テンソルのすべての要素について2^xを計算します。

・SinLayer、CosLayer、TanLayer、AsinLayer、AcosLayer、AtanLayer、SinhLayer、CoshLayer、TanhLayer、AsinhLayer、AcoshLayer、AtanhLayer
よく知られた(双曲線)トリガー関数です。

・ErfLayer
ガウス誤差関数を計算します。

これにより、「Core ML」でサポートされる数学プリミティブの数が大幅に増加します。既に持っていた数学関数とは異なり、これらはあらゆるランクのテンソルを扱うことができます。

新しいアクティベーション関数は1つだけです。

・GeluLayer
ガウス誤差線形単位の活性化、正確なもの、またはタンまたはシグモイド近似を使用したものです。

もちろん、任意の単項関数をアクティベーション関数として使用したり、異なる数学レイヤーを組み合わせて作成したりできます。

テンソルを比較するための新しいレイヤータイプもあります。

・EqualLayer、NotEqualLayer、LessThanLayer、LessEqualLayer、GreaterThanLayer、GreaterEqualLayer

・LogicalOrLayer、LogicalXorLayer、LogicalNotLayer、LogicalAndLayer

これらは、条件が真の場合は1.0、偽の場合は0.0の新しいテンソル(テンソル「マスク」とも呼ばれる)を出力します。これらのレイヤータイプはブロードキャストをサポートしているため、異なるランクのテンソルを比較できます。テンソルを(ハードコードされた)スカラー値と比較することもできます。

これらのレイヤータイプが役立つのは、新しい制御フロー操作(以下を参照)を使用することです。これにより、比較の結果に基づいて分岐したり、特定の条件がfalseになるまで繰り返し続けるループを作成したりできます。

以前は、2つ以上のテンソル間で要素単位の操作を行う少数のレイヤーがありました。「Core ML 3」はいくつかの新しいタイプを追加し、名前からもわかるように、これらはNumPyスタイルのブロードキャストを完全にサポートしているため、はるかに柔軟になりました。

・AddBroadcastableLayer
加算。

・SubtractBroadcastableLayer
減算。

・MultiplyBroadcastableLayer
乗算。

・DivideBroadcastableLayer
除算。

・FloorDivBroadcastableLayer
整数の結果を取得するための除算に続く切り捨て。

・ModBroadcastableLayer
除算の残り。

・PowBroadcastableLayer
最初のテンソルを2番目のテンソルに引き上げます。

・MinBroadcastableLayer、MaxBroadcastableLayer
最小および最大。

削減操作は、独自のレイヤーに移動しました。「Core ML」は、これらのほとんどまたはすべてを既にサポートしていますが、これらの新しいバージョンは、イメージだけでなく、任意のテンソルで動作できます。これで、1つ以上の軸に対して縮小を実行できます。

・ReduceSumLayer
指定された軸の合計を計算します。

・ReduceSumSquareLayer
テンソルの要素の二乗和を計算します。

・ReduceLogSumLayer
要素の自然対数の合計を計算します。

・ReduceLogSumExpLayer
log-sum-expトリックです。要素を指数化し、それらを合計して、自然対数を取ります。

・ReduceMeanLayer
要素の平均を計算します。

・ReduceProdLayer
すべての要素を一緒に乗算します。

・ReduceL1Layer、ReduceL2Layer
L1またはL2ノルムを計算します。

・ReduceMaxLayer、ReduceMinLayer
最大値または最小値を見つける。

・ArgMaxLayer、ArgMinLayer
最大値または最小値のインデックスを見つける。

・TopKLayer
k個の上位(または下位)値とそれらのインデックスを見つけます。これは、argmaxおよびargminのより一般的なバージョンです。kの値は入力によって提供されるため、モデルにハードコーディングする必要はありません。

数学的なものといえば、「Core ML 3」は次のものも追加します。

・BatchedMatMulLayer
2つの入力テンソル、または単一の入力テンソルと重みの固定セット(オプションのバイアス)間の汎用行列乗算です。ブロードキャストをサポートし、乗算を行う前に入力を転置できます。
言い換えると、gemmになります。

・LayerNormalizationLayerParams
ベータ(平均など)を減算し、ガンマ(たとえば、標準偏差)で除算する単純な正規化レイヤーです。どちらも固定の重みとして提供されます。これは、既存のMeanVarianceNormalizeLayerとは異なります。MeanVarianceNormalizeLayerは、同じ式を実行しますが、実際には推論時にテンソルから平均と分散を計算します。

ランクNテンソルまたはN次元テンソルとも呼ばれる任意のサイズのテンソルを使用するために、他の多くの既存の操作が拡張されました。そのようなレイヤータイプは、名前の「ND」で識別できます。

・SoftmaxNDLayer
古いsoftmaxはチャネル軸にのみ適用できます。これは任意の軸を使用できます。

・ConcatNDLayer
任意の軸で2つ以上の出力を連結します。

・SplitNDLayer
concatの反対です。以前は、チャネル軸上でのみ、同じサイズのパーツにのみ分割できました。現在では、任意の軸で分割でき、分割のサイズは異なる場合があります。

・TransposeLayerParams
名前にNDはありませんが、N次元テンソルをサポートすることを除いてPermuteLayerと同じです。

・EmbeddingNDLayer
既存のEmbeddingLayerと似ていますが、より柔軟なテンソル形状です。

・LoadConstantNDLayerParams
既存のLoadConstantレイヤーに似ていますが、より柔軟なテンソル形状です。

スライスを使用すると、元のテンソルの一部のみを保持し、残りを破棄できます。古いスライスレイヤーは、幅、高さ、またはチャネル軸に沿って入力テンソルをスライスできました。「Core ML 3」では、2つの新しいスライスレイヤーが提供され、任意の軸でのスライスがサポートされます。

・SliceStaticLayer
・SliceDynamicLayer

ドキュメントとしてこれらのレイヤーがどのように機能するかはまだ完全にはわかりませんが、インデックスまたはマスクでスライスできるようです。

なぜ2つの異なるバージョンがあるのかは、 実際に今後のいくつかのレイヤータイプでも、静的と動的のこの違いがわかります。

静的は基本的に「この操作に関するすべてが事前に知られている」ことを意味し、動的は「この操作の引数は実行ごとに変更できる」ことを意味します。たとえば、レイヤーの静的バージョンには、ハードコーディングされたoutputShapeプロパティがありますが、動的バージョンでは毎回異なる出力形状を使用できます。

「Core ML」は静的な画像ベースのモデルに限定されていませんが、制御フローやその他の動的な操作のメソッドも含まれているため、あらゆる種類の凝った方法でテンソルを操作できる必要があります。それらの機能を見てみましょう。

・GetShapeLayer
入力テンソルの形状を含むベクトルを返します。これにより、実行時に特定のテンソルの大きさを検査できます。

・BroadcastToStaticLayer、BroadcastToLikeLayer、BroadcastToDynamicLayer
これらは、一般的なNumPyブロードキャストルールに従ってテンソルの形状を変更します。

・RangeStaticLayer、RangeDynamicLayer
NumPyのarange()関数と同様に、指定された間隔で等間隔の値でテンソルを塗りつぶします。

・FillStaticLayer、FillLikeLayer、FillDynamicLayer
これらの関数は、テンソルを一定のスカラー値で埋めます。
通常はすべてゼロまたは1ですが、任意の浮動小数点値で対応します。

これらのレイヤータイプには、Like、Static、Dynamicの3つの異なるバリエーションがあることに注意してください。
これらはどういう意味ですか?

・静的は最も単純なもの
このレイヤーのすべてのプロパティは、mlmodelファイルにハードコーディングされています。何が起こっても、常に形状(32, 10, 7)のテンソルが必要になることがわかっている場合は、FillStaticLayerを使用します。FillStaticLayerとRangeStaticLayerは入力テンソルを取りませんが、BroadcastToStaticLayerは取ります。

・Likeは追加の入力テンソルを取り、その入力と同じ形状を持つ新しいテンソルを出力
レイヤーは、その追加の入力テンソルからの実際の値を無視します—形状のみを調べます。FillLikeLayerとRangeLikeLayerは1つの入力のみを受け取り、これを使用して出力テンソルの形状を決定します。一方、BroadcastToLikeLayerは2つの入力テンソルを受け取ります。1つはブロードキャストするもの、2つ目はブロードキャストする形状です。

・ダイナミックは似たようなもの
追加の入力テンソルも必要ですが、今回は重要なのはそのテンソルの形状ではなく、その内容です。たとえば、形状(32, 10, 7) のテンソルを塗りつぶすには、32、10、および7の3つの値を持つ形状(3)のテンソルを渡します。興味深いことに、FillDynamicLayerでは、スカラー値を動的に渡すことはできません。

「Core ML 3」では、ランダム分布からサンプリングすることで新しいテンソルを作成することもできます。

・RandomNormalStaticLayer、... LikeLayer、... DynamicLayer
・RandomUniformStaticLayer、... LikeLayer、... DynamicLayer
・RandomBernoulliStaticLayer、... LikeLayer、... DynamicLayer
・CategoricalDistributionLayer


レイヤーの再形成と平坦化のためのレイヤーはすでにありましたが、さらにバリエーションが追加されました。

・SqueezeLayer
サイズ1の寸法を削除します。

・ExpandDimsLayer
squeezeの反対で、サイズ1の新しいディメンションを追加します。

・FlattenTo2DLayer
入力テンソルを2次元行列に平坦化します。

ReshapeStaticLayer、ReshapeLikeLayer、ReshapeDynamicLayer

・RankPreservingReshapeLayer
これは、NumPyでreshape(...、-1)を使用するようなものです。
レイヤーは、新しい形状の残りの部分を自動的に推測します。

任意のテンソルの連結および分割操作に加えて、「Core ML 3」は次のテンソル操作操作も追加します。

・TileLayer
テンソルを指定された回数繰り返します。

・StackLayer
テンソルを新しい軸に沿って結合します(既存の軸に沿ってテンソルを結合するconcatとは対照的に)。

・ReverseLayer
入力テンソルの1つ以上の次元を反転します。

・ReverseSeqLayer
データのシーケンスを格納するテンソルの場合、シーケンスを逆にします。

・SlidingWindowsLayer
入力データ上でウィンドウをスライドさせ、すべてのステップでウィンドウの内容を含む新しいテンソルを返します。

また、収集および分散のサポートも新しくなりました。

・GatherLayer、GatherNDLayer、GatherAlongAxisLayer
一連のインデックスを指定すると、これらのインデックスで入力テンソルの部分のみが保持されます。

・ScatterLayer、ScatterNDLayer、ScatterAlongAxisLayer
あるテンソルの値を別のテンソルにコピーしますが、指定されたインデックスでのみです。コピー以外にも、加算、減算、乗算、除算、最大、最小などの累積モードがあります。

ある条件に基づいて要素を選択することについて言えば、マスクを処理するためのレイヤータイプがいくつかあります。

・WhereNonZeroLayer
ゼロではない要素のみで新しいテンソルを作成します。これを、たとえばLessThanLayerなどのテンソル比較のマスクテンソルで使用できます。

・WhereBroadcastableLayer
3つの入力テンソル、2つのデータテンソル、および1(true)または0(false)を含むマスクを取ります。マスクの値がtrueかfalseかに応じて、最初のデータテンソルまたは2番目のデータテンソルの要素を含む新しいテンソルを返します。

・UpperTriangularLayer、LowerTriangularLayer
対角線の下または上の要素をゼロにします。

・MatrixBandPartLayer
中央バンドの外側の要素をゼロにします。

coremltools 3.0のベータ3には、いくつかの新しいレイヤータイプが含まれています。

・ConstantPaddingLayer
テンソルの周りに一定量のパディングを追加します。既存のパディングレイヤーとは異なり、このレイヤーは、幅と高さの寸法だけでなく、どの軸でも機能します。

・NonMaximumSuppressionLayer
境界ボックスでNMSを実行するための別のモデルタイプが既にあり、オブジェクト検出検出モデルに続いてパイプラインに配置しましたが、NMSをニューラルネットワーク内で直接実行することも可能になりました。

最後に「Core ML 3」は、意思決定やループなどの制御フローのレイヤーを追加します。

以前は、「Core ML」はニューラルネットワークグラフを予測ごとに上から下に一度だけ実行していました。しかし、グラフの特定の部分を繰り返して、他の部分をスキップできるようになりました。ニューラルネットワークのどの部分が「Core ML」によって実行されるかは、モデルの実行ごとに異なります。これは、入力データの内容に完全に依存します。

制御フロー層は次のとおりです。

・BranchLayer
これはif-elseステートメントのようなものです。これには2つのNeuralNetworkオブジェクトが含まれています。1つはこのレイヤーへの入力がtrueのときに実行され、もう1つは入力がfalseのときに実行されます。うん、あなたはそれを正しく読んだ:ブランチはメインのニューラルネットワーク内に小さなニューラルネットワークを含んでいる。Core MLにはブールテンソルタイプがないため、実際にはtrueまたはfalseの代わりに1または0を渡します。(Core MLは、値が1e-6より大きい場合、条件を真と見なします。)

・LoopLayer
これは、whileループのようなものです。入力が指定されていない場合、ループはレイヤーで指定された最大反復回数だけ繰り返されます。ループする反復回数を渡すことで、これをオーバーライドできます。LoopLayerには、whileループの内部を表す「body」NeuralNetworkが含まれています。このニューラルネットのレイヤーは、反復ごとに実行されます。whileループの条件として機能するNeuralNetworkを含めることもできます。この「条件」ニューラルネットワークは、ループが開始する前に1回実行され、新しい反復が行われるたびに実行されます。 0より大きい値を出力する限り、ループは繰り返し続けます。

・LoopBreakLayer
通常のbreakステートメントのように、これをループの本体NeuralNetworkに入れてループを終了できます。

・LoopContinueLayer
通常のcontinueステートメントのように、現在のループの反復を停止して次のループの反復にスキップする場合、これをBody NeuralNetworkに入れます。

・CopyLayer
これは以前のテンソルを上書きするために使用されます。
たとえば、古い結果を新しいものに置き換えるために使用されます。


BranchLayerとLoopLayerには出力がないことに注意してください。
これらは常に、何らかの種類の出力を持つ子NeuralNetworkオブジェクトの1つに制御を渡します。(試したことはありませんが、これらのループとブランチもネストできると仮定するのは理にかなっています。)

これらの新しい制御フローレイヤーの使用例については、coremltoolsリポジトリからこのJupyterノートブックを確認してください。「Core ML」モデル内で単純な反復プロセスを実装する方法を示し、多くの新しいレイヤータイプを使用します。

例は次のように機能します。

(1)LoadConstantNDレイヤーを使用して、iteration_countという名前の出力に値0をロードします。
(2)特定の最大反復回数ループするLoopLayerを追加します。
(3)ループ内に、ある種の計算を実行する新しいニューラルネットワークを追加します。
(4)計算の最後に、算術レイヤーを使用してiteration_countから現在の値をインクリメントし、CopyLayerを使用してiteration_count出力内の値を上書きします。
(5)また、別のCopyLayerを使用して計算結果を元のテンソルにコピーし、ループの次の反復でこの新しい値を使用できるようにします。
(6)LessThanLayerを追加して、計算の出力を何らかの収束しきい値と比較し、このyes / noの結果をBranchLayerに送ります。
)7)LoopBreakLayerが含まれているBranchLayerに新しいニューラルネットワークを追加します。つまり、計算の出力が収束しきい値を下回るほど小さいために分岐が発生した場合、ループから抜け出します。

・LossLayer, CategoricalCrossEntropyLossLayer、MeanSquaredErrorLossLayer
損失関数。

・Optimizer, SGDOptimizer 、AdamOptimizer
利用可能なオプティマイザー。


これらはすべて「Core ML 3」の新しいレイヤータイプです。

新しいレイヤータイプのほとんどは、テンソルを作成、整形、および操作するためのものです。多くの新しい数学プリミティブもあります。多くの「実際の」ニューラルネットワークは追加されていません。しかし、これらの低レベルの操作を行うことで、まだ想像されていないあらゆる種類の新しいレイヤータイプを簡単にサポートできます。

繰り返しますが、新しいレイヤータイプを実装するために20の異なる数学レイヤーをCore ML mlmodelに追加する必要がある場合、カスタムレイヤーを書く方が速いかもしれません。


この記事が気に入ったらサポートをしてみませんか?