Source code for mxnet.symbol.symbol

# Licensed to the Apache Software Foundation (ASF) under one# or more contributor license agreements. See the NOTICE file# distributed with this work for additional information# regarding copyright ownership. The ASF licenses this file# to you 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.# coding: utf-8# pylint: disable=invalid-name, protected-access, too-many-arguments, too-many-lines# pylint: disable=import-error, no-name-in-module"""Symbolic configuration API of MXNet."""from__future__importabsolute_importas_abstry:from__builtin__importsliceaspy_sliceexceptImportError:frombuiltinsimportsliceaspy_slicefromarrayimportarrayimportctypesimportwarningsfromnumbersimportNumberimportnumpyas_numpyfrom..attributeimportAttrScopefrom..baseimport_LIB,numeric_types,c_array,c_array_buf,c_str,c_str_array,c_handle_arrayfrom..baseimportmx_uint,py_str,string_types,integer_typesfrom..baseimportNDArrayHandle,ExecutorHandle,SymbolHandlefrom..baseimportcheck_call,MXNetError,NotImplementedForSymbolfrom..contextimportContext,current_contextfrom..ndarrayimportNDArray,_DTYPE_NP_TO_MX,_DTYPE_MX_TO_NP,_GRAD_REQ_MAPfrom..ndarray.ndarrayimport_STORAGE_TYPE_STR_TO_IDfrom..ndarrayimport_ndarray_clsfrom..executorimportExecutorfrom.import_internalfrom.importopfrom._internalimportSymbolBase,_set_symbol_class__all__=["Symbol","var","Variable","Group","load","load_json","pow","maximum","minimum","hypot","eye","zeros","ones","full","arange","histogram"]

[docs]classSymbol(SymbolBase):"""Symbol is symbolic graph of the mxnet."""# disable dictionary storage, also do not have parent type.# pylint: disable=no-member__slots__=[]# Make numpy functions return Symbol instead of numpy object array__array_priority__=1000.0def__repr__(self):"""Gets a string representation of the symbol."""name=self.nameifnameisNone:name=', '.join([i.nameforiinself])return'<%s group [%s]>'%(self.__class__.__name__,name)else:return'<%s%s>'%(self.__class__.__name__,name)

def__copy__(self):returnself.__deepcopy__(None)def__deepcopy__(self,_):"""Returns a deep copy of the input object. This function returns a deep copy of the input object including the current state of all its parameters such as weights, biases, etc. Any changes made to the deep copy do not reflect in the original object. Example ------- >>> import copy >>> data = mx.sym.Variable('data') >>> data_1 = copy.deepcopy(data) >>> data_1 = 2*data >>> data_1.tojson() >>> data_1 is data # Data got modified False """handle=SymbolHandle()check_call(_LIB.MXSymbolCopy(self.handle,ctypes.byref(handle)))returnSymbol(handle)

[docs]def__getitem__(self,index):"""x.__getitem__(i) <=> x[i] Returns a sliced view of the input symbol. Example ------- >>> a = mx.sym.var('a') >>> a.__getitem__(0) <Symbol a> >>> a[0] <Symbol a> Parameters ---------- index : int or str Indexing key """output_count=len(self)ifisinstance(index,py_slice):start=0ifindex.startisNoneelseindex.startstop=output_countifindex.stopisNoneelseindex.stopstep=1ifindex.stepisNoneelseindex.stepreturnGroup([self[i]foriinrange(start,stop,step)])ifisinstance(index,string_types):# Returning this list of names is expensive. Some symbols may have hundreds of outputsoutput_names=self.list_outputs()idx=Nonefori,nameinenumerate(output_names):ifname==index:ifidxisnotNone:raiseValueError('There are multiple outputs with name \"%s\"'%index)idx=iifidxisNone:raiseValueError('Cannot find output that matches name \"%s\"'%index)index=idxifnotisinstance(index,int):raiseTypeError('Symbol only support integer index to fetch i-th output')ifindex>=output_count:# Important, python determines the end by this exceptionraiseIndexErrorhandle=SymbolHandle()check_call(_LIB.MXSymbolGetOutput(self.handle,mx_uint(index),ctypes.byref(handle)))returnSymbol(handle=handle)

@propertydefname(self):"""Gets name string from the symbol, this function only works for non-grouped symbol. Returns ------- value : str The name of this symbol, returns ``None`` for grouped symbol. """ret=ctypes.c_char_p()success=ctypes.c_int()check_call(_LIB.MXSymbolGetName(self.handle,ctypes.byref(ret),ctypes.byref(success)))ifsuccess.value!=0:returnpy_str(ret.value)else:returnNone

[docs]defattr_dict(self):"""Recursively gets all attributes from the symbol and its children. Example ------- >>> a = mx.sym.Variable('a', attr={'a1':'a2'}) >>> b = mx.sym.Variable('b', attr={'b1':'b2'}) >>> c = a+b >>> c.attr_dict() {'a': {'a1': 'a2'}, 'b': {'b1': 'b2'}} Returns ------- ret : Dict of str to dict There is a key in the returned dict for every child with non-empty attribute set. For each symbol, the name of the symbol is its key in the dict and the correspond value is that symbol's attribute list (itself a dictionary). """size=mx_uint()pairs=ctypes.POINTER(ctypes.c_char_p)()f_handle=_LIB.MXSymbolListAttrcheck_call(f_handle(self.handle,ctypes.byref(size),ctypes.byref(pairs)))ret={}foriinrange(size.value):name,key=py_str(pairs[i*2]).split('$')val=py_str(pairs[i*2+1])ifnamenotinret:ret[name]={}ret[name][key]=valreturnret

def_set_attr(self,**kwargs):"""Sets an attribute of the symbol. For example. A._set_attr(foo="bar") adds the mapping ``"{foo: bar}"`` to the symbol's attribute dictionary. Parameters ---------- **kwargs The attributes to set """forkey,valueinkwargs.items():ifnotisinstance(value,string_types):raiseValueError("Set Attr only accepts string values")check_call(_LIB.MXSymbolSetAttr(self.handle,c_str(key),c_str(str(value))))

[docs]defget_internals(self):"""Gets a new grouped symbol `sgroup`. The output of `sgroup` is a list of outputs of all of the internal nodes. Consider the following code: Example ------- >>> a = mx.sym.var('a') >>> b = mx.sym.var('b') >>> c = a + b >>> d = c.get_internals() >>> d <Symbol Grouped> >>> d.list_outputs() ['a', 'b', '_plus4_output'] Returns ------- sgroup : Symbol A symbol group containing all internal and leaf nodes of the computation graph used to compute the symbol. """handle=SymbolHandle()check_call(_LIB.MXSymbolGetInternals(self.handle,ctypes.byref(handle)))returnSymbol(handle=handle)

[docs]deflist_outputs(self):"""Lists all the outputs in the symbol. Example ------- >>> a = mx.sym.var('a') >>> b = mx.sym.var('b') >>> c = a + b >>> c.list_outputs() ['_plus12_output'] Returns ------- list of str List of all the outputs. For most symbols, this list contains only the name of this symbol. For symbol groups, this is a list with the names of all symbols in the group. """size=ctypes.c_uint()sarr=ctypes.POINTER(ctypes.c_char_p)()check_call(_LIB.MXSymbolListOutputs(self.handle,ctypes.byref(size),ctypes.byref(sarr)))return[py_str(sarr[i])foriinrange(size.value)]

[docs]deflist_auxiliary_states(self):"""Lists all the auxiliary states in the symbol. Example ------- >>> a = mx.sym.var('a') >>> b = mx.sym.var('b') >>> c = a + b >>> c.list_auxiliary_states() [] Example of auxiliary states in `BatchNorm`. >>> data = mx.symbol.Variable('data') >>> weight = mx.sym.Variable(name='fc1_weight') >>> fc1 = mx.symbol.FullyConnected(data = data, weight=weight, name='fc1', num_hidden=128) >>> fc2 = mx.symbol.BatchNorm(fc1, name='batchnorm0') >>> fc2.list_auxiliary_states() ['batchnorm0_moving_mean', 'batchnorm0_moving_var'] Returns ------- aux_states : list of str List of the auxiliary states in input symbol. Notes ----- Auxiliary states are special states of symbols that do not correspond to an argument, and are not updated by gradient descent. Common examples of auxiliary states include the `moving_mean` and `moving_variance` in `BatchNorm`. Most operators do not have auxiliary states. """size=ctypes.c_uint()sarr=ctypes.POINTER(ctypes.c_char_p)()check_call(_LIB.MXSymbolListAuxiliaryStates(self.handle,ctypes.byref(size),ctypes.byref(sarr)))return[py_str(sarr[i])foriinrange(size.value)]

