Operators in MXNet
11377 ワード
Operators in MXNet
MXNetのoperatorは、実際の計算と追加情報を含んでいるクラスです.これらの付加情報は、元の場所の更新や自動微分などの最適化を実現するためのシステムに役立ちます.この文書を続ける前に、まず特定の元の場所でデータを更新することによってメモリを節約する. pythonの端にいくつかの内部パラメータを隠します.コードが綺麗です. 入力tenssorと出力tenssorの関係を定義します.このようにシステムはタイプ検査を助けてくれます. は、システムから追加の空間を申請して計算を行う(e.g.calling Operator Interface
operatorコアのインターフェースは 一般的には、
[input/output semantics figure]
一部のoperatorは、必要な
Operator Property
このような可能性があります.convolutionにはいくつかの異なる実装があります.ユーザは、これらのアルゴリズムの中から最高性能を得るアルゴリズムを選択したいかもしれません.この目的を実現するために、operatorのsematicインターフェースを具体的な実装( InferShape: このインターフェースは2つの目的があります.(1)システムに各入力と出力のTensorのサイズを提供することで、システムは Request Resource:一部の動作は、 Backward dependency:2つの異なるoperator signatureを見ましょう. Inplace Option:メモリをさらに節約するために、私たちは元の場所で更新する傾向があります.これは主にelement-wise操作に使われます.この場合、入力tenssorと出力tenssorのshpeは一致します.このような状況に対して、次のインターフェースを提供しました.
このインターフェースは、
ATTENTION:Eveen with the abobove speciiiiication、it is not garanteted that input and outputtetesors will she the same spacace.In fact,thisisisisisisisis a hint for the sysstem forthe final dededesion the final dededeinininininininininininininininininininininininininininininininininininininininininininininininininininininininininindededededededededededesion.However.However,However the the the t need to considerthat. Expose Operator to Python:c+プログラミング言語の制限のため、ユーザーが以下のインターフェースを実現する必要があります.
Create Operator from Operator Property
上記の内容で
Create Operator
私たちが畳み込みoperatorを実現するには、kenalサイズ、strideサイズ、paddingサイズなどの情報が必要です.これらはパラメータとしてoperatorに渡す必要があります.
次のマクロ定義を使用して、PArameter構造とOperatoProperty類をMXNetのシステムに登録します.
All in a list
Finally!We almost covered the interface we need to define a new operator.Let's do a recap in a list: Use Use Pass parameter to operator class(may use Create operatousing Correctly implement the operator description interface such as the names of argments,etc. Correctly implement the [Optional]If additional resource are need,check [Optional]If [Optional]If inplace udate is supported,check Register the MXNetの旅を楽しんでください.
MXNetのoperatorは、実際の計算と追加情報を含んでいるクラスです.これらの付加情報は、元の場所の更新や自動微分などの最適化を実現するためのシステムに役立ちます.この文書を続ける前に、まず
mshadow
ライブラリを理解することを強く提案します.すべてのoperatorの計算は、システムから提供されるデータ構造mshadow::TBob
に基づいているので、このデータ構造はテンソル(Tensor)に似ています.MXNetのoperatorのインターフェースは、霊活性に努めています.現在提供されている柔軟性は、以下の点を含みます.cudnn
routines).operatorコアのインターフェースは
Forward
です.virtual void Forward(const OpContext &ctx,
const std::vector &in_data,
const std::vector &req,
const std::vector &out_data,
const std::vector &aux_states) = 0;
OpContext
のデータ構造は以下のコードです.struct OpContext {
int is_train;
RunContext run_ctx;
std::vector requested;
}
、オプラテラーがtrinかそれともtestかを知ることができます.operatorは、どのdevice(is_train
)上で動作し、次のパラメータによって追加のリソースを申請するかどうかを決定します.run_ctx
とin_data
は、それぞれ入力tenssorと出力tenssorを表しています.すべてのtenssorに必要な空間は、システムが申請と管理を行うものです.out_data
は、計算された構造がreq
にどのように書き込まれているかを示しています.言い換えれば、out_data
およびreq.size() == out_data.size()
は、req[i]
にどのように書き込まれているかに関係しています.out_data[i]
は、以下のように定義されています.enum OpReqType {
kNullOp,
kWriteTo,
kWriteInplace,
kAddTo
};
OpReqType
のすべてのタイプはout_data
であるべきです.kWriteTo
に代表されるtenssorが直接書き込むことができる元のメモリブロックを提供していることを示しています.場合によっては、例えばout_data
を表すtenssorを計算する時には、本来の結果をそのまま上書きするのではなく、勾配を積み重ねるのが一番いいです.このように計算するたびに必要なメモリ空間を申請する必要はありません.この場合、gradient
のタイプはreq
であるべきです.kAddTo
は、計算を容易にするために必要な追加のtenssorを表しています.今は使われていません.+=
operatorを除いて、ユーザーは場合によってはaux_states
インターフェースを実装する必要があります.以下のように定義されています.virtual void Backward(const OpContext &ctx,
const std::vector &out_grad,
const std::vector &in_data,
const std::vector &out_data,
const std::vector &req,
const std::vector &in_grad,
const std::vector &aux_states);
BackwardのインターフェースはForward
と同じ設計原則に従っています.Backward
、Forward
、out_grad
はoperator計算in_data
に必須である以外に、他の入力はout_data
と同じです.命名ポリシーとtouchの約束は似ています.以下の図でまとめられます.[input/output semantics figure]
一部のoperatorは、必要な
in_grad
、Forward
、out_grad
のパラメータではなく、この需要は、in_data
のインターフェースout_data
によって実現されてもよい.Operator Property
このような可能性があります.convolutionにはいくつかの異なる実装があります.ユーザは、これらのアルゴリズムの中から最高性能を得るアルゴリズムを選択したいかもしれません.この目的を実現するために、operatorのsematicインターフェースを具体的な実装(
OperatorProperty
クラス)から分離し、DeclareBackwardDependency
クラスに独立しています.Operator
インターフェースは以下の内容を含みます.virtual bool InferShape(std::vector *in_shape,
std::vector *out_shape,
std::vector *aux_shape) const = 0;
OperatorProperty
およびOperatorProperty
を行う前に、対応するメモリを事前に申請することができます.(2)型式検査を行い、運転前に明らかなエラーがないことを確認します.Forward
のshopはシステムが自動的に設定されています.(依存する前のOperatorのBackward
によると)、このインターフェースはin_shape
に戻ります.システムが提供した情報がshopのプッシュオフを完了するのに足りないと思ったら、またはshopが一致しない時に異常を投げます.out_shape
などの作業空間として追加のメモリを計算する必要があります.この場合、システムはこの部分のメモリを管理したほうがいいです.このようにシステムはメモリの重複利用などの最適化ができます.MXNetは2つのインターフェースを定義して目的を達成します.virtual std::vector ForwardResource(
const std::vector &in_shape) const;
virtual std::vector BackwardResource(
const std::vector &in_shape) const;
false
データ構造です.(cudnnConvolutionForward
で)現在は一つのタイプのflagsしか含まれていません.struct ResourceRequest {
enum Type {
kRandom, // get an mshadow::Random object
kTempSpace, // request temporay space
};
Type type;
};
ResourceRequest
およびresource.h
によって返された配列が非空である場合、システムは、ForwardResource
のBackwardResource
およびOperator
インターフェースのFoward
パラメータを介して対応するリソースを提供する.簡単な例では、これらのリソースを取得するなら、以下のようにすることができる.auto tmp_space_res = ctx.requested[kTempSpace].get_space(some_shape, some_stream);
auto rand_res = ctx.requested[kRandom].get_random(some_stream);
具体的な例はBackward
を参照することができる.ctx
で使用されているsrc/operator/cudnn_convolution-inl.h
変数は、FullyConnectedForward
で使用されていません.一方、out_data
ではFullyConnectedBackward
のすべての変数が使用されています.したがって、このPoolingBackward
tenssorは、backwardが必要でないときは、リリースする必要があります.ここでは、ゴミ回収(GC)の方法に挑戦があります.できるだけ速くしてください.このような状況に対して、インターフェースを提供します.void FullyConnectedForward(TBlob weight, TBlob in_data, TBlob out_data);
void FullyConnectedBackward(TBlob weight, TBlob in_data, TBlob out_grad, TBlob in_grad);
void PoolingForward(TBlob in_data, TBlob out_data);
void PoolingBackward(TBlob in_data, TBlob out_data, TBlob out_grad, TBlob in_grad);
ここのvectorのPoolingForward
要素は、異なるarraysのidを区別しています.このインターフェースが、out_data
とint
との異なる依存関係をどのように定義しているかを見てみましょう.virtual std::vector DeclareBackwardDependency(
const std::vector &out_grad,
const std::vector &in_data,
const std::vector &out_data) const;
このインターフェースは、
FullyConnected
およびPoolling
テンソスがin_data[0]
の計算において同じメモリ空間を使用すべきであるとシステムに教えている.同様に、out_data[0]
およびForward
は、同じメモリ空間を共有してout_grad[0]
の計算において同じメモリ空間を使用すべきである.ATTENTION:Eveen with the abobove speciiiiication、it is not garanteted that input and outputtetesors will she the same spacace.In fact,thisisisisisisisis a hint for the sysstem forthe final dededesion the final dededeinininininininininininininininininininininininininininininininininininininininininininininininininininininininininindededededededededededesion.However.However,However the the the t need to considerthat.
Create Operator from Operator Property
上記の内容で
in_grad[0]
に言及したことがありますが、すべての動作のセマンティカルトトリーを含みます.また、Backward
ポインタを作成する必要があります.Create Operator
Forward
の下のインターフェースを実装する:std::vector FullyConnectedProperty::DeclareBackwardDependency(
const std::vector &out_grad,
const std::vector &in_data,
const std::vector &out_data) const {
return {out_grad[0], in_data[0]}; // NOTE: out_data[0] is NOT included
}
std::vector PoolingProperty::DeclareBackwardDependency(
const std::vector &out_grad,
const std::vector &in_data,
const std::vector &out_data) const {
return {out_grad[0], in_data[0], out_data[0]};
}
For example:virtual std::vector<:pair void="">> ElewiseOpProperty::ForwardInplaceOption(
const std::vector &in_data,
const std::vector &out_data) const {
return { {in_data[0], out_data[0]} };
}
virtual std::vector<:pair void="">> ElewiseOpProperty::BackwardInplaceOption(
const std::vector &out_grad,
const std::vector &in_data,
const std::vector &out_data,
const std::vector &in_grad) const {
return { {out_grad[0], in_grad[0]} }
}
Parameeterize Operator私たちが畳み込みoperatorを実現するには、kenalサイズ、strideサイズ、paddingサイズなどの情報が必要です.これらはパラメータとしてoperatorに渡す必要があります.
Backward
およびOperatorProperty
計算プロセスはこれらのパラメータが必要です.パラメータを伝えるためには、ユーザはOperator
データ構造を定義する必要があります.// initial the property class from a list of key-value string pairs
virtual void Init(const vector> &kwargs) = 0;
// return the parameters in a key-value string map
virtual map GetParams() const = 0;
// return the name of arguments (for generating signature in python)
virtual vector ListArguments() const;
// return the name of output values
virtual vector ListOutputs() const;
// return the name of auxiliary states
virtual vector ListAuxiliaryStates() const;
// return the number of output values
virtual int NumOutputs() const;
// return the number of visible outputs
virtual int NumVisibleOutputs() const;
OperatorProperty
に入れて、クラス初期化の時に、このデータ構造をoperator類に伝えます.virtual Operator* CreateOperator(Context ctx) const = 0;
Register Operator to MXNet次のマクロ定義を使用して、PArameter構造とOperatoProperty類をMXNetのシステムに登録します.
class ConvolutionOp {
public:
void Forward( ... ) { ... }
void Backward( ... ) { ... }
};
class ConvolutionOpProperty : public OperatorProperty {
public:
Operator* CreateOperator(Context ctx) const {
return new ConvolutionOp;
}
};
このマクロ定義の最初のパラメータはnameで、2番目のパラメータはPropertyクラスの名前です.All in a list
Finally!We almost covered the interface we need to define a new operator.Let's do a recap in a list:
Forward
interface to write your actual computation logic(Backward
and ConvolutionParam
).ConvolutionOpProperty
interface to:Operator
interface).Forward
interface.Backward
interface to set the output tensor shop.OperatorProperty
and Init
.CreateOperator
does not need all the input and out put of InferShape
,check ForwardResource
.BackwardResource
and Backward
.Forward
class and the parameter class.