How to create a Tensor#

Note

  • Creating Tensor and NumPy create arrays in MegEngine in <https://numpy.org/doc/stable/user/basics.creation.html>similar way _ of;

  • Since ndarray is a more commonly supported format in the Python data science community (for example, SciPy, Pandas, OpenCV and other libraries provide good support for ndarray), if there is a creation method that NumPy has been implemented but MegEngine has not yet supported, you can create NumPy first ndarray, and then convert it to MegEngine Tensor. It is also the last method mentioned below.

Common way to create Tensor follows:

Warning

Any way to create a Tensor from existing data is created by copying, and does not share memory with the original data.

Convert Python sequence to Tensor#

The MegEngine Tensor can be defined using Python sequences (such as lists and tuples).

List: py:class:list and tuple: py:class:tuple are defined with [...] and (...) respectively, which can be used to define how Tensor creates:

  • A list of numbers will create a 1-dimensional Tensor;

  • A list of lists will create a 2-dimensional Tensor;

  • In the same way, further nesting of the list will create a higher-dimensional Tensor.

>>> a1D = megengine.Tensor([1, 2, 3, 4])
>>> a2D = megengine.Tensor([[1, 2], [3, 4]])
>>> a3D = megengine.Tensor([[[1, 2], [3, 4]], [[5, 6], [7, 8]]])

Warning

  • This way of writing actually calls the constructor of the: py:class:~.megengine.Tensor class, passing in the ``data’’ parameter;

  • megengine.tensor is an alias of megengine.Tensor, **there is essentially no difference between the two. **

See also

To convert Tensor to Python built-in data type, you can use: py:meth:~.Tensor.item or tolist.

Default data type#

See also

When you use: py: class: megengine.Tensor to define a new Tensor, the need to consider where each element :ref:’data type <tensor-dtype>’.

The default behavior is to create a Tensor with a 32-bit signed integer int32 or a floating point number ``float32’’.

>>> megengine.Tensor([1, 2, 3, 4]).dtype
numpy.int32
>>> megengine.Tensor([1., 2., 3., 4.]).dtype
numpy.float32

If the Tensor you want is a certain data type, you need to specify the dtype explicitly when creating the Tensor.

Specify the data type when creating#

The data type can be explicitly specified, but explicitly specifying dtype may cause unexpected overflow, such as:

>>> a = megengine.Tensor([127, 128, 129], dtype="int8")
>>> a
Tensor([ 127 -128 -127], dtype=int8, device=xpux:0)

An 8-bit signed integer represents an integer from -128 to 127. Assigning an int8 Tensor to an integer outside this range will cause an overflow.

If you perform calculations with unmatched data types, you may get unexpected results, such as:

>>> a = megengine.Tensor([2, 3, 4], dtype="uint8")
>>> b = megengine.Tensor([5, 6, 7], dtype="uint8")
>>> a - b
Tensor([253 253 253], dtype=uint8, device=xpux:0)

You may expect the result to be [-3, -3, -3], but under the uint8 data type, these values will be represented as 253.

Calculations between different data types#

Note that the above two Tensors, a and b, have the same dtype: uint8, so the data type of the resulting Tensor will also be the same. If you Tensor calculated between the two different `` dtype``, MegEngine type lifting will be required to meet the computing:

>>> a - b.astype("int8")
Tensor([-3 -3 -3], dtype=int16, device=xpux:0)

Note that a'' with data type ``uint8 and b with data type ``int8’’ are calculated, and finally a Tensor with data type ``int16’’ is obtained.

Use built-in functions to create Tensor#

Note

  • The functional sub-package of MegEngine has built-in functions for creating Tensor (located at creation);

  • The default data type of Tensor created using these functions is ``float32’’.

The dimensions thereof created by Tensor, these functions can generally be divided into three categories:

Create a 1-dimensional Tensor#

The functions to create a 1-dimensional Tensor such as: py:func:~.arange and linspace usually require at least two inputs, namely start and stop.

arange will create a Tensor with regularly increasing values, some usages are shown below:

>>> megengine.functional.arange(10)
Tensor([0. 1. 2. 3. 4. 5. 6. 7. 8. 9.], device=xpux:0)
>>> megengine.functional.arange(2, 10, dtype="float")
Tensor([2. 3. 4. 5. 6. 7. 8. 9.], device=xpux:0)
>>> megengine.functional.arange(2, 3, 0.1)
Tensor([2.  2.1 2.2 2.3 2.4 2.5 2.6 2.7 2.8 2.9], device=xpux:0)