[docs]definfer_type(self,*args,**kwargs):"""Infers the type of all arguments and all outputs, given the known types for some arguments. This function takes the known types of some arguments in either positional way or keyword argument way as input. It returns a tuple of `None` values if there is not enough information to deduce the missing types. Inconsistencies in the known types will cause an error to be raised. Example ------- >>> a = mx.sym.var('a') >>> b = mx.sym.var('b') >>> c = a + b >>> arg_types, out_types, aux_types = c.infer_type(a='float32') >>> arg_types [<type 'numpy.float32'>, <type 'numpy.float32'>] >>> out_types [<type 'numpy.float32'>] >>> aux_types [] Parameters ---------- *args : Type of known arguments in a positional way. Unknown type can be marked as None. **kwargs : Keyword arguments of known types. Returns ------- arg_types : list of numpy.dtype or None List of argument types. The order is same as the order of list_arguments(). out_types : list of numpy.dtype or None List of output types. The order is same as the order of list_outputs(). aux_types : list of numpy.dtype or None List of auxiliary state types. The order is same as the order of list_auxiliary_states(). """# pylint: disable=too-many-localsiflen(args)!=0andlen(kwargs)!=0:raiseValueError('Can only specify known argument \ types either by positional or kwargs way.')sdata=[]iflen(args)!=0:keys=c_array(ctypes.c_char_p,[])forsinargs:ifsisnotNone:s=_numpy.dtype(s).typeifsnotin_DTYPE_NP_TO_MX:raiseTypeError('Argument need to be one of '+str(_DTYPE_NP_TO_MX))sdata.append(_DTYPE_NP_TO_MX[s])else:sdata.append(-1)else:str_keys=[]fork,vinkwargs.items():v=_numpy.dtype(v).typeifvin_DTYPE_NP_TO_MX:str_keys.append(k)sdata.append(_DTYPE_NP_TO_MX[v])keys=c_str_array(str_keys)arg_type_size=mx_uint()arg_type_data=ctypes.POINTER(ctypes.c_int)()out_type_size=mx_uint()out_type_data=ctypes.POINTER(ctypes.c_int)()aux_type_size=mx_uint()aux_type_data=ctypes.POINTER(ctypes.c_int)()complete=ctypes.c_int()check_call(_LIB.MXSymbolInferType(self.handle,mx_uint(len(sdata)),keys,c_array_buf(ctypes.c_int,array('i',sdata)),ctypes.byref(arg_type_size),ctypes.byref(arg_type_data),ctypes.byref(out_type_size),ctypes.byref(out_type_data),ctypes.byref(aux_type_size),ctypes.byref(aux_type_data),ctypes.byref(complete)))ifcomplete.value!=0:arg_types=[_DTYPE_MX_TO_NP[arg_type_data[i]]foriinrange(arg_type_size.value)]out_types=[_DTYPE_MX_TO_NP[out_type_data[i]]foriinrange(out_type_size.value)]aux_types=[_DTYPE_MX_TO_NP[aux_type_data[i]]foriinrange(aux_type_size.value)]return(arg_types,out_types,aux_types)else:return(None,None,None)

# pylint: enable=too-many-locals

[docs]definfer_shape(self,*args,**kwargs):"""Infers the shapes of all arguments and all outputs given the known shapes of some arguments. This function takes the known shapes of some arguments in either positional way or keyword argument way as input. It returns a tuple of `None` values if there is not enough information to deduce the missing shapes. Example ------- >>> a = mx.sym.var('a') >>> b = mx.sym.var('b') >>> c = a + b >>> arg_shapes, out_shapes, aux_shapes = c.infer_shape(a=(3,3)) >>> arg_shapes [(3L, 3L), (3L, 3L)] >>> out_shapes [(3L, 3L)] >>> aux_shapes [] >>> c.infer_shape(a=(0,3)) # 0s in shape means unknown dimensions. So, returns None. (None, None, None) Inconsistencies in the known shapes will cause an error to be raised. See the following example: >>> data = mx.sym.Variable('data') >>> out = mx.sym.FullyConnected(data=data, name='fc1', num_hidden=1000) >>> out = mx.sym.Activation(data=out, act_type='relu') >>> out = mx.sym.FullyConnected(data=out, name='fc2', num_hidden=10) >>> weight_shape= (1, 100) >>> data_shape = (100, 100) >>> out.infer_shape(data=data_shape, fc1_weight=weight_shape) Error in operator fc1: Shape inconsistent, Provided=(1,100), inferred shape=(1000,100) Parameters ---------- *args : Shape of arguments in a positional way. Unknown shape can be marked as None. **kwargs : Keyword arguments of the known shapes. Returns ------- arg_shapes : list of tuple or None List of argument shapes. The order is same as the order of list_arguments(). out_shapes : list of tuple or None List of output shapes. The order is same as the order of list_outputs(). aux_shapes : list of tuple or None List of auxiliary state shapes. The order is same as the order of list_auxiliary_states(). """try:res=self._infer_shape_impl(False,*args,**kwargs)ifres[1]isNone:arg_shapes,_,_=self._infer_shape_impl(True,*args,**kwargs)arg_names=self.list_arguments()unknowns=[]forname,shapeinzip(arg_names,arg_shapes):ifnotshapeornot_numpy.prod(shape):iflen(unknowns)>=10:unknowns.append('...')breakunknowns.append('%s: %s'%(name,str(shape)))warnings.warn("Cannot decide shape for the following arguments "+"(0s in shape means unknown dimensions). "+"Consider providing them as input:\n\t"+"\n\t".join(unknowns),stacklevel=2)returnresexceptMXNetError:print("infer_shape error. Arguments:")fori,arginenumerate(args):print(" #%d: %s"%(i,arg))fork,vinkwargs.items():print(" %s: %s"%(k,v))raise

[docs]definfer_shape_partial(self,*args,**kwargs):"""Infers the shape partially. This functions works the same way as `infer_shape`, except that this function can return partial results. In the following example, information about fc2 is not available. So, `infer_shape` will return a tuple of `None` values but `infer_shape_partial` will return partial values. Example ------- >>> data = mx.sym.Variable('data') >>> prev = mx.sym.Variable('prev') >>> fc1 = mx.sym.FullyConnected(data=data, name='fc1', num_hidden=128) >>> fc2 = mx.sym.FullyConnected(data=prev, name='fc2', num_hidden=128) >>> out = mx.sym.Activation(data=mx.sym.elemwise_add(fc1, fc2), act_type='relu') >>> out.list_arguments() ['data', 'fc1_weight', 'fc1_bias', 'prev', 'fc2_weight', 'fc2_bias'] >>> out.infer_shape(data=(10,64)) (None, None, None) >>> out.infer_shape_partial(data=(10,64)) ([(10L, 64L), (128L, 64L), (128L,), (), (), ()], [(10L, 128L)], []) >>> # infers shape if you give information about fc2 >>> out.infer_shape(data=(10,64), prev=(10,128)) ([(10L, 64L), (128L, 64L), (128L,), (10L, 128L), (128L, 128L), (128L,)], [(10L, 128L)], []) Parameters ---------- *args : Shape of arguments in a positional way. Unknown shape can be marked as None **kwargs : Keyword arguments of known shapes. Returns ------- arg_shapes : list of tuple or None List of argument shapes. The order is same as the order of list_arguments(). out_shapes : list of tuple or None List of output shapes. The order is same as the order of list_outputs(). aux_shapes : list of tuple or None List of auxiliary state shapes. The order is same as the order of list_auxiliary_states(). """returnself._infer_shape_impl(True,*args,**kwargs)

[docs]defsave(self,fname):"""Saves symbol to a file. You can also use pickle to do the job if you only work on python. The advantage of `load`/`save` functions is that the file contents are language agnostic. This means the model saved by one language binding can be loaded by a different language binding of `MXNet`. You also get the benefit of being able to directly load/save from cloud storage(S3, HDFS). Parameters ---------- fname : str The name of the file. - "s3://my-bucket/path/my-s3-symbol" - "hdfs://my-bucket/path/my-hdfs-symbol" - "/path-to/my-local-symbol" See Also -------- symbol.load : Used to load symbol from file. """ifnotisinstance(fname,string_types):raiseTypeError('fname need to be string')check_call(_LIB.MXSymbolSaveToFile(self.handle,c_str(fname)))

[docs]deftojson(self):"""Saves symbol to a JSON string. See Also -------- symbol.load_json : Used to load symbol from JSON string. """json_str=ctypes.c_char_p()check_call(_LIB.MXSymbolSaveToJSON(self.handle,ctypes.byref(json_str)))returnpy_str(json_str.value)

