blob: f1204e2196b3747b6e7a4788734c74b0d11bcef4 [file] [log] [blame]
{
"cells": [
{
"cell_type": "markdown",
"id": "45d23af0",
"metadata": {},
"source": [
"<!--- Licensed to the Apache Software Foundation (ASF) under one -->\n",
"<!--- or more contributor license agreements. See the NOTICE file -->\n",
"<!--- distributed with this work for additional information -->\n",
"<!--- regarding copyright ownership. The ASF licenses this file -->\n",
"<!--- to you under the Apache License, Version 2.0 (the -->\n",
"<!--- \"License\"); you may not use this file except in compliance -->\n",
"<!--- with the License. You may obtain a copy of the License at -->\n",
"\n",
"<!--- http://www.apache.org/licenses/LICENSE-2.0 -->\n",
"\n",
"<!--- Unless required by applicable law or agreed to in writing, -->\n",
"<!--- software distributed under the License is distributed on an -->\n",
"<!--- \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -->\n",
"<!--- KIND, either express or implied. See the License for the -->\n",
"<!--- specific language governing permissions and limitations -->\n",
"<!--- under the License. -->\n",
"\n",
"# Step 1: Manipulate data with NP on MXNet\n",
"\n",
"This getting started exercise introduces the MXNet `np` package for ndarrays.\n",
"These ndarrays extend the functionality of the common NumPy ndarrays, by adding\n",
"support for gpu's and by adding auto-differentiation with autograd. Now, many\n",
"NumPy methods are available within MXNet; therefore, we will only briefly cover\n",
"some of what is available.\n",
"\n",
"## Import packages and create an array\n",
"To get started, run the following commands to import the `np` package together\n",
"with the NumPy extensions package `npx`. Together, `np` with `npx` make up the\n",
"NP on MXNet front end."
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "90e6cf9f",
"metadata": {},
"outputs": [],
"source": [
"import mxnet as mx\n",
"from mxnet import np, npx\n",
"npx.set_np() # Activate NumPy-like mode."
]
},
{
"cell_type": "markdown",
"id": "d881060f",
"metadata": {},
"source": [
"In this step, create a 2D array (also called a matrix). The following code\n",
"example creates a matrix with values from two sets of numbers: 1, 2, 3 and 4, 5,\n",
"6. This might also be referred to as a tuple of a tuple of integers."
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "29deaf0d",
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"[03:51:52] /work/mxnet/src/storage/storage.cc:202: Using Pooled (Naive) StorageManager for CPU\n"
]
},
{
"data": {
"text/plain": [
"array([[1., 2., 3.],\n",
" [5., 6., 7.]])"
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"np.array(((1, 2, 3), (5, 6, 7)))"
]
},
{
"cell_type": "markdown",
"id": "61329fe2",
"metadata": {},
"source": [
"You can also create a very simple matrix with the same shape (2 rows by 3\n",
"columns), but fill it with 1's."
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "9f6a5ec1",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[1, 1, 1],\n",
" [1, 1, 1]], dtype=int64)"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"x = np.full((2, 3), 1) \n",
"x"
]
},
{
"cell_type": "markdown",
"id": "00e4fe3c",
"metadata": {},
"source": [
"Alternatively, you could use the following array creation routine."
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "5f424812",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[1., 1., 1.],\n",
" [1., 1., 1.]])"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"x = np.ones((2, 3)) \n",
"x"
]
},
{
"cell_type": "markdown",
"id": "a366b941",
"metadata": {},
"source": [
"You can create arrays whose values are sampled randomly. For example, sampling\n",
"values uniformly between -1 and 1. The following code example creates the same\n",
"shape, but with random sampling."
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "143f0926",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[-0.9364808 , 0.16642416, 0.52422976],\n",
" [ 0.739336 , -0.68318725, 0.50007904]])"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"y = np.random.uniform(-1, 1, (2, 3))\n",
"y"
]
},
{
"cell_type": "markdown",
"id": "79c1e28c",
"metadata": {},
"source": [
"As with NumPy, the dimensions of each ndarray are shown by accessing the\n",
"`.shape` attribute. As the following code example shows, you can also query for\n",
"`size`, which is equal to the product of the components of the shape. In\n",
"addition, `.dtype` tells the data type of the stored values. As you notice when\n",
"we generate random uniform values we generate `float32` not `float64` as normal\n",
"NumPy arrays."
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "968dc216",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"((2, 3), 6, dtype('float32'))"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"(x.shape, x.size, x.dtype)"
]
},
{
"cell_type": "markdown",
"id": "748ccb47",
"metadata": {},
"source": [
"You could also specifiy the datatype when you create your ndarray."
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "e2853502",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"dtype('int8')"
]
},
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"x = np.full((2, 3), 1, dtype=\"int8\") \n",
"x.dtype"
]
},
{
"cell_type": "markdown",
"id": "3f7ca385",
"metadata": {},
"source": [
"Versus the default of `float32`."
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "2cabe402",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"dtype('int64')"
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"x = np.full((2, 3), 1) \n",
"x.dtype"
]
},
{
"cell_type": "markdown",
"id": "6fc21c3f",
"metadata": {},
"source": [
"When we multiply, by default we use the datatype with the most precision."
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "8635a98a",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"dtype('float32')"
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"x = x.astype(\"int8\") + x.astype(int) + x.astype(\"float32\")\n",
"x.dtype"
]
},
{
"cell_type": "markdown",
"id": "6017862f",
"metadata": {},
"source": [
"## Performing operations on an array\n",
"\n",
"A ndarray supports a large number of standard mathematical operations. Here are\n",
"some examples. You can perform element-wise multiplication by using the\n",
"following code example."
]
},
{
"cell_type": "code",
"execution_count": 10,
"id": "e5ec935e",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[-2.8094425 , 0.49927247, 1.5726893 ],\n",
" [ 2.218008 , -2.0495617 , 1.5002371 ]])"
]
},
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"x * y"
]
},
{
"cell_type": "markdown",
"id": "0a4d26fe",
"metadata": {},
"source": [
"You can perform exponentiation by using the following code example."
]
},
{
"cell_type": "code",
"execution_count": 11,
"id": "1acef361",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[0.39200494, 1.1810739 , 1.6891572 ],\n",
" [2.0945444 , 0.5050048 , 1.6488516 ]])"
]
},
"execution_count": 11,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"np.exp(y)"
]
},
{
"cell_type": "markdown",
"id": "9c25f445",
"metadata": {},
"source": [
"You can also find a matrix’s transpose to compute a proper matrix-matrix product\n",
"by using the following code example."
]
},
{
"cell_type": "code",
"execution_count": 12,
"id": "429922d3",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[-0.7374809, 1.6686834],\n",
" [-0.7374809, 1.6686834]])"
]
},
"execution_count": 12,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"np.dot(x, y.T)"
]
},
{
"cell_type": "markdown",
"id": "917baffa",
"metadata": {},
"source": [
"Alternatively, you could use the matrix multiplication function."
]
},
{
"cell_type": "code",
"execution_count": 13,
"id": "5aaabbe2",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[-0.7374809, 1.6686834],\n",
" [-0.7374809, 1.6686834]])"
]
},
"execution_count": 13,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"np.matmul(x, y.T)"
]
},
{
"cell_type": "markdown",
"id": "4ba5dcf6",
"metadata": {},
"source": [
"You can leverage built in operators, like summation."
]
},
{
"cell_type": "code",
"execution_count": 14,
"id": "96162bab",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array(18.)"
]
},
"execution_count": 14,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"x.sum()"
]
},
{
"cell_type": "markdown",
"id": "9cdd9460",
"metadata": {},
"source": [
"You can also gather a mean value."
]
},
{
"cell_type": "code",
"execution_count": 15,
"id": "bee6b82a",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array(3.)"
]
},
"execution_count": 15,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"x.mean()"
]
},
{
"cell_type": "markdown",
"id": "80fb7fb8",
"metadata": {},
"source": [
"You can perform flatten and reshape just like you normally would in NumPy!"
]
},
{
"cell_type": "code",
"execution_count": 16,
"id": "a0eefd14",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([3., 3., 3., 3., 3., 3.])"
]
},
"execution_count": 16,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"x.flatten()"
]
},
{
"cell_type": "code",
"execution_count": 17,
"id": "cdbe9c14",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[3.],\n",
" [3.],\n",
" [3.],\n",
" [3.],\n",
" [3.],\n",
" [3.]])"
]
},
"execution_count": 17,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"x.reshape(6, 1)"
]
},
{
"cell_type": "markdown",
"id": "37b5433d",
"metadata": {},
"source": [
"## Indexing an array\n",
"\n",
"The ndarrays support slicing in many ways you might want to access your data.\n",
"The following code example shows how to read a particular element, which returns\n",
"a 1D array with shape `(1,)`."
]
},
{
"cell_type": "code",
"execution_count": 18,
"id": "b73bf348",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array(0.50007904)"
]
},
"execution_count": 18,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"y[1, 2]"
]
},
{
"cell_type": "markdown",
"id": "d0e5561f",
"metadata": {},
"source": [
"This example shows how to read the second and third columns from `y`."
]
},
{
"cell_type": "code",
"execution_count": 19,
"id": "10686a42",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[ 0.16642416, 0.52422976],\n",
" [-0.68318725, 0.50007904]])"
]
},
"execution_count": 19,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"y[:, 1:3]"
]
},
{
"cell_type": "markdown",
"id": "14b01434",
"metadata": {},
"source": [
"This example shows how to write to a specific element."
]
},
{
"cell_type": "code",
"execution_count": 20,
"id": "4d27cc54",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[-0.9364808, 2. , 2. ],\n",
" [ 0.739336 , 2. , 2. ]])"
]
},
"execution_count": 20,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"y[:, 1:3] = 2\n",
"y"
]
},
{
"cell_type": "markdown",
"id": "75a9d982",
"metadata": {},
"source": [
"You can perform multi-dimensional slicing, which is shown in the following code\n",
"example."
]
},
{
"cell_type": "code",
"execution_count": 21,
"id": "edfc61f4",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[-0.9364808, 2. , 2. ],\n",
" [ 4. , 4. , 2. ]])"
]
},
"execution_count": 21,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"y[1:2, 0:2] = 4\n",
"y"
]
},
{
"cell_type": "markdown",
"id": "3b3ac5b4",
"metadata": {},
"source": [
"## Converting between MXNet ndarrays and NumPy arrays\n",
"\n",
"You can convert MXNet ndarrays to and from NumPy ndarrays, as shown in the\n",
"following example. The converted arrays do not share memory."
]
},
{
"cell_type": "code",
"execution_count": 22,
"id": "abf80d1b",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(numpy.ndarray,\n",
" array([[3., 3., 3.],\n",
" [3., 3., 3.]], dtype=float32))"
]
},
"execution_count": 22,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"a = x.asnumpy()\n",
"(type(a), a)"
]
},
{
"cell_type": "code",
"execution_count": 23,
"id": "5ddeab66",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(mxnet.numpy.ndarray,\n",
" array([[3., 3., 3.],\n",
" [3., 3., 3.]]))"
]
},
"execution_count": 23,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"a = np.array(a)\n",
"(type(a), a)"
]
},
{
"cell_type": "markdown",
"id": "9416b60f",
"metadata": {},
"source": [
"Additionally, you can move them to different GPU devices. You will dive more\n",
"into this later, but here is an example for now."
]
},
{
"cell_type": "code",
"execution_count": 24,
"id": "c02f7062",
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"[03:51:54] /work/mxnet/src/storage/storage.cc:202: Using Pooled (Naive) StorageManager for GPU\n"
]
},
{
"data": {
"text/plain": [
"array([[3., 3., 3.],\n",
" [3., 3., 3.]], device=gpu(0))"
]
},
"execution_count": 24,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"a.copyto(mx.gpu(0))"
]
},
{
"cell_type": "markdown",
"id": "1aa1bd2d",
"metadata": {},
"source": [
"## Next Steps\n",
"\n",
"Ndarrays also have some additional features which make Deep Learning possible\n",
"and efficient. Namely, differentiation, and being able to leverage GPU's.\n",
"Another important feature of ndarrays that we will discuss later is \n",
"autograd. But first, we will abstract an additional level and talk about building\n",
"Neural Network Layers [Step 2: Create a neural network](./2-create-nn.ipynb)"
]
}
],
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}