| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293 |
- # Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
- #
- # Licensed under the Apache License, Version 2.0 (the "License");
- # you may not use this file except in compliance with the License.
- # You may obtain a copy of the License at
- #
- # http://www.apache.org/licenses/LICENSE-2.0
- #
- # Unless required by applicable law or agreed to in writing, software
- # distributed under the License is distributed on an "AS IS" BASIS,
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- # See the License for the specific language governing permissions and
- # limitations under the License.
- import inspect
- import warnings
- from functools import reduce
- import numpy as np
- import paddle
- from paddle.base import core, unique_name
- from paddle.base.data_feeder import check_dtype
- from paddle.base.framework import (
- Program,
- Variable,
- default_main_program,
- in_dygraph_mode,
- in_dynamic_or_pir_mode,
- in_pir_mode,
- name_scope,
- program_guard,
- static_only,
- )
- from paddle.base.param_attr import ParamAttr
- from paddle.base.wrapped_decorator import signature_safe_contextmanager
- from paddle.common_ops_import import (
- LayerHelper,
- check_type,
- check_variable_and_dtype,
- )
- from paddle.nn.initializer import Constant, Normal
- __all__ = []
- @static_only
- def fc(
- x,
- size,
- num_flatten_dims=1,
- weight_attr=None,
- bias_attr=None,
- activation=None,
- name=None,
- ):
- r"""
- Fully-Connected layer can take a tensor or a list of tensor as its inputs.
- It creates a 2-D weight tensor for each input tensor, which represents its
- weight matrix from each input unit to each output unit. The fully connected
- layer multiplies each input tensor with its corresponding weight to produce
- an output tensor with shape :math:`[batch\_size, *, size]` , where :math:`*`
- means any number of additional dimensions. If a list of tensor is given,
- the results of multiple output tensors with shape :math:`[batch\_size, *, size]`
- will be summed up. If :attr:`bias_attr` is not False, a 1-D bias tensor will
- be created and added to the output. Finally, if :attr:`activation` is not None,
- it will be applied to the output as well.
- For a single input tensor :math:`X` , the equation is:
- .. math::
- Out = Act({XW + b})
- For a list of input tensor, the equation is:
- .. math::
- Out = Act({\sum_{i=0}^{N-1}X_iW_i + b})
- where:
- * :math:`N`: The number of the input tensors. :math:`N` equals to :math:`len(X)` if :math:`X` is list of tensor.
- * :math:`X_i`: The i-th input tensor.
- * :math:`W_i`: The i-th weight matrix corresponding i-th input tensor.
- * :math:`b`: The bias created by this layer (if needed).
- * :math:`Act`: The activation function.
- * :math:`Out`: The output tensor.
- .. code-block:: text
- # Case 1, input is a single tensor:
- x.data = [[[0.1, 0.2],
- [0.3, 0.4]]]
- x.shape = (1, 2, 2) # 1 is batch_size
- out = paddle.static.nn.fc(x=x, size=1, num_flatten_dims=2)
- # Get the output:
- out.data = [[0.83234344], [0.34936576]]
- out.shape = (1, 2, 1)
- # Case 2, input is a list of tensor:
- x0.data = [[[0.1, 0.2],
- [0.3, 0.4]]]
- x0.shape = (1, 2, 2) # 1 is batch_size
- x1.data = [[[0.1, 0.2, 0.3]]]
- x1.shape = (1, 1, 3)
- out = paddle.static.nn.fc(x=[x0, x1], size=2)
- # Get the output:
- out.data = [[0.18669507, 0.1893476]]
- out.shape = (1, 2)
- Args:
- x (Tensor|list[Tensor]|tuple[Tensor]): A tensor or a list/tuple of tensors. The number of dimensions
- of each tensor is at least 2. The data type should be float16, float32 or float64.
- size (int): The number of output units in this layer, which also means the feature
- size of output tensor.
- num_flatten_dims (int, optional): The fc layer can accept an input tensor with more than
- two dimensions. If this happens, the multi-dimensional tensor will first be flattened
- into a 2-D matrix. The parameter :attr:`num_flatten_dims` determines how the input
- tensor is flattened: the first :math:`num\_flatten\_dims` (inclusive, index starts from 1)
- dimensions will be flatten to form the first dimension of the final matrix (height of
- the matrix), and the rest :math:`rank(x) - num\_flatten\_dims` dimensions are
- flattened to form the second dimension of the final matrix (width of the matrix).
- For example, assuming that :attr:`x` is a 5-dimensional tensor with a shape
- :math:`[2, 3, 4, 5, 6]` , and :attr:`num_flatten_dims` = 3.
- Then, the flattened matrix will have a shape :math:`[2 * 3 * 4, 5 * 6] = [24, 30]` .
- Default: 1.
- weight_attr (ParamAttr, optional): The attribute for the learnable weight.
- The default value is None, and the weight will be initialized to zero.
- For detailed information, please refer to :attr:`paddle.ParamAttr`.
- Warning, if x is a list of tensor, weight_attr should also be a list of same length.
- bias_attr (ParamAttr|bool, optional): The attribute of the learnable bias.
- If it is set to False, no bias will be added to the output.
- If it is set to None or one kind of ParamAttr, a bias parameter will
- be created according to ParamAttr. For detailed information, please refer
- to :attr:`paddle.ParamAttr`. The default value is None and the bias will be
- initialized to zero.
- activation (str, optional): Activation to be applied to the output of
- this layer, such as tanh, softmax, sigmoid, relu. For more information,
- please refer to :ref:`api_guide_activations_en` . Default: None.
- name (str, optional): The default value is None. Normally there is no need for user to set
- it. For more information, please refer to :ref:`api_guide_Name` .
- Returns:
- Tensor, its shape is :math:`[batch\_size, *, size]` , and the data type is same with input.
- Examples:
- .. code-block:: python
- >>> import paddle
- >>> paddle.enable_static()
- >>> # When input is a single tensor
- >>> x = paddle.static.data(name="x", shape=[1, 2, 2], dtype="float32")
- >>> out = paddle.static.nn.fc(
- ... x=x,
- ... size=1,
- ... num_flatten_dims=2,
- ... weight_attr=paddle.ParamAttr(initializer=paddle.nn.initializer.Constant(value=0.5)),
- ... bias_attr=paddle.ParamAttr(initializer=paddle.nn.initializer.Constant(value=1.0)))
- >>> print(out)
- var fc_0.tmp_1 : LOD_TENSOR.shape(1, 2, 1).dtype(float32).stop_gradient(False)
- >>> # When input is multiple tensors
- >>> x0 = paddle.static.data(name="x0", shape=[1, 2, 2], dtype="float32")
- >>> x1 = paddle.static.data(name="x1", shape=[1, 1, 3], dtype="float32")
- >>> out = paddle.static.nn.fc(
- ... x=[x0, x1],
- ... size=2,
- ... weight_attr=paddle.ParamAttr(initializer=paddle.nn.initializer.Constant(value=0.5)),
- ... bias_attr=paddle.ParamAttr(initializer=paddle.nn.initializer.Constant(value=1.0)))
- >>> print(out)
- var fc_1.tmp_3 : LOD_TENSOR.shape(1, 2).dtype(float32).stop_gradient(False)
- """
- def fc_base(
- input,
- size,
- num_flatten_dims=1,
- param_attr=None,
- bias_attr=None,
- act=None,
- name=None,
- ):
- helper = LayerHelper("fc", **locals())
- check_type(
- input, 'input', (list, tuple, Variable, paddle.pir.Value), 'fc'
- )
- if isinstance(input, (list, tuple)):
- for i, input_x in enumerate(input):
- check_type(
- input_x,
- 'input[' + str(i) + ']',
- (Variable, paddle.pir.Value),
- 'fc',
- )
- dtype = helper.input_dtype()
- check_dtype(
- dtype, 'input', ['float16', 'uint16', 'float32', 'float64'], 'fc'
- )
- mul_results = []
- for input_var, param_attr in helper.iter_inputs_and_params():
- input_shape = input_var.shape
- if num_flatten_dims == -1:
- num_flatten_dims = len(input_shape) - 1
- param_shape = [
- reduce(lambda a, b: a * b, input_shape[num_flatten_dims:], 1)
- ] + [size]
- w = helper.create_parameter(
- attr=param_attr, shape=param_shape, dtype=dtype, is_bias=False
- )
- if in_pir_mode():
- if len(input_var.shape) > 2:
- new_shape = (
- input_var.shape[0],
- np.prod(input_var.shape[1:]),
- )
- input_var = paddle.reshape(input_var, new_shape)
- tmp = paddle.matmul(input_var, w)
- else:
- tmp = helper.create_variable_for_type_inference(dtype)
- helper.append_op(
- type="mul",
- inputs={"X": input_var, "Y": w},
- outputs={"Out": tmp},
- attrs={
- "x_num_col_dims": num_flatten_dims,
- "y_num_col_dims": 1,
- },
- )
- mul_results.append(tmp)
- if len(mul_results) == 1:
- pre_bias = mul_results[0]
- elif in_pir_mode():
- pre_bias = paddle.add_n(mul_results)
- else:
- pre_bias = helper.create_variable_for_type_inference(dtype)
- helper.append_op(
- type="sum",
- inputs={"X": mul_results},
- outputs={"Out": pre_bias},
- attrs={},
- )
- # add bias
- pre_activation = helper.append_bias_op(
- pre_bias, dim_start=num_flatten_dims
- )
- # add activation
- return helper.append_activation(pre_activation)
- return fc_base(
- input=x,
- size=size,
- num_flatten_dims=num_flatten_dims,
- param_attr=weight_attr,
- bias_attr=bias_attr,
- act=activation,
- name=name,
- )
- def instance_norm(
- input, epsilon=1e-05, param_attr=None, bias_attr=None, name=None
- ):
- r"""
- **Instance Normalization Layer**
- Can be used as a normalizer function for convolution or fully_connected operations.
- The required data format for this layer is one of the following:
- DataLayout: NCHW `[batch, in_channels, in_height, in_width]`
- Refer to `Instance Normalization: The Missing Ingredient for
- Fast Stylization <https://arxiv.org/pdf/1607.08022.pdf>`_
- for more details.
- :math:`input` is the input features over a mini-batch.
- .. math::
- \mu_{\beta} &\gets \frac{1}{HW} \sum_{i=1}^{HW} x_i \qquad &//
- \ mean\ of\ one\ feature\ map\ in\ mini-batch \\
- \sigma_{\beta}^{2} &\gets \frac{1}{HW} \sum_{i=1}^{HW}(x_i -
- \mu_{\beta})^2 \qquad &//\ variance\ of\ one\ feature\ map\ in\ mini-batch \\
- \hat{x_i} &\gets \frac{x_i - \mu_\beta} {\sqrt{
- \sigma_{\beta}^{2} + \epsilon}} \qquad &//\ normalize \\
- y_i &\gets \gamma \hat{x_i} + \beta \qquad &//\ scale\ and\ shift
- Note:
- `H` means height of feature map, `W` means width of feature map.
- Args:
- input(Tensor): The rank of input tensor can be 2, 3, 4, 5.
- The data type is float32 or float64.
- epsilon(float, Default 1e-05): A value added to the denominator for
- numerical stability. Default is 1e-5.
- param_attr(ParamAttr|None|bool, optional): The parameter attribute for Parameter `scale`
- of instance_norm. If it is set to None or one attribute of ParamAttr, instance_norm
- will create ParamAttr as param_attr, the name of scale can be set in ParamAttr.
- If the Initializer of the param_attr is not set, the parameter is initialized
- with Xavier. If the param_attr is set to False, instance_norm will not create param_attr.
- Default: None.
- bias_attr(ParamAttr|None|bool, optional): The parameter attribute for the bias of instance_norm.
- If it is set to None or one attribute of ParamAttr, instance_norm
- will create ParamAttr as bias_attr, the name of bias can be set in ParamAttr.
- If the Initializer of the bias_attr is not set, the bias is initialized zero.
- If the bias_attr is set to False, instance_norm will not create bias_attr.
- Default: None.
- name(string, Default None): A name for this layer(optional). If set None, the layer
- will be named automatically.
- Returns:
- A Tensor which is the result after applying instance normalization on the input,
- has same shape and data type with input.
- Examples:
- .. code-block:: python
- >>> import paddle
- >>> paddle.enable_static()
- >>> x = paddle.static.data(name='x', shape=[3, 7, 3, 7], dtype='float32')
- >>> hidden1 = paddle.static.nn.fc(x, size=200)
- >>> hidden2 = paddle.static.nn.instance_norm(hidden1)
- """
- check_variable_and_dtype(
- input,
- 'input',
- ['uint16', 'float16', 'float32', 'float64'],
- 'instance_norm',
- )
- if param_attr is False:
- assert (
- bias_attr is False
- ), "param_attr and bias_attr must be set to False at the same time in instance_norm"
- helper = LayerHelper('instance_norm', **locals())
- dtype = helper.input_dtype()
- # use fp32 for in parameter
- if dtype == paddle.float16:
- dtype = paddle.float32
- input_shape = input.shape
- if len(input.shape) < 2 or len(input.shape) > 5:
- raise ValueError(
- f'expected 2D or 3D or 4D or 5D input (got {len(input.shape)}D input, input shape is: {input_shape})'
- )
- channel_num = input_shape[1]
- param_shape = [channel_num]
- if param_attr and bias_attr:
- # create parameter
- scale = helper.create_parameter(
- attr=helper.param_attr,
- shape=param_shape,
- dtype=dtype,
- default_initializer=Constant(1.0),
- )
- bias = helper.create_parameter(
- attr=helper.bias_attr,
- shape=param_shape,
- dtype=dtype,
- is_bias=True,
- default_initializer=Constant(0.0),
- )
- # create output
- saved_mean = helper.create_variable_for_type_inference(
- dtype=dtype, stop_gradient=True
- )
- saved_variance = helper.create_variable_for_type_inference(
- dtype=dtype, stop_gradient=True
- )
- instance_norm_out = helper.create_variable_for_type_inference(dtype)
- inputs = {"X": input}
- if param_attr and bias_attr:
- inputs["Scale"] = scale
- inputs["Bias"] = bias
- helper.append_op(
- type="instance_norm",
- inputs=inputs,
- outputs={
- "Y": instance_norm_out,
- "SavedMean": saved_mean,
- "SavedVariance": saved_variance,
- },
- attrs={
- "epsilon": epsilon,
- },
- )
- return instance_norm_out
- @static_only
- def continuous_value_model(input, cvm, use_cvm=True):
- r"""
- **continuous_value_model layers**
- Now, this OP is used in CTR project to remove or dispose show and click value in :attr:`input`.
- :attr:`input` is an embedding vector including show and click value, whose shape is :math:`[N, D]` (N is batch size. D is `2 + embedding dim` ).
- Show and click at first two dims of embedding vector D.
- If :attr:`use_cvm` is True, it will calculate :math:`log(show)` and :math:`log(click)` , and output shape is :math:`[N, D]` .
- If :attr:`use_cvm` is False, it will remove show and click from :attr:`input` , and output shape is :math:`[N, D - 2]` .
- :attr:`cvm` is show_click info, whose shape is :math:`[N, 2]` .
- Args:
- input (Variable): The input variable. A 2-D LoDTensor with shape :math:`[N, D]` , where N is the batch size, D is `2 + the embedding dim` . `lod level = 1` .
- A Tensor with type float32, float64.
- cvm (Variable): Show and click variable. A 2-D Tensor with shape :math:`[N, 2]` , where N is the batch size, 2 is show and click.
- A Tensor with type float32, float64.
- use_cvm (bool): Use show_click or not. if use, the output dim is the same as input.
- if not use, the output dim is `input dim - 2` (remove show and click)
- Returns:
- Variable: A 2-D LodTensor with shape :math:`[N, M]` . if :attr:`use_cvm` = True, M is equal to input dim D. if False, M is equal to `D - 2`. \
- A Tensor with same type as input.
- Examples:
- .. code-block:: python
- >>> import paddle
- >>> paddle.enable_static()
- >>> input = paddle.static.data(name="input", shape=[64, 1], dtype="int64")
- >>> label = paddle.static.data(name="label", shape=[64, 1], dtype="int64")
- >>> w0 = paddle.full(shape=(100, 1), fill_value=2).astype(paddle.float32)
- >>> embed = paddle.nn.functional.embedding(input, w0)
- >>> ones = paddle.full_like(label, 1, dtype="int64")
- >>> show_clk = paddle.cast(paddle.concat([ones, label], axis=1), dtype='float32')
- >>> show_clk.stop_gradient = True
- >>> input_with_cvm = paddle.static.nn.continuous_value_model(embed[:, 0], show_clk, True)
- """
- helper = LayerHelper('cvm', **locals())
- out = helper.create_variable(dtype=input.dtype)
- check_variable_and_dtype(
- input, 'input', ['float16', 'float32', 'float64'], 'cvm'
- )
- helper.append_op(
- type='cvm',
- inputs={'X': [input], 'CVM': [cvm]},
- outputs={'Y': [out]},
- attrs={"use_cvm": use_cvm},
- )
- return out
- @static_only
- def data_norm(
- input,
- act=None,
- epsilon=1e-05,
- param_attr=None,
- data_layout='NCHW',
- in_place=False,
- name=None,
- moving_mean_name=None,
- moving_variance_name=None,
- do_model_average_for_mean_and_var=True,
- slot_dim=-1,
- sync_stats=False,
- summary_decay_rate=0.9999999,
- enable_scale_and_shift=False,
- ):
- r"""
- **Data Normalization Layer**
- This op can be used as a normalizer function for conv2d and fully_connected operations.
- The required data format for this layer is one of the following:
- 1. NHWC `[batch, in_height, in_width, in_channels]`
- 2. NCHW `[batch, in_channels, in_height, in_width]`
- :math:`input` is the input features over a mini-batch.
- .. math::
- \mu_{\beta} &\gets \frac{1}{m} \sum_{i=1}^{m} x_i \qquad &//
- \ mini-batch\ mean \\
- \sigma_{\beta}^{2} &\gets \frac{1}{m} \sum_{i=1}^{m}(x_i -
- \mu_{\beta})^2 \qquad &//\ mini-batch\ variance \\
- \hat{x_i} &\gets \frac{x_i - \mu_\beta} {\sqrt{
- \sigma_{\beta}^{2} + \epsilon}} \qquad &//\ normalize \\
- y_i &\gets \gamma \hat{x_i} + \beta \qquad &//\ scale\ and\ shift
- Args:
- input (Tensor): The input Tensor.
- act (str, optional): Activation type, linear|relu|prelu|... Default: None.
- epsilon(float, optional): Whether to add small values into the variance during calculations
- to prevent division by zero. Default: 1e-05.
- param_attr (ParamAttr, optional): The parameter attribute for Parameter `scale`. Default: None.
- data_layout (str, optional): Specify the data format of the input, and the data format of the output
- will be consistent with that of the input. An optional string from: `"NCHW"`, `"NHWC"`.
- The default is `"NCHW"`. When it is `"NCHW"`, the data is stored in the order of:
- `[batch_size, input_channels, input_height, input_width]`. Default: `"NCHW"`.
- in_place (bool, optional): Make the input and output of batch norm reuse memory. Default: False.
- name (str, optional): A name for this layer (optional). If set None, the layer
- will be named automatically. Default: None.
- moving_mean_name (str, optional): The name of moving_mean which store the global Mean. Default: None.
- moving_variance_name (str, optional): The name of the moving_variance which store the global Variance. Default: None.
- do_model_average_for_mean_and_var (bool, optional): Whether parameter mean and variance
- should do model average when model average is enabled. Default: True.
- slot_dim (int, optional): The embedding dimension of one slot. Slot is a set of one specific feature. In pslib mode,
- we distinguish feature ids by slot and pull their embeddings from parameter server (pslib). The first
- place of the embedding is the historical show number (occurrence time of this feature id with a label 0).
- If the input of this op is concated by slot-wise embeddings, and the show number is zero when this slot
- is new or empty, the normalization result may be impractical. To avoid this, we add slot_dim to locate
- the show number and judge if the show number is zero. If so, we choose to skip normalization on this
- embedding. Default: -1.
- sync_stats (bool, optional): When running with multiple GPU cards, using allreduce to sync the
- summary messages. Default: False.
- summary_decay_rate (float, optional): The decay rate when updating summary. Default: 0.9999999.
- enable_scale_and_shift (bool, optional): do scale&shift after normalization. Default: False.
- Returns:
- Tensor: A tensor which is the result after applying data normalization on the input.
- Examples:
- .. code-block:: python
- >>> import paddle
- >>> paddle.enable_static()
- >>> x = paddle.randn(shape=[32, 100])
- >>> hidden2 = paddle.static.nn.data_norm(input=x)
- """
- helper = LayerHelper('data_norm', **locals())
- dtype = helper.input_dtype()
- input_shape = input.shape
- if len(input_shape) < 2:
- raise ValueError(
- f"The shape pf Input < 2 (got {len(input_shape)}D input, input shape is: {input_shape})"
- )
- if data_layout == 'NCHW':
- channel_num = input_shape[1]
- else:
- if data_layout == 'NHWC':
- channel_num = input_shape[-1]
- else:
- raise ValueError("unsupported data layout:" + data_layout)
- param_shape = [channel_num]
- batch_size_default = 1e4
- batch_sum_default = 0.0
- batch_square_sum_default = 1e4
- scale_w_default = 1.0
- bias_default = 0.0
- if param_attr and isinstance(param_attr, dict):
- batch_size_default = param_attr.get("batch_size", 1e4)
- batch_sum_default = param_attr.get("batch_sum", 0.0)
- batch_square_sum_default = param_attr.get("batch_square", 1e4)
- if enable_scale_and_shift:
- scale_w_default = param_attr.get("scale_w", 1.0)
- bias_default = param_attr.get("bias", 0.0)
- # create scale and shift(bias) when enable_scale_and_shift is True
- if name is None:
- name = "dn"
- if enable_scale_and_shift:
- scale_w = helper.create_parameter(
- attr=ParamAttr(
- name=name + '.scale_w',
- initializer=Constant(value=float(scale_w_default)),
- trainable=True,
- ),
- shape=param_shape,
- dtype=input.dtype,
- )
- bias = helper.create_parameter(
- attr=ParamAttr(
- name=name + '.bias',
- initializer=Constant(value=float(bias_default)),
- trainable=True,
- ),
- shape=param_shape,
- dtype=input.dtype,
- )
- # create parameter
- batch_size = helper.create_parameter(
- attr=ParamAttr(
- name=name + '.batch_size',
- initializer=Constant(value=float(batch_size_default)),
- trainable=True,
- ),
- shape=param_shape,
- dtype=input.dtype,
- )
- batch_sum = helper.create_parameter(
- attr=ParamAttr(
- name=name + '.batch_sum',
- initializer=Constant(value=float(batch_sum_default)),
- trainable=True,
- ),
- shape=param_shape,
- dtype=input.dtype,
- )
- batch_square_sum = helper.create_parameter(
- attr=ParamAttr(
- name=name + '.batch_square_sum',
- initializer=Constant(value=float(batch_square_sum_default)),
- trainable=True,
- ),
- shape=param_shape,
- dtype=input.dtype,
- )
- means = helper.create_variable(dtype=dtype, stop_gradient=True)
- scales = helper.create_variable(dtype=dtype, stop_gradient=True)
- data_norm_out = input if in_place else helper.create_variable(dtype=dtype)
- inputs = {
- "X": input,
- "BatchSize": batch_size,
- "BatchSum": batch_sum,
- "BatchSquareSum": batch_square_sum,
- }
- attrs = {
- "epsilon": epsilon,
- "data_layout": data_layout,
- "sync_stats": sync_stats,
- "summary_decay_rate": summary_decay_rate,
- }
- if slot_dim > 0:
- attrs["slot_dim"] = slot_dim
- if enable_scale_and_shift:
- attrs["enable_scale_and_shift"] = enable_scale_and_shift
- if enable_scale_and_shift:
- inputs["scale_w"] = scale_w
- inputs["bias"] = bias
- helper.append_op(
- type="data_norm",
- inputs=inputs,
- outputs={
- "Y": data_norm_out,
- "Means": means,
- "Scales": scales,
- "BatchSize": batch_size,
- "BatchSum": batch_sum,
- "BatchSquareSum": batch_square_sum,
- },
- attrs=attrs,
- )
- return helper.append_activation(data_norm_out)
- def group_norm(
- input,
- groups,
- epsilon=1e-05,
- param_attr=None,
- bias_attr=None,
- act=None,
- data_layout='NCHW',
- name=None,
- ):
- """
- **Group Normalization Layer**
- Refer to `Group Normalization <https://arxiv.org/abs/1803.08494>`_ .
- Parameters:
- input(Tensor): Tensor with dimension greater than 1, the data type is float32 or float64.
- groups(int): The number of groups that divided from channels, the data type
- is int32.
- epsilon(float, optional): The small value added to the variance to prevent
- division by zero, the data type is float32. Default: 1e-05.
- param_attr(ParamAttr|bool, optional): ParamAttr object that specifies weight parameter
- attribute. If a bool type, only False is supported, which means there is no weight parameter.
- Default: None, the default weight parameter attribute is used. For more information, please
- refer to :ref:`api_guide_ParamAttr` .
- bias_attr(ParamAttr|bool, optional): ParamAttr object that specifies bias parameter
- attribute. If a bool type, only False is supported, which means there is no bias parameter.
- Default: None, the default bias parameter attribute is used. For more information, please
- refer to :ref:`api_guide_ParamAttr` .
- act(str, optional): Activation to be applied to the output of group normalization.
- data_layout(str, optional): Specify the data format of the input, and the data format of the output
- will be consistent with that of the input. An optional string from: `"NCHW"`, `"NHWC"`.
- The default is `"NCHW"`. When it is `"NCHW"`, the data is stored in the order of:
- `[batch_size, input_channels, *]`.
- name (str, optional): The default value is None. Normally there is no need for user to set this
- property. For more information, please refer to :ref:`api_guide_Name` .
- Returns:
- Tensor: A Tensor has same data type and data format with `input`.
- Examples:
- .. code-block:: python
- >>> import paddle
- >>> paddle.enable_static()
- >>> data = paddle.static.data(name='data', shape=[2, 8, 32, 32], dtype='float32')
- >>> x = paddle.static.nn.group_norm(input=data, groups=4)
- >>> print(x.shape)
- (2, 8, 32, 32)
- """
- helper = LayerHelper('group_norm', **locals())
- dtype = helper.input_dtype()
- check_variable_and_dtype(
- input,
- 'input',
- ['float16', 'uint16', 'float32', 'float64'],
- 'group_norm',
- )
- # create input and parameters
- inputs = {'X': input}
- input_shape = input.shape
- if len(input_shape) < 2:
- raise ValueError(
- f"The dimensions of Op(static.nn.group_norm)'s input should be more than 1. But received {len(input_shape)}"
- )
- if data_layout != 'NCHW' and data_layout != 'NHWC':
- raise ValueError(
- "Param(data_layout) of Op(static.nn.group_norm) got wrong value: received "
- + data_layout
- + " but only NCHW or NHWC supported."
- )
- channel_num = input_shape[1] if data_layout == 'NCHW' else input_shape[-1]
- param_shape = [channel_num]
- if param_attr:
- scale = helper.create_parameter(
- attr=helper.param_attr,
- shape=param_shape,
- dtype=dtype,
- default_initializer=Constant(1.0),
- )
- inputs['Scale'] = scale
- if bias_attr:
- bias = helper.create_parameter(
- attr=helper.bias_attr, shape=param_shape, dtype=dtype, is_bias=True
- )
- inputs['Bias'] = bias
- # create output
- mean_out = helper.create_variable(dtype=dtype, stop_gradient=True)
- variance_out = helper.create_variable(dtype=dtype, stop_gradient=True)
- group_norm_out = helper.create_variable(dtype=dtype)
- helper.append_op(
- type="group_norm",
- inputs=inputs,
- outputs={
- "Y": group_norm_out,
- "Mean": mean_out,
- "Variance": variance_out,
- },
- attrs={
- "epsilon": epsilon,
- "groups": groups,
- "data_layout": data_layout,
- },
- )
- return helper.append_activation(group_norm_out)
- def conv2d(
- input,
- num_filters,
- filter_size,
- stride=1,
- padding=0,
- dilation=1,
- groups=None,
- param_attr=None,
- bias_attr=None,
- use_cudnn=True,
- act=None,
- name=None,
- data_format="NCHW",
- ):
- r"""
- The convolution2D layer calculates the output based on the input, filter
- and strides, paddings, dilations, groups parameters. Input and
- Output are in NCHW or NHWC format, where N is batch size, C is the number of
- channels, H is the height of the feature, and W is the width of the feature.
- Filter is in MCHW format, where M is the number of output image channels,
- C is the number of input image channels, H is the height of the filter,
- and W is the width of the filter. If the groups is greater than 1,
- C will equal the number of input image channels divided by the groups.
- Please refer to UFLDL's `convolution
- <http://ufldl.stanford.edu/tutorial/supervised/FeatureExtractionUsingConvolution/>`_
- for more details.
- If bias attribution and activation type are provided, bias is added to the
- output of the convolution, and the corresponding activation function is
- applied to the final result.
- For each input :math:`X`, the equation is:
- .. math::
- Out = \sigma (W \\ast X + b)
- Where:
- * :math:`X`: Input value, a tensor with NCHW or NHWC format.
- * :math:`W`: Filter value, a tensor with MCHW format.
- * :math:`\\ast`: Convolution operation.
- * :math:`b`: Bias value, a 2-D tensor with shape [M, 1].
- * :math:`\\sigma`: Activation function.
- * :math:`Out`: Output value, the shape of :math:`Out` and :math:`X` may be different.
- Example:
- - Input:
- Input shape: :math:`(N, C_{in}, H_{in}, W_{in})`
- Filter shape: :math:`(C_{out}, C_{in}, H_f, W_f)`
- - Output:
- Output shape: :math:`(N, C_{out}, H_{out}, W_{out})`
- Where
- .. math::
- H_{out}&= \\frac{(H_{in} + 2 * paddings[0] - (dilations[0] * (H_f - 1) + 1))}{strides[0]} + 1 \\\\
- W_{out}&= \\frac{(W_{in} + 2 * paddings[1] - (dilations[1] * (W_f - 1) + 1))}{strides[1]} + 1
- Args:
- input (Tensor): The input is 4-D Tensor with shape [N, C, H, W], the data type
- of input is float16 or float32 or float64.
- num_filters(int): The number of filter. It is as same as the output
- image channel.
- filter_size (int|tuple): The filter size. If filter_size
- is a tuple, it must contain two integers, (filter_size_height,
- filter_size_width). Otherwise, filter_size_height = filter_size_width =\
- filter_size.
- stride (int|tuple, optional): The stride size. It means the stride in convolution.
- If stride is a tuple, it must contain two integers, (stride_height, stride_width).
- Otherwise, stride_height = stride_width = stride. Default: stride = 1.
- padding (string|int|list|tuple, optional): The padding size. It means the number of zero-paddings
- on both sides for each dimension.If `padding` is a string, either 'VALID' or
- 'SAME' which is the padding algorithm. If padding size is a tuple or list,
- it could be in three forms: `[pad_height, pad_width]` or
- `[pad_height_top, pad_height_bottom, pad_width_left, pad_width_right]`, and when
- `data_format` is `"NCHW"`, `padding` can be in the form `[[0,0], [0,0],
- [pad_height_top, pad_height_bottom], [pad_width_left, pad_width_right]]`.
- when `data_format` is `"NHWC"`, `pool_padding` can be in the form
- `[[0,0], [pad_height_top, pad_height_bottom], [pad_width_left, pad_width_right], [0,0]]`.
- Default: padding = 0.
- dilation (int|tuple, optional): The dilation size. It means the spacing between the kernel
- points. If dilation is a tuple, it must contain two integers, (dilation_height,
- dilation_width). Otherwise, dilation_height = dilation_width = dilation.
- Default: dilation = 1.
- groups (int, optional): The groups number of the Conv2d Layer. According to grouped
- convolution in Alex Krizhevsky's Deep CNN paper: when group=2,
- the first half of the filters is only connected to the first half
- of the input channels, while the second half of the filters is only
- connected to the second half of the input channels. Default: groups=1.
- param_attr (ParamAttr|None, optional): The parameter attribute for learnable parameters/weights
- of conv2d. If it is set to None or one attribute of ParamAttr, conv2d
- will create ParamAttr as param_attr. If the Initializer of the param_attr
- is not set, the parameter is initialized with :math:`Normal(0.0, std)`,
- and the :math:`std` is :math:`(\frac{2.0 }{filter\_elem\_num})^{0.5}`. Default: None.
- bias_attr (ParamAttr|bool|None, optional): The parameter attribute for the bias of conv2d.
- If it is set to False, no bias will be added to the output units.
- If it is set to None or one attribute of ParamAttr, conv2d
- will create ParamAttr as bias_attr. If the Initializer of the bias_attr
- is not set, the bias is initialized zero. Default: None.
- use_cudnn (bool, optional): Use cudnn kernel or not, it is valid only when the cudnn
- library is installed. Default: True
- act (str, optional): Activation type, if it is set to None, activation is not appended.
- Default: None
- name(str|None, optional): For detailed information, please refer
- to :ref:`api_guide_Name`. Usually name is no need to set and
- None by default.
- data_format (str, optional): Specify the data format of the input, and the data format of the output
- will be consistent with that of the input. An optional string from: `"NCHW"`, `"NHWC"`.
- The default is `"NCHW"`. When it is `"NCHW"`, the data is stored in the order of:
- `[batch_size, input_channels, input_height, input_width]`.
- Returns:
- A Tensor representing the conv2d, whose data type is the
- same with input. If act is None, the tensor storing the convolution
- result, and if act is not None, the tensor storing convolution
- and non-linearity activation result.
- Examples:
- .. code-block:: python
- >>> import paddle
- >>> paddle.enable_static()
- >>> data = paddle.static.data(name='data', shape=[None, 3, 32, 32], dtype='float32')
- >>> conv2d = paddle.static.nn.conv2d(input=data, num_filters=2, filter_size=3, act="relu")
- >>> print(conv2d.shape)
- (-1, 2, 30, 30)
- """
- check_variable_and_dtype(
- input, 'input', ['uint16', 'float16', 'float32', 'float64'], 'conv2d'
- )
- if len(input.shape) != 4:
- raise ValueError(
- "Input size should be 4, " f"but received {len(input.shape)}"
- )
- num_channels = input.shape[1]
- if not isinstance(use_cudnn, bool):
- raise ValueError(
- "Attr(use_cudnn) should be True or False. Received "
- "Attr(use_cudnn): %s. " % str(use_cudnn)
- )
- if data_format not in ["NCHW", "NHWC"]:
- raise ValueError(
- "Attr(data_format) should be 'NCHW' or 'NHWC'. Received "
- "Attr(data_format): %s." % str(data_format)
- )
- channel_last = data_format == "NHWC"
- num_channels = input.shape[3] if channel_last else input.shape[1]
- if num_channels < 0:
- raise ValueError(
- f"The channel dimension of the input({str(input.shape)}) should be defined. "
- f"Received: {str(num_channels)}."
- )
- assert param_attr is not False, "param_attr should not be False here."
- if groups is None:
- num_filter_channels = num_channels
- elif groups <= 0:
- raise ValueError(
- "the groups of input must be greater than 0, "
- f"but received the groups of input is {groups}"
- )
- else:
- if num_channels % groups != 0:
- raise ValueError(
- "the channel of input must be divisible by groups,"
- f"received: the channel of input is {num_channels}, the shape of input is {input.shape}"
- f", the groups is {groups}"
- )
- num_filter_channels = num_channels // groups
- l_type = 'conv2d'
- if (
- num_channels == groups
- and num_filters % num_channels == 0
- and not use_cudnn
- ):
- l_type = 'depthwise_conv2d'
- if (
- num_channels == groups
- and num_filters % num_channels == 0
- and core.is_compiled_with_rocm()
- ):
- l_type = 'depthwise_conv2d'
- helper = LayerHelper(l_type, **locals())
- dtype = helper.input_dtype()
- filter_size = paddle.utils.convert_to_list(filter_size, 2, 'filter_size')
- stride = paddle.utils.convert_to_list(stride, 2, 'stride')
- dilation = paddle.utils.convert_to_list(dilation, 2, 'dilation')
- # padding
- def _update_padding(padding, data_format):
- if isinstance(padding, (list, tuple)) and len(padding) == 4:
- if isinstance(padding[0], (list, tuple)) and (
- data_format == "NCHW"
- ):
- if not (padding[0] == [0, 0] and padding[1] == [0, 0]):
- raise ValueError(
- "Non-zero padding(%s) in the batch or channel dimensions "
- "is not supported." % str(padding)
- )
- padding = padding[2:4]
- padding = [ele for a_list in padding for ele in a_list]
- elif isinstance(padding[0], (list, tuple)) and (
- data_format == "NHWC"
- ):
- if not (padding[0] == [0, 0] and padding[3] == [0, 0]):
- raise ValueError(
- "Non-zero padding(%s) in the batch or channel dimensions "
- "is not supported." % str(padding)
- )
- padding = padding[1:3]
- padding = [ele for a_list in padding for ele in a_list]
- padding = paddle.utils.convert_to_list(padding, 4, 'padding')
- if paddle.utils._is_symmetric_padding(padding, 2):
- padding = [padding[0], padding[2]]
- else:
- padding = paddle.utils.convert_to_list(padding, 2, 'padding')
- return padding
- padding_algorithm = "EXPLICIT"
- if isinstance(padding, str):
- padding = padding.upper()
- if padding not in ["SAME", "VALID"]:
- raise ValueError(
- "Unknown padding: '%s'. It can only be 'SAME' or 'VALID'."
- % str(padding)
- )
- if padding == "VALID":
- padding_algorithm = "VALID"
- padding = [0, 0]
- elif padding == "SAME":
- padding_algorithm = "SAME"
- padding = [0, 0]
- padding = _update_padding(padding, data_format)
- filter_shape = [num_filters, int(num_filter_channels)] + filter_size
- def _get_default_param_initializer():
- filter_elem_num = filter_size[0] * filter_size[1] * num_channels
- if filter_elem_num <= 0:
- raise ValueError(
- "Invalid filter number, excepted number is larger than 0, but"
- f" received {filter_elem_num}, please check the input shape and "
- "filter size."
- )
- std = (2.0 / filter_elem_num) ** 0.5
- return Normal(0.0, std)
- filter_param = helper.create_parameter(
- attr=helper.param_attr,
- shape=filter_shape,
- dtype=dtype,
- default_initializer=_get_default_param_initializer(),
- )
- pre_bias = helper.create_variable_for_type_inference(dtype)
- if (
- core.is_compiled_with_cuda()
- and paddle.base.get_flags("FLAGS_conv2d_disable_cudnn")[
- "FLAGS_conv2d_disable_cudnn"
- ]
- ):
- use_cudnn = False
- helper.append_op(
- type=l_type,
- inputs={
- 'Input': input,
- 'Filter': filter_param,
- },
- outputs={"Output": pre_bias},
- attrs={
- 'strides': stride,
- 'paddings': padding,
- 'dilations': dilation,
- 'groups': groups,
- 'use_cudnn': use_cudnn,
- 'fuse_relu_before_depthwise_conv': False,
- "padding_algorithm": padding_algorithm,
- "data_format": data_format,
- },
- )
- if data_format == 'NCHW':
- pre_act = helper.append_bias_op(pre_bias, dim_start=1, dim_end=2)
- else:
- pre_act = helper.append_bias_op(pre_bias, dim_start=3, dim_end=4)
- return helper.append_activation(pre_act)
- def conv3d(
- input,
- num_filters,
- filter_size,
- stride=1,
- padding=0,
- dilation=1,
- groups=None,
- param_attr=None,
- bias_attr=None,
- use_cudnn=True,
- act=None,
- name=None,
- data_format="NCDHW",
- ):
- r"""
- The convolution3D layer calculates the output based on the input, filter
- and strides, paddings, dilations, groups parameters. Input(Input) and
- Output(Output) are in NCDHW or NDHWC format. Where N is batch size C is the number of
- channels, D is the depth of the feature, H is the height of the feature,
- and W is the width of the feature. Convolution3D is similar with Convolution2D
- but adds one dimension(depth). If bias attribution and activation type are
- provided, bias is added to the output of the convolution, and the
- corresponding activation function is applied to the final result.
- For each input :math:`X`, the equation is:
- .. math::
- Out = \sigma (W \ast X + b)
- In the above equation:
- * :math:`X`: Input value, a tensor with NCDHW or NDHWC format.
- * :math:`W`: Filter value, a tensor with MCDHW format.
- * :math:`\ast`: Convolution operation.
- * :math:`b`: Bias value, a 2-D tensor with shape [M, 1].
- * :math:`\sigma`: Activation function.
- * :math:`Out`: Output value, the shape of :math:`Out` and :math:`X` may be different.
- Example:
- - Input:
- Input shape: :math:`(N, C_{in}, D_{in}, H_{in}, W_{in})`
- Filter shape: :math:`(C_{out}, C_{in}, D_f, H_f, W_f)`
- - Output:
- Output shape: :math:`(N, C_{out}, D_{out}, H_{out}, W_{out})`
- Where
- .. math::
- D_{out}&= \frac{(D_{in} + 2 * paddings[0] - (dilations[0] * (D_f - 1) + 1))}{strides[0]} + 1 \\
- H_{out}&= \frac{(H_{in} + 2 * paddings[1] - (dilations[1] * (H_f - 1) + 1))}{strides[1]} + 1 \\
- W_{out}&= \frac{(W_{in} + 2 * paddings[2] - (dilations[2] * (W_f - 1) + 1))}{strides[2]} + 1
- Args:
- input (Tensor): The input is 5-D Tensor with shape [N, C, D, H, W], the data
- type of input is float16 or float32 or float64.
- num_filters(int): The number of filter. It is as same as the output
- image channel.
- filter_size (int|tuple): The filter size. If filter_size is a tuple,
- it must contain three integers, (filter_size_depth, filter_size_height,
- filter_size_width). Otherwise, filter_size_depth = filter_size_height = \
- filter_size_width = filter_size.
- stride (int|tuple): The stride size. It means the stride in convolution. If stride is a
- tuple, it must contain three integers, (stride_depth, stride_height, stride_width).
- Otherwise, stride_depth = stride_height = stride_width = stride. Default: stride = 1.
- padding (string|int|list|tuple): The padding size. It means the number of zero-paddings
- on both sides for each dimension. If `padding` is a string, either 'VALID' or
- 'SAME' which is the padding algorithm. If padding size is a tuple or list,
- it could be in three forms: `[pad_depth, pad_height, pad_width]` or
- `[pad_depth_front, pad_depth_back, pad_height_top, pad_height_bottom, pad_width_left, pad_width_right]`,
- and when `data_format` is `"NCDHW"`, `pool_padding` can be in the form
- `[[0,0], [0,0], [pad_depth_front, pad_depth_back], [pad_height_top, pad_height_bottom], [pad_width_left, pad_width_right]]`.
- when `data_format` is `"NDHWC"`, `pool_padding` can be in the form
- `[[0,0], [pad_depth_front, pad_depth_back], [pad_height_top, pad_height_bottom], [pad_width_left, pad_width_right], [0,0]]`.
- Default: padding = 0.
- dilation (int|tuple): The dilation size. It means the spacing between the kernel points.
- If dilation is a tuple, it must contain three integers, (dilation_depth, dilation_height,
- dilation_width). Otherwise, dilation_depth = dilation_height = dilation_width = dilation.
- Default: dilation = 1.
- groups (int): The groups number of the Conv3d Layer. According to grouped
- convolution in Alex Krizhevsky's Deep CNN paper: when group=2,
- the first half of the filters is only connected to the first half
- of the input channels, while the second half of the filters is only
- connected to the second half of the input channels. Default: groups=1
- param_attr (ParamAttr|None): The parameter attribute for learnable parameters/weights
- of conv3d. If it is set to None or one attribute of ParamAttr, conv3d
- will create ParamAttr as param_attr. If it is set to None, the parameter
- is initialized with :math:`Normal(0.0, std)`, and the :math:`std` is
- :math:`(\\frac{2.0 }{filter\_elem\_num})^{0.5}`. Default: None.
- bias_attr (ParamAttr|bool|None): The parameter attribute for the bias of conv3d.
- If it is set to False, no bias will be added to the output units.
- If it is set to None or one attribute of ParamAttr, conv3d
- will create ParamAttr as bias_attr. If the Initializer of the bias_attr
- is not set, the bias is initialized zero. Default: None.
- use_cudnn (bool): Use cudnn kernel or not, it is valid only when the cudnn
- library is installed. Default: True
- act (str): Activation type, if it is set to None, activation is not appended.
- Default: None.
- name(str|None): For detailed information, please refer
- to :ref:`api_guide_Name`. Usually name is no need to set and
- None by default.
- data_format (str, optional): Specify the data format of the input, and the data format of the output
- will be consistent with that of the input. An optional string from: `"NCHW"`, `"NHWC"`.
- The default is `"NCHW"`. When it is `"NCHW"`, the data is stored in the order of:
- `[batch_size, input_channels, input_height, input_width]`.
- Returns:
- A Tensor representing the conv3d, whose data type is
- the same with input. If act is None, the tensor variable storing the
- convolution result, and if act is not None, the tensor variable storing
- convolution and non-linearity activation result.
- Examples:
- .. code-block:: python
- >>> import paddle
- >>> import numpy as np
- >>> np.random.seed(1107)
- >>> paddle.seed(1107)
- >>> paddle.enable_static()
- >>> data = paddle.static.data(name='data', shape=[None, 3, 12, 32, 32], dtype='float32')
- >>> param_attr = paddle.framework.ParamAttr(name='conv3d.weight', initializer=paddle.nn.initializer.XavierNormal(), learning_rate=0.001)
- >>> res = paddle.static.nn.conv3d(input=data, num_filters=2, filter_size=3, act="relu", param_attr=param_attr)
- >>> place = paddle.CPUPlace()
- >>> exe = paddle.static.Executor(place)
- >>> exe.run(paddle.static.default_startup_program())
- >>> x = np.random.rand(1, 3, 12, 32, 32).astype("float32")
- >>> output, = exe.run(feed={"data": x}, fetch_list=[res])
- >>> print(output.shape)
- (1, 2, 10, 30, 30)
- """
- l_type = 'conv3d'
- assert param_attr is not False, "param_attr should not be False here."
- helper = LayerHelper(l_type, **locals())
- dtype = helper.input_dtype()
- if not isinstance(use_cudnn, bool):
- raise ValueError(
- "Attr(use_cudnn) should be True or False. Received "
- "Attr(use_cudnn): %s. " % str(use_cudnn)
- )
- if data_format not in ["NCDHW", "NDHWC"]:
- raise ValueError(
- "Attr(data_format) should be 'NCDHW' or 'NDHWC'. Received "
- "Attr(data_format): %s." % str(data_format)
- )
- channel_last = data_format == "NDHWC"
- if len(input.shape) != 5:
- raise ValueError(
- f"Input should be 5D tensor, but received input with the shape of {input.shape}"
- )
- num_channels = input.shape[4] if channel_last else input.shape[1]
- if num_channels < 0:
- raise ValueError(
- f"The channel dimension of the input({str(input.shape)}) should be defined. "
- f"Received: {str(num_channels)}."
- )
- if groups is None:
- num_filter_channels = num_channels
- elif groups <= 0:
- raise ValueError(
- f"the groups of conv3d should be greater than 0. Received groups: {groups}"
- )
- else:
- if num_channels % groups != 0:
- raise ValueError(
- "The number of input channels must be divisible by Attr(groups). "
- f"Received: number of channels({str(num_channels)}), groups({str(groups)})."
- )
- num_filter_channels = num_channels // groups
- filter_size = paddle.utils.convert_to_list(filter_size, 3, 'filter_size')
- stride = paddle.utils.convert_to_list(stride, 3, 'stride')
- dilation = paddle.utils.convert_to_list(dilation, 3, 'dilation')
- def _update_padding(padding, data_format):
- if isinstance(padding, (list, tuple)) and len(padding) == 5:
- if isinstance(padding[0], (list, tuple)) and (
- data_format == "NCDHW"
- ):
- if not (padding[0] == [0, 0] and padding[1] == [0, 0]):
- raise ValueError(
- "Non-zero padding(%s) in the batch or channel dimensions "
- "is not supported." % str(padding)
- )
- padding = padding[2:5]
- padding = [ele for a_list in padding for ele in a_list]
- elif isinstance(padding[0], (list, tuple)) and (
- data_format == "NDHWC"
- ):
- if not (padding[0] == [0, 0] and padding[4] == [0, 0]):
- raise ValueError(
- "Non-zero padding(%s) in the batch or channel dimensions "
- "is not supported." % str(padding)
- )
- padding = padding[1:4]
- padding = [ele for a_list in padding for ele in a_list]
- padding = paddle.utils.convert_to_list(padding, 6, 'padding')
- if paddle.utils._is_symmetric_padding(padding, 3):
- padding = [padding[0], padding[2], padding[4]]
- elif isinstance(padding, (list, tuple)) and len(padding) == 6:
- padding = paddle.utils.convert_to_list(padding, 6, 'padding')
- if paddle.utils._is_symmetric_padding(padding, 3):
- padding = [padding[0], padding[2], padding[4]]
- else:
- padding = paddle.utils.convert_to_list(padding, 3, 'padding')
- return padding
- padding_algorithm = "EXPLICIT"
- if isinstance(padding, str):
- padding = padding.upper()
- if padding not in ["SAME", "VALID"]:
- raise ValueError(
- "Unknown padding: '%s'. It can only be 'SAME' or 'VALID'."
- % str(padding)
- )
- if padding == "VALID":
- padding_algorithm = "VALID"
- padding = [0, 0, 0]
- elif padding == "SAME":
- padding_algorithm = "SAME"
- padding = [0, 0, 0]
- padding = _update_padding(padding, data_format)
- input_shape = input.shape
- filter_shape = [num_filters, num_filter_channels] + filter_size
- def _get_default_param_initializer():
- filter_elem_num = (
- filter_size[0] * filter_size[1] * filter_size[2] * num_channels
- )
- if filter_elem_num <= 0:
- raise ValueError(
- "Invalid filter number, excepted number is larger than 0, but"
- f" received {filter_elem_num}, please check the input shape and "
- "filter size."
- )
- std = (2.0 / filter_elem_num) ** 0.5
- return Normal(0.0, std)
- filter_param = helper.create_parameter(
- attr=helper.param_attr,
- shape=filter_shape,
- dtype=dtype,
- default_initializer=_get_default_param_initializer(),
- )
- pre_bias = helper.create_variable_for_type_inference(dtype)
- helper.append_op(
- type=l_type,
- inputs={
- 'Input': input,
- 'Filter': filter_param,
- },
- outputs={"Output": pre_bias},
- attrs={
- 'strides': stride,
- 'paddings': padding,
- 'dilations': dilation,
- 'groups': groups,
- 'use_cudnn': use_cudnn,
- "padding_algorithm": padding_algorithm,
- "data_format": data_format,
- },
- )
- if data_format == 'NCDHW':
- pre_act = helper.append_bias_op(pre_bias, dim_start=1, dim_end=2)
- else:
- pre_act = helper.append_bias_op(pre_bias, dim_start=4, dim_end=5)
- return helper.append_activation(pre_act)
- def conv2d_transpose(
- input,
- num_filters,
- output_size=None,
- filter_size=None,
- padding=0,
- stride=1,
- dilation=1,
- groups=None,
- param_attr=None,
- bias_attr=None,
- use_cudnn=True,
- act=None,
- name=None,
- data_format='NCHW',
- ):
- r"""
- The convolution2D transpose layer calculates the output based on the input,
- filter, and dilations, strides, paddings. Input(Input) and output(Output)
- are in NCHW or NHWC format. Where N is batch size, C is the number of channels,
- H is the height of the feature, and W is the width of the feature.
- Parameters(dilations, strides, paddings) are two elements. These two elements
- represent height and width, respectively. The details of convolution transpose
- layer, please refer to the following explanation and references
- `therein <https://arxiv.org/pdf/1603.07285.pdf>`_.
- If bias attribution and activation type are provided, bias is added to
- the output of the convolution, and the corresponding activation function
- is applied to the final result.
- For each input :math:`X`, the equation is:
- .. math::
- Out = \sigma (W \ast X + b)
- Where:
- * :math:`X`: Input value, a 4-D Tensor with NCHW or NHWC format.
- * :math:`W`: Filter value, a 4-D Tensor with MCHW format.
- * :math:`\ast`: Convolution operation.
- * :math:`b`: Bias value, a 2-D Tensor with shape [M, 1].
- * :math:`\sigma`: Activation function.
- * :math:`Out`: Output value, a 4-D Tensor with data format 'NCHW' or 'NHWC', the shape of :math:`Out` and :math:`X` may be different.
- Example:
- - Input:
- Input shape: :math:`(N, C_{in}, H_{in}, W_{in})`
- Filter shape: :math:`(C_{in}, C_{out}, H_f, W_f)`
- - Output:
- Output shape: :math:`(N, C_{out}, H_{out}, W_{out})`
- Where
- .. math::
- H^\prime_{out} &= (H_{in} - 1) * strides[0] - 2 * paddings[0] + dilations[0] * (H_f - 1) + 1 \\
- W^\prime_{out} &= (W_{in} - 1) * strides[1] - 2 * paddings[1] + dilations[1] * (W_f - 1) + 1 \\
- H_{out} &\in [ H^\prime_{out}, H^\prime_{out} + strides[0] ] \\
- W_{out} &\in [ W^\prime_{out}, W^\prime_{out} + strides[1] ]
- If `padding` = `"SAME"`:
- .. math::
- H^\prime_{out} &= \frac{(H_{in} + stride[0] - 1)}{stride[0]} \\
- W^\prime_{out} &= \frac{(H_{in} + stride[1] - 1)}{stride[1]}
- If `padding` = `"VALID"`:
- .. math::
- H^\prime_{out} &= (H_{in} - 1) * strides[0] + dilations[0] * (H_f - 1) + 1 \\
- W^\prime_{out} &= (W_{in} − 1) * strides[1] + dilations[1] * (W_f − 1) + 1
- If output_size is None, :math:`H_{out} = H^\prime_{out}, W_{out} = W^\prime_{out}`;
- else, the :math:`H_{out}` of the output size must between :math:`H^\prime_{out}`
- and :math:`H^\prime_{out} + strides[0]`, and the :math:`W_{out}` of the output size must
- between :math:`W^\prime_{out}` and :math:`W^\prime_{out} + strides[1]`,
- Since transposed convolution can be treated as the inverse of convolution, and according to the input-output formula for convolution,
- different sized input feature layers may correspond to the same sized output feature layer,
- the size of the output feature layer for a fixed sized input feature layer is not unique to transposed convolution
- If `output_size` is specified, `conv2d_transpose` can compute the kernel size automatically.
- Args:
- input(Tensor): 4-D Tensor with [N, C, H, W] or [N, H, W, C] format where N is the batch_size,
- C is the input_channels, H is the input_height and W is the input_width.
- Its data type is float32 or float64.
- num_filters(int): The number of the filter. It is as same as the output
- image channel.
- output_size(int|tuple, optional): The output image size. If output size is a
- tuple, it must contain two integers, (image_height, image_width). None if use
- filter_size, padding, and stride to calculate output_size.
- If output_size and filter_size are specified at the same time, They
- should follow the formula above. Default: None. output_size and filter_size
- should not be None at the same time.
- filter_size(int|tuple, optional): The filter size. If filter_size is a tuple,
- it must contain two integers, (filter_size_height, filter_size_width).
- Otherwise, filter_size_height = filter_size_width = filter_size. None if
- use output size to calculate filter_size. Default: None. filter_size and
- output_size should not be None at the same time.
- padding(str|int|list|tuple, optional): The padding size. It means the number of zero-paddings
- on both sides for each dimension. If `padding` is a string, either 'VALID' or
- 'SAME' which is the padding algorithm. If `padding` is a tuple or list,
- it could be in three forms:
- (1) Contains 4 binary groups: when `data_format` is `"NCHW"`, `padding` can be in the form
- `[[0,0], [0,0], [pad_height_top, pad_height_bottom], [pad_width_left, pad_width_right]]`.
- when `data_format` is `"NHWC"`, `padding` can be in the form
- `[[0,0], [pad_height_top, pad_height_bottom], [pad_width_left, pad_width_right], [0,0]]`.
- (2) Contains 4 integer values:`[pad_height_top, pad_height_bottom, pad_width_left, pad_width_right]`
- (3) Contains 2 integer values:`[pad_height, pad_width]`, in this case, `padding_height_top = padding_height_bottom = padding_height`,
- `padding_width_left = padding_width_right = padding_width`. If an integer, `padding_height = padding_width = padding`. Default: padding = 0.
- stride(int|tuple, optional): The stride size. It means the stride in transposed convolution.
- If stride is a tuple, it must contain two integers, (stride_height, stride_width).
- Otherwise, stride_height = stride_width = stride. Default: stride = 1.
- dilation(int|tuple, optional): The dilation size. It means the spacing between the kernel points.
- If dilation is a tuple, it must contain two integers, (dilation_height, dilation_width).
- Otherwise, dilation_height = dilation_width = dilation. Default: dilation = 1.
- groups(int, optional): The groups number of the Conv2d transpose layer. Inspired by
- grouped convolution in Alex Krizhevsky's Deep CNN paper, in which
- when group=2, the first half of the filters is only connected to the
- first half of the input channels, while the second half of the
- filters is only connected to the second half of the input channels.
- Default: groups = 1.
- param_attr (ParamAttr, optional): The parameter attribute for learnable parameters/weights
- of conv2d_transpose. If it is set to None or one attribute of ParamAttr, conv2d_transpose
- will create ParamAttr as param_attr. If the Initializer of the param_attr
- is not set, the parameter is initialized with Xavier. Default: None.
- bias_attr (ParamAttr|bool, optional): Specifies the object for the bias parameter attribute.
- The default value is None, which means that the default bias parameter attribute is used.
- For detailed information, please refer to :ref:`api_paddle_ParamAttr`.
- The default bias initialisation for the conv2d_transpose operator is 0.0.
- use_cudnn(bool, optional): Use cudnn kernel or not, it is valid only when the cudnn
- library is installed. Default: True.
- act (str, optional): Activation type, if it is set to None, activation is not appended.
- Default: None.
- name(str, optional): For detailed information, please refer
- to :ref:`api_guide_Name`. Usually name is no need to set and
- None by default.
- data_format (str, optional): Specify the data format of the input, and the data format of the output
- will be consistent with that of the input. An optional string from: `"NCHW"`, `"NHWC"`.
- The default is `"NCHW"`. When it is `"NCHW"`, the data is stored in the order of:
- `[batch_size, input_channels, input_height, input_width]`.
- Returns:
- A Tensor representing the conv2d_transpose, whose
- data type is the same with input and shape is (num_batches, channels, out_h,
- out_w) or (num_batches, out_h, out_w, channels). If act is None, the tensor
- storing the transposed convolution result, and if act is not None, the
- tensor storing transposed convolution and non-linearity activation
- result.
- Raises:
- ValueError: If the type of `use_cudnn` is not bool.
- ValueError: If `data_format` is not "NCHW" or "NHWC".
- ValueError: If `padding` is a string, but not "SAME" or "VALID".
- ValueError: If `padding` is a tuple, but the element corresponding to the input's batch size is not 0
- or the element corresponding to the input's channel is not 0.
- ValueError: If `output_size` and filter_size are None at the same time.
- ShapeError: If the input is not 4-D Tensor.
- ShapeError: If the input's dimension size and filter's dimension size not equal.
- ShapeError: If the dimension size of input minus the size of `stride` is not 2.
- ShapeError: If the number of input channels is not equal to filter's channels.
- ShapeError: If the size of `output_size` is not equal to that of `stride`.
- Examples:
- .. code-block:: python
- >>> import paddle
- >>> paddle.enable_static()
- >>> data = paddle.static.data(name='data', shape=[None, 3, 32, 32], dtype='float32')
- >>> conv2d_transpose = paddle.static.nn.conv2d_transpose(input=data, num_filters=2, filter_size=3)
- >>> print(conv2d_transpose.shape)
- (-1, 2, 34, 34)
- """
- assert (
- param_attr is not False
- ), "param_attr should not be False in conv2d_transpose."
- if len(input.shape) != 4:
- raise ValueError(
- "Input size should be 4, " f"but received {len(input.shape)}"
- )
- if num_filters == 0:
- raise ValueError("num of filters should not be 0.")
- if data_format not in ['NCHW', 'NHWC']:
- raise ValueError(
- "Attr(data_format) of Op(paddle.static.nn.layers.conv2d_transpose) got wrong value: received "
- + data_format
- + " but only NCHW or NHWC supported."
- )
- input_channel = input.shape[1] if data_format == 'NCHW' else input.shape[-1]
- op_type = 'conv2d_transpose'
- if (
- input_channel == groups
- and num_filters == input_channel
- and not use_cudnn
- ):
- op_type = 'depthwise_conv2d_transpose'
- helper = LayerHelper(op_type, **locals())
- if not isinstance(input, Variable):
- raise TypeError("Input of conv2d_transpose must be Tensor")
- stride = paddle.utils.convert_to_list(stride, 2, 'stride')
- dilation = paddle.utils.convert_to_list(dilation, 2, 'dilation')
- if not isinstance(use_cudnn, bool):
- raise ValueError("use_cudnn should be True or False")
- def _update_padding(padding, data_format):
- if isinstance(padding, (list, tuple)) and len(padding) == 4:
- if isinstance(padding[0], (list, tuple)) and (
- data_format == "NCHW"
- ):
- if not (padding[0] == [0, 0] and padding[1] == [0, 0]):
- raise ValueError(
- "Non-zero padding(%s) in the batch or channel dimensions "
- "is not supported." % str(padding)
- )
- padding = padding[2:4]
- padding = [ele for a_list in padding for ele in a_list]
- elif isinstance(padding[0], (list, tuple)) and (
- data_format == "NHWC"
- ):
- if not (padding[0] == [0, 0] and padding[3] == [0, 0]):
- raise ValueError(
- "Non-zero padding(%s) in the batch or channel dimensions "
- "is not supported." % str(padding)
- )
- padding = padding[1:3]
- padding = [ele for a_list in padding for ele in a_list]
- padding = paddle.utils.convert_to_list(padding, 4, 'padding')
- else:
- padding = paddle.utils.convert_to_list(padding, 2, 'padding')
- padding = [padding[0], padding[0], padding[1], padding[1]]
- return padding
- padding_algorithm = "EXPLICIT"
- if isinstance(padding, str):
- padding = padding.upper()
- if padding not in ["SAME", "VALID"]:
- raise ValueError(
- "Unknown padding: '%s'. It can only be 'SAME' or 'VALID'."
- % str(padding)
- )
- if padding == "VALID":
- padding_algorithm = "VALID"
- padding = [0, 0, 0, 0]
- elif padding == "SAME":
- padding_algorithm = "SAME"
- padding = [0, 0, 0, 0]
- padding = _update_padding(padding, data_format)
- if output_size is None:
- output_size = []
- elif isinstance(output_size, (list, tuple)):
- if paddle.utils._contain_var(output_size):
- output_size = paddle.utils._convert_to_tensor_list(output_size)
- else:
- output_size = paddle.utils.convert_to_list(
- output_size, 2, 'output_size'
- )
- elif isinstance(output_size, int):
- output_size = paddle.utils.convert_to_list(
- output_size, 2, 'output_size'
- )
- elif isinstance(output_size, Variable):
- check_dtype(
- output_size.dtype,
- 'output_size',
- ['int32', 'int64'],
- 'conv2d_transpose',
- )
- if len(output_size.shape) == 1 and (
- output_size.shape[0] == 1 or output_size.shape[0] == 2
- ):
- if output_size.shape[0] == 1:
- output_size = [output_size, output_size]
- else:
- raise ValueError("output_size must contain one or two integers.")
- else:
- raise ValueError(
- "output_size should be int, list[int] or tuple[int] or Tensor"
- )
- if filter_size is None:
- if output_size == []:
- raise ValueError("output_size must be set when filter_size is None")
- if not in_dygraph_mode():
- if isinstance(output_size, Variable) or paddle.utils._contain_var(
- output_size
- ):
- raise ValueError(
- "filter_size should not be None when output_size is Tensor or contain Tensor in static graph mode."
- )
- else:
- output_size = paddle.utils.convert_shape_to_list(output_size)
- if len(output_size) == 1:
- output_size = paddle.utils.convert_to_list(
- output_size[0], 2, 'output_size'
- )
- h_in = input.shape[2] if data_format == 'NCHW' else input.shape[1]
- w_in = input.shape[3] if data_format == 'NCHW' else input.shape[2]
- filter_size_h = (
- output_size[0]
- - (h_in - 1) * stride[0]
- + padding[0]
- + padding[1]
- - 1
- ) // dilation[0] + 1
- filter_size_w = (
- output_size[1]
- - (w_in - 1) * stride[1]
- + padding[2]
- + padding[3]
- - 1
- ) // dilation[1] + 1
- filter_size = [filter_size_h, filter_size_w]
- else:
- filter_size = paddle.utils.convert_to_list(
- filter_size, 2, 'conv2d_transpose.filter_size'
- )
- if len(padding) == 4 and paddle.utils._is_symmetric_padding(padding, 2):
- padding = [padding[0], padding[2]]
- if groups is None:
- groups = 1
- elif groups <= 0:
- raise ValueError(
- "the groups of input must be greater than 0, "
- f"but received the groups of input is {groups}"
- )
- filter_shape = [input_channel, num_filters // groups] + filter_size
- img_filter = helper.create_parameter(
- dtype=input.dtype, shape=filter_shape, attr=helper.param_attr
- )
- pre_bias = helper.create_variable_for_type_inference(dtype=input.dtype)
- helper.append_op(
- type=op_type,
- inputs={'Input': [input], 'Filter': [img_filter]},
- outputs={'Output': pre_bias},
- attrs={
- 'output_size': output_size,
- 'strides': stride,
- 'paddings': padding,
- 'padding_algorithm': padding_algorithm,
- 'dilations': dilation,
- 'groups': groups,
- 'use_cudnn': use_cudnn,
- 'data_format': data_format,
- },
- )
- if data_format == 'NCHW':
- pre_act = helper.append_bias_op(pre_bias, dim_start=1, dim_end=2)
- else:
- pre_act = helper.append_bias_op(pre_bias, dim_start=3, dim_end=4)
- out = helper.append_activation(pre_act)
- return out
- def conv3d_transpose(
- input,
- num_filters,
- output_size=None,
- filter_size=None,
- padding=0,
- stride=1,
- dilation=1,
- groups=None,
- param_attr=None,
- bias_attr=None,
- use_cudnn=True,
- act=None,
- name=None,
- data_format='NCDHW',
- ):
- r"""
- The convolution3D transpose layer calculates the output based on the input,
- filter, and dilations, strides, paddings. Input(Input) and output(Output)
- are in NCDHW or NDHWC format. Where N is batch size, C is the number of channels,
- D is the depth of the feature, H is the height of the feature, and W
- is the width of the feature. Parameters(dilations, strides, paddings) are
- two elements. These two elements represent height and width, respectively.
- The details of convolution transpose layer, please refer to the following
- explanation and references `therein <https://arxiv.org/pdf/1603.07285.pdf>`_.
- If bias attribution and activation type are provided, bias is added to
- the output of the convolution, and the corresponding activation function
- is applied to the final result.
- For each input :math:`X`, the equation is:
- .. math::
- Out = \sigma (W \ast X + b)
- In the above equation:
- * :math:`X`: Input value, a Tensor with NCDHW or NDHWC format.
- * :math:`W`: Filter value, a Tensor with MCDHW format.
- * :math:`\ast`: Convolution operation.
- * :math:`b`: Bias value, a 2-D Tensor with shape [M, 1].
- * :math:`\sigma`: Activation function.
- * :math:`Out`: Output value, the shape of :math:`Out` and :math:`X` may be different.
- Example:
- - Input:
- Input shape: :math:`(N, C_{in}, D_{in}, H_{in}, W_{in})`
- Filter shape: :math:`(C_{in}, C_{out}, D_f, H_f, W_f)`
- - Output:
- Output shape: :math:`(N, C_{out}, D_{out}, H_{out}, W_{out})`
- Where
- .. math::
- D^\prime_{out} &= (D_{in} - 1) * strides[0] - 2 * paddings[0] + dilations[0] * (D_f - 1) + 1 \\
- H^\prime_{out} &= (H_{in} - 1) * strides[1] - 2 * paddings[1] + dilations[1] * (H_f - 1) + 1 \\
- W^\prime_{out} &= (W_{in} - 1) * strides[2] - 2 * paddings[2] + dilations[2] * (W_f - 1) + 1 \\
- D_{out} &\in [ D^\prime_{out}, D^\prime_{out} + strides[0] ] \\
- H_{out} &\in [ H^\prime_{out}, H^\prime_{out} + strides[1] ] \\
- W_{out} &\in [ W^\prime_{out}, W^\prime_{out} + strides[2] ]
- If `padding` = `"SAME"`:
- .. math::
- D^\prime_{out} &= \frac{(D_{in} + stride[0] - 1)}{stride[0]} \\
- H^\prime_{out} &= \frac{(H_{in} + stride[1] - 1)}{stride[1]} \\
- W^\prime_{out} &= \frac{(H_{in} + stride[2] - 1)}{stride[2]}
- If `padding` = `"VALID"`:
- .. math::
- D^\prime_{out} &= (D_{in} - 1) * strides[0] + dilations[0] * (D_f - 1) + 1 \\
- H^\prime_{out} &= (H_{in} - 1) * strides[1] + dilations[1] * (H_f - 1) + 1 \\
- W^\prime_{out} &= (W_{in} − 1) * strides[2] + dilations[2] * (W_f − 1) + 1
- If `output_size` is None, :math:`D_{out} = D^\prime_{out}, :math:`H_{out} = \
- H^\prime_{out}, W_{out} = W^\prime_{out}`; else, the specified `output_size_depth` (the depth of the output feature layer) :math:`D_{out}`
- must between :math:`D^\prime_{out}` and :math:`D^\prime_{out} + strides[0]`(not including :math:`D^\prime_{out} + strides[0]`),
- the specified `output_size_height` (the height of the output feature layer) :math:`H_{out}` must between :math:`H^\prime_{out}`
- and :math:`H^\prime_{out} + strides[1]`(not including :math:`H^\prime_{out} + strides[1]`),
- and the specified `output_size_width` (the width of the output feature layer) :math:`W_{out}` must
- between :math:`W^\prime_{out}` and :math:`W^\prime_{out} + strides[2]`(not including :math:`W^\prime_{out} + strides[2]`).
- Since transposed convolution can be treated as the inverse of convolution,
- and since different sized input feature layers may correspond to the same sized output feature layer according to the input-output formula for convolution,
- the size of the output feature layer for a fixed sized input feature layer is not unique to transposed convolution.
- If `output_size` is specified, `conv3d_transpose` can compute the kernel size automatically.
- Args:
- input(Tensor): The input is 5-D Tensor with shape [N, C, D, H, W] or [N, D, H, W, C], the data type
- of input is float32 or float64.
- num_filters(int): The number of the filter. It is as same as the output
- image channel.
- output_size(int|tuple, optional): The output image size. If output size is a
- tuple, it must contain three integers, (image_depth, image_height, image_width). This
- parameter only works when filter_size is None. If output_size and filter_size are
- specified at the same time, They should follow the formula above. Default: None.
- Output_size and filter_size should not be None at the same time.
- filter_size(int|tuple, optional): The filter size. If filter_size is a tuple,
- it must contain three integers, (filter_size_depth, filter_size_height,
- filter_size_width). Otherwise, filter_size_depth = filter_size_height = \
- filter_size_width = filter_size. None if use output size to
- calculate filter_size. Default: None. filter_size and output_size should not be
- None at the same time.
- padding(int|list|str|tuple, optional): The padding size. The padding argument effectively
- adds `dilation * (kernel - 1)` amount of zero-padding on both sides of input. If `padding` is a string,
- either 'VALID' or 'SAME' supported, which is the padding algorithm. If `padding`
- is a tuple or list, it could be in three forms: `[pad_depth, pad_height, pad_width]` or
- `[pad_depth_front, pad_depth_back, pad_height_top, pad_height_bottom, pad_width_left, pad_width_right]`,
- and when `data_format` is `'NCDHW'`, `padding` can be in the form
- `[[0,0], [0,0], [pad_depth_front, pad_depth_back], [pad_height_top, pad_height_bottom], [pad_width_left, pad_width_right]]`.
- when `data_format` is `'NDHWC'`, `padding` can be in the form
- `[[0,0], [pad_depth_front, pad_depth_back], [pad_height_top, pad_height_bottom], [pad_width_left, pad_width_right], [0,0]]`.
- Default: padding = 0.
- stride(int|tuple, optional): The stride size. It means the stride in transposed convolution.
- If stride is a tuple, it must contain three integers, (stride_depth, stride_height,
- stride_width). Otherwise, stride_depth = stride_height = stride_width = stride.
- Default: stride = 1.
- dilation(int|tuple, optional): The dilation size. It means the spacing between the kernel points.
- If dilation is a tuple, it must contain three integers, (dilation_depth, dilation_height,
- dilation_width). Otherwise, dilation_depth = dilation_height = dilation_width = dilation.
- Default: dilation = 1.
- groups(int, optional): The groups number of the Conv3d transpose layer. Inspired by
- grouped convolution in Alex Krizhevsky's Deep CNN paper, in which
- when group=2, the first half of the filters is only connected to the
- first half of the input channels, while the second half of the
- filters is only connected to the second half of the input channels.
- Default: groups=1
- param_attr (ParamAttr, optional): The parameter attribute for learnable parameters/weights
- of conv3d_transpose. If it is set to None or one attribute of ParamAttr, conv3d_transpose
- will create ParamAttr as param_attr. If the Initializer of the param_attr
- is not set, the parameter is initialized with Xavier. Default: None.
- bias_attr (ParamAttr|bool, optional): The parameter attribute for the bias of conv3d_transpose.
- If it is set to False, no bias will be added to the output units.
- If it is set to None or one attribute of ParamAttr, conv3d_transpose
- will create ParamAttr as bias_attr. If the Initializer of the bias_attr
- is not set, the bias is initialized zero. Default: None.
- use_cudnn(bool, optional): Use cudnn kernel or not, it is valid only when the cudnn
- library is installed. Default: True
- act (str, optional): Activation type, if it is set to None, activation is not appended.
- Default: None.
- name(str, optional): For detailed information, please refer
- to :ref:`api_guide_Name`. Usually name is no need to set and
- None by default.
- data_format (str, optional): Specify the data format of the input, and the data format of the output
- will be consistent with that of the input. An optional string from: `"NCHW"`, `"NHWC"`.
- The default is `"NCHW"`. When it is `"NCHW"`, the data is stored in the order of:
- `[batch_size, input_channels, input_height, input_width]`.
- Returns:
- A Tensor representing the conv3d_transpose, whose data
- type is the same with input and shape is (num_batches, channels, out_d, out_h,
- out_w) or (num_batches, out_d, out_h, out_w, channels). If act is None, the tensor
- variable storing the transposed convolution result, and if act is not None, the tensor
- variable storing transposed convolution and non-linearity activation result.
- Examples:
- .. code-block:: python
- >>> import paddle
- >>> import numpy as np
- >>> paddle.seed(1107)
- >>> np.random.seed(1107)
- >>> paddle.enable_static()
- >>> data = paddle.static.data(name='data', shape=[None, 3, 12, 32, 32], dtype='float32')
- >>> param_attr = paddle.framework.ParamAttr(name='conv3d.weight', initializer=paddle.nn.initializer.XavierNormal(), learning_rate=0.001)
- >>> res = paddle.static.nn.conv3d_transpose(input=data, num_filters=2, filter_size=3, act="relu", param_attr=param_attr)
- >>> place = paddle.CPUPlace()
- >>> exe = paddle.static.Executor(place)
- >>> exe.run(paddle.static.default_startup_program())
- >>> x = np.random.rand(1, 3, 12, 32, 32).astype("float32")
- >>> output = exe.run(feed={"data": x}, fetch_list=[res.mean()])
- >>> print(output)
- [array(0.5148856, dtype=float32)]
- """
- assert (
- param_attr is not False
- ), "param_attr should not be False in conv3d_transpose."
- if data_format not in ['NCDHW', 'NDHWC']:
- raise ValueError(
- "Param(data_format) of Op(paddle.static.nn.conv3d_transpose) got wrong value: received "
- + data_format
- + " but only NCDHW or NDHWC supported."
- )
- l_type = "conv3d_transpose"
- helper = LayerHelper(l_type, **locals())
- if not isinstance(input, Variable):
- raise TypeError("Input of conv3d_transpose must be Tensor")
- if len(input.shape) != 5:
- raise ValueError(
- f"Input should be 5D tensor, but received input with the shape of {input.shape}"
- )
- input_channel = (
- input.shape[1] if data_format == 'NCDHW' else input.shape[-1]
- )
- stride = paddle.utils.convert_to_list(stride, 3, 'stride')
- dilation = paddle.utils.convert_to_list(dilation, 3, 'dilation')
- if not isinstance(use_cudnn, bool):
- raise ValueError("use_cudnn should be True or False")
- def _update_padding(padding, data_format):
- if isinstance(padding, (list, tuple)) and len(padding) == 5:
- if isinstance(padding[0], (list, tuple)) and (
- data_format == "NCDHW"
- ):
- if not (padding[0] == [0, 0] and padding[1] == [0, 0]):
- raise ValueError(
- "Non-zero padding(%s) in the batch or channel dimensions "
- "is not supported." % str(padding)
- )
- padding = padding[2:5]
- padding = [ele for a_list in padding for ele in a_list]
- elif isinstance(padding[0], (list, tuple)) and (
- data_format == "NDHWC"
- ):
- if not (padding[0] == [0, 0] and padding[4] == [0, 0]):
- raise ValueError(
- "Non-zero padding(%s) in the batch or channel dimensions "
- "is not supported." % str(padding)
- )
- padding = padding[1:4]
- padding = [ele for a_list in padding for ele in a_list]
- padding = paddle.utils.convert_to_list(padding, 6, 'padding')
- elif isinstance(padding, (list, tuple)) and len(padding) == 6:
- padding = paddle.utils.convert_to_list(padding, 6, 'padding')
- else:
- padding = paddle.utils.convert_to_list(padding, 3, 'padding')
- padding = [
- padding[0],
- padding[0],
- padding[1],
- padding[1],
- padding[2],
- padding[2],
- ]
- return padding
- padding_algorithm = "EXPLICIT"
- if isinstance(padding, str):
- padding = padding.upper()
- if padding not in ["SAME", "VALID"]:
- raise ValueError(
- "Unknown padding: '%s'. It can only be 'SAME' or 'VALID'."
- % str(padding)
- )
- if padding == "VALID":
- padding_algorithm = "VALID"
- padding = [0, 0, 0, 0, 0, 0]
- elif padding == "SAME":
- padding_algorithm = "SAME"
- padding = [0, 0, 0, 0, 0, 0]
- padding = _update_padding(padding, data_format)
- if filter_size is None:
- if output_size is None:
- raise ValueError("output_size must be set when filter_size is None")
- if isinstance(output_size, int):
- output_size = [output_size, output_size, output_size]
- d_in = input.shape[2] if data_format == 'NCDHW' else input.shape[1]
- h_in = input.shape[3] if data_format == 'NCDHW' else input.shape[2]
- w_in = input.shape[4] if data_format == 'NCDHW' else input.shape[3]
- filter_size_d = (
- output_size[0]
- - (d_in - 1) * stride[0]
- + padding[0]
- + padding[1]
- - 1
- ) // dilation[0] + 1
- filter_size_h = (
- output_size[1]
- - (h_in - 1) * stride[1]
- + padding[2]
- + padding[3]
- - 1
- ) // dilation[1] + 1
- filter_size_w = (
- output_size[2]
- - (w_in - 1) * stride[2]
- + padding[4]
- + padding[5]
- - 1
- ) // dilation[2] + 1
- filter_size = [filter_size_d, filter_size_h, filter_size_w]
- else:
- filter_size = paddle.utils.convert_to_list(
- filter_size, 3, 'conv3d_transpose.filter_size'
- )
- if len(padding) == 6 and paddle.utils._is_symmetric_padding(padding, 3):
- padding = [padding[0], padding[2], padding[4]]
- if output_size is None:
- output_size = []
- elif isinstance(output_size, (list, tuple, int)):
- output_size = paddle.utils.convert_to_list(
- output_size, 3, 'output_size'
- )
- else:
- raise ValueError("output_size should be int, list[int] or tuple[int]")
- groups = 1 if groups is None else groups
- if groups <= 0:
- raise ValueError(
- f"the groups of conv3d_transpose should be greater than 0. Received groups: {groups}"
- )
- if num_filters % groups != 0:
- raise ValueError(
- "Attr(num_filters) must be divisible by groups,"
- f"Received: Attr(num_filters) is {num_filters}, the groups is {groups}"
- )
- filter_shape = [input_channel, num_filters // groups] + filter_size
- img_filter = helper.create_parameter(
- dtype=input.dtype, shape=filter_shape, attr=helper.param_attr
- )
- if data_format == 'NCDHW':
- data_format = 'NCHW'
- if data_format == 'NDHWC':
- data_format = 'NHWC'
- pre_bias = helper.create_variable_for_type_inference(dtype=input.dtype)
- helper.append_op(
- type=l_type,
- inputs={'Input': [input], 'Filter': [img_filter]},
- outputs={'Output': pre_bias},
- attrs={
- 'output_size': output_size,
- 'strides': stride,
- 'paddings': padding,
- 'padding_algorithm': padding_algorithm,
- 'dilations': dilation,
- 'groups': groups,
- 'use_cudnn': use_cudnn,
- 'data_format': data_format,
- },
- )
- if data_format == 'NCHW':
- pre_act = helper.append_bias_op(pre_bias, dim_start=1, dim_end=2)
- else:
- pre_act = helper.append_bias_op(pre_bias, dim_start=4, dim_end=5)
- out = helper.append_activation(pre_act)
- return out
- def deformable_conv(
- input,
- offset,
- mask,
- num_filters,
- filter_size,
- stride=1,
- padding=0,
- dilation=1,
- groups=None,
- deformable_groups=None,
- im2col_step=None,
- param_attr=None,
- bias_attr=None,
- modulated=True,
- name=None,
- ):
- r"""
- **Deformable Convolution op**
- Compute 2-D deformable convolution on 4-D input.
- Given input image x, output feature map y, the deformable convolution operation can be expressed as follow:
- Deformable Convolution v2:
- .. math::
- y(p) = \sum_{k=1}^{K}{w_k * x(p + p_k + \Delta p_k) * \Delta m_k}
- Deformable Convolution v1:
- .. math::
- y(p) = \sum_{k=1}^{K}{w_k * x(p + p_k + \Delta p_k)}
- Where :math:`\Delta p_k` and :math:`\Delta m_k` are the learnable offset and modulation scalar for the k-th location,
- Which :math:`\Delta m_k` is one in deformable convolution v1. Please refer to `Deformable ConvNets v2: More Deformable, Better Results
- <https://arxiv.org/abs/1811.11168v2>`_ and `Deformable Convolutional Networks <https://arxiv.org/abs/1703.06211>`_.
- Example:
- - Input:
- Input shape: :math:`(N, C_{in}, H_{in}, W_{in})`
- Filter shape: :math:`(C_{out}, C_{in}, H_f, W_f)`
- Offset shape: :math:`(N, 2 * deformable\_groups * H_f * H_w, H_{in}, W_{in})`
- Mask shape: :math:`(N, deformable\_groups * H_f * H_w, H_{in}, W_{in})`
- - Output:
- Output shape: :math:`(N, C_{out}, H_{out}, W_{out})`
- Where
- .. math::
- H_{out}&= \frac{(H_{in} + 2 * paddings[0] - (dilations[0] * (H_f - 1) + 1))}{strides[0]} + 1 \\
- W_{out}&= \frac{(W_{in} + 2 * paddings[1] - (dilations[1] * (W_f - 1) + 1))}{strides[1]} + 1
- Args:
- input (Tensor): The input image with [N, C, H, W] format. A Tensor with type
- float32, float64.
- offset (Tensor): The input coordinate offset of deformable convolution layer.
- A Tensor with type float32, float64.
- Mask (Tensor, Optional): The input mask of deformable convolution layer.
- A Tensor with type float32, float64. It should be None when you use
- deformable convolution v1.
- num_filters(int): The number of filter. It is as same as the output
- image channel.
- filter_size (int|tuple): The filter size. If filter_size is a tuple,
- it must contain two integers, (filter_size_H, filter_size_W).
- Otherwise, the filter will be a square.
- stride (int|tuple): The stride size. If stride is a tuple, it must
- contain two integers, (stride_H, stride_W). Otherwise, the
- stride_H = stride_W = stride. Default: stride = 1.
- padding (int|tuple): The padding size. If padding is a tuple, it must
- contain two integers, (padding_H, padding_W). Otherwise, the
- padding_H = padding_W = padding. Default: padding = 0.
- dilation (int|tuple): The dilation size. If dilation is a tuple, it must
- contain two integers, (dilation_H, dilation_W). Otherwise, the
- dilation_H = dilation_W = dilation. Default: dilation = 1.
- groups (int): The groups number of the deformable conv layer. According to
- grouped convolution in Alex Krizhevsky's Deep CNN paper: when group=2,
- the first half of the filters is only connected to the first half
- of the input channels, while the second half of the filters is only
- connected to the second half of the input channels. Default: groups=1.
- deformable_groups (int): The number of deformable group partitions.
- Default: deformable_groups = 1.
- im2col_step (int): Maximum number of images per im2col computation;
- The total batch size should be devisable by this value or smaller
- than this value; if you face out of memory problem, you can try
- to use a smaller value here.
- Default: im2col_step = 64.
- param_attr (ParamAttr, Optional): The parameter attribute for learnable parameters/weights
- of deformable conv. If it is set to None or one attribute of ParamAttr,
- deformable conv will create ParamAttr as param_attr.
- If the Initializer of the param_attr is not set, the parameter is
- initialized with :math:`Normal(0.0, std)`, and the
- :math:`std` is :math:`(\\frac{2.0 }{filter\_elem\_num})^{0.5}`. Default: None.
- bias_attr (ParamAttr|bool, Optional): The parameter attribute for the bias of
- deformable conv layer. If it is set to False, no bias will be added
- to the output units. If it is set to None or one attribute of ParamAttr, conv2d
- will create ParamAttr as bias_attr. If the Initializer of the bias_attr
- is not set, the bias is initialized zero. Default: None.
- modulated (bool): Make sure which version should be used between v1 and v2, where v2 is \
- used while True. Default: True.
- name(str, Optional): For details, please refer to :ref:`api_guide_Name`.
- Generally, no setting is required. Default: None.
- Returns:
- Tensor: The tensor variable storing the deformable convolution \
- result. A Tensor with type float32, float64.
- Examples:
- .. code-block:: python
- >>> # deformable conv v2:
- >>> import paddle
- >>> paddle.enable_static()
- >>> C_in, H_in, W_in = 3, 32, 32
- >>> filter_size, deformable_groups = 3, 1
- >>> data = paddle.static.data(name='data', shape=[None, C_in, H_in, W_in], dtype='float32')
- >>> offset = paddle.static.data(name='offset', shape=[None, 2*deformable_groups*filter_size**2, H_in, W_in], dtype='float32')
- >>> mask = paddle.static.data(name='mask', shape=[None, deformable_groups*filter_size**2, H_in, W_in], dtype='float32')
- >>> out = paddle.static.nn.common.deformable_conv(input=data, offset=offset, mask=mask,
- ... num_filters=2, filter_size=filter_size, padding=1, modulated=True)
- >>> # deformable conv v1:
- >>> import paddle
- >>> C_in, H_in, W_in = 3, 32, 32
- >>> filter_size, deformable_groups = 3, 1
- >>> data = paddle.static.data(name='data', shape=[None, C_in, H_in, W_in], dtype='float32')
- >>> offset = paddle.static.data(name='offset', shape=[None, 2*deformable_groups*filter_size**2, H_in, W_in], dtype='float32')
- >>> out = paddle.static.nn.common.deformable_conv(input=data, offset=offset, mask=None,
- ... num_filters=2, filter_size=filter_size, padding=1, modulated=False)
- """
- check_variable_and_dtype(
- input, "input", ['float32', 'float64'], 'deformable_conv'
- )
- check_variable_and_dtype(
- offset, "offset", ['float32', 'float64'], 'deformable_conv'
- )
- check_type(
- mask, 'mask', (paddle.static.Variable, type(None)), 'deformable_conv'
- )
- if input.ndim != 4:
- raise ValueError(
- f'The input should be of [N, C, H, W] format, but received {input.shape}'
- )
- num_channels = input.shape[1]
- assert param_attr is not False, "param_attr should not be False here."
- helper = LayerHelper('deformable_conv', **locals())
- dtype = helper.input_dtype()
- if not isinstance(input, paddle.static.Variable):
- raise TypeError("Input of deformable_conv must be Tensor")
- if not isinstance(offset, paddle.static.Variable):
- raise TypeError("Input Offset of deformable_conv must be Tensor")
- if groups is None:
- num_filter_channels = num_channels
- else:
- if groups == 0:
- raise ValueError("groups should not be 0.")
- if num_channels % groups != 0:
- raise ValueError("num_channels must be divisible by groups.")
- num_filter_channels = num_channels // groups
- filter_size = paddle.utils.convert_to_list(filter_size, 2, 'filter_size')
- stride = paddle.utils.convert_to_list(stride, 2, 'stride')
- padding = paddle.utils.convert_to_list(padding, 2, 'padding')
- dilation = paddle.utils.convert_to_list(dilation, 2, 'dilation')
- input_shape = input.shape
- filter_shape = [num_filters, int(num_filter_channels)] + filter_size
- def _get_default_param_initializer():
- filter_elem_num = filter_size[0] * filter_size[1] * num_channels
- if filter_elem_num <= 0:
- raise ValueError(
- "Invalid filter number, excepted number is larger than 0, but"
- f" received {filter_elem_num}, please check the input shape and "
- "filter size."
- )
- std = (2.0 / filter_elem_num) ** 0.5
- return paddle.nn.initializer.normal.Normal(0.0, std)
- filter_param = helper.create_parameter(
- attr=helper.param_attr,
- shape=filter_shape,
- dtype=dtype,
- default_initializer=_get_default_param_initializer(),
- )
- pre_bias = helper.create_variable_for_type_inference(dtype)
- if modulated:
- helper.append_op(
- type='deformable_conv',
- inputs={
- 'Input': input,
- 'Filter': filter_param,
- 'Offset': offset,
- 'Mask': mask,
- },
- outputs={"Output": pre_bias},
- attrs={
- 'strides': stride,
- 'paddings': padding,
- 'dilations': dilation,
- 'groups': groups,
- 'deformable_groups': deformable_groups,
- 'im2col_step': im2col_step,
- },
- )
- else:
- helper.append_op(
- type='deformable_conv_v1',
- inputs={
- 'Input': input,
- 'Filter': filter_param,
- 'Offset': offset,
- },
- outputs={"Output": pre_bias},
- attrs={
- 'strides': stride,
- 'paddings': padding,
- 'dilations': dilation,
- 'groups': groups,
- 'deformable_groups': deformable_groups,
- 'im2col_step': im2col_step,
- },
- )
- output = helper.append_bias_op(pre_bias, dim_start=1, dim_end=2)
- return output
- @static_only
- def deform_conv2d(
- x,
- offset,
- mask,
- num_filters,
- filter_size,
- stride=1,
- padding=0,
- dilation=1,
- groups=1,
- deformable_groups=1,
- im2col_step=1,
- weight_attr=None,
- bias_attr=None,
- name=None,
- ):
- r"""
- Compute 2-D deformable convolution on 4-D input.
- Given input image x, output feature map y, the deformable convolution operation can be expressed as follow:
- Deformable Convolution v2:
- .. math::
- y(p) = \sum_{k=1}^{K}{w_k * x(p + p_k + \Delta p_k) * \Delta m_k}
- Deformable Convolution v1:
- .. math::
- y(p) = \sum_{k=1}^{K}{w_k * x(p + p_k + \Delta p_k)}
- Where :math:`\Delta p_k` and :math:`\Delta m_k` are the learnable offset and modulation scalar for the k-th location,
- Which :math:`\Delta m_k` is one in deformable convolution v1. Please refer to `Deformable ConvNets v2: More Deformable, Better Results
- <https://arxiv.org/abs/1811.11168v2>`_ and `Deformable Convolutional Networks <https://arxiv.org/abs/1703.06211>`_.
- Example:
- - Input:
- X shape: :math:`(N, C_{in}, H_{in}, W_{in})`
- Filter shape: :math:`(C_{out}, C_{in}, H_f, W_f)`
- Offset shape: :math:`(N, 2 * deformable\_groups * H_f * H_w, H_{in}, W_{in})`
- Mask shape: :math:`(N, deformable\_groups * H_f * H_w, H_{in}, W_{in})`
- - Output:
- Output shape: :math:`(N, C_{out}, H_{out}, W_{out})`
- Where
- .. math::
- H_{out}&= \frac{(H_{in} + 2 * paddings[0] - (dilations[0] * (H_f - 1) + 1))}{strides[0]} + 1 \\
- W_{out}&= \frac{(W_{in} + 2 * paddings[1] - (dilations[1] * (W_f - 1) + 1))}{strides[1]} + 1
- Args:
- x (Tensor): The input image with [N, C, H, W] format. A Tensor with type
- float32, float64.
- offset (Tensor): The input coordinate offset of deformable convolution layer.
- A Tensor with type float32, float64.
- mask (Tensor): The input mask of deformable convolution layer.
- A Tensor with type float32, float64. It should be None when you use
- deformable convolution v1.
- num_filters(int): The number of filter. It is as same as the output
- image channel.
- filter_size (int|list|tuple): The filter size. If filter_size is a list/tuple,
- it must contain two integers, (filter_size_H, filter_size_W).
- Otherwise, the filter will be a square.
- stride (int|list|tuple, Optional): The stride size. If stride is a list/tuple, it must
- contain two integers, (stride_H, stride_W). Otherwise, the
- stride_H = stride_W = stride. Default: stride = 1.
- padding (int|list|tuple, Optional): The padding size. If padding is a list/tuple, it must
- contain two integers, (padding_H, padding_W). Otherwise, the
- padding_H = padding_W = padding. Default: padding = 0.
- dilation (int|list|tuple, Optional): The dilation size. If dilation is a list/tuple, it must
- contain two integers, (dilation_H, dilation_W). Otherwise, the
- dilation_H = dilation_W = dilation. Default: dilation = 1.
- groups (int, Optional): The groups number of the deformable conv layer. According to
- grouped convolution in Alex Krizhevsky's Deep CNN paper: when group=2,
- the first half of the filters is only connected to the first half
- of the input channels, while the second half of the filters is only
- connected to the second half of the input channels. Default: groups=1.
- deformable_groups (int, Optional): The number of deformable group partitions.
- Default: deformable_groups = 1.
- im2col_step (int, Optional): Maximum number of images per im2col computation;
- The total batch size should be devisable by this value or smaller
- than this value; if you face out of memory problem, you can try
- to use a smaller value here.
- Default: im2col_step = 1.
- weight_attr (ParamAttr, Optional): The parameter attribute for learnable parameters/weights
- of deformable conv. If it is set to None or one attribute of ParamAttr,
- deformable conv will create ParamAttr as weight_attr.
- If the Initializer of the weight_attr is not set, the parameter is
- initialized with :math:`Normal(0.0, std)`, and the
- :math:`std` is :math:`(\frac{2.0 }{filter\_elem\_num})^{0.5}`. Default: None.
- bias_attr (ParamAttr|bool, Optional): The parameter attribute for the bias of
- deformable conv layer. If it is set to False, no bias will be added
- to the output units. If it is set to None or one attribute of ParamAttr, conv2d
- will create ParamAttr as bias_attr. If the Initializer of the bias_attr
- is not set, the bias is initialized zero. Default: None.
- name(str, Optional): For details, please refer to :ref:`api_guide_Name`.
- Generally, no setting is required. Default: None.
- Returns:
- Tensor: The tensor storing the deformable convolution result. A Tensor with type float32, float64.
- Examples:
- .. code-block:: python
- >>> # deformable conv v2:
- >>> import paddle
- >>> paddle.enable_static()
- >>> C_in, H_in, W_in = 3, 32, 32
- >>> filter_size, deformable_groups = 3, 1
- >>> data = paddle.static.data(name='data', shape=[None, C_in, H_in, W_in], dtype='float32')
- >>> offset = paddle.static.data(name='offset', shape=[None, 2*deformable_groups*filter_size**2, H_in, W_in], dtype='float32')
- >>> mask = paddle.static.data(name='mask', shape=[None, deformable_groups*filter_size**2, H_in, W_in], dtype='float32')
- >>> out = paddle.static.nn.deform_conv2d(x=data, offset=offset, mask=mask,
- ... num_filters=2, filter_size=filter_size, padding=1)
- >>> # deformable conv v1:
- >>> import paddle
- >>> paddle.enable_static()
- >>> C_in, H_in, W_in = 3, 32, 32
- >>> filter_size, deformable_groups = 3, 1
- >>> data = paddle.static.data(name='data', shape=[None, C_in, H_in, W_in], dtype='float32')
- >>> offset = paddle.static.data(name='offset', shape=[None, 2*deformable_groups*filter_size**2, H_in, W_in], dtype='float32')
- >>> out = paddle.static.nn.deform_conv2d(x=data, offset=offset, mask=None,
- ... num_filters=2, filter_size=filter_size, padding=1)
- """
- if mask is None:
- return deformable_conv(
- input=x,
- offset=offset,
- mask=mask,
- num_filters=num_filters,
- filter_size=filter_size,
- stride=stride,
- padding=padding,
- dilation=dilation,
- groups=groups,
- deformable_groups=deformable_groups,
- im2col_step=im2col_step,
- param_attr=weight_attr,
- bias_attr=bias_attr,
- modulated=False,
- name=name,
- )
- else:
- return deformable_conv(
- input=x,
- offset=offset,
- mask=mask,
- num_filters=num_filters,
- filter_size=filter_size,
- stride=stride,
- padding=padding,
- dilation=dilation,
- groups=groups,
- deformable_groups=deformable_groups,
- im2col_step=im2col_step,
- param_attr=weight_attr,
- bias_attr=bias_attr,
- modulated=True,
- name=name,
- )
- def bilinear_tensor_product(
- x, y, size, act=None, name=None, param_attr=None, bias_attr=None
- ):
- r"""
- This layer performs bilinear tensor product on two inputs.
- .. math::
- out_{i} = x * W_{i} * {y^\mathrm{T}}, i=0,1,...,size-1
- In this formula:
- - :math:`x`: the first input contains M elements, shape is [batch_size, M].
- - :math:`y`: the second input contains N elements, shape is [batch_size, N].
- - :math:`W_{i}`: the i-th learned weight, shape is [M, N].
- - :math:`out_{i}`: the i-th element of out, shape is [batch_size, size].
- - :math:`y^\mathrm{T}`: the transpose of :math:`y_{2}`.
- Args:
- x (Tensor): 2-D input tensor with shape [batch_size, M]. Data type
- is float32 or float64.
- y (Tensor): 2-D input tensor with shape [batch_size, N]. Data type
- should be same as **x**.
- size (int): The dimension of this layer.
- act (str|None): Activation to be applied to the output of this layer. Default None.
- name(str|None): For detailed information, please refer to
- :ref:`api_guide_Name` . Usually name is no need to set and None by default.
- param_attr (ParamAttr|None): To specify the weight parameter attribute.
- Default: None, which means the default weight parameter property is
- used. See usage for details in :ref:`api_paddle_ParamAttr` .
- bias_attr (ParamAttr|None): To specify the bias parameter attribute.
- Default: None, which means the default bias parameter property is
- used. See usage for details in :ref:`api_paddle_ParamAttr` .
- Returns:
- Tensor, A 2-D Tensor of shape [batch_size, size]. Data type is the same as input **x**.
- Examples:
- .. code-block:: python
- >>> import paddle
- >>> paddle.enable_static()
- >>> x = paddle.static.data("t1", shape=[-1, 5], dtype="float32")
- >>> y = paddle.static.data("t2", shape=[-1, 4], dtype="float32")
- >>> tensor = paddle.static.nn.bilinear_tensor_product(x, y, size=1000)
- """
- helper = LayerHelper('bilinear_tensor_product', **locals())
- dtype = helper.input_dtype('x')
- if len(x.shape) != 2 or len(y.shape) != 2:
- raise ValueError(
- f"Input x and y should be 2D tensor, but received x with the shape of {x.shape}, y with the shape of {y.shape}"
- )
- param_shape = [size, x.shape[1], y.shape[1]]
- w = helper.create_parameter(
- attr=helper.param_attr, shape=param_shape, dtype=dtype, is_bias=False
- )
- out = helper.create_variable_for_type_inference(dtype=dtype)
- inputs = {"X": x, "Y": y, "Weight": w}
- if helper.bias_attr:
- bias_size = [1, size]
- bias = helper.create_parameter(
- attr=helper.bias_attr, shape=bias_size, dtype=dtype, is_bias=True
- )
- inputs["Bias"] = bias
- helper.append_op(
- type="bilinear_tensor_product", inputs=inputs, outputs={"Out": out}
- )
- # add activation
- return helper.append_activation(out)
- def batch_norm(
- input,
- act=None,
- is_test=False,
- momentum=0.9,
- epsilon=1e-05,
- param_attr=None,
- bias_attr=None,
- data_layout='NCHW',
- in_place=False,
- name=None,
- moving_mean_name=None,
- moving_variance_name=None,
- do_model_average_for_mean_and_var=True,
- use_global_stats=False,
- ):
- r"""
- **Batch Normalization Layer**
- Can be used as a normalizer function for convolution or fully_connected operations.
- The required data format for this layer is one of the following:
- 1. NHWC `[batch, in_height, in_width, in_channels]`
- 2. NCHW `[batch, in_channels, in_height, in_width]`
- Refer to `Batch Normalization: Accelerating Deep Network Training by Reducing
- Internal Covariate Shift <https://arxiv.org/pdf/1502.03167.pdf>`_
- for more details.
- :math:`input` is the input features over a mini-batch.
- .. math::
- \mu_{\beta} &\gets \frac{1}{m} \sum_{i=1}^{m} x_i \qquad &//
- \ mini-batch\ mean \\
- \sigma_{\beta}^{2} &\gets \frac{1}{m} \sum_{i=1}^{m}(x_i -
- \mu_{\\beta})^2 \qquad &//\ mini-batch\ variance \\
- \hat{x_i} &\gets \frac{x_i - \mu_\beta} {\sqrt{
- \sigma_{\beta}^{2} + \epsilon}} \qquad &//\ normalize \\
- y_i &\gets \gamma \hat{x_i} + \beta \qquad &//\ scale\ and\ shift
- moving\_mean = moving\_mean * momentum + mini-batch\_mean * (1. - momentum) \\
- moving\_var = moving\_var * momentum + mini-batch\_var * (1. - momentum)
- moving_mean is global mean and moving_var is global variance.
- When use_global_stats = True, the :math:`\\mu_{\\beta}`
- and :math:`\\sigma_{\\beta}^{2}` are not the statistics of one mini-batch.
- They are global (or running) statistics. (It usually got from the
- pre-trained model.)
- The training and testing (or inference) have the same behavior:
- .. math::
- \hat{x_i} &\gets \frac{x_i - \mu_\beta} {\sqrt{
- \sigma_{\beta}^{2} + \epsilon}} \\
- y_i &\gets \gamma \hat{x_i} + \beta
- Note:
- if build_strategy.sync_batch_norm=True, the batch_norm in network will use
- sync_batch_norm automatically.
- `is_test = True` can only be used in test program and inference program, `is_test` CANNOT be set to True in train program, if you want to use global status from pre_train model in train program, please set `use_global_stats = True`.
- Args:
- input(Tensor): The rank of input Tensor can be 2, 3, 4, 5. The data type
- is float16 or float32 or float64.
- act(string, Default None): Activation type, linear|relu|prelu|...
- is_test (bool, Default False): A flag indicating whether it is in
- test phrase or not.
- momentum(float|Tensor, Default 0.9): The value used for the moving_mean and
- moving_var computation. This should be a float number or a 0-D Tensor with
- shape [] and data type as float32. The updated formula is:
- :math:`moving\_mean = moving\_mean * momentum + new\_mean * (1. - momentum)`
- :math:`moving\_var = moving\_var * momentum + new\_var * (1. - momentum)`
- Default is 0.9.
- epsilon(float, Default 1e-05): A value added to the denominator for
- numerical stability. Default is 1e-5.
- param_attr(ParamAttr|None): The parameter attribute for Parameter `scale`
- of batch_norm. If it is set to None or one attribute of ParamAttr, batch_norm
- will create ParamAttr as param_attr, the name of scale can be set in ParamAttr.
- If the Initializer of the param_attr is not set, the parameter is initialized
- with Xavier. Default: None.
- bias_attr(ParamAttr|None): The parameter attribute for the bias of batch_norm.
- If it is set to None or one attribute of ParamAttr, batch_norm
- will create ParamAttr as bias_attr, the name of bias can be set in ParamAttr.
- If the Initializer of the bias_attr is not set, the bias is initialized zero.
- Default: None.
- data_layout (str, optional): Specify the data format of the input, and the data format of the output
- will be consistent with that of the input. An optional string from: `"NCHW"`, `"NHWC"`.
- The default is `"NCHW"`. When it is `"NCHW"`, the data is stored in the order of:
- `[batch_size, input_channels, input_height, input_width]`.
- in_place(bool, Default False): Make the input and output of batch norm reuse memory.
- name(str|None): For detailed information, please refer to :ref:`api_guide_Name`.
- Usually name is no need to set and None by default.
- moving_mean_name(str, Default None): The name of moving_mean which store the global Mean. If it
- is set to None, batch_norm will save global mean with a random name, otherwise, batch_norm
- will save global mean with the string.
- moving_variance_name(str, Default None): The name of the moving_variance which store the global Variance.
- If it is set to None, batch_norm will save global variance with a random name, otherwise, batch_norm
- will save global variance with the string.
- do_model_average_for_mean_and_var(bool, Default True): Whether parameter mean and variance should do model
- average when model average is enabled.
- use_global_stats(bool, Default False): Whether to use global mean and
- variance. In inference or test mode, set use_global_stats to true
- or is_test to true, and the behavior is equivalent.
- In train mode, when setting use_global_stats True, the global mean
- and variance are also used during train period.
- Returns:
- A Tensor which is the result after applying batch normalization on the input,
- has same shape and data type with input.
- Examples:
- .. code-block:: python
- >>> import paddle
- >>> paddle.enable_static()
- >>> x = paddle.static.data(name='x', shape=[3, 7, 3, 7], dtype='float32')
- >>> hidden1 = paddle.static.nn.fc(x=x, size=200)
- >>> print(hidden1.shape)
- (3, 200)
- >>> hidden2 = paddle.static.nn.batch_norm(input=hidden1)
- >>> print(hidden2.shape)
- (3, 200)
- """
- assert (
- bias_attr is not False
- ), "bias_attr should not be False in batch_norm."
- helper = LayerHelper('batch_norm', **locals())
- check_variable_and_dtype(
- input,
- 'input',
- ['uint16', 'float16', 'float32', 'float64'],
- 'batch_norm',
- )
- dtype = helper.input_dtype()
- # use fp32 for bn parameter
- if dtype == paddle.float16 or dtype == paddle.bfloat16:
- dtype = paddle.float32
- input_shape = input.shape
- if len(input.shape) < 2 or len(input.shape) > 5:
- raise ValueError(
- f'expected 2D or 3D or 4D or 5D input (got {len(input.shape)}D input, input shape is: {input_shape})'
- )
- if data_layout == 'NCHW':
- channel_num = input_shape[1]
- else:
- if data_layout == 'NHWC':
- channel_num = input_shape[-1]
- else:
- raise ValueError("unsupported data layout:" + data_layout)
- param_shape = [channel_num]
- # create parameter
- scale = helper.create_parameter(
- attr=helper.param_attr,
- shape=param_shape,
- dtype=dtype,
- default_initializer=paddle.nn.initializer.Constant(1.0),
- )
- bias = helper.create_parameter(
- attr=helper.bias_attr, shape=param_shape, dtype=dtype, is_bias=True
- )
- mean = helper.create_parameter(
- attr=paddle.ParamAttr(
- name=moving_mean_name,
- initializer=paddle.nn.initializer.Constant(0.0),
- trainable=False,
- do_model_average=do_model_average_for_mean_and_var,
- ),
- shape=param_shape,
- dtype=dtype,
- )
- mean.stop_gradient = True
- variance = helper.create_parameter(
- attr=paddle.ParamAttr(
- name=moving_variance_name,
- initializer=paddle.nn.initializer.Constant(1.0),
- trainable=False,
- do_model_average=do_model_average_for_mean_and_var,
- ),
- shape=param_shape,
- dtype=dtype,
- )
- variance.stop_gradient = True
- # create output
- # mean and mean_out share the same memory
- mean_out = mean
- # variance and variance_out share the same memory
- variance_out = variance
- if in_dygraph_mode():
- inputs_has_MomentumTensor = False
- attrs_has_momentum = False
- tmp_tensor_type = core.eager.Tensor
- if isinstance(momentum, tmp_tensor_type):
- inputs_has_MomentumTensor = True
- else:
- attrs_has_momentum = True
- attrs_ = ()
- if attrs_has_momentum:
- attrs_ = (
- 'momentum',
- momentum,
- 'epsilon',
- epsilon,
- 'is_test',
- is_test,
- 'data_layout',
- data_layout,
- 'fuse_with_relu',
- False,
- 'use_global_stats',
- use_global_stats,
- )
- else:
- attrs_ = (
- 'epsilon',
- epsilon,
- 'is_test',
- is_test,
- 'data_layout',
- data_layout,
- 'fuse_with_relu',
- False,
- 'use_global_stats',
- use_global_stats,
- )
- if inputs_has_MomentumTensor:
- batch_norm_out, _, _, _, _, _ = paddle._legacy_C_ops.batch_norm(
- input,
- scale,
- bias,
- mean,
- variance,
- momentum,
- mean_out,
- variance_out,
- *attrs_,
- )
- else:
- batch_norm_out, _, _, _, _, _ = paddle._legacy_C_ops.batch_norm(
- input,
- scale,
- bias,
- mean,
- variance,
- None,
- mean_out,
- variance_out,
- *attrs_,
- )
- return paddle.base.dygraph_utils._append_activation_in_dygraph(
- batch_norm_out, act=act
- )
- saved_mean = helper.create_variable_for_type_inference(
- dtype=dtype, stop_gradient=True
- )
- saved_variance = helper.create_variable_for_type_inference(
- dtype=dtype, stop_gradient=True
- )
- reserve_space = None
- if not is_test:
- reserve_space = helper.create_variable_for_type_inference(
- dtype=helper.input_dtype(), stop_gradient=True
- )
- batch_norm_out = (
- input if in_place else helper.create_variable_for_type_inference(dtype)
- )
- inputs = {
- "X": input,
- "Scale": scale,
- "Bias": bias,
- "Mean": mean,
- "Variance": variance,
- "MeanOut": mean_out,
- "VarianceOut": variance_out,
- }
- attrs = {
- "epsilon": epsilon,
- "is_test": is_test,
- "data_layout": data_layout,
- "fuse_with_relu": False,
- "use_global_stats": use_global_stats,
- }
- if isinstance(momentum, paddle.static.Variable):
- inputs['MomemtumTensor'] = momentum
- else:
- attrs['momentum'] = momentum
- outputs = {
- "Y": batch_norm_out,
- "MeanOut": mean_out,
- "VarianceOut": variance_out,
- "SavedMean": saved_mean,
- "SavedVariance": saved_variance,
- }
- if reserve_space is not None:
- outputs["ReserveSpace"] = reserve_space
- helper.append_op(
- type="batch_norm", inputs=inputs, outputs=outputs, attrs=attrs
- )
- return helper.append_activation(batch_norm_out)
- @static_only
- def prelu(x, mode, param_attr=None, data_format="NCHW", name=None):
- r"""
- prelu activation.
- .. math::
- prelu(x) = max(0, x) + \alpha * min(0, x)
- There are three modes for the activation:
- .. code-block:: text
- all: All elements share same alpha.
- channel: Elements in same channel share same alpha.
- element: All elements do not share alpha. Each element has its own alpha.
- Parameters:
- x (Tensor): The input Tensor or LoDTensor with data type float32.
- mode (str): The mode for weight sharing.
- param_attr (ParamAttr|None, optional): The parameter attribute for the learnable \
- weight (alpha), it can be create by ParamAttr. None by default. \
- For detailed information, please refer to :ref:`api_paddle_ParamAttr`.
- data_format(str, optional): Data format that specifies the layout of input.
- It may be "NC", "NCL", "NCHW", "NCDHW", "NLC", "NHWC" or "NDHWC". Default: "NCHW".
- name (str, optional): Name for the operation (optional, default is None). \
- For more information, please refer to :ref:`api_guide_Name`.
- Returns:
- Tensor: A tensor with the same shape and data type as x.
- Examples:
- .. code-block:: python
- >>> import paddle
- >>> paddle.enable_static()
- >>> x = paddle.static.data(name="x", shape=[None, 5, 10, 10], dtype="float32")
- >>> mode = 'channel'
- >>> output = paddle.static.nn.prelu(
- ... x,mode,param_attr=paddle.ParamAttr(name='alpha'))
- """
- check_variable_and_dtype(x, 'x', ['float16', 'float32', 'float64'], 'prelu')
- helper = LayerHelper('prelu', **locals())
- if mode not in ['all', 'channel', 'element']:
- raise ValueError('mode should be one of all, channel, element.')
- alpha_shape = [1]
- if mode == 'channel':
- true_data_format = [
- 'NC',
- 'NCL',
- 'NCHW',
- 'NCDHW',
- 'NLC',
- 'NHWC',
- 'NDHWC',
- ]
- if data_format not in true_data_format:
- raise ValueError(
- "data_format must be one of 'NC', 'NCL', 'NCHW', 'NCDHW', "
- f"'NLC', 'NHWC', 'NDHWC' but receive {data_format}"
- )
- data_format = 'NCHW' if data_format[1] == 'C' else 'NHWC'
- assert (
- len(x.shape) >= 2
- ), "The size of input shape should be equal or larger than 2 in prelu() when mode is 'channel'"
- # NOTE(zhiqiu): The alpha_shape should be [1, channel] + [1] * len(x.shape[2:]).
- # To be consistent with Prelu, it is simplified.
- # NOTE(zhiqiu): Revert shape to [1, channel, 1, 1] for compatibility with saved model of old version.
- # NOTE(GuoxiaWang): support NHWC data format
- if data_format == 'NHWC':
- alpha_shape = [1, 1, 1, x.shape[-1]]
- else:
- alpha_shape = [1, x.shape[1], 1, 1]
- elif mode == 'element':
- assert (
- len(x.shape) >= 1
- ), "The size of input shape should be equal or larger than 1 in prelu() when mode is 'element'"
- alpha_shape = [1] + list(x.shape)[1:]
- dtype = helper.input_dtype(input_param_name='x')
- alpha = helper.create_parameter(
- attr=helper.param_attr,
- shape=alpha_shape,
- dtype=dtype,
- is_bias=False,
- default_initializer=paddle.nn.initializer.Constant(0.25),
- )
- out = helper.create_variable_for_type_inference(dtype)
- helper.append_op(
- type="prelu",
- inputs={"X": x, 'Alpha': alpha},
- attrs={"mode": mode, "data_format": data_format},
- outputs={"Out": out},
- )
- return out
- class PyFuncRegistry:
- _register_funcs = []
- def __init__(self, func):
- if func is None or not callable(func):
- raise TypeError('func must be a Python function')
- self._func = func
- # find named args using reflection
- args = inspect.getfullargspec(self._func)
- if len(args[0]) == 0 and args[1] is None and args[2] is None:
- # Function with no inputs
- self._named_args = None
- else:
- self._named_args = args[0]
- self._id = core._append_python_callable_object_and_return_id(self)
- '''
- Why record self here?
- 1. For debug usage. Users can call
- :code:`py_func.registered_func(idx)` method
- to find the registered function corresponding
- to :code:`idx`.
- 2. For increasing reference count of self.
- It seems that to release Python object
- whose reference count is 1 would cause
- segmentation fault error in C++ side.
- May be lack of Python GC in C++ side?
- '''
- PyFuncRegistry._register_funcs.append(self)
- @classmethod
- def registered_func(cls, idx):
- return cls._register_funcs[idx]._func
- @classmethod
- def registered_func_num(cls):
- return len(cls._register_funcs)
- @property
- def id(self):
- return self._id
- def __call__(self, *args):
- if self._named_args is None:
- func_ret = self._func()
- else:
- kwargs = {}
- idx = 0
- for arg in self._named_args:
- kwargs[arg] = args[idx]
- idx += 1
- func_ret = self._func(*args[idx:], **kwargs)
- if not isinstance(func_ret, (list, tuple)):
- func_ret = (func_ret,)
- ret = []
- for each_ret in func_ret:
- if each_ret is None or isinstance(each_ret, core.LoDTensor):
- ret.append(each_ret)
- continue
- if not isinstance(each_ret, np.ndarray):
- each_ret = np.array(each_ret)
- tensor = core.LoDTensor()
- tensor.set(each_ret, core.CPUPlace())
- ret.append(tensor)
- return tuple(ret)
- @static_only
- def py_func(func, x, out, backward_func=None, skip_vars_in_backward_input=None):
- """
- This is used to register customized Python OP to Paddle. The design
- principe of py_func is that Tensor and numpy array can be converted to each
- other easily. So you can use Python and numpy API to register a python OP.
- The forward function of the registered OP is ``func`` and the backward function
- of that is ``backward_func``. Paddle will call ``func`` at forward runtime and
- call ``backward_func`` at backward runtime(if ``backward_func`` is not None).
- ``x`` is the input of ``func``, whose type must be Tensor; ``out`` is
- the output of ``func``, whose type can be either Tensor or numpy array.
- The input of the backward function ``backward_func`` is ``x``, ``out`` and
- the gradient of ``out``. If ``out`` have no gradient, the relevant input of
- ``backward_func`` is None. If ``x`` do not have a gradient, the user should
- return None in ``backward_func``.
- The data type and shape of ``out`` should also be set correctly before this
- API is called, and the data type and shape of the gradient of ``out`` and
- ``x`` will be inferred automatically.
- This API can also be used to debug the neural network by setting the ``func``
- as a function that only print variables.
- Args:
- func (callable): The forward function of the registered OP. When the network
- is running, the forward output ``out`` will be calculated according to this
- function and the forward input ``x``. In ``func`` , it's suggested that we
- actively convert Tensor into a numpy array, so that we can use Python and
- numpy API arbitrarily. If not, some operations of numpy may not be compatible.
- x (Tensor|tuple(Tensor)|list[Tensor]): The input of the forward function ``func``.
- It can be Tensor|tuple(Tensor)|list[Tensor]. In addition, Multiple Tensor
- should be passed in the form of tuple(Tensor) or list[Tensor].
- out (T|tuple(T)|list[T]): The output of the forward function ``func``, it can be
- T|tuple(T)|list[T], where T can be either Tensor or numpy array. Since Paddle
- cannot automatically infer the shape and type of ``out``, you must create
- ``out`` in advance.
- backward_func (callable, optional): The backward function of the registered OP.
- Its default value is None, which means there is no reverse calculation. If
- it is not None, ``backward_func`` is called to calculate the gradient of
- ``x`` when the network is at backward runtime.
- skip_vars_in_backward_input (Tensor, optional): It's used to limit the input
- list of ``backward_func``, and it can be Tensor|tuple(Tensor)|list[Tensor].
- It must belong to either ``x`` or ``out``. The default value is None, which means
- that no tensors need to be removed from ``x`` and ``out``. If it is not None,
- these tensors will not be the input of ``backward_func``. This parameter is only
- useful when ``backward_func`` is not None.
- Returns:
- Tensor|tuple(Tensor)|list[Tensor], The output ``out`` of the forward function ``func``.
- Examples:
- .. code-block:: python
- :name: code-example1
- >>> import paddle
- >>> import numpy as np
- >>> np.random.seed(1107)
- >>> paddle.seed(1107)
- >>> paddle.enable_static()
- >>> # Creates a forward function, Tensor can be input directly without
- >>> # being converted into numpy array.
- >>> def tanh(x):
- ... return np.tanh(x)
- >>> # Skip x in backward function and return the gradient of x
- >>> # Tensor must be actively converted to numpy array, otherwise,
- >>> # operations such as +/- can't be used.
- >>> def tanh_grad(y, dy):
- ... return np.array(dy) * (1 - np.square(np.array(y)))
- >>> # Creates a forward function for debugging running networks(print value)
- >>> def debug_func(x):
- ... # print(x)
- ... pass
- >>> def create_tmp_var(name, dtype, shape):
- ... return paddle.static.default_main_program().current_block().create_var(
- ... name=name, dtype=dtype, shape=shape)
- >>> def simple_net(img, label):
- ... hidden = img
- ... for idx in range(4):
- ... hidden = paddle.static.nn.fc(hidden, size=200)
- ... new_hidden = create_tmp_var(name='hidden_{}'.format(idx),
- ... dtype=hidden.dtype, shape=hidden.shape)
- ... # User-defined forward and backward
- ... hidden = paddle.static.py_func(func=tanh, x=hidden,
- ... out=new_hidden, backward_func=tanh_grad,
- ... skip_vars_in_backward_input=hidden)
- ... # User-defined debug functions that print out the input Tensor
- ... paddle.static.py_func(func=debug_func, x=hidden, out=None)
- ... prediction = paddle.static.nn.fc(hidden, size=10, activation='softmax')
- ... ce_loss = paddle.nn.loss.CrossEntropyLoss()
- ... return ce_loss(prediction, label)
- >>> x = paddle.static.data(name='x', shape=[1,4], dtype='float32')
- >>> y = paddle.static.data(name='y', shape=[1], dtype='int64')
- >>> res = simple_net(x, y)
- >>> exe = paddle.static.Executor(paddle.CPUPlace())
- >>> exe.run(paddle.static.default_startup_program())
- >>> input1 = np.random.random(size=[1,4]).astype('float32')
- >>> input2 = np.random.randint(1, 10, size=[1], dtype='int64')
- >>> out = exe.run(paddle.static.default_main_program(),
- ... feed={'x':input1, 'y':input2},
- ... fetch_list=[res.name])
- >>> print(out[0].shape)
- ()
- .. code-block:: python
- :name: code-example2
- >>> # This example shows how to turn Tensor into numpy array and
- >>> # use numpy API to register an Python OP
- >>> import paddle
- >>> import numpy as np
- >>> np.random.seed(1107)
- >>> paddle.seed(1107)
- >>> paddle.enable_static()
- >>> def element_wise_add(x, y):
- ... # Tensor must be actively converted to numpy array, otherwise,
- ... # numpy.shape can't be used.
- ... x = np.array(x)
- ... y = np.array(y)
- ... if x.shape != y.shape:
- ... raise AssertionError("the shape of inputs must be the same!")
- ... result = np.zeros(x.shape, dtype='int32')
- ... for i in range(len(x)):
- ... for j in range(len(x[0])):
- ... result[i][j] = x[i][j] + y[i][j]
- ... return result
- >>> def create_tmp_var(name, dtype, shape):
- ... return paddle.static.default_main_program().current_block().create_var(
- ... name=name, dtype=dtype, shape=shape)
- >>> def py_func_demo():
- ... start_program = paddle.static.default_startup_program()
- ... main_program = paddle.static.default_main_program()
- ... # Input of the forward function
- ... x = paddle.static.data(name='x', shape=[2, 3], dtype='int32')
- ... y = paddle.static.data(name='y', shape=[2, 3], dtype='int32')
- ... # Output of the forward function, name/dtype/shape must be specified
- ... output = create_tmp_var('output','int32', [3, 1])
- ... # Multiple Tensor should be passed in the form of tuple(Tensor) or list[Tensor]
- ... paddle.static.py_func(func=element_wise_add, x=[x, y], out=output)
- ... exe=paddle.static.Executor(paddle.CPUPlace())
- ... exe.run(start_program)
- ... # Feed numpy array to main_program
- ... input1 = np.random.randint(1, 10, size=[2, 3], dtype='int32')
- ... input2 = np.random.randint(1, 10, size=[2, 3], dtype='int32')
- ... out = exe.run(main_program,
- ... feed={'x':input1, 'y':input2},
- ... fetch_list=[output.name])
- ... print("{0} + {1} = {2}".format(input1, input2, out))
- >>> py_func_demo()
- >>> # [[1 5 4] + [[3 7 7] = [array([[ 4, 12, 11]
- >>> # [9 4 8]] [2 3 9]] [11, 7, 17]], dtype=int32)]
- """
- helper = LayerHelper('py_func', **locals())
- check_type(x, 'X', (list, tuple, Variable, type(None)), 'py_func')
- if x is None:
- x = []
- elif isinstance(x, Variable):
- x = [x]
- elif isinstance(x, tuple):
- x = list(x)
- elif not isinstance(x, (list, tuple, Variable)):
- raise TypeError('Input must be Tensor/list(Tensor)/tuple(Tensor)')
- check_type(out, 'Out', (list, tuple, Variable, type(None)), 'py_func')
- if out is None:
- out_list = []
- elif isinstance(out, Variable):
- out_list = [out]
- elif isinstance(out, tuple):
- out_list = list(out)
- elif isinstance(out, list):
- out_list = out
- else:
- raise TypeError('Output must be Tensor/list(Tensor)/tuple(Tensor)')
- fwd_func_id = PyFuncRegistry(func).id
- bwd_func_id = (
- PyFuncRegistry(backward_func).id if backward_func is not None else -1
- )
- for each_out in out_list:
- if len(each_out.shape) == 0:
- raise ValueError(
- 'Output shapes of py_func should be provided by users manually'
- )
- backward_skip_vars = set()
- if backward_func is not None and skip_vars_in_backward_input is not None:
- if isinstance(skip_vars_in_backward_input, Variable):
- skip_vars_in_backward_input = [skip_vars_in_backward_input]
- fwd_in_out = [v.name for v in x]
- fwd_in_out.extend([v.name for v in out_list])
- fwd_in_out = set(fwd_in_out)
- backward_skip_vars = set()
- for v in skip_vars_in_backward_input:
- if v.name not in fwd_in_out:
- raise ValueError(
- f'Tensor {v.name} is not found in forward inputs and outputs'
- )
- backward_skip_vars.add(v.name)
- helper.append_op(
- type='py_func',
- inputs={'X': x},
- outputs={'Out': out_list},
- attrs={
- 'forward_callable_id': fwd_func_id,
- 'backward_callable_id': bwd_func_id,
- 'backward_skip_vars': list(backward_skip_vars),
- },
- )
- return out
- def row_conv(input, future_context_size, param_attr=None, act=None):
- r"""
- :api_attr: Static Graph
- The row convolution is called lookahead convolution. It was
- introduced in the following paper for DeepSpeech2:
- http://www.cs.cmu.edu/~dyogatam/papers/wang+etal.iclrworkshop2016.pdf
- The main motivation is that a bidirectional RNN, useful in DeepSpeech
- like speech models, learns representation for a sequence by performing a
- forward and a backward pass through the entire sequence. However, unlike
- unidirectional RNNs, bidirectional RNNs are challenging to deploy in an online
- and low-latency setting. The lookahead convolution incorporates information
- from future subsequences in a computationally efficient manner to improve
- unidirectional recurrent neural networks. The row convolution is
- different from the 1D sequence convolution, and is computed as follows:
- Given an input sequence :math:`X` of length :math:`t` and input dimension :math:`D`,
- and a filter (:math:`W`) of size :math:`context \times D`,
- the output sequence is convolved as:
- .. math::
- Out_{i} = \sum_{j=i}^{i + context - 1} X_{j} \cdot W_{j-i}
- In the above equation:
- * :math:`Out_{i}`: The i-th row of output variable with shape [1, D].
- * :math:`context`: Future context size.
- * :math:`X_{j}`: The j-th row of input variable with shape [1, D].
- * :math:`W_{j-i}`: The (j-i)-th row of parameters with shape [1, D].
- More details about row_conv please refer to
- the design document
- https://github.com/PaddlePaddle/Paddle/issues/2228#issuecomment-303903645 .
- Args:
- input (Tensor): The input is a Tensor, the shape of Tensor input has shape
- (B x T x N), B is batch size.
- future_context_size (int): Future context size. Please note, the shape
- of convolution kernel is [future_context_size + 1, D].
- param_attr (ParamAttr): Attributes of parameters, including
- name, initializer etc.
- act (str): Non-linear activation to be applied to output Tensor.
- Returns:
- Tensor: The output is a Tensor, which has same type and same shape as input.
- Examples:
- .. code-block:: python
- >>> # for LodTensor inputs
- >>> import paddle
- >>> paddle.enable_static()
- >>> x = paddle.static.data(name='x', shape=[9, 16],
- ... dtype='float32', lod_level=1)
- >>> out_x = paddle.static.nn.row_conv(input=x, future_context_size=2)
- >>> # for Tensor inputs
- >>> y = paddle.static.data(name='y', shape=[9, 4, 16], dtype='float32')
- >>> out_y = paddle.static.nn.row_conv(input=y, future_context_size=2)
- """
- helper = LayerHelper('row_conv', **locals())
- check_variable_and_dtype(input, 'input', ['float32'], 'row_conv')
- dtype = helper.input_dtype()
- filter_shape = [future_context_size + 1, input.shape[-1]]
- filter_param = helper.create_parameter(
- attr=helper.param_attr, shape=filter_shape, dtype=dtype
- )
- out = helper.create_variable_for_type_inference(dtype)
- helper.append_op(
- type='row_conv',
- inputs={'X': [input], 'Filter': [filter_param]},
- outputs={'Out': [out]},
- )
- return helper.append_activation(out)
- def spectral_norm(weight, dim=0, power_iters=1, eps=1e-12, name=None):
- r"""
- :api_attr: Static Graph
- **Spectral Normalization Layer**
- This operation calculates the spectral normalization value of weight parameters of
- fc, conv1d, conv2d, conv3d layers which should be 2-D, 3-D, 4-D, 5-D
- Parameters. Output tensor will be in same shape with input tensor.
- Calculations are showed as follows.
- Step 1:
- Generate vector U in shape of [H], and V in shape of [W].
- While H is the :attr:`dim` th dimension of the input weights,
- and W is the product result of remaining dimensions.
- Step 2:
- :attr:`power_iters` should be a positive integer, do following
- calculations with U and V for :attr:`power_iters` rounds. Calculations
- as follows:
- .. math::
- \mathbf{v} := \\frac{\mathbf{W}^{T} \mathbf{u}}{\|\mathbf{W}^{T} \mathbf{u}\|_2}
- \mathbf{u} := \\frac{\mathbf{W}^{T} \mathbf{v}}{\|\mathbf{W}^{T} \mathbf{v}\|_2}
- Step 3:
- Calculate :math:`\sigma(\mathbf{W})` and normalize weight values.
- .. math::
- \sigma(\mathbf{W}) = \mathbf{u}^{T} \mathbf{W} \mathbf{v}
- \mathbf{W} = \\frac{\mathbf{W}}{\sigma(\mathbf{W})}
- Refer to `Spectral Normalization <https://arxiv.org/abs/1802.05957>`_ .
- Args:
- weight(Tensor): The input weight tensor of spectral_norm operator,
- This can be a 2-D, 3-D, 4-D, 5-D tensor which is the
- weights of fc, conv1d, conv2d, conv3d layer.
- The data type is float32 or float64.
- dim(int): The index of dimension which should be permuted
- to the first before reshaping Input(Weight) to
- matrix, it should be set as 0 if Input(Weight) is
- the weight of fc layer, and should be set as 1 if
- Input(Weight) is the weight of conv layer, default 0.
- power_iters(int): number of power iterations to calculate spectral norm, default 1.
- eps(float): epsilon for numerical stability in calculating norms, it will be added to
- the denominator to avoid divide zero. Default 1e-12.
- name(str, optional): For detailed information, please refer
- to :ref:`api_guide_Name`. Usually name is no need to set and
- None by default.
- Returns:
- Tensor: A tensor of weight parameters after spectral normalization.
- The data type and shape is same as input tensor.
- Examples:
- .. code-block:: python
- >>> import paddle
- >>> paddle.enable_static()
- >>> weight = paddle.static.data(name='weight', shape=[2, 8, 32, 32], dtype='float32')
- >>> x = paddle.static.nn.spectral_norm(weight=weight, dim=1, power_iters=2)
- >>> print(x.shape)
- (2, 8, 32, 32)
- """
- helper = LayerHelper('spectral_norm', **locals())
- check_variable_and_dtype(
- weight, 'weight', ['float32', 'float64'], 'spectral_norm'
- )
- check_type(dim, 'dim', int, 'spectral_norm')
- check_type(power_iters, 'power_iters', int, 'spectral_norm')
- check_type(eps, 'eps', float, 'spectral_norm')
- dtype = weight.dtype
- # create input and parameters
- input_shape = weight.shape
- assert weight.numel() > 0, "Any dimension of input cannot be equal to 0."
- if dim not in [0, 1]:
- raise ValueError(
- f"The input `dim` must be 0 (if weight in fc) or 1 (if weight in conv), but received dim={dim}"
- )
- h = input_shape[dim]
- w = np.prod(input_shape) // h
- u = helper.create_parameter(
- attr=ParamAttr(),
- shape=[h],
- dtype=dtype,
- default_initializer=Normal(0.0, 1.0),
- )
- u.stop_gradient = True
- v = helper.create_parameter(
- attr=ParamAttr(),
- shape=[w],
- dtype=dtype,
- default_initializer=Normal(0.0, 1.0),
- )
- v.stop_gradient = True
- if in_dynamic_or_pir_mode():
- return paddle._C_ops.spectral_norm(weight, u, v, dim, power_iters, eps)
- inputs = {'Weight': weight}
- inputs['U'] = u
- inputs['V'] = v
- # create output
- out = helper.create_variable(dtype=dtype)
- helper.append_op(
- type="spectral_norm",
- inputs=inputs,
- outputs={
- "Out": out,
- },
- attrs={
- "dim": dim,
- "power_iters": power_iters,
- "eps": eps,
- },
- )
- return out
- # For debug usage
- py_func.registered_func = PyFuncRegistry.registered_func
- py_func.registered_func_num = PyFuncRegistry.registered_func_num
- def layer_norm(
- input,
- scale=True,
- shift=True,
- begin_norm_axis=1,
- epsilon=1e-05,
- param_attr=None,
- bias_attr=None,
- act=None,
- name=None,
- ):
- r"""
- **Layer Normalization Layer**
- The API implements the function of the Layer Normalization Layer and can be applied to mini-batch input data.
- Refer to `Layer Normalization <https://arxiv.org/pdf/1607.06450v1.pdf>`_
- The formula is as follows:
- .. math::
- \mu & = \frac{1}{H}\sum_{i=1}^{H} x_i
- \sigma & = \sqrt{\frac{1}{H}\sum_{i=1}^{H}{(x_i - \mu)^2} + \epsilon}
- y & = f(\frac{g}{\sigma}(x - \mu) + b)
- - :math:`x`: the vector representation of the summed inputs to the neurons in that layer.
- - :math:`H`: the number of hidden units in a layers
- - :math:`\\epsilon`: the small value added to the variance to prevent division by zero.
- - :math:`g`: the trainable scale parameter.
- - :math:`b`: the trainable bias parameter.
- Args:
- input(Tensor): A multi-dimension ``Tensor`` , and the data type is float32 or float64.
- scale(bool, optional): Whether to learn the adaptive gain :math:`g` after
- normalization. Default: True.
- shift(bool, optional): Whether to learn the adaptive bias :math:`b` after
- normalization. Default: True.
- begin_norm_axis(int, optional): The normalization will be performed along
- dimensions from :attr:`begin_norm_axis` to :attr:`rank(input)`.
- Default: 1.
- epsilon(float, optional): The small value added to the variance to prevent
- division by zero. Default: 1e-05.
- param_attr(ParamAttr, optional): The parameter attribute for the learnable
- gain :math:`g`. If :attr:`scale` is False, :attr:`param_attr` is
- omitted. If :attr:`scale` is True and :attr:`param_attr` is None,
- a default :code:`ParamAttr` would be added as scale. The
- :attr:`param_attr` is initialized as 1 if it is added. Default: None.
- bias_attr(ParamAttr, optional): The parameter attribute for the learnable
- bias :math:`b`. If :attr:`shift` is False, :attr:`bias_attr` is
- omitted. If :attr:`shift` is True and :attr:`param_attr` is None,
- a default :code:`ParamAttr` would be added as bias. The
- :attr:`bias_attr` is initialized as 0 if it is added. Default: None.
- act(str, optional): Activation to be applied to the output of layer normalization.
- Default: None.
- name(str, optional): The default value is None. Normally there is no need for user to set this property. For more information, please refer to :ref:`api_guide_Name` .
- Returns:
- Tensor: ``Tensor`` indicating the normalized result, the data type is the same as ``input`` , and the return dimension is the same as ``input`` .
- Examples:
- .. code-block:: python
- >>> import paddle
- >>> paddle.enable_static()
- >>> x = paddle.static.data(name='x', shape=[8, 32, 32], dtype='float32')
- >>> output = paddle.static.nn.layer_norm(input=x, begin_norm_axis=1)
- >>> print(output.shape)
- (8, 32, 32)
- """
- assert (
- in_dygraph_mode() is not True
- ), "please use LayerNorm instead of layer_norm in dygraph mode!"
- helper = LayerHelper('layer_norm', **locals())
- check_variable_and_dtype(
- input, 'input', ['float32', 'float64'], 'layer_norm'
- )
- dtype = helper.input_dtype()
- # create input and parameters
- inputs = {'X': input}
- input_shape = input.shape
- param_shape = [reduce(lambda x, y: x * y, input_shape[begin_norm_axis:], 1)]
- if scale:
- assert (
- param_attr is not False
- ), "param_attr should not be False when using scale."
- scale = helper.create_parameter(
- attr=helper.param_attr,
- shape=param_shape,
- dtype=dtype,
- default_initializer=Constant(1.0),
- )
- inputs['Scale'] = scale
- else:
- if param_attr:
- warnings.warn("param_attr is only available with scale is True.")
- if shift:
- assert (
- bias_attr is not False
- ), "bias_attr should not be False when using shift."
- bias = helper.create_parameter(
- attr=helper.bias_attr, shape=param_shape, dtype=dtype, is_bias=True
- )
- inputs['Bias'] = bias
- else:
- if bias_attr:
- warnings.warn("bias_attr is only available with shift is True.")
- # create output
- mean_out = helper.create_variable_for_type_inference(
- dtype=dtype, stop_gradient=True
- )
- variance_out = helper.create_variable_for_type_inference(
- dtype=dtype, stop_gradient=True
- )
- layer_norm_out = helper.create_variable_for_type_inference(dtype)
- helper.append_op(
- type="layer_norm",
- inputs=inputs,
- outputs={
- "Y": layer_norm_out,
- "Mean": mean_out,
- "Variance": variance_out,
- },
- attrs={"epsilon": epsilon, "begin_norm_axis": begin_norm_axis},
- )
- return helper.append_activation(layer_norm_out)
- @static_only
- def embedding(
- input,
- size,
- is_sparse=False,
- is_distributed=False,
- padding_idx=None,
- param_attr=None,
- dtype='float32',
- ):
- r"""
- :api_attr: Static Graph
- The operator is used to lookup embeddings vector of ids provided by :attr:`input` .
- It automatically constructs a 2D embedding matrix based on the
- input :attr:`size` (vocab_size, emb_size) and :attr:`dtype` .
- The shape of output Tensor is generated by appending an emb_size dimension to the
- last dimension of the input Tensor shape.
- **Note:** The id in :attr:`input` must satisfy :math:`0 =< id < size[0]` ,
- otherwise the program will throw an exception and exit.
- .. code-block:: text
- Case 1:
- input is a Tensor. padding_idx = -1
- input.data = [[1, 3], [2, 4], [4, 127]]
- input.shape = [3, 2]
- Given size = [128, 16]
- output is a Tensor:
- out.shape = [3, 2, 16]
- out.data = [[[0.129435295, 0.244512452, ..., 0.436322452],
- [0.345421456, 0.524563927, ..., 0.144534654]],
- [[0.345249859, 0.124939536, ..., 0.194353745],
- [0.945345345, 0.435394634, ..., 0.435345365]],
- [[0.945345345, 0.435394634, ..., 0.435345365],
- [0.0, 0.0, ..., 0.0 ]]] # padding data
- The input padding_idx is less than 0, it is automatically converted to padding_idx = -1 + 128 = 127
- It will pad all-zero data when ids is 127.
- Case 2:
- input is a LoDTensor with 1-level LoD. padding_idx = 0
- input.lod = [[2, 3]]
- input.data = [[1], [3], [2], [4], [0]]
- input.shape = [5, 1]
- Given size = [128, 16]
- output is a LoDTensor:
- out.lod = [[2, 3]]
- out.shape = [5, 1, 16]
- out.data = [[[0.129435295, 0.244512452, ..., 0.436322452]],
- [[0.345421456, 0.524563927, ..., 0.144534654]],
- [[0.345249859, 0.124939536, ..., 0.194353745]],
- [[0.945345345, 0.435394634, ..., 0.435345365]],
- [[0.0, 0.0, ..., 0.0 ]]] # padding data
- It will pad all-zero data when ids is 0.
- Args:
- input(Tensor): A Tensor or LoDTensor with type int64, which contains the id information.
- The value of the input id should satisfy :math:`0<= id < size[0]` .
- size(tuple|list): The shape of lookup table parameter. It should have two elements which
- indicates the size of the dictionary of embeddings and the size of each embedding vector respectively.
- is_sparse(bool): The flag indicating whether to use sparse update. This parameter only
- affects the performance of the backwards gradient update. It is recommended to set
- True because sparse update is faster. But some optimizer does not support sparse update
- In these case, is_sparse must be False. Default: False.
- is_distributed(bool): Whether to store the embedding matrix in a distributed manner. Only used
- in multi-machine distributed CPU training. Default: False.
- padding_idx(int|long|None): padding_idx needs to be in the interval [-vocab_size, vocab_size).
- If :math:`padding\_idx < 0`, the :math:`padding\_idx` will automatically be converted
- to :math:`vocab\_size + padding\_idx` . It will output all-zero padding data whenever lookup
- encounters :math:`padding\_idx` in id. And the padding data will not be updated while training.
- If set None, it makes no effect to output. Default: None.
- param_attr(ParamAttr): To specify the weight parameter property. Default: None, which means the
- default weight parameter property is used. In addition,
- user-defined or pre-trained word vectors can be loaded with the :attr:`param_attr` parameter.
- The local word vector needs to be transformed into numpy format, and the shape of local word
- vector should be consistent with :attr:`size` .
- dtype(str): It refers to the data type of output Tensor.
- It must be float32 or float64. Default: float32.
- Returns:
- Tensor: Embedding Tensor or LoDTensor mapped by input. The data type is the same as :attr:`dtype` .
- Static Examples:
- .. code-block:: python
- >>> import paddle
- >>> import numpy as np
- >>> paddle.enable_static()
- >>> x = paddle.static.data(name="x", shape = [2, 4], dtype=np.int64)
- >>> output = paddle.static.nn.embedding(x, (10, 3),
- ... param_attr=paddle.nn.initializer.Constant(value=1.0))
- >>> m_output=paddle.mean(output)
- >>> place = paddle.CPUPlace()
- >>> exe = paddle.static.Executor(place)
- >>> exe.run(paddle.static.default_startup_program())
- >>> x = np.array([[7, 2, 4, 5],[4, 3, 2, 9]], dtype=np.int64)
- >>> out, = exe.run(paddle.static.default_main_program(), feed={'x':x}, fetch_list=[output])
- >>> print(out)
- [[[1. 1. 1.]
- [1. 1. 1.]
- [1. 1. 1.]
- [1. 1. 1.]]
- [[1. 1. 1.]
- [1. 1. 1.]
- [1. 1. 1.]
- [1. 1. 1.]]]
- """
- helper = LayerHelper('embedding', **locals())
- check_variable_and_dtype(input, 'input', ['int64'], 'embedding')
- check_dtype(
- dtype,
- 'dtype',
- ['float16', 'float32', 'float64', 'uint16'],
- 'embedding',
- )
- remote_prefetch = is_sparse and (not is_distributed)
- if remote_prefetch:
- assert is_sparse is True and is_distributed is False
- w = helper.create_parameter(
- attr=helper.param_attr, shape=size, dtype=dtype, is_bias=False
- )
- tmp = helper.create_variable_for_type_inference(dtype)
- padding_idx = (
- -1
- if padding_idx is None
- else padding_idx
- if padding_idx >= 0
- else (size[0] + padding_idx)
- )
- helper.append_op(
- type='lookup_table_v2',
- inputs={'Ids': input, 'W': w},
- outputs={'Out': tmp},
- attrs={
- 'is_sparse': is_sparse,
- 'is_distributed': is_distributed,
- 'remote_prefetch': remote_prefetch,
- 'padding_idx': padding_idx,
- },
- )
- return tmp
- def sparse_embedding(
- input,
- size,
- padding_idx=None,
- is_test=False,
- entry=None,
- table_class="MemorySparseTable",
- param_attr=None,
- dtype='float32',
- slot=None,
- ):
- r"""
- :api_attr: Static Graph
- The OP is used as the operator of the Embedding Lookup layer in the large-scale
- sparse training of the parameter server mode, instead of using the paddle.nn.functional.embedding.
- The operator is used to lookup embeddings vector of ids provided by :attr:`input` .
- It automatically constructs a 2D embedding matrix based on the input :attr:`size`
- (vocab_size, emb_size) and :attr:`dtype` .
- The shape of output Tensor is generated by appending an emb_size dimension to the
- last dimension of the input Tensor shape.
- **Note:** The id in :attr:`input` must satisfy :math:`0 =< id < size[0]` , otherwise
- the program will throw an exception and exit.
- .. code-block:: text
- Case 1:
- input is a Tensor. padding_idx = -1
- input.data = [[1, 3], [2, 4], [4, 127]]
- input.shape = [3, 2]
- Given size = [128, 16]
- output is a Tensor:
- out.shape = [3, 2, 16]
- out.data = [[[0.129435295, 0.244512452, ..., 0.436322452],
- [0.345421456, 0.524563927, ..., 0.144534654]],
- [[0.345249859, 0.124939536, ..., 0.194353745],
- [0.945345345, 0.435394634, ..., 0.435345365]],
- [[0.945345345, 0.435394634, ..., 0.435345365],
- [0.0, 0.0, ..., 0.0 ]]] # padding data
- The input padding_idx is less than 0, it is automatically converted to padding_idx = -1 + 128 = 127
- It will pad all-zero data when ids is 127.
- Case 2:
- input is a LoDTensor with 1-level LoD. padding_idx = 0
- input.lod = [[2, 3]]
- input.data = [[1], [3], [2], [4], [0]]
- input.shape = [5, 1]
- Given size = [128, 16]
- output is a LoDTensor:
- out.lod = [[2, 3]]
- out.shape = [5, 1, 16]
- out.data = [[[0.129435295, 0.244512452, ..., 0.436322452]],
- [[0.345421456, 0.524563927, ..., 0.144534654]],
- [[0.345249859, 0.124939536, ..., 0.194353745]],
- [[0.945345345, 0.435394634, ..., 0.435345365]],
- [[0.0, 0.0, ..., 0.0 ]]] # padding data
- It will pad all-zero data when ids is 0.
- Args:
- input(Tensor): A Tensor or LoDTensor with type int64, which contains the id
- information. The value of the input id should satisfy :math:`0<= id < size[0]` .
- size(tuple|list): The shape of lookup table parameter (vocab_size, emb_size). It
- should have two elements which indicates the size of the dictionary of embeddings
- and the size of each embedding vector respectively. The initial parameter size
- is 0 in the large-scale sparse scenario, which will gradually expand with the
- training. So if vocab_size is temporarily useless, its value can be any integer.
- The emb_size is the dimensional configuration of the word embedding weight parameter.
- padding_idx(int|long|None, optional): padding_idx needs to be in the interval [-vocab_size, vocab_size).
- If :math:`padding\_idx < 0`, the :math:`padding\_idx` will automatically be converted
- to :math:`vocab\_size + padding\_idx` . It will output all-zero padding data whenever
- lookup encounters :math:`padding\_idx` in id. And the padding data will not be updated
- while training. If set None, it makes no effect to output. Default: None.
- is_test(bool, optional): Training or prediction mode. In prediction mode (is_test=False),
- the output is not initialized and created, and it is filled with 0 and returned. Default: False.
- entry(str, optional): Entry config with parameter server whose value is ProbabilityEntry,
- CountFilterEntry or None. Default: None.
- table_class(str, optional): The type of the sparse table. The value can be CommonSparseTable
- or SSDSparseTable. The default is CommonSparseTable.
- param_attr(ParamAttr, optional): To specify the weight parameter property. Default: None, which means the
- default weight parameter property is used. In addition, user-defined or pre-trained word
- vectors can be loaded with the :attr:`param_attr` parameter. The local word vector needs
- to be transformed into numpy format, and the shape of local word vector should be consistent
- with :attr:`size` .
- dtype(str): It refers to the data type of output Tensor. It must be float32 or
- float64. Default: float32.
- Returns:
- Tensor: Embedding Tensor or LoDTensor mapped by input. The data type is the same as :attr:`dtype` .
- Examples:
- .. code-block:: python
- >>> import paddle
- >>> paddle.enable_static()
- >>> sparse_feature_dim = 1024
- >>> embedding_size = 64
- >>> # Only when the feature appear more than 10 times or more will be participated in the training.
- >>> entry = paddle.distributed.CountFilterEntry(10)
- >>> input = paddle.static.data(name='ins', shape=[1], dtype='int64')
- >>> emb = paddle.static.nn.sparse_embedding(
- ... input=input,
- ... size=[sparse_feature_dim, embedding_size],
- ... is_test=False,
- ... entry=entry,
- ... param_attr=paddle.ParamAttr(name="SparseFeatFactors",
- ... initializer=paddle.nn.initializer.Uniform()))
- """
- helper = LayerHelper('sparse_embedding', **locals())
- check_variable_and_dtype(
- input, 'input', ['int64'], 'paddle.incubate.layers.sparse_embedding'
- )
- check_dtype(
- dtype,
- 'dtype',
- ['float32', 'float64'],
- 'paddle.static.nn.sparse_embedding',
- )
- if input.size == 0:
- raise ValueError("input size should not be 0")
- w = helper.create_parameter(
- attr=helper.param_attr,
- shape=size,
- type=core.VarDesc.VarType.SELECTED_ROWS,
- dtype=dtype,
- is_bias=False,
- )
- tmp = helper.create_variable_for_type_inference(dtype)
- padding_idx = (
- -1
- if padding_idx is None
- else padding_idx
- if padding_idx >= 0
- else (size[0] + padding_idx)
- )
- if table_class not in [
- "CommonSparseTable",
- "SSDSparseTable",
- "MemorySparseTable",
- ]:
- raise ValueError(
- "table_class must be in [CommonSparseTable, SSDSparseTable, MemorySparseTable]"
- )
- entry_str = "none"
- if entry is not None:
- if entry.__class__.__name__ not in [
- "ProbabilityEntry",
- "CountFilterEntry",
- "ShowClickEntry",
- ]:
- raise ValueError(
- "entry must be instance in [paddle.distributed.ProbabilityEntry, paddle.distributed.CountFilterEntry, paddle.distributed.ShowClickEntry]"
- )
- entry_str = entry._to_attr()
- if slot is None:
- slot = 0
- helper.append_op(
- type='lookup_table',
- inputs={'Ids': input, 'W': w},
- outputs={'Out': tmp},
- attrs={
- 'padding_idx': padding_idx,
- 'is_sparse': True,
- 'is_distributed': True,
- 'remote_prefetch': True,
- 'is_test': is_test,
- 'entry': entry_str,
- 'table_class': table_class,
- 'slot': slot,
- },
- )
- return tmp
- class ExponentialMovingAverage:
- r"""
- Compute the moving average of parameters with exponential decay.
- Given a parameter :math:`\\theta`, its exponential moving average (EMA)
- will be
- .. math::
- \text{EMA}_0 & = 0
- \text{EMA}_t & = \text{decay} * \text{EMA}_{t-1} + (1 - \text{decay}) * \theta_t
- The average results calculated by **update()** method will be saved in
- temporary variables which are created and maintained by the object, and can
- be applied to parameters of current model by calling **apply()** method. And
- the **restore()** method is used to restore the parameters.
- **Bias correction**. All EMAs are initialized to :math:`0` and hence they will be
- zero biased, which can be corrected by divided by a factor
- :math:`(1 - \text{decay}^t)` , i.e., the actual EMAs applied to parameters
- when calling **apply()** method would be
- .. math::
- \widehat{\text{EMA}}_t = \frac{\text{EMA}_t}{1 - \text{decay}^t}
- **Decay rate scheduling**. A large decay rate very close to 1 would result
- in that the averages move very slowly. And a better strategy is to set a
- relative smaller decay rate in the very beginning. The argument **thres_steps**
- allows users to pass a Variable to schedule the decay rate, in this case,
- the actual decay rate becomes
- .. math::
- \min(\text{decay}, \frac{1 + \text{thres_steps}}{10 + \text{thres_steps}})
- Usually **thres_steps** can be the global training steps.
- Args:
- decay (float, optional): The exponential decay rate, usually close to 1, such as 0.999, 0.9999, ... . Default 0.999.
- thres_steps (Variable|None, optional): If not `None`, schedule the decay rate. Default None.
- name (str|None, optional): For detailed information, please refer to :ref:`api_guide_Name`. Usually name is no need to set and None by default.
- Examples:
- .. code-block:: python
- >>> import numpy
- >>> import paddle
- >>> import paddle.static as static
- >>> from paddle.static import ExponentialMovingAverage
- >>> paddle.enable_static()
- >>> data = static.data(name='x', shape=[-1, 5], dtype='float32')
- >>> hidden = static.nn.fc(x=data, size=10)
- >>> cost = paddle.mean(hidden)
- >>> test_program = static.default_main_program().clone(for_test=True)
- >>> optimizer = paddle.optimizer.Adam(learning_rate=0.001)
- >>> optimizer.minimize(cost)
- >>> ema = ExponentialMovingAverage(0.999)
- >>> ema.update()
- >>> place = paddle.CPUPlace()
- >>> exe = static.Executor(place)
- >>> exe.run(static.default_startup_program())
- >>> for pass_id in range(3):
- ... for batch_id in range(6):
- ... data = numpy.random.random(size=(10, 5)).astype('float32')
- ... exe.run(program=static.default_main_program(),
- ... feed={'x': data},
- ... fetch_list=[cost.name])
- ... # usage 1
- ... with ema.apply(exe):
- ... data = numpy.random.random(size=(10, 5)).astype('float32')
- ... exe.run(program=test_program,
- ... feed={'x': data},
- ... fetch_list=[hidden.name])
- ... # usage 2
- ... with ema.apply(exe, need_restore=False):
- ... data = numpy.random.random(size=(10, 5)).astype('float32')
- ... exe.run(program=test_program,
- ... feed={'x': data},
- ... fetch_list=[hidden.name])
- ... ema.restore(exe)
- """
- def __init__(self, decay=0.999, thres_steps=None, name=None):
- if in_dygraph_mode():
- raise Exception(
- "In dygraph, don't support ExponentialMovingAverage."
- )
- self._decay = decay
- self._thres_steps = thres_steps
- self._name = name if name is not None else ''
- self._decay_var = self._get_ema_decay()
- self._step_counter_name = "@EMA_STEP_COUNTER@"
- self._params_tmps = []
- for param in default_main_program().global_block().all_parameters():
- if param.do_model_average:
- tmp = param.block.create_var(
- name=unique_name.generate(
- ".".join([self._name + param.name, 'ema_tmp'])
- ),
- dtype=param.dtype,
- persistable=False,
- stop_gradient=True,
- )
- self._params_tmps.append((param, tmp))
- self._ema_vars = {}
- for param, tmp in self._params_tmps:
- with param.block.program._optimized_guard([param, tmp]), name_scope(
- 'moving_average'
- ):
- self._ema_vars[param.name] = self._create_ema_vars(param)
- self.apply_program = Program()
- block = self.apply_program.global_block()
- with program_guard(main_program=self.apply_program):
- decay_pow, global_step = self._get_decay_pow(block)
- for param, tmp in self._params_tmps:
- param = block._clone_variable(param)
- tmp = block._clone_variable(tmp)
- ema = block._clone_variable(self._ema_vars[param.name])
- paddle.assign(param, output=tmp)
- # bias correction
- param_val = paddle.static.nn.cond(
- global_step > 0,
- lambda: ema / (1.0 - decay_pow),
- lambda: ema,
- )
- paddle.assign(param_val, output=param)
- self.restore_program = Program()
- block = self.restore_program.global_block()
- with program_guard(main_program=self.restore_program):
- for param, tmp in self._params_tmps:
- tmp = block._clone_variable(tmp)
- param = block._clone_variable(param)
- paddle.assign(tmp, output=param)
- def _get_ema_decay(self):
- with default_main_program()._lr_schedule_guard():
- decay_var = paddle.static.create_global_var(
- shape=[1],
- value=self._decay,
- dtype='float32',
- persistable=True,
- name="scheduled_ema_decay_rate",
- )
- if self._thres_steps is not None:
- decay_t = (self._thres_steps + 1.0) / (self._thres_steps + 10.0)
- decay_val = paddle.static.nn.cond(
- decay_t < self._decay,
- lambda: decay_t,
- lambda: np.array([self._decay], dtype=np.float32),
- )
- paddle.assign(decay_val, decay_var)
- return decay_var
- def _get_decay_pow(self, block):
- global_step = paddle.static.create_global_var(
- name=self._step_counter_name,
- shape=[1],
- value=0,
- dtype='int64',
- persistable=True,
- )
- global_step = paddle.cast(global_step, "float32")
- decay_var = block._clone_variable(self._decay_var)
- decay_pow_acc = paddle.pow(decay_var, global_step)
- return decay_pow_acc, global_step
- def _create_ema_vars(self, param):
- param_ema = paddle.static.create_global_var(
- name=unique_name.generate(self._name + param.name + '_ema'),
- shape=param.shape,
- value=0.0,
- dtype=param.dtype,
- persistable=True,
- )
- return param_ema
- def update(self):
- """
- Update Exponential Moving Average. Should only call this method in
- train program.
- """
- global_step = paddle.optimizer.lr.autoincreased_step_counter(
- counter_name=self._step_counter_name
- )
- param_master_emas = []
- for param, tmp in self._params_tmps:
- with param.block.program._optimized_guard([param, tmp]), name_scope(
- 'moving_average'
- ):
- param_ema = self._ema_vars[param.name]
- if param.name + '.master' in self._ema_vars:
- master_ema = self._ema_vars[param.name + '.master']
- param_master_emas.append([param_ema, master_ema])
- else:
- ema_t = param_ema * self._decay_var + param * (
- 1 - self._decay_var
- )
- paddle.assign(ema_t, output=param_ema)
- # for fp16 params
- for param_ema, master_ema in param_master_emas:
- default_main_program().global_block().append_op(
- type="cast",
- inputs={"X": master_ema},
- outputs={"Out": param_ema},
- attrs={
- "in_dtype": master_ema.dtype,
- "out_dtype": param_ema.dtype,
- },
- )
- @signature_safe_contextmanager
- def apply(self, executor, need_restore=True):
- """
- Apply moving average to parameters for evaluation.
- Args:
- executor (Executor): The Executor to execute applying.
- need_restore (bool, optional): Whether to restore parameters after
- applying. Default True.
- """
- executor.run(self.apply_program)
- try:
- yield
- finally:
- if need_restore:
- self.restore(executor)
- def restore(self, executor):
- """Restore parameters.
- Args:
- executor (Executor): The Executor to execute restoring.
- """
- executor.run(self.restore_program)
|