@staticmethoddef_get_ndarray_inputs(arg_key,args,arg_names,allow_missing):"""Helper function to get NDArray lists handles from various inputs. Parameters ---------- arg_key : str The name of argument, used for error message. args : list of NDArray or dict of str to NDArray Input arguments to the symbols. If type is list of NDArray, the position is in the same order of arg_names. If type is dict of str to NDArray, then it maps the name of arguments to the corresponding NDArray, args_names : list of string List of argument names. allow_missing : boolean Whether missing argument is allowed. When allowed, the missing handle will be set to None(null) Returns ------- handles : list of NDArrayHandle The positional list of NDArrayHandles generated from input. """# setup argsarg_handles=[]arg_arrays=[]ifisinstance(args,list):iflen(args)!=len(arg_names):raiseValueError('Length of %s does not match the number of arguments'%arg_key)fornarrinargs:ifnarrisNoneandallow_missing:arg_handles.append(None)elifnotisinstance(narr,NDArray):raiseTypeError('Only accept list of NDArrays or dict of str to NDArray')else:arg_handles.append(narr.handle)arg_arrays=argselifisinstance(args,dict):fornameinarg_names:ifnameinargs:narr=args[name]ifnotisinstance(narr,NDArray):raiseTypeError('Only accept list of NDArrays or dict of str to NDArray')arg_handles.append(narr.handle)arg_arrays.append(narr)else:ifallow_missing:arg_handles.append(None)arg_arrays.append(None)else:raiseValueError('key `%s` is missing in `%s`'%(name,arg_key))else:raiseTypeError('Only accept list of NDArrays or dict of str to NDArray')returnc_array(NDArrayHandle,arg_handles),arg_arrays# pylint: disable=too-many-locals

[docs]defsimple_bind(self,ctx,grad_req='write',type_dict=None,stype_dict=None,group2ctx=None,shared_arg_names=None,shared_exec=None,shared_buffer=None,**kwargs):"""Bind current symbol to get an executor, allocate all the arguments needed. Allows specifying data types. This function simplifies the binding procedure. You need to specify only input data shapes. Before binding the executor, the function allocates arguments and auxiliary states that were not explicitly specified. Allows specifying data types. Example ------- >>> x = mx.sym.Variable('x') >>> y = mx.sym.FullyConnected(x, num_hidden=4) >>> exe = y.simple_bind(mx.cpu(), x=(5,4), grad_req='null') >>> exe.forward() [<NDArray 5x4 @cpu(0)>] >>> exe.outputs[0].asnumpy() array([[ 0., 0., 0., 0.], [ 0., 0., 0., 0.], [ 0., 0., 0., 0.], [ 0., 0., 0., 0.], [ 0., 0., 0., 0.]], dtype=float32) >>> exe.arg_arrays [<NDArray 5x4 @cpu(0)>, <NDArray 4x4 @cpu(0)>, <NDArray 4 @cpu(0)>] >>> exe.grad_arrays [<NDArray 5x4 @cpu(0)>, <NDArray 4x4 @cpu(0)>, <NDArray 4 @cpu(0)>] Parameters ---------- ctx : Context The device context the generated executor to run on. grad_req: string {'write', 'add', 'null'}, or list of str or dict of str to str, optional To specify how we should update the gradient to the `args_grad`. - 'write' means every time gradient is written to specified `args_grad` NDArray. - 'add' means every time gradient is added to the specified NDArray. - 'null' means no action is taken, the gradient may not be calculated. type_dict : Dict of str->numpy.dtype Input type dictionary, name->dtype stype_dict : Dict of str->str Input storage type dictionary, name->storage_type group2ctx : Dict of string to mx.Context The dict mapping the `ctx_group` attribute to the context assignment. shared_arg_names : List of string The argument names whose `NDArray` of shared_exec can be reused for initializing the current executor. shared_exec : Executor The executor whose arg_arrays, arg_arrays, grad_arrays, and aux_arrays can be reused for initializing the current executor. shared_buffer : Dict of string to `NDArray` The dict mapping argument names to the `NDArray` that can be reused for initializing the current executor. This buffer will be checked for reuse if one argument name of the current executor is not found in `shared_arg_names`. The `NDArray` s are expected have default storage type. kwargs : Dict of str->shape Input shape dictionary, name->shape Returns ------- executor : mxnet.Executor The generated executor """# data typesnum_provided_arg_types=0provided_arg_type_names=ctypes.POINTER(ctypes.c_char_p)()# provided type argument namesprovided_arg_type_data=ctypes.POINTER(mx_uint)()# provided typesiftype_dictisnotNone:provided_arg_type_names=[]provided_arg_type_data=[]fork,vintype_dict.items():v=_numpy.dtype(v).typeifvin_DTYPE_NP_TO_MX:provided_arg_type_names.append(k)provided_arg_type_data.append(_DTYPE_NP_TO_MX[v])num_provided_arg_types=mx_uint(len(provided_arg_type_names))provided_arg_type_names=c_str_array(provided_arg_type_names)provided_arg_type_data=c_array_buf(ctypes.c_int,array('i',provided_arg_type_data))# storage typesnum_provided_arg_stypes=0# provided storage type argument namesprovided_arg_stype_names=ctypes.POINTER(ctypes.c_char_p)()provided_arg_stype_data=ctypes.POINTER(mx_uint)()# provided storage typesifstype_dictisnotNone:provided_arg_stype_names=[]provided_arg_stype_data=[]fork,vinstype_dict.items():ifvin_STORAGE_TYPE_STR_TO_ID:provided_arg_stype_names.append(k)provided_arg_stype_data.append(_STORAGE_TYPE_STR_TO_ID[v])num_provided_arg_stypes=mx_uint(len(provided_arg_stype_names))provided_arg_stype_names=c_str_array(provided_arg_stype_names)provided_arg_stype_data=c_array_buf(ctypes.c_int,array('i',provided_arg_stype_data))provided_arg_shape_data=[]# shape data# argument shape index in sdata,# e.g. [sdata[indptr[0]], sdata[indptr[1]]) is the shape of the first argprovided_arg_shape_idx=[0]provided_arg_shape_names=[]# provided argument namesfork,vinkwargs.items():# if k not in listed_arguments and k not in listed_aux_states:# raise ValueError('arg name %s is not valid', k)ifisinstance(v,tuple):provided_arg_shape_names.append(k)provided_arg_shape_data.extend(v)provided_arg_shape_idx.append(len(provided_arg_shape_data))provided_req_type_list_len=0provided_grad_req_types=ctypes.POINTER(ctypes.c_char_p)()provided_grad_req_names=ctypes.POINTER(ctypes.c_char_p)()ifgrad_reqisnotNone:ifisinstance(grad_req,string_types):# use provided_req_type_list_len = 0 to indicate this situationprovided_req_type_list_len=0provided_grad_req_types=[grad_req]elifisinstance(grad_req,list):iflen(grad_req)==0:raiseRuntimeError('grad_req in simple_bind cannot be an empty list')provided_grad_req_types=grad_reqprovided_req_type_list_len=len(provided_grad_req_types)elifisinstance(grad_req,dict):iflen(grad_req)==0:raiseRuntimeError('grad_req in simple_bind cannot be an empty dict')provided_grad_req_names=[]provided_grad_req_types=[]fork,vingrad_req.items():provided_grad_req_names.append(k)provided_grad_req_types.append(v)provided_grad_req_names=c_str_array(provided_grad_req_names)provided_req_type_list_len=len(provided_grad_req_types)provided_grad_req_types=c_str_array(provided_grad_req_types)num_ctx_map_keys=mx_uint(0)ctx_map_keys=ctypes.POINTER(ctypes.c_char_p)()ctx_map_dev_types=ctypes.POINTER(ctypes.c_int)()ctx_map_dev_ids=ctypes.POINTER(ctypes.c_int)()ifgroup2ctxisnotNone:ctx_map_keys=[]ctx_map_dev_types=[]ctx_map_dev_ids=[]forkey,valingroup2ctx.items():ctx_map_keys.append(key)ctx_map_dev_types.append(val.device_typeid)ctx_map_dev_ids.append(val.device_id)num_ctx_map_keys=mx_uint(len(ctx_map_keys))ctx_map_keys=c_str_array(ctx_map_keys)ctx_map_dev_types=c_array(ctypes.c_int,array('i',ctx_map_dev_types))ctx_map_dev_ids=c_array(ctypes.c_int,array('i',ctx_map_dev_ids))# prepare param namesshared_arg_name_list=[]ifshared_arg_namesisnotNone:ifnotisinstance(shared_arg_names,list):raiseValueError('shared_arg_names in simple_bind must be a list or None')shared_arg_name_list=shared_arg_names# prepare shared_bufferifshared_bufferisNone:shared_buffer_len=ctypes.c_int(-1)shared_buffer_names=ctypes.POINTER(ctypes.c_char_p)()shared_buffer_handles=ctypes.POINTER(NDArrayHandle)()else:ifnotisinstance(shared_buffer,dict):raiseValueError('shared_buffer in simple_bind must be dict or None')buffer_names=shared_buffer.keys()buffer_arrays=shared_buffer.values()forvinbuffer_arrays:assert(v.stype=='default'), \
"shared_buffer is expected to only contain NDArrays with default storage"shared_buffer_names=c_str_array(buffer_names)shared_buffer_len=ctypes.c_int(len(buffer_arrays))shared_buffer_handles=c_handle_array(buffer_arrays)updated_shared_buffer_names=ctypes.POINTER(ctypes.c_char_p)()updated_shared_buffer_handles=ctypes.POINTER(NDArrayHandle)()# prepare shared_exec_handleshared_exec_handle=shared_exec.handleifshared_execisnotNoneelseExecutorHandle()# prepare current executor handleexe_handle=ExecutorHandle()# prepare current executor's in_args, arg_grads, and aux_statesnum_in_args=ctypes.c_uint()in_arg_handles=ctypes.POINTER(NDArrayHandle)()arg_grad_handles=ctypes.POINTER(NDArrayHandle)()num_aux_states=ctypes.c_uint()aux_state_handles=ctypes.POINTER(NDArrayHandle)()try:check_call(_LIB.MXExecutorSimpleBind(self.handle,ctypes.c_int(ctx.device_typeid),ctypes.c_int(ctx.device_id),num_ctx_map_keys,ctx_map_keys,ctx_map_dev_types,ctx_map_dev_ids,mx_uint(provided_req_type_list_len),provided_grad_req_names,provided_grad_req_types,mx_uint(len(provided_arg_shape_names)),c_str_array(provided_arg_shape_names),c_array_buf(mx_uint,array('I',provided_arg_shape_data)),c_array_buf(mx_uint,array('I',provided_arg_shape_idx)),num_provided_arg_types,provided_arg_type_names,provided_arg_type_data,num_provided_arg_stypes,provided_arg_stype_names,provided_arg_stype_data,mx_uint(len(shared_arg_name_list)),c_str_array(shared_arg_name_list),ctypes.byref(shared_buffer_len),shared_buffer_names,shared_buffer_handles,ctypes.byref(updated_shared_buffer_names),ctypes.byref(updated_shared_buffer_handles),ctypes.byref(num_in_args),ctypes.byref(in_arg_handles),ctypes.byref(arg_grad_handles),ctypes.byref(num_aux_states),ctypes.byref(aux_state_handles),shared_exec_handle,ctypes.byref(exe_handle)))exceptMXNetErrorase:error_msg="simple_bind error. Arguments:\n"fork,vinkwargs.items():error_msg+="%s: %s\n"%(k,v)error_msg+="%s"%eraiseRuntimeError(error_msg)# update shared_bufferifshared_bufferisnotNone:foriinrange(shared_buffer_len.value):k=py_str(updated_shared_buffer_names[i])v=NDArray(NDArrayHandle(updated_shared_buffer_handles[i]))shared_buffer[k]=v# create in_args, arg_grads, and aux_states for the current executorarg_arrays=[_ndarray_cls(NDArrayHandle(in_arg_handles[i]))foriinrange(num_in_args.value)]grad_arrays=[_ndarray_cls(NDArrayHandle(arg_grad_handles[i]))ifarg_grad_handles[i]isnotNoneelseNoneforiinrange(num_in_args.value)]aux_arrays=[_ndarray_cls(NDArrayHandle(aux_state_handles[i]))foriinrange(num_aux_states.value)]executor=Executor(exe_handle,self,ctx,grad_req,group2ctx)executor.arg_arrays=arg_arraysexecutor.grad_arrays=grad_arraysexecutor.aux_arrays=aux_arraysreturnexecutor