The value in the Tensor obtained by using this function does not include the end point ``stop’’, that is, the range is ``(start, stop)’’.

linspace will create a Tensor with the specified number of elements, and spaced equally between the specified start value and end value. For example:

>>> megengine.functional.linspace(1., 4., 6)
Tensor([1.  1.6 2.2 2.8 3.4 4. ], device=xpux:0)

The advantage of using this function is that it can guarantee the number of elements in the Tensor, the starting point and the ending point of the value.

Note

The best practice for using arange in NumPy is to use integer start, stop and step values. This is due to the machine showing the existence of floating point rounding error, it is possible to `` arange`` non-integer values obtained when an incoming unintended consequences:

>>> np.arange(7.8, 8.4, 0.05)
array([7.8 , 7.85, 7.9 , 7.95, 8.  , 8.05, 8.1 , 8.15, 8.2 , 8.25, 8.3 ,
    8.35, 8.4 ])

Due to the accumulation of floating-point errors in NumPy, the final result will see the value 8.4.

In the MegEngine, `` arange`` internal calls `` linspace`` be achieved with the result obtained at this time is different from the NumPy:

>>> megengine.functional.arange(7.8, 8.4, 0.05)
Tensor([7.8  7.85 7.9  7.95 8.   8.05 8.1  8.15 8.2  8.25 8.3  8.35], device=xpux:0)

Create a 2-dimensional Tensor#

The function to create a 2-dimensional Tensor is usually defined by the attributes of a special matrix expressed as a 2-dimensional array.

For example: py:func:~.eye defines a 2-dimensional identity matrix, the elements with the same row index and column index are 1, and the rest are 0, as shown below:

>>> megengine.functional.eye(3)
Tensor([[1. 0. 0.]
 [0. 1. 0.]
 [0. 0. 1.]], device=xpux:0)
>>> megengine.functional.eye(3, 5)
Tensor([[1. 0. 0. 0. 0.]
 [0. 1. 0. 0. 0.]
 [0. 0. 1. 0. 0.]], device=xpux:0)

Create n-dimensional Tensor#

Such functions such as: py:func:~.ones, zeros can usually create a Tensor according to a given shape.

>>> megengine.functional.zeros((2, 3))
Tensor([[0. 0. 0.]
 [0. 0. 0.]], device=xpux:0)
>>> megengine.functional.zeros((2, 3, 2))
Tensor([[[0. 0.]
  [0. 0.]
  [0. 0.]]
 [[0. 0.]
  [0. 0.]
  [0. 0.]]], device=xpux:0)

See also

  • In essence, they are all achieved by calling: py:func:~.full to create a Tensor that meets the given shape and value;

  • Use zeros_like, ones_like, full_like to create according to the input Tensor shape.

Randomly generated using random sub-package#

For example, use: py:func:~.random.normal to sample:

>>> a = megengine.random.normal(100, 1, (5,))
Tensor([ 99.8308 101.949  100.2816 101.8977  99.9773], device=xpux:0)

Use: py:func:~.random.uniform to sample:

>>> megengine.random.uniform(10, 20, (5,))
Tensor([12.557  17.8996 10.0152 18.2324 11.2644], device=xpux:0)

See also

Operate based on existing Tensor#

Note

Use: py:func:~.functional.copy function to copy a Tensor.

See also

For more details, please refer to the How to operate Tensor page.

Convert NumPy ndarray to MegEngine Tensor#

We can also pass: py:class:~.megengine.Tensor, pass in ndarray as input data to get the corresponding Tensor.

>>> a = np.array([1, 2, 3])
>>> a.dtype
dtype('int64')
>>> b = megengine.Tensor(a)
>>> Tensor([1 2 3], dtype=int32, device=xpux:0)
Tensor([1 2 3], dtype=int32, device=xpux:0)

Through Tensor’s numpy method, we can get the result of Tensor converted to ndarray:

>>> b.numpy()
array([1, 2, 3], dtype=int32)

See also

Related precautions, such as data type, are consistent with Convert Python sequence to Tensor.