[docs]defbind(self,ctx,args,args_grad=None,grad_req='write',aux_states=None,group2ctx=None,shared_exec=None):"""Binds the current symbol to an executor and returns it. We first declare the computation and then bind to the data to run. This function returns an executor which provides method `forward()` method for evaluation and a `outputs()` method to get all the results. Example ------- >>> a = mx.sym.Variable('a') >>> b = mx.sym.Variable('b') >>> c = a + b <Symbol _plus1> >>> ex = c.bind(ctx=mx.cpu(), args={'a' : mx.nd.ones([2,3]), 'b' : mx.nd.ones([2,3])}) >>> ex.forward() [<NDArray 2x3 @cpu(0)>] >>> ex.outputs[0].asnumpy() [[ 2. 2. 2.] [ 2. 2. 2.]] Parameters ---------- ctx : Context The device context the generated executor to run on. args : list of NDArray or dict of str to NDArray Input arguments to the symbol. - If the input type is a list of `NDArray`, the order should be same as the order of `list_arguments()`. - If the input type is a dict of str to `NDArray`, then it maps the name of arguments to the corresponding `NDArray`. - In either case, all the arguments must be provided. args_grad : list of NDArray or dict of str to `NDArray`, optional When specified, `args_grad` provides NDArrays to hold the result of gradient value in backward. - If the input type is a list of `NDArray`, the order should be same as the order of `list_arguments()`. - If the input type is a dict of str to `NDArray`, then it maps the name of arguments to the corresponding NDArray. - When the type is a dict of str to `NDArray`, one only need to provide the dict for required argument gradient. Only the specified argument gradient will be calculated. grad_req : {'write', 'add', 'null'}, or list of str or dict of str to str, optional To specify how we should update the gradient to the `args_grad`. - 'write' means everytime gradient is write to specified `args_grad` `NDArray`. - 'add' means everytime gradient is add to the specified NDArray. - 'null' means no action is taken, the gradient may not be calculated. aux_states : list of `NDArray`, or dict of str to `NDArray`, optional Input auxiliary states to the symbol, only needed when the output of `list_auxiliary_states()` is not empty. - If the input type is a list of `NDArray`, the order should be same as the order of `list_auxiliary_states()`. - If the input type is a dict of str to `NDArray`, then it maps the name of `auxiliary_states` to the corresponding `NDArray`, - In either case, all the auxiliary states need to be provided. group2ctx : Dict of string to mx.Context The dict mapping the `ctx_group` attribute to the context assignment. shared_exec : mx.executor.Executor Executor to share memory with. This is intended for runtime reshaping, variable length sequences, etc. The returned executor shares state with `shared_exec`, and should not be used in parallel with it. Returns ------- executor : Executor The generated executor Notes ----- Auxiliary states are the special states of symbols that do not correspond to an argument, and do not have gradient but are still useful for the specific operations. Common examples of auxiliary states include the `moving_mean` and `moving_variance` states in `BatchNorm`. Most operators do not have auxiliary states and in those cases, this parameter can be safely ignored. One can give up gradient by using a dict in `args_grad` and only specify gradient they interested in. """# pylint: disable=too-many-locals, too-many-branchesifnotisinstance(ctx,Context):raiseTypeError("Context type error")listed_arguments=self.list_arguments()args_handle,args=self._get_ndarray_inputs('args',args,listed_arguments,False)# setup args gradientifargs_gradisNone:args_grad_handle=c_array(NDArrayHandle,[None]*len(args))else:args_grad_handle,args_grad=self._get_ndarray_inputs('args_grad',args_grad,listed_arguments,True)ifaux_statesisNone:aux_states=[]aux_args_handle,aux_states=self._get_ndarray_inputs('aux_states',aux_states,self.list_auxiliary_states(),False)# setup requirementsifisinstance(grad_req,string_types):ifgrad_reqnotin_GRAD_REQ_MAP:raiseValueError('grad_req must be in %s'%str(_GRAD_REQ_MAP))reqs_array=c_array_buf(mx_uint,array('I',[_GRAD_REQ_MAP[grad_req]]*len(listed_arguments)))elifisinstance(grad_req,list):reqs_array=c_array_buf(mx_uint,array('I',[_GRAD_REQ_MAP[item]foritemingrad_req]))elifisinstance(grad_req,dict):req_array=[]fornameinlisted_arguments:ifnameingrad_req:req_array.append(_GRAD_REQ_MAP[grad_req[name]])else:req_array.append(0)reqs_array=c_array_buf(mx_uint,array('I',req_array))ctx_map_keys=[]ctx_map_dev_types=[]ctx_map_dev_ids=[]ifgroup2ctx:forkey,valingroup2ctx.items():ctx_map_keys.append(key)ctx_map_dev_types.append(val.device_typeid)ctx_map_dev_ids.append(val.device_id)handle=ExecutorHandle()shared_handle=shared_exec.handleifshared_execisnotNoneelseExecutorHandle()check_call(_LIB.MXExecutorBindEX(self.handle,ctypes.c_int(ctx.device_typeid),ctypes.c_int(ctx.device_id),mx_uint(len(ctx_map_keys)),c_str_array(ctx_map_keys),c_array_buf(ctypes.c_int,array('i',ctx_map_dev_types)),c_array_buf(ctypes.c_int,array('i',ctx_map_dev_ids)),mx_uint(len(args)),args_handle,args_grad_handle,reqs_array,mx_uint(len(aux_states)),aux_args_handle,shared_handle,ctypes.byref(handle)))executor=Executor(handle,self,ctx,grad_req,group2ctx)executor.arg_arrays=argsexecutor.grad_arrays=args_gradexecutor.aux_arrays=aux_statesreturnexecutor

defgradient(self,wrt):"""Gets the autodiff of current symbol. This function can only be used if current symbol is a loss function. .. note:: This function is currently not implemented. Parameters ---------- wrt : Array of String keyword arguments of the symbol that the gradients are taken. Returns ------- grad : Symbol A gradient Symbol with returns to be the corresponding gradients. """handle=SymbolHandle()c_wrt=c_str_array(wrt)check_call(_LIB.MXSymbolGrad(self.handle,mx_uint(len(wrt)),c_wrt,ctypes.byref(handle)))returnSymbol(handle)# pylint: enable= no-memberdefeval(self,ctx=None,**kwargs):"""Evaluates a symbol given arguments. The `eval` method combines a call to `bind` (which returns an executor) with a call to `forward` (executor method). For the common use case, where you might repeatedly evaluate with same arguments, eval is slow. In that case, you should call `bind` once and then repeatedly call forward. This function allows simpler syntax for less cumbersome introspection. Example ------- >>> a = mx.sym.Variable('a') >>> b = mx.sym.Variable('b') >>> c = a + b >>> ex = c.eval(ctx = mx.cpu(), a = mx.nd.ones([2,3]), b = mx.nd.ones([2,3])) >>> ex [<NDArray 2x3 @cpu(0)>] >>> ex[0].asnumpy() array([[ 2., 2., 2.], [ 2., 2., 2.]], dtype=float32) Parameters ---------- ctx : Context The device context the generated executor to run on. kwargs : Keyword arguments of type `NDArray` Input arguments to the symbol. All the arguments must be provided. Returns ---------- result : a list of NDArrays corresponding to the values taken by each symbol when evaluated on given args. When called on a single symbol (not a group), the result will be a list with one element. """ifctxisNone:ctx=current_context()returnself.bind(ctx,kwargs).forward()

[docs]defreshape(self,*args,**kwargs):"""Convenience fluent method for :py:func:`reshape`. The arguments are the same as for :py:func:`reshape`, with this array as data. """returnop.reshape(self,*args,**kwargs)

[docs]defreshape_like(self,*args,**kwargs):"""Convenience fluent method for :py:func:`reshape_like`. The arguments are the same as for :py:func:`reshape_like`, with this array as data. """returnop.reshape_like(self,*args,**kwargs)

[docs]defastype(self,*args,**kwargs):"""Convenience fluent method for :py:func:`cast`. The arguments are the same as for :py:func:`cast`, with this array as data. """returnop.cast(self,*args,**kwargs)

[docs]defzeros_like(self,*args,**kwargs):"""Convenience fluent method for :py:func:`zeros_like`. The arguments are the same as for :py:func:`zeros_like`, with this array as data. """returnop.zeros_like(self,*args,**kwargs)

[docs]defones_like(self,*args,**kwargs):"""Convenience fluent method for :py:func:`ones_like`. The arguments are the same as for :py:func:`ones_like`, with this array as data. """returnop.ones_like(self,*args,**kwargs)

[docs]defbroadcast_axes(self,*args,**kwargs):"""Convenience fluent method for :py:func:`broadcast_axes`. The arguments are the same as for :py:func:`broadcast_axes`, with this array as data. """returnop.broadcast_axes(self,*args,**kwargs)

defrepeat(self,*args,**kwargs):"""Convenience fluent method for :py:func:`repeat`. The arguments are the same as for :py:func:`repeat`, with this array as data. """returnop.repeat(self,*args,**kwargs)

[docs]defpad(self,*args,**kwargs):"""Convenience fluent method for :py:func:`pad`. The arguments are the same as for :py:func:`pad`, with this array as data. """returnop.pad(self,*args,**kwargs)

[docs]defswapaxes(self,*args,**kwargs):"""Convenience fluent method for :py:func:`swapaxes`. The arguments are the same as for :py:func:`swapaxes`, with this array as data. """returnop.swapaxes(self,*args,**kwargs)

defsplit(self,*args,**kwargs):"""Convenience fluent method for :py:func:`split`. The arguments are the same as for :py:func:`split`, with this array as data. """returnop.split(self,*args,**kwargs)

[docs]defslice(self,*args,**kwargs):"""Convenience fluent method for :py:func:`slice`. The arguments are the same as for :py:func:`slice`, with this array as data. """returnop.slice(self,*args,**kwargs)

[docs]defslice_axis(self,*args,**kwargs):"""Convenience fluent method for :py:func:`slice_axis`. The arguments are the same as for :py:func:`slice_axis`, with this array as data. """returnop.slice_axis(self,*args,**kwargs)

[docs]defslice_like(self,*args,**kwargs):"""Convenience fluent method for :py:func:`slice_like`. The arguments are the same as for :py:func:`slice_like`, with this array as data. """returnop.slice_like(self,*args,**kwargs)

[docs]deftake(self,*args,**kwargs):"""Convenience fluent method for :py:func:`take`. The arguments are the same as for :py:func:`take`, with this array as data. """returnop.take(self,*args,**kwargs)

[docs]defone_hot(self,*args,**kwargs):"""Convenience fluent method for :py:func:`one_hot`. The arguments are the same as for :py:func:`one_hot`, with this array as data. """returnop.one_hot(self,*args,**kwargs)

[docs]defpick(self,*args,**kwargs):"""Convenience fluent method for :py:func:`pick`. The arguments are the same as for :py:func:`pick`, with this array as data. """returnop.pick(self,*args,**kwargs)

[docs]defsort(self,*args,**kwargs):"""Convenience fluent method for :py:func:`sort`. The arguments are the same as for :py:func:`sort`, with this array as data. """returnop.sort(self,*args,**kwargs)

[docs]deftopk(self,*args,**kwargs):"""Convenience fluent method for :py:func:`topk`. The arguments are the same as for :py:func:`topk`, with this array as data. """returnop.topk(self,*args,**kwargs)

[docs]defargsort(self,*args,**kwargs):"""Convenience fluent method for :py:func:`argsort`. The arguments are the same as for :py:func:`argsort`, with this array as data. """returnop.argsort(self,*args,**kwargs)

[docs]defargmax(self,*args,**kwargs):"""Convenience fluent method for :py:func:`argmax`. The arguments are the same as for :py:func:`argmax`, with this array as data. """returnop.argmax(self,*args,**kwargs)

[docs]defargmax_channel(self,*args,**kwargs):"""Convenience fluent method for :py:func:`argmax_channel`. The arguments are the same as for :py:func:`argmax_channel`, with this array as data. """returnop.argmax_channel(self,*args,**kwargs)

[docs]defargmin(self,*args,**kwargs):"""Convenience fluent method for :py:func:`argmin`. The arguments are the same as for :py:func:`argmin`, with this array as data. """returnop.argmin(self,*args,**kwargs)

[docs]defclip(self,*args,**kwargs):"""Convenience fluent method for :py:func:`clip`. The arguments are the same as for :py:func:`clip`, with this array as data. """returnop.clip(self,*args,**kwargs)

defabs(self,*args,**kwargs):"""Convenience fluent method for :py:func:`abs`. The arguments are the same as for :py:func:`abs`, with this array as data. """returnop.abs(self,*args,**kwargs)

[docs]defsign(self,*args,**kwargs):"""Convenience fluent method for :py:func:`sign`. The arguments are the same as for :py:func:`sign`, with this array as data. """returnop.sign(self,*args,**kwargs)

[docs]defflatten(self,*args,**kwargs):"""Convenience fluent method for :py:func:`flatten`. The arguments are the same as for :py:func:`flatten`, with this array as data. """returnop.flatten(self,*args,**kwargs)

[docs]defshape_array(self,*args,**kwargs):"""Convenience fluent method for :py:func:`shape_array`. The arguments are the same as for :py:func:`shape_op`, with this array as data. """returnop.shape_array(self,*args,**kwargs)

[docs]defsize_array(self,*args,**kwargs):"""Convenience fluent method for :py:func:`size_array`. The arguments are the same as for :py:func:`size_array`, with this array as data. """returnop.size_array(self,*args,**kwargs)

[docs]defexpand_dims(self,*args,**kwargs):"""Convenience fluent method for :py:func:`expand_dims`. The arguments are the same as for :py:func:`expand_dims`, with this array as data. """returnop.expand_dims(self,*args,**kwargs)

[docs]defbroadcast_to(self,*args,**kwargs):"""Convenience fluent method for :py:func:`broadcast_to`. The arguments are the same as for :py:func:`broadcast_to`, with this array as data. """returnop.broadcast_to(self,*args,**kwargs)

[docs]defbroadcast_like(self,*args,**kwargs):"""Convenience fluent method for :py:func:`broadcast_like`. The arguments are the same as for :py:func:`broadcast_like`, with this array as data. """returnop.broadcast_like(self,*args,**kwargs)

[docs]deftile(self,*args,**kwargs):"""Convenience fluent method for :py:func:`tile`. The arguments are the same as for :py:func:`tile`, with this array as data. """returnop.tile(self,*args,**kwargs)

[docs]deftranspose(self,*args,**kwargs):"""Convenience fluent method for :py:func:`transpose`. The arguments are the same as for :py:func:`transpose`, with this array as data. """returnop.transpose(self,*args,**kwargs)

[docs]defflip(self,*args,**kwargs):"""Convenience fluent method for :py:func:`flip`. The arguments are the same as for :py:func:`flip`, with this array as data. """returnop.flip(self,*args,**kwargs)

[docs]defdepth_to_space(self,*args,**kwargs):"""Convenience fluent method for :py:func:`depth_to_space`. The arguments are the same as for :py:func:`depth_to_space`, with this array as data. """returnop.depth_to_space(self,*args,**kwargs)

[docs]defspace_to_depth(self,*args,**kwargs):"""Convenience fluent method for :py:func:`space_to_depth`. The arguments are the same as for :py:func:`space_to_depth`, with this array as data. """returnop.space_to_depth(self,*args,**kwargs)

[docs]defdiag(self,k=0,**kwargs):"""Convenience fluent method for :py:func:`diag`. The arguments are the same as for :py:func:`diag`, with this array as data. """returnop.diag(self,k,**kwargs)

[docs]defsum(self,*args,**kwargs):"""Convenience fluent method for :py:func:`sum`. The arguments are the same as for :py:func:`sum`, with this array as data. """returnop.sum(self,*args,**kwargs)

[docs]defnansum(self,*args,**kwargs):"""Convenience fluent method for :py:func:`nansum`. The arguments are the same as for :py:func:`nansum`, with this array as data. """returnop.nansum(self,*args,**kwargs)

[docs]defprod(self,*args,**kwargs):"""Convenience fluent method for :py:func:`prod`. The arguments are the same as for :py:func:`prod`, with this array as data. """returnop.prod(self,*args,**kwargs)

[docs]defnanprod(self,*args,**kwargs):"""Convenience fluent method for :py:func:`nanprod`. The arguments are the same as for :py:func:`nanprod`, with this array as data. """returnop.nanprod(self,*args,**kwargs)

[docs]defmean(self,*args,**kwargs):"""Convenience fluent method for :py:func:`mean`. The arguments are the same as for :py:func:`mean`, with this array as data. """returnop.mean(self,*args,**kwargs)

[docs]defmax(self,*args,**kwargs):"""Convenience fluent method for :py:func:`max`. The arguments are the same as for :py:func:`max`, with this array as data. """returnop.max(self,*args,**kwargs)

[docs]defmin(self,*args,**kwargs):"""Convenience fluent method for :py:func:`min`. The arguments are the same as for :py:func:`min`, with this array as data. """returnop.min(self,*args,**kwargs)

[docs]defnorm(self,*args,**kwargs):"""Convenience fluent method for :py:func:`norm`. The arguments are the same as for :py:func:`norm`, with this array as data. """returnop.norm(self,*args,**kwargs)

[docs]defround(self,*args,**kwargs):"""Convenience fluent method for :py:func:`round`. The arguments are the same as for :py:func:`round`, with this array as data. """returnop.round(self,*args,**kwargs)

[docs]defrint(self,*args,**kwargs):"""Convenience fluent method for :py:func:`rint`. The arguments are the same as for :py:func:`rint`, with this array as data. """returnop.rint(self,*args,**kwargs)

[docs]deffix(self,*args,**kwargs):"""Convenience fluent method for :py:func:`fix`. The arguments are the same as for :py:func:`fix`, with this array as data. """returnop.fix(self,*args,**kwargs)

[docs]deffloor(self,*args,**kwargs):"""Convenience fluent method for :py:func:`floor`. The arguments are the same as for :py:func:`floor`, with this array as data. """returnop.floor(self,*args,**kwargs)

[docs]defceil(self,*args,**kwargs):"""Convenience fluent method for :py:func:`ceil`. The arguments are the same as for :py:func:`ceil`, with this array as data. """returnop.ceil(self,*args,**kwargs)

[docs]deftrunc(self,*args,**kwargs):"""Convenience fluent method for :py:func:`trunc`. The arguments are the same as for :py:func:`trunc`, with this array as data. """returnop.trunc(self,*args,**kwargs)

[docs]defsin(self,*args,**kwargs):"""Convenience fluent method for :py:func:`sin`. The arguments are the same as for :py:func:`sin`, with this array as data. """returnop.sin(self,*args,**kwargs)

[docs]defcos(self,*args,**kwargs):"""Convenience fluent method for :py:func:`cos`. The arguments are the same as for :py:func:`cos`, with this array as data. """returnop.cos(self,*args,**kwargs)

[docs]deftan(self,*args,**kwargs):"""Convenience fluent method for :py:func:`tan`. The arguments are the same as for :py:func:`tan`, with this array as data. """returnop.tan(self,*args,**kwargs)

[docs]defarcsin(self,*args,**kwargs):"""Convenience fluent method for :py:func:`arcsin`. The arguments are the same as for :py:func:`arcsin`, with this array as data. """returnop.arcsin(self,*args,**kwargs)

[docs]defarccos(self,*args,**kwargs):"""Convenience fluent method for :py:func:`arccos`. The arguments are the same as for :py:func:`arccos`, with this array as data. """returnop.arccos(self,*args,**kwargs)

[docs]defarctan(self,*args,**kwargs):"""Convenience fluent method for :py:func:`arctan`. The arguments are the same as for :py:func:`arctan`, with this array as data. """returnop.arctan(self,*args,**kwargs)

[docs]defdegrees(self,*args,**kwargs):"""Convenience fluent method for :py:func:`degrees`. The arguments are the same as for :py:func:`degrees`, with this array as data. """returnop.degrees(self,*args,**kwargs)

[docs]defradians(self,*args,**kwargs):"""Convenience fluent method for :py:func:`radians`. The arguments are the same as for :py:func:`radians`, with this array as data. """returnop.radians(self,*args,**kwargs)

[docs]defsinh(self,*args,**kwargs):"""Convenience fluent method for :py:func:`sinh`. The arguments are the same as for :py:func:`sinh`, with this array as data. """returnop.sinh(self,*args,**kwargs)

[docs]defcosh(self,*args,**kwargs):"""Convenience fluent method for :py:func:`cosh`. The arguments are the same as for :py:func:`cosh`, with this array as data. """returnop.cosh(self,*args,**kwargs)

[docs]deftanh(self,*args,**kwargs):"""Convenience fluent method for :py:func:`tanh`. The arguments are the same as for :py:func:`tanh`, with this array as data. """returnop.tanh(self,*args,**kwargs)

[docs]defarcsinh(self,*args,**kwargs):"""Convenience fluent method for :py:func:`arcsinh`. The arguments are the same as for :py:func:`arcsinh`, with this array as data. """returnop.arcsinh(self,*args,**kwargs)

[docs]defarccosh(self,*args,**kwargs):"""Convenience fluent method for :py:func:`arccosh`. The arguments are the same as for :py:func:`arccosh`, with this array as data. """returnop.arccosh(self,*args,**kwargs)

[docs]defarctanh(self,*args,**kwargs):"""Convenience fluent method for :py:func:`arctanh`. The arguments are the same as for :py:func:`arctanh`, with this array as data. """returnop.arctanh(self,*args,**kwargs)

[docs]defexp(self,*args,**kwargs):"""Convenience fluent method for :py:func:`exp`. The arguments are the same as for :py:func:`exp`, with this array as data. """returnop.exp(self,*args,**kwargs)

[docs]defexpm1(self,*args,**kwargs):"""Convenience fluent method for :py:func:`expm1`. The arguments are the same as for :py:func:`expm1`, with this array as data. """returnop.expm1(self,*args,**kwargs)

[docs]deflog(self,*args,**kwargs):"""Convenience fluent method for :py:func:`log`. The arguments are the same as for :py:func:`log`, with this array as data. """returnop.log(self,*args,**kwargs)

[docs]deflog10(self,*args,**kwargs):"""Convenience fluent method for :py:func:`log10`. The arguments are the same as for :py:func:`log10`, with this array as data. """returnop.log10(self,*args,**kwargs)

[docs]deflog2(self,*args,**kwargs):"""Convenience fluent method for :py:func:`log2`. The arguments are the same as for :py:func:`log2`, with this array as data. """returnop.log2(self,*args,**kwargs)

[docs]deflog1p(self,*args,**kwargs):"""Convenience fluent method for :py:func:`log1p`. The arguments are the same as for :py:func:`log1p`, with this array as data. """returnop.log1p(self,*args,**kwargs)

[docs]defsqrt(self,*args,**kwargs):"""Convenience fluent method for :py:func:`sqrt`. The arguments are the same as for :py:func:`sqrt`, with this array as data. """returnop.sqrt(self,*args,**kwargs)

[docs]defrsqrt(self,*args,**kwargs):"""Convenience fluent method for :py:func:`rsqrt`. The arguments are the same as for :py:func:`rsqrt`, with this array as data. """returnop.rsqrt(self,*args,**kwargs)

[docs]defcbrt(self,*args,**kwargs):"""Convenience fluent method for :py:func:`cbrt`. The arguments are the same as for :py:func:`cbrt`, with this array as data. """returnop.cbrt(self,*args,**kwargs)

[docs]defrcbrt(self,*args,**kwargs):"""Convenience fluent method for :py:func:`rcbrt`. The arguments are the same as for :py:func:`rcbrt`, with this array as data. """returnop.rcbrt(self,*args,**kwargs)

[docs]defsquare(self,*args,**kwargs):"""Convenience fluent method for :py:func:`square`. The arguments are the same as for :py:func:`square`, with this array as data. """returnop.square(self,*args,**kwargs)

defreciprocal(self,*args,**kwargs):"""Convenience fluent method for :py:func:`reciprocal`. The arguments are the same as for :py:func:`reciprocal`, with this array as data. """returnop.reciprocal(self,*args,**kwargs)

[docs]defrelu(self,*args,**kwargs):"""Convenience fluent method for :py:func:`relu`. The arguments are the same as for :py:func:`relu`, with this array as data. """returnop.relu(self,*args,**kwargs)

[docs]defsigmoid(self,*args,**kwargs):"""Convenience fluent method for :py:func:`sigmoid`. The arguments are the same as for :py:func:`sigmoid`, with this array as data. """returnop.sigmoid(self,*args,**kwargs)

[docs]defsoftmax(self,*args,**kwargs):"""Convenience fluent method for :py:func:`softmax`. The arguments are the same as for :py:func:`softmax`, with this array as data. """returnop.softmax(self,*args,**kwargs)

[docs]deflog_softmax(self,*args,**kwargs):"""Convenience fluent method for :py:func:`log_softmax`. The arguments are the same as for :py:func:`log_softmax`, with this array as data. """returnop.log_softmax(self,*args,**kwargs)

defsoftmin(self,*args,**kwargs):"""Convenience fluent method for :py:func:`softmin`. The arguments are the same as for :py:func:`softmin`, with this array as data. """returnop.softmin(self,*args,**kwargs)defsqueeze(self,*args,**kwargs):"""Convenience fluent method for :py:func:`squeeze`. The arguments are the same as for :py:func:`squeeze`, with this array as data. """returnop.squeeze(self,*args,**kwargs)defget_backend_symbol(self,backend):"""Return symbol for target backend. Parameters ---------- backend : str The backend names. Returns ------- out : Symbol The created Symbol for target backend. """out=SymbolHandle()check_call(_LIB.MXGenBackendSubgraph(self.handle,c_str(backend),ctypes.byref(out)))returnSymbol(out)defwait_to_read(self):raiseNotImplementedForSymbol(self.wait_to_read,None)defasnumpy(self):raiseNotImplementedForSymbol(self.asnumpy,None)defasscalar(self):raiseNotImplementedForSymbol(self.asscalar,None)defcopy(self):raiseNotImplementedForSymbol(self.copy,None)defas_in_context(self):raiseNotImplementedForSymbol(self.as_in_context,None)defdetach(self):raiseNotImplementedForSymbol(self.detach,None)defbackward(self):raiseNotImplementedForSymbol(self.backward,None)

defvar(name,attr=None,shape=None,lr_mult=None,wd_mult=None,dtype=None,init=None,stype=None,**kwargs):"""Creates a symbolic variable with specified name. Example ------- >>> data = mx.sym.Variable('data', attr={'a': 'b'}) >>> data <Symbol data> >>> csr_data = mx.sym.Variable('csr_data', stype='csr') >>> csr_data <Symbol csr_data> >>> row_sparse_weight = mx.sym.Variable('weight', stype='row_sparse') >>> row_sparse_weight <Symbol weight> Parameters ---------- name : str Variable name. attr : Dict of strings Additional attributes to set on the variable. Format {string : string}. shape : tuple The shape of a variable. If specified, this will be used during the shape inference. If one has specified a different shape for this variable using a keyword argument when calling shape inference, this shape information will be ignored. lr_mult : float The learning rate multiplier for input variable. wd_mult : float Weight decay multiplier for input variable. dtype : str or numpy.dtype The dtype for input variable. If not specified, this value will be inferred. init : initializer (mxnet.init.*) Initializer for this variable to (optionally) override the default initializer. stype : str The storage type of the variable, such as 'row_sparse', 'csr', 'default', etc kwargs : Additional attribute variables Additional attributes must start and end with double underscores. Returns ------- variable : Symbol A symbol corresponding to an input to the computation graph. """ifnotisinstance(name,string_types):raiseTypeError('Expect a string for variable `name`')handle=SymbolHandle()check_call(_LIB.MXSymbolCreateVariable(c_str(name),ctypes.byref(handle)))ret=Symbol(handle)ifnothasattr(AttrScope._current,"value"):AttrScope._current.value=AttrScope()attr=AttrScope._current.value.get(attr)attr={}ifattrisNoneelseattrifshapeisnotNone:attr['__shape__']=str(shape)iflr_multisnotNone:attr['__lr_mult__']=str(lr_mult)ifwd_multisnotNone:attr['__wd_mult__']=str(wd_mult)ifdtypeisnotNone:attr['__dtype__']=str(_DTYPE_NP_TO_MX[_numpy.dtype(dtype).type])ifinitisnotNone:ifnotisinstance(init,string_types):init=init.dumps()attr['__init__']=initifstypeisnotNone:attr['__storage_type__']=str(_STORAGE_TYPE_STR_TO_ID[stype])fork,vinkwargs.items():ifk.startswith('__')andk.endswith('__'):attr[k]=str(v)else:raiseValueError('Attribute name=%s is not supported.'' Additional attributes must start and end with double underscores,'' e.g, __yourattr__'%k)ret._set_attr(**attr)returnret# for back compatibilityVariable=vardefGroup(symbols):"""Creates a symbol that contains a collection of other symbols, grouped together. Example ------- >>> a = mx.sym.Variable('a') >>> b = mx.sym.Variable('b') >>> mx.sym.Group([a,b]) <Symbol Grouped> Parameters ---------- symbols : list List of symbols to be grouped. Returns ------- sym : Symbol A group symbol. """ifnotsymbolsorany(notisinstance(sym,Symbol)forsyminsymbols):raiseTypeError('Expected a list of symbols as input')handle=SymbolHandle()check_call(_LIB.MXSymbolCreateGroup(mx_uint(len(symbols)),c_handle_array(symbols),ctypes.byref(handle)))returnSymbol(handle)defload(fname):"""Loads symbol from a JSON file. You can also use pickle to do the job if you only work on python. The advantage of load/save is the file is language agnostic. This means the file saved using save can be loaded by other language binding of mxnet. You also get the benefit being able to directly load/save from cloud storage(S3, HDFS). Parameters ---------- fname : str The name of the file, examples: - `s3://my-bucket/path/my-s3-symbol` - `hdfs://my-bucket/path/my-hdfs-symbol` - `/path-to/my-local-symbol` Returns ------- sym : Symbol The loaded symbol. See Also -------- Symbol.save : Used to save symbol into file. """ifnotisinstance(fname,string_types):raiseTypeError('fname need to be string')handle=SymbolHandle()check_call(_LIB.MXSymbolCreateFromFile(c_str(fname),ctypes.byref(handle)))returnSymbol(handle)defload_json(json_str):"""Loads symbol from json string. Parameters ---------- json_str : str A JSON string. Returns ------- sym : Symbol The loaded symbol. See Also -------- Symbol.tojson : Used to save symbol into json string. """ifnotisinstance(json_str,string_types):raiseTypeError('fname required to be string')handle=SymbolHandle()check_call(_LIB.MXSymbolCreateFromJSON(c_str(json_str),ctypes.byref(handle)))returnSymbol(handle)# pylint: disable=no-member# pylint: disable=redefined-builtindefpow(base,exp):"""Returns element-wise result of base element raised to powers from exp element. Both inputs can be Symbol or scalar number. Broadcasting is not supported. Use `broadcast_pow` instead. Parameters --------- base : Symbol or scalar The base symbol exp : Symbol or scalar The exponent symbol Returns ------- Symbol or scalar The bases in x raised to the exponents in y. Examples -------- >>> mx.sym.pow(2, 3) 8 >>> x = mx.sym.Variable('x') >>> y = mx.sym.Variable('y') >>> z = mx.sym.pow(x, 2) >>> z.eval(x=mx.nd.array([1,2]))[0].asnumpy() array([ 1., 4.], dtype=float32) >>> z = mx.sym.pow(3, y) >>> z.eval(y=mx.nd.array([2,3]))[0].asnumpy() array([ 9., 27.], dtype=float32) >>> z = mx.sym.pow(x, y) >>> z.eval(x=mx.nd.array([3,4]), y=mx.nd.array([2,3]))[0].asnumpy() array([ 9., 64.], dtype=float32) """ifisinstance(base,Symbol)andisinstance(exp,Symbol):return_internal._Power(base,exp)ifisinstance(base,Symbol)andisinstance(exp,Number):return_internal._PowerScalar(base,scalar=exp)ifisinstance(base,Number)andisinstance(exp,Symbol):return_internal._RPowerScalar(exp,scalar=base)ifisinstance(base,Number)andisinstance(exp,Number):returnbase**expelse:raiseTypeError('types (%s, %s) not supported'%(str(type(base)),str(type(exp))))# pylint: disable=no-member# pylint: disable=redefined-builtindefmaximum(left,right):"""Returns element-wise maximum of the input elements. Both inputs can be Symbol or scalar number. Broadcasting is not supported. Parameters --------- left : Symbol or scalar First symbol to be compared. right : Symbol or scalar Second symbol to be compared. Returns ------- Symbol or scalar The element-wise maximum of the input symbols. Examples -------- >>> mx.sym.maximum(2, 3.5) 3.5 >>> x = mx.sym.Variable('x') >>> y = mx.sym.Variable('y') >>> z = mx.sym.maximum(x, 4) >>> z.eval(x=mx.nd.array([3,5,2,10]))[0].asnumpy() array([ 4., 5., 4., 10.], dtype=float32) >>> z = mx.sym.maximum(x, y) >>> z.eval(x=mx.nd.array([3,4]), y=mx.nd.array([10,2]))[0].asnumpy() array([ 10., 4.], dtype=float32) """ifisinstance(left,Symbol)andisinstance(right,Symbol):return_internal._Maximum(left,right)ifisinstance(left,Symbol)andisinstance(right,Number):return_internal._MaximumScalar(left,scalar=right)ifisinstance(left,Number)andisinstance(right,Symbol):return_internal._MaximumScalar(right,scalar=left)ifisinstance(left,Number)andisinstance(right,Number):returnleftifleft>rightelserightelse:raiseTypeError('types (%s, %s) not supported'%(str(type(left)),str(type(right))))# pylint: disable=no-member# pylint: disable=redefined-builtindefminimum(left,right):"""Returns element-wise minimum of the input elements. Both inputs can be Symbol or scalar number. Broadcasting is not supported. Parameters --------- left : Symbol or scalar First symbol to be compared. right : Symbol or scalar Second symbol to be compared. Returns ------- Symbol or scalar The element-wise minimum of the input symbols. Examples -------- >>> mx.sym.minimum(2, 3.5) 2 >>> x = mx.sym.Variable('x') >>> y = mx.sym.Variable('y') >>> z = mx.sym.minimum(x, 4) >>> z.eval(x=mx.nd.array([3,5,2,10]))[0].asnumpy() array([ 3., 4., 2., 4.], dtype=float32) >>> z = mx.sym.minimum(x, y) >>> z.eval(x=mx.nd.array([3,4]), y=mx.nd.array([10,2]))[0].asnumpy() array([ 3., 2.], dtype=float32) """ifisinstance(left,Symbol)andisinstance(right,Symbol):return_internal._Minimum(left,right)ifisinstance(left,Symbol)andisinstance(right,Number):return_internal._MinimumScalar(left,scalar=right)ifisinstance(left,Number)andisinstance(right,Symbol):return_internal._MinimumScalar(right,scalar=left)ifisinstance(left,Number)andisinstance(right,Number):returnleftifleft<rightelserightelse:raiseTypeError('types (%s, %s) not supported'%(str(type(left)),str(type(right))))# pylint: disable=no-member# pylint: disable=redefined-builtindefhypot(left,right):"""Given the "legs" of a right triangle, returns its hypotenuse. Equivalent to :math:`\\sqrt(left^2 + right^2)`, element-wise. Both inputs can be Symbol or scalar number. Broadcasting is not supported. Parameters --------- left : Symbol or scalar First leg of the triangle(s). right : Symbol or scalar Second leg of the triangle(s). Returns ------- Symbol or scalar The hypotenuse of the triangle(s) Examples -------- >>> mx.sym.hypot(3, 4) 5.0 >>> x = mx.sym.Variable('x') >>> y = mx.sym.Variable('y') >>> z = mx.sym.hypot(x, 4) >>> z.eval(x=mx.nd.array([3,5,2]))[0].asnumpy() array([ 5., 6.40312433, 4.47213602], dtype=float32) >>> z = mx.sym.hypot(x, y) >>> z.eval(x=mx.nd.array([3,4]), y=mx.nd.array([10,2]))[0].asnumpy() array([ 10.44030666, 4.47213602], dtype=float32) """ifisinstance(left,Symbol)andisinstance(right,Symbol):return_internal._Hypot(left,right)ifisinstance(left,Symbol)andisinstance(right,Number):return_internal._HypotScalar(left,scalar=right)ifisinstance(left,Number)andisinstance(right,Symbol):return_internal._HypotScalar(right,scalar=left)ifisinstance(left,Number)andisinstance(right,Number):return_numpy.hypot(left,right)else:raiseTypeError('types (%s, %s) not supported'%(str(type(left)),str(type(right))))defeye(N,M=0,k=0,dtype=None,**kwargs):"""Returns a new symbol of 2-D shpae, filled with ones on the diagonal and zeros elsewhere. Parameters ---------- N: int Number of rows in the output. M: int, optional Number of columns in the output. If 0, defaults to N. k: int, optional Index of the diagonal: 0 (the default) refers to the main diagonal, a positive value refers to an upper diagonal, and a negative value to a lower diagonal. dtype : str or numpy.dtype, optional The value type of the inner value, default to ``np.float32``. Returns ------- out : Symbol The created Symbol. """ifdtypeisNone:dtype=_numpy.float32return_internal._eye(N,M,k,dtype=dtype,**kwargs)defzeros(shape,dtype=None,**kwargs):"""Returns a new symbol of given shape and type, filled with zeros. Parameters ---------- shape : int or sequence of ints Shape of the new array. dtype : str or numpy.dtype, optional The value type of the inner value, default to ``np.float32``. Returns ------- out : Symbol The created Symbol. """ifdtypeisNone:dtype=_numpy.float32return_internal._zeros(shape=shape,dtype=dtype,**kwargs)defones(shape,dtype=None,**kwargs):"""Returns a new symbol of given shape and type, filled with ones. Parameters ---------- shape : int or sequence of ints Shape of the new array. dtype : str or numpy.dtype, optional The value type of the inner value, default to ``np.float32``. Returns ------- out : Symbol The created Symbol """ifdtypeisNone:dtype=_numpy.float32return_internal._ones(shape=shape,dtype=dtype,**kwargs)deffull(shape,val,dtype=None,**kwargs):"""Returns a new array of given shape and type, filled with the given value `val`. Parameters ---------- shape : int or sequence of ints Shape of the new array. val : scalar Fill value. dtype : str or numpy.dtype, optional The value type of the inner value, default to ``np.float32``. Returns ------- out : Symbol The created Symbol """ifdtypeisNone:dtype=_numpy.float32return_internal._full(shape=shape,dtype=dtype,value=float(val),**kwargs)# pylint: disable=redefined-outer-namedefarange(start,stop=None,step=1.0,repeat=1,infer_range=False,name=None,dtype=None):"""Returns evenly spaced values within a given interval. Parameters ---------- start : number Start of interval. The interval includes this value. The default start value is 0. stop : number, optional End of interval. The interval does not include this value. step : number, optional Spacing between values. repeat : int, optional "The repeating time of all elements. E.g repeat=3, the element a will be repeated three times --> a, a, a. infer_range : boolean, optional When set to True, infer the stop position from the start, step, repeat, and output tensor size. dtype : str or numpy.dtype, optional The value type of the inner value, default to ``np.float32``. Returns ------- out : Symbol The created Symbol """ifdtypeisNone:dtype=_numpy.float32return_internal._arange(start=start,stop=stop,step=step,repeat=repeat,infer_range=infer_range,name=name,dtype=dtype)defhistogram(a,bins=10,range=None,**kwargs):"""Compute the histogram of the input data. Parameters ---------- a : NDArray Input data. The histogram is computed over the flattened array. bins : int or sequence of scalars If bins is an int, it defines the number of equal-width bins in the given range (10, by default). If bins is a sequence, it defines the bin edges, including the rightmost edge, allowing for non-uniform bin widths. range : (float, float), required if bins is an integer The lower and upper range of the bins. If not provided, range is simply (a.min(), a.max()). Values outside the range are ignored. The first element of the range must be less than or equal to the second. range affects the automatic bin computation as well, the range will be equally divided by the number of bins. """ifisinstance(bins,Symbol):return_internal._histogram(data=a,bins=bins,**kwargs)elifisinstance(bins,integer_types):ifrangeisNone:raiseValueError("null range is not supported in symbol mode")return_internal._histogram(data=a,bin_cnt=bins,range=range,**kwargs)raiseValueError("bins argument should be either an integer or an NDArray")_set_symbol_class(Symbol)