Skip to content

Instantly share code, notes, and snippets.

@mvoelk
Last active April 30, 2025 15:08
Show Gist options
  • Save mvoelk/7fafa31e2b63c194cf93a3b7913dfa32 to your computer and use it in GitHub Desktop.
Save mvoelk/7fafa31e2b63c194cf93a3b7913dfa32 to your computer and use it in GitHub Desktop.
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"# Overview\n",
"\n",
"Gist https://gist.github.com/mvoelk/7fafa31e2b63c194cf93a3b7913dfa32\n",
"\n",
"Google Colab https://colab.research.google.com/gist/mvoelk/7fafa31e2b63c194cf93a3b7913dfa32\n",
"\n",
"- **Jupyter Notebook** is what you see here, an interactive Python shell and a document format\n",
"- **NumPy** is a Python library for matrix calculation, linear algebra, etc., similar to MATLAB\n",
"- **Matplotlib** is plotting library, similar to the MATLAB plot functions, and is often used with NumPy\n",
"- **TensorFlow** works similar to NumPy, but offers GPU support and allows automatic differentiation (backpropagation) for neural networks training\n",
"- **Keras** is a high level API for Deep Learning on top of TensorFlow, PyTorch or JAX\n",
"- **Pandas** is a library for data analysis and manipulation"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Numpy\n",
"\n",
"Deep learning libraries like TensorFlow and PyTorch come with NumPy-like low-level API"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'1.24.4'"
]
},
"execution_count": 1,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"import numpy as np\n",
"\n",
"np.__version__"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"from numpy import *"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([], dtype=float64)"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"array([])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Arrays"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([1, 2, 3, 4, 5])"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# 1D Array\n",
"np.array([1, 2, 3, 4, 5])"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[1, 2, 3],\n",
" [4, 5, 6]])"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# 2D Array\n",
"np.array([\n",
" [1, 2, 3],\n",
" [4, 5, 6],\n",
"])"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[[1, 2, 3],\n",
" [4, 5, 6]],\n",
"\n",
" [[1, 2, 3],\n",
" [4, 5, 6]]])"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# 3D Array\n",
"np.array([[[1, 2, 3], [4, 5, 6]], [[1, 2, 3], [4, 5, 6]]])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Shape"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[1, 2, 3, 4],\n",
" [5, 6, 7, 8]])"
]
},
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"a = np.array([[1, 2, 3, 4], [5, 6, 7, 8]])\n",
"a"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(2, 4)"
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"a.shape"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[1, 2],\n",
" [3, 4],\n",
" [5, 6],\n",
" [7, 8]])"
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"np.reshape(a, (4,2))"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([1, 2, 3, 4, 5, 6, 7, 8])"
]
},
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"np.reshape(a, (-1,))"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[[[[1, 2, 3, 4]]]]])"
]
},
"execution_count": 11,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"a = np.array([1, 2, 3, 4], ndmin=5)\n",
"a"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(1, 1, 1, 1, 4)"
]
},
"execution_count": 12,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"a.shape"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Indexing"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"2"
]
},
"execution_count": 13,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"a = np.array([1, 2, 3, 4, 5])\n",
"\n",
"a[1]"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"4"
]
},
"execution_count": 14,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"a[-2]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"by list of indices"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([2, 5, 4])"
]
},
"execution_count": 15,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"a[[1,4,3]]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Slicing\n",
"\n",
"Takes elements from one given index to another given index\n",
"\n",
"- Slice instead of index have the notation [start:end:step]\n",
"- Start is considered 0 if omitted\n",
"- Step is considered 1 if omitted\n",
"- The result includes the start index, but excludes the end index"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([1, 3])"
]
},
"execution_count": 16,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"a = np.array([1, 2, 3, 4, 5])\n",
"\n",
"a[0:4:2]"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([6, 7])"
]
},
"execution_count": 17,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"a = np.array([[[1, 2, 3], [4, 5, 6]], [[1, 2, 3], [4, 5, 7]]])\n",
"\n",
"a[:,1,2]"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(2, 2, 3)"
]
},
"execution_count": 18,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"a.shape"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[3],\n",
" [3]])"
]
},
"execution_count": 19,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"a[:,0:1,2]"
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[2, 5],\n",
" [2, 5]])"
]
},
"execution_count": 20,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"a[...,1] # ellipsis notation, in this case equivalent to a[:,:,1]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Broadcasting"
]
},
{
"cell_type": "code",
"execution_count": 21,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[62, 64, 66],\n",
" [42, 44, 46]])"
]
},
"execution_count": 21,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"a1 = np.array([\n",
" [21, 22, 23], \n",
" [1, 2, 3]]\n",
")\n",
"\n",
"a2 = np.array(\n",
" [41, 42, 43]\n",
")\n",
"\n",
"a1 + a2"
]
},
{
"cell_type": "code",
"execution_count": 22,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"((2, 3), (3,))"
]
},
"execution_count": 22,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"a1.shape, a2.shape"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Data Types"
]
},
{
"cell_type": "code",
"execution_count": 23,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"dtype('int64')"
]
},
"execution_count": 23,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"a = np.array([[1,2,3]])\n",
"a.dtype"
]
},
{
"cell_type": "code",
"execution_count": 24,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[1, 2, 3]], dtype=int32)"
]
},
"execution_count": 24,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"np.array([[1,2,3]], dtype='int32')"
]
},
{
"cell_type": "code",
"execution_count": 25,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[1., 2., 3.]], dtype=float32)"
]
},
"execution_count": 25,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"np.array([[1,2,3]], dtype='float32')"
]
},
{
"cell_type": "code",
"execution_count": 26,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[1, 2, 3]], dtype=int8)"
]
},
"execution_count": 26,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"np.array([[1,2,3]], dtype=np.int8)"
]
},
{
"cell_type": "code",
"execution_count": 27,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[1., 2., 3.]], dtype=float32)"
]
},
"execution_count": 27,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"np.float32([[1,2,3]])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Copy vs View"
]
},
{
"cell_type": "code",
"execution_count": 28,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(array([42, 2, 3, 4, 5]), array([1, 2, 3, 4, 5]))"
]
},
"execution_count": 28,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"a = np.array([1, 2, 3, 4, 5])\n",
"c = a.copy()\n",
"a[0] = 42\n",
"a, c"
]
},
{
"cell_type": "code",
"execution_count": 29,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(array([42, 2, 3, 4, 5]), array([42, 2, 3, 4, 5]))"
]
},
"execution_count": 29,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"a = np.array([1, 2, 3, 4, 5])\n",
"v = a.view()\n",
"a[0] = 42\n",
"a, v"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Check with the base attribute if an array owns its data\n",
"- The copy owns its data and returns None\n",
"- The view does not own its data and returns the owner array"
]
},
{
"cell_type": "code",
"execution_count": 30,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"None\n",
"[42 2 3 4 5]\n"
]
}
],
"source": [
"print(a.base)\n",
"print(v.base)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Iteration"
]
},
{
"cell_type": "code",
"execution_count": 31,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(array([[[ 0, 1],\n",
" [ 2, 3]],\n",
" \n",
" [[ 4, 5],\n",
" [ 6, 7]],\n",
" \n",
" [[ 8, 9],\n",
" [10, 11]]]),\n",
" (3, 2, 2))"
]
},
"execution_count": 31,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"a = np.arange(12).reshape((3,2,-1))\n",
"a, a.shape"
]
},
{
"cell_type": "code",
"execution_count": 32,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"0 1 2 3 4 5 6 7 8 9 10 11 "
]
}
],
"source": [
"for x in a:\n",
" for y in x:\n",
" for z in y:\n",
" print(z, end=' ')"
]
},
{
"cell_type": "code",
"execution_count": 33,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"0 1 2 3 4 5 6 7 8 9 10 11 "
]
}
],
"source": [
"for x in np.nditer(a):\n",
" print(x, end=' ')"
]
},
{
"cell_type": "code",
"execution_count": 34,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"(0, 0, 0) 0\n",
"(0, 0, 1) 1\n",
"(0, 1, 0) 2\n",
"(0, 1, 1) 3\n",
"(1, 0, 0) 4\n",
"(1, 0, 1) 5\n",
"(1, 1, 0) 6\n",
"(1, 1, 1) 7\n",
"(2, 0, 0) 8\n",
"(2, 0, 1) 9\n",
"(2, 1, 0) 10\n",
"(2, 1, 1) 11\n"
]
}
],
"source": [
"for idx, x in np.ndenumerate(a):\n",
" print(idx, x)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Join and Split"
]
},
{
"cell_type": "code",
"execution_count": 35,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([1, 2, 3, 4, 5, 6])"
]
},
"execution_count": 35,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"a1 = np.array([1, 2, 3])\n",
"a2 = np.array([4, 5, 6])\n",
"\n",
"np.concatenate((a1, a2))"
]
},
{
"cell_type": "code",
"execution_count": 36,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[1, 4],\n",
" [2, 5],\n",
" [3, 6]])"
]
},
"execution_count": 36,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"np.stack((a1, a2), axis=1)"
]
},
{
"cell_type": "code",
"execution_count": 37,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[array([1, 2]), array([3, 4]), array([5, 6])]"
]
},
"execution_count": 37,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"a = np.array([1, 2, 3, 4, 5, 6])\n",
"\n",
"# by number of sections\n",
"np.split(a, 3, axis=0)"
]
},
{
"cell_type": "code",
"execution_count": 38,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[array([1, 2]), array([3]), array([4, 5, 6])]"
]
},
"execution_count": 38,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# by index\n",
"np.split(a, [2,3], axis=0)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Unique"
]
},
{
"cell_type": "code",
"execution_count": 39,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([1, 2, 3, 4, 5])"
]
},
"execution_count": 39,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"a = np.array([1, 2, 3, 4, 5, 4, 4])\n",
"\n",
"np.unique(a)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Search"
]
},
{
"cell_type": "code",
"execution_count": 40,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(array([3, 5, 6]),)"
]
},
"execution_count": 40,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"a = np.array([1, 2, 3, 4, 5, 4, 4])\n",
"\n",
"# return indices of matching elements\n",
"np.where(a == 4)"
]
},
{
"cell_type": "code",
"execution_count": 41,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(array([1, 3, 5, 6]),)"
]
},
"execution_count": 41,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"a = np.array([1, 2, 3, 4, 5, 4, 4])\n",
"\n",
"np.where(a%2 == 0)"
]
},
{
"cell_type": "code",
"execution_count": 42,
"metadata": {},
"outputs": [],
"source": [
"np.where?"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Sort"
]
},
{
"cell_type": "code",
"execution_count": 43,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([0, 1, 2, 3])"
]
},
"execution_count": 43,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"a = np.array([3, 2, 0, 1])\n",
"\n",
"np.sort(a)"
]
},
{
"cell_type": "code",
"execution_count": 44,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array(['apple', 'banana', 'cherry'], dtype='<U6')"
]
},
"execution_count": 44,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"a = np.array(['banana', 'cherry', 'apple'])\n",
"\n",
"np.sort(a)"
]
},
{
"cell_type": "code",
"execution_count": 45,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([2, 0, 1])"
]
},
"execution_count": 45,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# return indices\n",
"np.argsort(a)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Filter"
]
},
{
"cell_type": "code",
"execution_count": 46,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([41, 43])"
]
},
"execution_count": 46,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"a = np.array([41, 42, 43, 44])\n",
"\n",
"x = [True, False, True, False]\n",
"\n",
"a[x]"
]
},
{
"cell_type": "code",
"execution_count": 47,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([43, 44])"
]
},
"execution_count": 47,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"a = np.array([41, 42, 43, 44, 42])\n",
"\n",
"a[a > 42]"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Linear Algebra"
]
},
{
"cell_type": "code",
"execution_count": 48,
"metadata": {},
"outputs": [],
"source": [
"a1 = np.array([[0,1,2],[3,4,5],[6,7,8]])\n",
"a2 = np.array([[1,0,1],[2,1,1],[0,2,1]])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Elementwise Operations"
]
},
{
"cell_type": "code",
"execution_count": 49,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[1, 1, 3],\n",
" [5, 5, 6],\n",
" [6, 9, 9]])"
]
},
"execution_count": 49,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"a1 + a2"
]
},
{
"cell_type": "code",
"execution_count": 50,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[ 0, 0, 2],\n",
" [ 6, 4, 5],\n",
" [ 0, 14, 8]])"
]
},
"execution_count": 50,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"a1 * a2"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Scala Operations"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Actually a special case of broadcasting"
]
},
{
"cell_type": "code",
"execution_count": 51,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[ 2, 3, 4],\n",
" [ 5, 6, 7],\n",
" [ 8, 9, 10]])"
]
},
"execution_count": 51,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"2 + a1"
]
},
{
"cell_type": "code",
"execution_count": 52,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[ 0, 2, 4],\n",
" [ 6, 8, 10],\n",
" [12, 14, 16]])"
]
},
"execution_count": 52,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"2 * a1"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Matrix Multiplication"
]
},
{
"cell_type": "code",
"execution_count": 53,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[ 2, 5, 3],\n",
" [11, 14, 12],\n",
" [20, 23, 21]])"
]
},
"execution_count": 53,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"np.dot(a1, a2)"
]
},
{
"cell_type": "code",
"execution_count": 54,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[ 33, 43, 53],\n",
" [114, 151, 188],\n",
" [195, 259, 323]])"
]
},
"execution_count": 54,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"np.linalg.multi_dot([a1, a2, a1])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Matrix muliplication Operator, since Python 3.5"
]
},
{
"cell_type": "code",
"execution_count": 55,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[ 2, 5, 3],\n",
" [11, 14, 12],\n",
" [20, 23, 21]])"
]
},
"execution_count": 55,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"a1 @ a2"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Cross Product"
]
},
{
"cell_type": "code",
"execution_count": 56,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[-4, 2, -1],\n",
" [ 3, -6, 3],\n",
" [-1, 2, -1]])"
]
},
"execution_count": 56,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"np.cross(a1, a2, axisa=-1, axisb=-2)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Scalar Product, Inner Product, Outer Product"
]
},
{
"cell_type": "code",
"execution_count": 57,
"metadata": {},
"outputs": [],
"source": [
"v1 = np.float32([1,2,3])\n",
"v2 = np.float32([6,5,4])"
]
},
{
"cell_type": "code",
"execution_count": 58,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"28.0"
]
},
"execution_count": 58,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"np.inner(v1, v2)"
]
},
{
"cell_type": "code",
"execution_count": 59,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"28.0"
]
},
"execution_count": 59,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"v1 @ v2"
]
},
{
"cell_type": "code",
"execution_count": 60,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[ 6., 5., 4.],\n",
" [12., 10., 8.],\n",
" [18., 15., 12.]], dtype=float32)"
]
},
"execution_count": 60,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"np.outer(v1, v2)"
]
},
{
"cell_type": "code",
"execution_count": 61,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[ 6., 5., 4.],\n",
" [12., 10., 8.],\n",
" [18., 15., 12.]], dtype=float32)"
]
},
"execution_count": 61,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"v1[:,None] @ v2[None,:]"
]
},
{
"cell_type": "code",
"execution_count": 62,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([1., 2., 3.], dtype=float32)"
]
},
"execution_count": 62,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"v1"
]
},
{
"cell_type": "code",
"execution_count": 63,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[[1.]],\n",
"\n",
" [[2.]],\n",
"\n",
" [[3.]]], dtype=float32)"
]
},
"execution_count": 63,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"v1[...,None,np.newaxis]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Transpose"
]
},
{
"cell_type": "code",
"execution_count": 64,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[0, 3, 6],\n",
" [1, 4, 7],\n",
" [2, 5, 8]])"
]
},
"execution_count": 64,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"np.transpose(a1)"
]
},
{
"cell_type": "code",
"execution_count": 65,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[0, 3, 6],\n",
" [1, 4, 7],\n",
" [2, 5, 8]])"
]
},
"execution_count": 65,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"a1.T"
]
},
{
"cell_type": "code",
"execution_count": 66,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[0, 1, 2],\n",
" [3, 4, 5],\n",
" [6, 7, 8]])"
]
},
"execution_count": 66,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"a1.T.base"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Inverse Matrix"
]
},
{
"cell_type": "code",
"execution_count": 67,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[-0.33333333, 0.66666667, -0.33333333],\n",
" [-0.66666667, 0.33333333, 0.33333333],\n",
" [ 1.33333333, -0.66666667, 0.33333333]])"
]
},
"execution_count": 67,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"np.linalg.inv(a2)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Norms\n",
"\n",
"Frobenius Norm"
]
},
{
"cell_type": "code",
"execution_count": 68,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"14.2828568570857"
]
},
"execution_count": 68,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"np.linalg.norm(a1)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"L2 Norm along the last axis"
]
},
{
"cell_type": "code",
"execution_count": 69,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([ 2.23606798, 7.07106781, 12.20655562])"
]
},
"execution_count": 69,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"np.linalg.norm(a1, axis=-1)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"L1 Norm along the last axis"
]
},
{
"cell_type": "code",
"execution_count": 70,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([ 3., 12., 21.])"
]
},
"execution_count": 70,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"np.linalg.norm(a1, ord=1, axis=-1)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"L0 or Maximum Norm along the last axis"
]
},
{
"cell_type": "code",
"execution_count": 71,
"metadata": {
"scrolled": true
},
"outputs": [
{
"data": {
"text/plain": [
"array([2., 3., 3.])"
]
},
"execution_count": 71,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"np.linalg.norm(a1, ord=0, axis=-1)"
]
},
{
"cell_type": "code",
"execution_count": 72,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[0, 1, 2],\n",
" [3, 4, 5],\n",
" [6, 7, 8]])"
]
},
"execution_count": 72,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"a1"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Einsum\n",
"\n",
"Things like transpose, matrix multiplication, inner and outer product, tensor product etc. can also be done using Einstein notation\n",
"- More versatile, especially when dealing with many dimensions\n",
"- Typically faster an less code compared to other solutions"
]
},
{
"cell_type": "code",
"execution_count": 73,
"metadata": {},
"outputs": [],
"source": [
"a3 = np.arange(24).reshape((4,3,2))\n",
"a4 = np.arange(24).reshape((4,2,3))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Example: batch matrix multiplication"
]
},
{
"cell_type": "code",
"execution_count": 74,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[[ 0, 3],\n",
" [ 2, 12],\n",
" [ 8, 25]],\n",
"\n",
" [[ 36, 63],\n",
" [ 56, 90],\n",
" [ 80, 121]],\n",
"\n",
" [[144, 195],\n",
" [182, 240],\n",
" [224, 289]],\n",
"\n",
" [[324, 399],\n",
" [380, 462],\n",
" [440, 529]]])"
]
},
"execution_count": 74,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"np.einsum('bij, bji -> bij', a3, a4)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"https://numpy.org/doc/stable/reference/generated/numpy.einsum.html"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Random"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Seed\n",
"\n",
"Sets the initial condition for the random number generator"
]
},
{
"cell_type": "code",
"execution_count": 75,
"metadata": {},
"outputs": [],
"source": [
"np.random.seed(1337)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Integers Values\n",
"\n",
"Generate a random integer values from 0 to 100"
]
},
{
"cell_type": "code",
"execution_count": 76,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"23"
]
},
"execution_count": 76,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"np.random.randint(100)"
]
},
{
"cell_type": "code",
"execution_count": 77,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[61, 92, 39, 89, 39],\n",
" [90, 82, 84, 72, 9],\n",
" [ 6, 54, 90, 23, 24]])"
]
},
"execution_count": 77,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"np.random.randint(100, size=(3, 5))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Float Values"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Generate a random float values from 0 to 1"
]
},
{
"cell_type": "code",
"execution_count": 78,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"0.11527422668314946"
]
},
"execution_count": 78,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"np.random.rand()"
]
},
{
"cell_type": "code",
"execution_count": 79,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[0.38627507, 0.62850118, 0.12505793, 0.98354861, 0.44322487],\n",
" [0.78955834, 0.79411858, 0.36126157, 0.41610394, 0.58425813],\n",
" [0.76017177, 0.18780841, 0.28816715, 0.67021886, 0.49964826]])"
]
},
"execution_count": 79,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"np.random.rand(3, 5)"
]
},
{
"cell_type": "code",
"execution_count": 80,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[0.17856868, 0.4131413 , 0.19919524, 0.5316994 , 0.8323707 ],\n",
" [0.18525095, 0.95735922, 0.42541467, 0.50400704, 0.51047095],\n",
" [0.01579145, 0.73169007, 0.99330504, 0.16287753, 0.12663478]])"
]
},
"execution_count": 80,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"np.random.uniform(size=(3,5))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Choice\n",
"\n",
"Returns an random value based on an array of values"
]
},
{
"cell_type": "code",
"execution_count": 81,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"5"
]
},
"execution_count": 81,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"np.random.choice([3, 5, 7, 9])"
]
},
{
"cell_type": "code",
"execution_count": 82,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[5, 3, 5, 7, 3],\n",
" [3, 5, 9, 3, 7],\n",
" [5, 5, 3, 5, 5]])"
]
},
"execution_count": 82,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"np.random.choice([3, 5, 7, 9], size=(3, 5))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Choose elements with certain probability (discrete distribution)"
]
},
{
"cell_type": "code",
"execution_count": 83,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([7, 7, 7, 7, 7, 7, 5, 3, 3, 7, 7, 7, 5, 7, 3, 7, 7, 5, 7, 7])"
]
},
"execution_count": 83,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"np.random.choice([3, 5, 7, 9], p=[0.1, 0.3, 0.6, 0.0], size=(20))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Schuffle\n",
"\n",
"Randomly changes the location of elements in an array (the array is modified)"
]
},
{
"cell_type": "code",
"execution_count": 84,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([3, 5, 1, 2, 4])"
]
},
"execution_count": 84,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"a = np.array([1, 2, 3, 4, 5])\n",
"\n",
"np.random.shuffle(a)\n",
"\n",
"a"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Permutation\n",
"\n",
"Returns a random permutation of the array elements"
]
},
{
"cell_type": "code",
"execution_count": 85,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(array([1, 2, 3, 4, 5]), array([3, 4, 2, 5, 1]))"
]
},
"execution_count": 85,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"a = np.array([1, 2, 3, 4, 5])\n",
"\n",
"b = np.random.permutation(a)\n",
"\n",
"a, b"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Distribution\n",
"\n",
"Normal, Binomial, Poisson, Uniform, Logistic, Multinomial, Expoinential, ..."
]
},
{
"cell_type": "code",
"execution_count": 86,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[-0.13062312, -1.31026002, -2.17131242],\n",
" [-1.06618141, -0.03316184, 1.46639575]])"
]
},
"execution_count": 86,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# with zero mean and standard deviation of one\n",
"np.random.normal(size=(2, 3))"
]
},
{
"cell_type": "code",
"execution_count": 87,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[2.75328619, 2.33997916, 2.39489902],\n",
" [0.49442913, 2.13597421, 1.60877572]])"
]
},
"execution_count": 87,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# with given mean (loc) and standard deviation (scale)\n",
"np.random.normal(loc=1, scale=2, size=(2, 3))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Matplotlib\n",
"\n",
"https://matplotlib.org/stable/api/index.html"
]
},
{
"cell_type": "code",
"execution_count": 88,
"metadata": {},
"outputs": [],
"source": [
"import matplotlib.pyplot as plt\n",
"import numpy as np"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Basic Plot"
]
},
{
"cell_type": "code",
"execution_count": 89,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAYoAAADgCAYAAAAdZiGYAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/bCgiHAAAACXBIWXMAAAsTAAALEwEAmpwYAABAmUlEQVR4nO3dd3hURdvA4d+kh1RIIEBCD50QSOhNigoovQkIglQLiKKAHUV8rZ8F8AWkg3QQRECQrkgPhBJqQg01CZBGeub74yy+iJC62bNl7uvai+zu2XOeIdl99pyZeUZIKVEURVGUx7HTOwBFURTFvKlEoSiKouRIJQpFURQlRypRKIqiKDlSiUJRFEXJkUoUiqIoSo5UolBsnhCiuhAiXAiRKIR4zUTHLC+ESBJC2JvieIpSGELNo1BsnRBiDpAgpXyjCI9xERgmpdxaVMdQlKKizigUBSoAEXoHoSjmSiUKxaYJIbYDbYBphktB14QQwx54frAQYvcD96UQ4iUhxDkhxF0hxA9CCPHA88OFEKcMl7FOCiFChBCLgPLAr4ZjjBdCVDTsy8HwurJCiHVCiNtCiEghxPAH9vmREGKFEGKhYb8RQogGDzw/QQhx1fDcGSFEu6L9X1NsjUoUik2TUrYF/gRGSSndgbN5eFknoCFQF+gDtAcQQvQGPgJeADyBLkCclHIgcBnoLKV0l1J++Yh9LgOigbJAL+A/Qoi2DzzfxbCNN7AOmGY4ZnVgFNBQSulhiOVi3lqvKHmjEoWi5N/nUsq7UsrLwA6gnuHxYcCXUsqDUhMppbyU286EEOWA5sAEKWWqlDIcmI2WcO7bLaXcKKXMAhYBwYbHswBnoJYQwlFKeVFKGWWMRirKfSpRKEr+3Xjg53uAu+HnckBBPqTLArellIkPPHYJ8M/hmC5CCAcpZSTwOtqZzC0hxDIhRNkCxKAoj6UShaL8UzJQ7IH7pfPx2itAlcc8l9PwwmtACSGExwOPlQeu5uWgUsolUsoWaJ3yEvgiL69TlLxSiUJR/ikc6CGEKCaECASG5uO1s4G3hBChQhMohKhgeO4mUPlRL5JSXgH2AJ8JIVyEEHUNx/0ptwMa5oC0FUI4A6lACpCdj5gVJVcqUSjKP30LpKN9sC8AFuf1hVLKlcCnwBIgEVgLlDA8/RnwvmGk1FuPeHk/oCLa2cUaYGIe51w4A58DsWiXp0oB7+Q1ZkXJCzXhTlEURcmROqNQFEVRcqQShaIoipIjlSgURVGUHKlEoSiKouRIJQpFURQlRw56B2Bsvr6+smLFio99Pjk5GTc3N9MFZALW2CawznapNlkGa2wT5NyusLCwWCllyUc9Z3WJomLFihw6dOixz+/cuZPWrVubLiATsMY2gXW2S7XJMlhjmyDndgkhHluXTF16UhRFUXKkEoWiKIqSI10ThRBirhDilhDixGOeF0KIKYaFXI4JIUJMHaOiKIqt07uPYj7aAiwLH/N8R6Cq4dYYmG74N18yMjKIjo4mNTUVLy8vTp06VcBwzYOLiwsBAQE4OjrqHYqiKDZA10QhpfxDCFExh026AgulVpBqnxDCWwhRRkp5PT/HiY6OxsPDg4oVK5KUlISHh0fuLzJTUkri4uKIjo6mUqVKeoejPEpmGlw/qt2yMv7xVMCVSNh78n8PuHqDfwPwrQr/W1FVeUBWtuTy7XucvZlI5K0kou/cw8XRHg8XRzycHXB3ccDDxQF3Z+1fDxdH/L1dcXPW+3uw9dC9KKAhUayXUtZ5xHPr0VYT2224vw1tFbBDD203AhgB4OfnF7ps2bJ/7MfLy4sqVaoghCArKwt7e/uiaYyJSCmJiooiPj4egKSkJNzd3XN5leWxlHY5p8bimXAGz4TTeCacwSMxCjuZma99ZDh4kOBZjQTPGsR7VSfRoypZDsVyf6EZMObv6U5qNhcTsrmamM3VpGyuJkmuJ2eT8UDhdA8nyMiC1KzH78deQNXidtTxtSfI155yHnbY5SMRW8rfXn7l1K42bdqESSkbPOo5q0i5UsofgR8BGjRoIB8e/nXq1Ck8PT0BSExMtOgzivtcXFyoX78+YJtD+XSVkQonVkPkFrhyABIM6ws5uEDZ+lCnPZRrBGVDwOmfY9Z3795NixYt/vdA0k24cgDH6AP4XDmAz0VDVXNhB6VqQUBDqNMDKrY02zOOwv6e0jKz+D3iJisOXWF3ZCz3v7uW9XKhahkP2vu5U9XPg2p+HgSWcsfdcKaQnS1JSs8kKTWTpLRMElMzSEzNJDE1kxPX4vnjbCyrziaw6mwGvu5OtKxaklbVfGlZtSS+7s5F2iZzVdB2mXuiuIq2vOR9AeRx1S9LMGzYMMaOHUutWrX0DkXJi8SbcGgOHJwD92LBMwDKNdaSQkAjKB0EDk457iLT0V273HSfqzeUrA4hA7X7KXfh6iG4chCiD8DxVRA2T9t3k1egTk9wyPlDzlKcup7A8oNXWBt+lbv3MvD3dmVMu6o8Ua0kgaXc8XDJuQ/Ozk7g6eKI5yO26xxclnc6wq2EVP48F8sf52LYdTaGNUe0j48gfy8GNqlA9xB/HO3V4M/cmHuiWAeMEkIsQ+vEjs9v/4Q5mz17tt4hKHlx/Rjsmw4nVml9DtU6QNNXiuZbvqs3BD6p3QAyUuDYCu34a1+GLROh4TBoMATcHzmJ1qwlpGawLvwaKw5d4Vh0PE72djxd24/nGpajeRVf7OyM+/9ZytOFnqEB9AwNIDtbGs40Yth4/AbjVx9jyvZzvNomkJ4hATg5qITxOLomCiHEUqA14CuEiAYmAo4AUsoZwEbgGSASbUH5F/WJtPCSk5Pp06cP0dHRZGVl8cEHHzB9+nS+/vprGjRogLu7O2PGjGH9+vW4urryyy+/4Ofnp3fYtis7C85uhn3/hYt/gqMbhA6Gxi+Bz+OWxS4Cjq4QOghCXoDzO7SEsfM/8Of/Qd3e2lmGX23TxVNAiakZTNl2jkX7LpGakU2N0h5M7FyLbvX8Ke6W81mYsdjZCeoGeFM3wJtX2wSy48wtvt8WyTs/H2fqtnO83CaQPg0CcHaw7D7MoqD3qKd+uTwvgVeNecwvfo/iXGyKMXdJrbKeTOyc85t106ZNlC1blg0bNgAQHx/P9OnT/34+OTmZJk2a8OmnnzJ+/HhmzZrF+++/b9Q4lTw69Sts+RBunwevcvDUJ9qlIdfi+sUkBFRpq91izsL+6RC+FI78pD3W8Utt5JSZkVLyS/g1/rPxFDFJafSoH8CgZhUI8vdC6NjnIoSgbQ0/2lQvxR/nYvl+61k+WHuCH7ZH8nLrKpTJUit/PsjcLz1ZjaCgIN58800mTJhAp06daNmy5T+ed3JyolOnTgCEhoayZcsWPcK0bYk3YeNbcGod+NWBXvOgZhewN7O3Sclq0OlbaPsBhM2Hv76H6c3hifHQfAzYm8f8mlPXE5j4SwQHLt4mOMCLWS80ILict95h/YMQgieqlaRVVV/2RMXx/dZzTFwXgbez4EaxiwxoXMHol8MskZm9A4rehKer6DLqqVq1ahw+fJiNGzfy/vvv065du3887+jo+Pc3LHt7ezIz8ze8UikEKSF8MWx+VxvR1O5DaPaa2XzgPlaxEtByLNR7Hn4bB9s/gYi10HWqNvpKJ/EpGXy75SyL9l3C08WBz3sE0adBObP+wBVC0DzQl+aBvuyNiuOjVQf48JcIfjt+g6/7BOPv7ap3iLqyuUShl2vXrlGiRAkGDBiAt7e36sg2F7cvwPrX4fxOKN8Mukwxy0s4OfLwgz4LtUtmG96CWW2h6Sho/Q44mW4uRna2ZPXhaL7YdJrbyek837gCbz5dDe9ipumDMJamVXx4u5ELMe6BfPxrBB2+/YNJ3WrTrZ6/rpfL9KQShYkcP36ccePGYWdnh6OjI9OnT+ett97SOyzblZ0F+2fA9skg7OHZbyD0RbCz4JEvNTtrI7G2fAB7psDp9dB5ClRqmftrC+nK7Xu8vjycsEt3CCnvzfwXG1HH36vIj1tUhBD0aViOJpV9GLsinDeWH2XryVtM7lbHZJ3v5kQlChNp37497du3/8djO3fu/PvnpKSkv3/u1asXvXr1MlVotufmSVg3WpuvULU9dPoGvAL0jso4XL2hy1So0wt+fQ0WdIKQQfD0J+BSNB/cJ2KzeGPabjKzJV/1qkvPkACzvsyUH+V9irF8ZFNm/hHFt1vOcvDibb7sVZfW1UvpHZpJWfDXJ0UpgOOrYFYbuHMBes6B/sutJ0k8qPIT8PJeaDYajiyCH9tA7DmjHkJKyfSdUfzfoVRKejizblQLept5X0RB2NsJXmkdyJpXmuPl6sjgeQf5YO0JUtJzqCFiZVSiUGxDdjbs+A+sHqqV1nhlPwT1MtuyGEbhVAyengyDN0JqPMxuB1HbjbLrpLRMXll8mC82naZhaXvWvNKcSr7Wt3Tog+r4e/Hr6BYMbVGJRfsu8eyUPzl5LUHvsExCJQrF+qXfg1Uvwq4voN4AeGGtRc5qLrAKTWH4dvD0h596wYFZhdpdVEwS3X74i99P3uT9Z2vycrCzzVRqdXG054NOtVg8rDHJ6Zn0nrGHXWdj9A6ryKlEoVi3hGswryOc/EWbONd1mtXUSsqX4hVg6O9Q9SltrsiGtyAr/0OwN0fcoOu0v7iTnM6ioY0Y1rKyTY4Eah7oyy+vtqBciWIMmX+QFYeu6B1SkVKJQrFeVw9r1+bjIqHfMmj+mnVfasqNswf0XaLNETk4Cxb3hJQ7eXppVrbk681nGLkojCol3fh1dAuaVfEt4oDNW2kvF1a+1JRmVXwYv+oY3245i97LNhQVlSgU63TiZ5j3DNg7ad+kq3fQOyLzYGevjYDq+gNc/AtmPwlxUTm+JDUji5d+CmPajkj6NizH8pFNKWvjE9Du83BxZO7ghvQMCeD7becYv+oYGVnZub/QwqhEoVgXKWHnF1qfRJm62rV5CyiaZ3L1B8CgdXDvtjZB7/yuR26Wkp7F8IWH2HLyJh91rsXnPevi4qiK5j3I0d6Or3vX5bV2VVkZFs2Q+QdJTM3I/YUWRCUKxXpkZ8O6UVp11eB+MOhX2+q0zq8KzbRE6lEafuqhnYU9ICktk8HzDvBXZCxf9arL4OZq6d3HEUIw9qlqfNEziD1RcfSZuY+bCal6h2U0KlGY0MKFC6lbty7BwcEMHDiQixcv0rZtW+rWrUu7du24fPkyACtXrqROnToEBwfTqlUrnaO2ENnZ2iS6Iz9Bq3HQbbptdlrnV4lKMHSLtpLe6mEQsQbQ6jUNnLOfQ5fu8F3f+vRuUC6XHSkAzzUsz5xBDbgcl0z3H/7i7M1EvUMyCtsY0/YA5x0TIe6McXdaOgg6fp7jJhEREUyePJk9e/bg6+vL7du3GTRo0N+3uXPn8tprr7F27VomTZrE5s2b8ff35+7du8aN1RplZ8OvoyH8J2g1Htq8a9ud1vnl4gnPr9SGzq4aSmJaJv13l+bszUR+6B9Chzql9Y7QorSuXorlI5vy4vyD9Jq+h8XDmhAUYLnlTECdUZjM9u3b6d27N76+2kiREiVKsHfvXvr37w/AwIED2b17NwDNmzdn8ODBzJo1i6ws25n9WSD3k8QRlSQKxdkDBqwio0woxdaNIDBmKz++0EAliQKq4+/Fzy83w8PFkYFz93PmhmWfWdjcGUVam49x0qHMeH7MmDGD/fv3s2HDBkJDQwkLC8PHx0fvsMxPdrZWz+j+5SaVJArleqoDw+LfYJL8iO8cpiIy6wPd9A7LYpUrUYwlwxvTe8Zenp+9nxUjm1C5pLveYRWIOqMwkbZt27Jy5Uri4uIAuH37Ns2aNWPZsmUALF68+O/FjKKiomjcuDGTJk2iZMmSXLli3ZN5CiQ7G9aP0eoYtRoHbd5TSaIQrty+R5+Ze7mUZI8YsAoR0ABWDdEmKioFVsHHjSXDGyOl5PnZ+7ly+57eIRWIShQmUrt2bd577z2eeOIJgoODGTt2LFOnTmXevHnUrVuXRYsW8f333wMwbtw4goKCqFOnDs2aNSM4OFjn6M1Mdra2hsThhdDyLZUkCul+kkhIyWTxsMaEVC0PA1aDShZGEVjKg0VDG3MvPYv+s/dxPd64SzGbgs1detLT/Y7rB23f/u8ibT///PO/HlMM/k4SC7Qk0fZ9lSQKIS4pjRfmHiAlI4ulw5tQq6yn9oSzBzy/Chb30pJFr3lQq4u+wVqwWmU9WTikEc/P3s/zs/azfGRTSnpYzqg8dUahWA4pYcMbhiTxpkoShZSclsmQ+Qe5Hp/CnEEN/5ck7nPx1JJF2RBtAuOpX/UJ1EoEl/Nm3osNuR6fyoDZ+7mTnK53SHmmEoViObZPhrD50GIstP1AJYlCyMjK5pXFhzl+NZ5p/UIIrVD80Ru6eGqXocrW184sLv5l2kCtTMOKJZg9qAEX4pIZOHc/8SmWMYNbJQrFMoQtgD+/hpAXoN2HKkkUgpSSCauPsetsDP/pHsSTtfxyfoGLJ/RfAd4VYFl/iDlrmkCtVPNAX2YOCOXMjURenHeA5LT8V/E1NZtJFNZU1dGa2pIn57bC+jcg8EltbWuVJArli01n+PnwVd58qhp9G5XP24uKlYABq8DeUas6m3SraIO0cm1qlGJK3/ocjY7npZ/CzL6QoE0kChcXF+Li4qziA1ZKSVxcHC4uLnqHYhrXj8LKQeBXC3rP1z6olAKbu/sCM3ZFMaBJeUa1Dczfi4tX1M4skmNhSR9ITy6SGG1Fx6AyfNY9iD/PxTJxXYRZfz7ZxKingIAAoqOjiYmJITU11eI/ZF1cXAgIsMJ1nh/inBoDi0eCizf0X6mNxFEK7Nej1/hkw0k61C7Nx13qFGzBIf8Q6DVXuwS1aij0XWz8QG1In4bluBCXzPSdUVT2dWNYy8p6h/RINpEoHB0dqVRJq3y5c+dO6tevr3NESq5S7lL32CTIugdDNoNnGb0jsmh7ImMZuyKchhVL8F3fetjbFeLyXfWO0PFLbaW838ZDsU7GC9QGjXu6Ohdjk/l04ynKlyjG07XNr2yKTVx6UixMZjqsGIhryjV47iftspNSYBHX4hmxKIzKvu7MeqGBcdaTaDTcsFLebMpdWVv4/dkwOzvBN33qUdffizHLwjlxNV7vkP5F10QhhOgghDgjhIgUQrz9iOcHCyFihBDhhtswPeJUTEhKrVz4hT84U/1VqPyE3hFZtJsJqbw47yCeLg7MH9IQL1cj9vE8+THU7k6V8/P/tZaFkj+uTvbMGtSAEm5ODF1wkBvx5rWWhW6JQghhD/wAdARqAf2EEI/66rhcSlnPcJtt0iAV09v5GRxbBm3e42bptnpHY9FSM7IYuSiMpLRM5r7YkDJeRl6+1M4Ous0g3rMmrHkJLu017v5tTCkPF2YPakBSaiZDFxw0q2Gzep5RNAIipZTnpZTpwDKgq47xKHo78hPs+kJbprPVOL2jsWhSSt5bc4LwK3f5pk8wNUp75v6ignB04XjQu+BdDpb1g9jIojmOjahZxpNp/UM4dT2BMcvCyco2j5FQQq8hWUKIXkAHKeUww/2BQGMp5agHthkMfAbEAGeBN6SU/yqlKoQYAYwA8PPzC71fkfVRkpKScHe3zFK/j2MNbfKMP0O98He5612b40EfIu0crKJdDzNVm36/mMGS0+l0reJI96pORXqspKQkfO2TCDk8jgxHTw6HfEWWQ7EiPWZR0/tvb+ulDH46lU77ig70q2G8mlA5tatNmzZhUsoGj3xSSqnLDegFzH7g/kBg2kPb+ADOhp9HAttz229oaKjMyY4dO3J83hJZfJsSbkj5dXUpvw2SMjnu74ctvl2PYIo27T4XIyu/s0EOX3BQZmVlF/nx/m7T+V1SflRcyqX9pczKKvLjFiVz+Nub+MsJWWHCerlo70Wj7TOndgGH5GM+V/W89HQVeHAh3gDDY3+TUsZJKdMMd2cDoSaKTTGVzHRtQl1qPPRdos0AVgrsctw9Xl1ymCol3fjmuXrYFWYYbH5VagVPfwKn18Pub0x3XCv1/rM1aVO9JBPXRbAnKlbXWPRMFAeBqkKISkIIJ6AvsO7BDYQQDw6e7wKcMmF8iilsfhcu74UuU6F0Hb2jsWjJaZkMX3gIKWHWCw1wd9ZhmlSTVyCot1bA8dwW0x/fijjY2zG1fwgVfYoxeskRXdex0C1RSCkzgVHAZrQEsEJKGSGEmCSEuF/4/jUhRIQQ4ijwGjBYn2iVInFkMRycBc1GQ1AvvaOxaNnZkrErwjl3K5Ef+odQwcdNn0CEgM5TwK8OrB4KcVH6xGEl3J0dmDkwlNSMLF7+6TBpmVm6xKHrPAop5UYpZTUpZRUp5aeGxz6UUq4z/PyOlLK2lDJYStlGSnlaz3gVI7p6WCv0V+kJaPeR3tFYvKnbI9kccZP3nq1Fi6q++gbjVAz6/gTCDpYPgLQkfeOxcIGlPPiqdzDhV+4yeb0+F1XUzGzF9JJiYPlAcPfTVk6zt4lKMkVmc8QNvt16lp4hAQxpXlHvcDTFK2o1oWJOw7pR2kRKpcCeCSrDyFaVWbTvEqvDok1+fJUoFNPKyoCVg+FeLDy3CNx89I7Iop29mcjY5eEEl/Pm0+4FLPRXVKq0hXYTIWIN7JmidzQWb1z76jSpXIJ31xwn4pppy3yoRKGY1pYP4dJu6Pw9lK2ndzQWLTktk5d+CsPVyYEfB4Yap4aTsTUfA7W6wdaPIOrf68Mreedgb8fUfiEUL+bEyz8dJv6e6VbHU4lCMZ2jy2Hff6HxyxDcV+9oLJqUknfXHOdibDJT+tXDz9NMS+cLAV1/gJI1tKVU71zUOyKLVtLDmf8OCOF6fAqvLz9CtolmbqtEoZjGjePw6xio0EIba68UypIDl/kl/Bpjn6pGsyo6d17nxtldqwIss7XO7Qz9hnlag5Dyxfmwc212nIlh6nbTlExRiUIpemmJsGIQuHqrVeqM4MTVeD5ed5InqpXkldb5XKVOLz5VoMds7QvDpnf0jsbiDWhcnh4h/ny37Sw7zhT9srQqUShFS0r49XW4cwF6zgH3knpHZNHiUzJ4ZfFhfNyd+NbUM68Lq9rT0Px1CJsHx1fpHY1FE0LwabcgapT25PVl4Vy5fa9Ij6cShVK0Di+AE6ugzXtQsbne0Vg0KSXjVx3l2t0UpvWvTwm3oi32VyTavg/lmmiXIdVkvEJxdbJnxoAQpJS8vDisSCfjqUShFJ0bx2HjeG2YZIuxekdj8eb+dZHNETd5u2MNQitYaE0se0foNUf7d8UgyDCvBXosTQUfN77pU48TVxP4bGPRzUdWiUIpGmmJ2nwJ1+LQ/UdtkRulwA5fvsNnG0/xVC0/hraopHc4heMVAN1nws3jsFn1VxTWk4a/ifl7LrI54kaRHEO9exXjk1Irz3H7vPbtUfVLFMqd5HRGLT5MGW8Xvu4dbF6T6gqqWnttjsWhuXBitd7RWLwJHWpQN8CLcSuPEn3H+P0VKlEoxnd4IRxfCW3ehYot9I7GomVnS95YEU5sUjr/7R9q3DWv9db2AyjXGNap/orCcnKwY2q/+kgJo5ceISMr26j7V4lCMa4bJ+C38VC5DbR4U+9oLN70XVHsPBPDB51rERTgpXc4xmXvqNWDsnfQ1iRR/RWFUsHHjc96BnHk8l3+7/ezRt23ShSK8aQlaf0SLt7QY5bqlyikQxdv83+/n6FzcFkGNC6vdzhFwysAus3QBj78/p7e0Vi8TnXL0r9xeWbsimKnEedXqHeyYhxSwoaxcDsKes5W/RKFFH8vgzHLwilXohj/Mbdif8ZWvQM0ew0OzoYTP+sdjcX7sFMtapT2YOyKo9xMMM5ZmkoUinEcWQTHlkPrd6BSS72jsWhSSiasPsbNhFSm9K2Ph4sV9Us8TrsPIaARrHtN9VcUkoujPdP6h5CSnsWYZUfIMkI9KJUolMK7dVqbL1G5NbRU/RKFteTAZTZF3GB8h+oEl/PWOxzTuN9fYWevFQ/MTNc7IosWWMqdT7rVYd/520zdfq7Q+1OJQimcjFTtje3kZpgvYYalri3ImRuJTPr1JK2qlWRYi8p6h2Na3uW0SrPXw2H7JL2jsXi9QgPoEeLP99vOsScqtlD7UolCKZwtH8KtCOg+Azz89I7GoqVmZDF66WE8XBz4v97BllXHyVhqdoIGQ2HPVIjcpnc0Fu+TrnWo5OvG68vCiU1KK/B+VKJQCu7Mb3BgJjR5Fao+pXc0Fu+T9Sc5ezOJb/rUo6SHs97h6Kf9p1CyJqx5SVs2VykwN2cHpvUL4W5KBuNWHkUWcElalSiUgkm4DmtfgdJ14cmJekdj8TaduM7i/ZcZ2aoyrarZ+IgxR1etvyItAda+BNnGnTxma2qV9eS9Z2qy40wMWy9lFmgfKlEo+ZedBWtGQGaq9oZ2sOFvv0Zw9W4K41cdIzjAizefrq53OObBr5Z2ZhG5FfZP1zsai/dC0wq0q1GK5WfSOXktId+vV4lCyb+/vocLf0DHL8G3qt7RWLTMrGxeX3aEbAlT+tXHyUG9Jf/WYCjU6ARbJsK1cL2jsWhCCL7sVRd3J8HopYdJSc9fSXL1V6nkz5WDsH0y1O4B9QfoHY3Fm7I9koMX7zC5Wx0q+LjpHY55EQK6TAW3krB6qDbzXykwH3dnhgc5cz42mUnrT+brtSpRKHmXGq+9YT39odO32htZKbB95+OYtv0cPUMC6FbfX+9wzFOxEtDjR20S3m8T9I7G4tX2tWdEq8osPXCZTSeu5/l1KlEoeSMlrB8L8dFaiQ5Xb70jsmh376XzxvJwKvi48XHX2nqHY94qtYRWb0H4T2oJVSN486nq1A3wYsLq41y7m5Kn16hEoeTN0aXakqat34HyjfWOxqJJKXl79XFik9KY0rc+7s4Oeodk/p54Wyvxsf4NuHNR72gsmpODHd/3rU9GVjZvLA/PU4kPlSiU3MVFwYa3oEILaKmWNC2s5QevsCniBm89Xd36SocXFXsH7UwWYPUwyMrQNx4LV8nXjUld67D/wm3+uyMy1+11TRRCiA5CiDNCiEghxNuPeN5ZCLHc8Px+IURFHcK0bZnpWokOe0ftWrEq0VEo15Ky+fjXk7QI9GV4Sxsr0VFYxStA5+8g+iDs+kLvaCxezxB/ugSX5btt5wi7dCfHbXVLFEIIe+AHoCNQC+gnhKj10GZDgTtSykDgW0D9dZjajsla7Z2u08BLdbgWRlpmFjOOpuHqZM83fWy0REdh1ekJ9QbAH1/Dxd16R2PRhBBM7l6HMl4ujFl2JMdtc00UQojRQojiRovufxoBkVLK81LKdGAZ0PWhbboCCww/rwLaiVwK81+7m0JqRv7GCCuPEbVDmzMR+iLU7Kx3NBbvq01nuJyYzZc961LK00XvcCxXxy+gRGX4eQSk5PxNWMmZp4sj3/etz/X4nNetELnV/hBCTAb6AoeBucBmWdCCIf/cby+gg5RymOH+QKCxlHLUA9ucMGwTbbgfZdgm9qF9jQBGADiVDgwd+ME0BtR69GzhpKQk3N3dCxu+WSmKNjmmx9Pg0BgyHdwIC/2GbHvTz762pt/V8ZhM/i8sjVZlJEOCraNN9+nxe/JIOEf9I28T59OQiNoTjD5U25r+9h70uHati0rn22Htw6SUDR75QillrjdAAO3RvvVHAv8BquTltTnssxcw+4H7A4FpD21zAgh44H4U4JvTfssE1pIVJqyXW0/ekI+yY8eORz5uyYzepuxsKRc/J+UkXymvHzPuvvPBWn5XMYmpMvSTLfKpb3bKzVu36x2O0en2e9r9nZQTPaU8NN/ou7aWv72HPa5dmdrQp0PyMZ+reeqjkFJK4IbhlgkUB1YJIb7MUxp7tKtAuQfuBxgee+Q2QggHwAuIy2mnZTxdqVnGk3GrjnHLSMsA2pyDs+Hsb/DUJCgdpHc0Fk1KybiVR0lIzdBKdNirfgmjaToaKj0Bm96GmLN6R2PR7HPpL8tLH8UYIUQY8CXwFxAkpXwZCAV6FiK2g0BVIUQlIYQT2uWtdQ9tsw4YZPi5F7DdkLRyiBem9qvHvfRMxq44SrYRlgG0KTdPwu/vQ+BT0PglvaOxePP3XGTHmRjef7YmNUp76h2OdbGzg+4zwcFFqxiQWfD1FpSc5eWMogTQQ0rZXkq5UkqZASClzAY6FfTAUspMYBSwGTgFrJBSRgghJgkhuhg2mwP4CCEigbHAv4bQPkpgKQ8mdq7N7shYZv15vqAh2p6MFO0N5+wJ3aarEh2FdOp6Ap9tPE27GqUY2KSC3uFYJ88y0O2/cOMYbFOr4hWVXKeESikfu9iAlPJUYQ4updwIbHzosQ8f+DkV6F2QffdtWI5dZ2L4avMZmlbxoW6Ad2FCtQ1bPoRbJ+H51eBu42siFFJKehavLT2CVzFHvuxVl1wG6ymFUb0jNBwOe6dBlTYQ+KTeEVkdq52ZLYTg855BlPRw5rWlR0hOK9iCHTbjzCY48KNhtTr1RiusTzac5NytJL7pE4yPu1qvo8g9/QmUqgVrXlar4hUBq00UAN7FnPjuuXpcvn2Piesi9A7HfCXegF9e0Tqu1Wp1hfbb8ess2X+ZkU9UpmVVdWZmEo6u0HOOVuH4l1e0IpaK0Vh1ogBoXNmHUW0CWRUWzbqj1/QOx/xkZ8OakZB+D3qq1eoKK/rOPSasPkZwOW/eUqvVmdb9VfHO/Q77Z+gdjVWx+kQB8Fq7qoSU9+a9n48Tc0+tv/sPe76H8zuh4+dQspre0Vg0bbW6cLIlTO1bH0d7m3h7mZeGw6BaR62/7fpRvaOxGjbxl+xgr5XVBZh5LI3MLJUsALhyALZ9ArW7Q8ig3LdXcjRl2zkOXbrDp93rUN6nmN7h2CYhoOsPUMwXVr4IaYl6R2QVbCJRAJQrUYxPewQReTeb77ed0zsc/aXchVVDtUJ/nb9XQ2ELaW9UHFN3RNIrNICu9VTxRF25+UDPWXDnAmwcp3c0VsFmEgVAl+CytPR3YNqOSPZExub+AmslJawbDYnXoNc8cFFrIhTG7eR0Xl9+hEo+bnzcRa1WZxYqtoAnJmgLboUv1Tsai2dTiQJgQE0nKvu6MWZ5OLFJNjqTM2wenFoHbT+AgEfXAFPyRkrJ+FVHuZOslehwU6vVmY9W46BCc9jwJsTmvjiP8ng2lyicHQTT+oeQkJLBG8vDba/Ex80I2PQOVGkLzV7TOxqLt3DvJbaeusXbHWtQx1+dmZkVO3voMQscnGDVYFXioxBsLlEA1CzjycTOtfnzXCwz/7ChEh/pyVoHn7OnViPHziZ//UZz8loCn248RdsapXixeUW9w1EexctfK0dz47g2EkopEJv9pOjXqBzP1i3D17+fIezSbb3DMY1Nb0PsWW1JU/dSekdj0e6lZzJ66WG8XR35SpXoMG/VO0Ljl7W5Fac35r698i82myiEEHzWIwh/b1dGLznC3XvpeodUtE6shsMLocUbWj0cpVA+WhfB+dhkvnuunirRYQme+hhK19Vmbcc/vJqBkhubTRSgLQM4rX99YpLSGLfqGLlUMLdcty/Ar69DQCNo867e0Vi8VWHRrDgUzautA2kW6Kt3OEpeODhD7/mQlQGrh0GWqv2WHzadKADqBnjzdseabDl5k/l7LuodjvFlpmulw4WAnrPB3lHviCzamRuJvL/2OE0ql+D1J6vqHY6SHz5V4Nlv4PIe+OMrvaOxKDafKACGNK/IkzX9+M/GUxyPjtc7HOPa9jFcDYMuU6G4WhOhMJLTMnllcRjuzo5M6VsfB1Wiw/IEPwfB/WHXF3B+l97RWAz1l47WX/FVr7r4ujszaulhElMz9A7JOE6u02r0NxwGtbrqHY1Fk1Ly7prjXIhNZkq/epTydNE7JKWgnvkKfKtqZ9oJqlBoXqhEYVDczYkp/eoTfSeFd34+bvn9FXFR8Mur4B8K7f+jdzQWb8mBy/wSfo03nqxGsyqqX8KiObtDn0VaxeSVL2r9FkqOVKJ4QMOKJRj7VDXWH7vO4v2X9Q6n4NLvwYoXtAlHveer0uGFdOJqPB+vO0mraiV5tU2g3uEoxlCqBnSZAlf2wdaP9I7G7KlE8ZCXn6hC6+ol+fjXCI5cvqN3OPknJWx8S5uB3WM2eJfXOyKLlpCawSuLD1PCTVsEy85OzZewGkG9/reE6sl1ekdj1lSieIidneC75+rh5+nCK4sPE2dp9aAOL4TwxfDEeLWkaSFJKRm/8hjX7qbww/P1KeHmpHdIirG1/1S7PPvLq9rlWuWRVKJ4BO9iTswYEMrt5HRGLz1iOetXXAvXyipXaatVzlQKZe5fF9kUcYMJHWoQWqGE3uEoRcHBGXovADsHWD5Qu2yr/ItKFI9Rx9+Lyd3qsCcqjq9/P6t3OLlLuaP1S7j5apec7Oz1jsiiHb58h882nuKpWn4Ma1lJ73CUouRdTlu/4tZJrdKspQ9kKQIqUeSgd4Ny9G9cnhm7oth04rre4TyezIY1L2tD/Xov0BZuUQrsTnI6oxYfprSXC1/3ClZ1nGxB4JOG9SuWwOEFekdjdlSiyMXEzrUIDvDirZXHiIpJ0jucRyp/+Wc4+5t2vbVcQ73DsWiZWdmMWnqY2KR0/vt8CF7F1Ex2m/HEeO2y7cbxuCeq/ooHqUSRC2cHe6YPCMXJwY6XFoWRnGZmNWIu/EGlC4u1da8bjdA7Gov3n42n+Ssyjsnd61A3wFvvcBRTsrPXLtu6+VI74nPtcq4CqESRJ2W9XZnarz5RMUlMWG1GxQMTrsGqIdwrVlYr0aEukRTKykNXmPvXBV5sXpE+DcrpHY6iBzcf6L0A57Tb8PNIyM7SOyKzoBJFHjUP9GVc+xqsP3adObsv6B2ONjpjaT/ISCGi9gRw9tA7Iot25PId3ltzgmZVfHjvmZp6h6PoqVxDIgOHwLnNsG2S3tGYBZUo8uGlJyrTvrYfn/12mv3n4/QLREpY+zJcPwo953DPTU2qK4ybCamMXBSGn5czP/QPUcX+FK6VfQZCX4S/voOjy/QOR3e6vCOEECWEEFuEEOcM/xZ/zHZZQohww033qZNCCL7qHUyFEsV4dclhou/oNOZ61xdwcq22GEv1DvrEYCVSM7IYuSiMpLRMZr3QgOJqUp0C2mXcZ76Cii1h3Wi4ckDviHSl11ent4FtUsqqwDbD/UdJkVLWM9y6mC68x/N0ceTHF0JJy8xm6PxDpq80G7EGdn6mlUpu9pppj21lpJS8t+YE4Vfu8k2fYGqU9tQ7JMWc2DtCn4Xg6Q/L+sPdK3pHpBu9EkVX4P5g5QVAN53iKJDAUh5Mfz6UyJgk087cvnZEmy9RrjF0/k51XhfSvL8usvpwNGPaVaVDnTJ6h6OYo2IloP9yyEzT+gTTzHOIfFETeozgEULclVJ6G34WwJ379x/aLhMIBzKBz6WUax+zvxHACAA/P7/QZcsef00xKSkJd3f3wjXAYOeVDOZHpNOuvAMDaxVthVantNuEhr2FFHaEhX5NhpP3388Zs03mpCjbFRGbxf+FpVKvpD2j6jtjZ6Kka42/K1toU4m4wwQd/4RY30ba4BFhmf1YOf2u2rRpEyalbPDIJ6WURXIDtgInHnHrCtx9aNs7j9mHv+HfysBFoEpuxw0NDZU52bFjR47P59enG07KChPWy3m7zxt1v/+Qfk/Kma2lnFxGyuvH/vW0sdtkLoqqXRdjk2TdjzbLp77ZKRNTM4rkGI9jjb8rm2nTnh+knOgp5bZPTB6PseT0uwIOycd8rjoYLVX9OwE9tnSpEOKmEKKMlPK6EKIMcOsx+7hq+Pe8EGInUB8wqymTEzrU4GJsMpPWn6S8TzHa1vAz7gGkhF9GwbXD8NxiKB1k3P3bmPiUDIYvPATArBca4O5cZG8Bxdo0eVmrB/XHV1Cyhlam3Ebodf60Dhhk+HkQ8MvDGwghigshnA0/+wLNgZMmizCP7O0E3/WtR62ynoxecoST1xKMe4A/v4YTq6Ddh1Czk3H3bWNSM7IYvvAQF2KT+e/zIVTwcdM7JMWSCAHPfgMVmsPaVyA6TO+ITEavRPE58JQQ4hzwpOE+QogGQojZhm1qAoeEEEeBHWh9FGaXKACKOTkw+4WGeLg4MnTBQW4lpBpnxyfXwfbJENQHWow1zj5tVFa25I3l4Ry4cJuvewfTPFAtZ6oUgIOTtoyqhx8s6wfxV/WOyCR0SRRSyjgpZTspZVUp5ZNSytuGxw9JKYcZft4jpQySUgYb/p2jR6x5VdrLhdmDGhCfksGwhYdISS/k1P+Lf8HPw8G/gSrPUUhSSj7+NYLfTtzg/Wdr0rWev94hKZbMzQf6LdeqI/zUA+7d1juiImeZXfdmqo6/F1P61uf41XjeWB5OdnYBR5RdPwpL+2rLmPZfAY4uxg3UxvywI5KFey8xslVlhrWsrHc4ijXwqwX9lsDtC7C4t9UPm1WJwsierOXH+8/WYlPEDT7ZcDL/BQRjI2FRD3DxgoFr1NoShbTi4BW+/v0s3ev7M6FDDb3DUaxJpVbQe542v2n589pcCyulEkURGNK8IkOaV2LeXxf5v/ysjhcfDYu6aT8PXAteAUURns3Yduom76w5TqtqJfmyV13s7NTlO8XIajwLXafB+Z2weihkmdkyBEaixgYWASEEH3SqSUpGFtN2ROLiaMeotlVzflFyHCzqDqnxMHg9+AaaJlgrFXbpDq8uOUztsp5Mfz4ER1XoTykq9fpr79tNb8P6162yT1EliiIihODTbnVIy8ji69/P4uJo//jr46kJsLgn3L2sXW4qE2zaYK1M5K0khi44SGlPF+YOboibmiuhFLUmL2ud2n98Ca7e8NQnVpUs1DuoCNnZCb7sVZe0zGwmbziFi6M9A5pU+OdGGalawbEbx6HvEqjQTJ9grcSN+FQGzT2Ag51g4ZDG+LoXbWkVRflbm3e1VfH2TAXXEtDSeoa0q0RRxBzs7fj2uXqkZWbx/toTuDja0yvU0PeQlQmrhsDF3dBjFlRrr2+wFu7q3RSen7WPu/fSWT6yKeV9iukdkmJLhICOX0LqXdj2MbgWhwYv6h2VUagLtybg5GDHtP4htKzqy/hVR1l/7BpkZ2t17s9s0Ore1+2td5gW7XLcPfrM2EtcUjoLhzamjr+X3iEptsjODrpNh6rtYf0bcGK13hEZhUoUJuLiaM+PAxvQoGIJ3lwWxtVFw+HoEmjzHjQarnd4Fi0qJok+M/eSnJ7JkuFNCK3wyHWwFMU07B2h93wo3xR+HgHHV+kdUaGpRGFCrk72zB0QxAL3H/C/sIpLdUZBq3F6h2XRTt9I4LmZe8nMzmbZiCYEBagzCcUMOBXT1rEo1xhWD4MDs/SOqFBUojCl1ATcV/alSfpepruO5OnwFvx+8qbeUVmsE1fj6fvjPuztBMtGNFUr1CnmxcUTBqyG6h1h41uw8wutGrQFUonCVJJiYEEnuLwXesziuVGTqVHGk5d+CmPh3ot6R2dxwi7dod+sfbg5ObBiZFMCS1nXwjmKlXB01YoIBveHnf+B3yZo/ZMWRiUKU7h7GeZ1gJiz0Hcp1O1DCTcnlg1vQtsafnz4SwSf/Xaq4LWhbMzeqDgGztmPj5sTK15qqsqFK+bN3gG6/gBNR8GBmbBmBGRl6B1VvqhEUdRunYY57SE5Bl5YC9We/vspVyd7Zg4MZWCTCszcdZ4xy8NJyyxk1Vkr98fZGAbPO4C/tysrRjbF39tV75AUJXd2dvD0ZGg3EY6v1NbfTr+nd1R5phJFUYo+pJ1JyCwYvBHKN/nXJvZ2gklda/N2xxr8evQaA+ccIP6eZX3bMJVlBy4zbMEhKpd0Z9mIJpTyVFV1FQsihDYJr/P3ELVNK9mTckfvqPJEJYqiErUdFnTRqsAO2Qyl6zx2UyEELz1Rhe/71iP88l16zthD9B3L+bZR1NIys3jn52O8/fNxGlcuwbLhTfBRM64VSxU6GHrN05Y3nvcsJN7QO6JcqURhbNnZsPtb+KkXlKikJYkSlfL00q71/Fk4tBG3ElLp/t89nLgaX8TBmr9rd1PoM3MfSw9c4dU2VZj/YiO8ijnqHZaiFE7tbtpaM3cuwswn4MKfekeUI5UojCkpBhb3gq0fQa0u8OJG8Cidr100qezDqpeb4Wgn6DNzL1ttePjsqbgsOk/dTdStJGYMCGVc+xrYq1LhirWo0gaG/g7OHrCwC+z8HLLNs49SJQpjufAnzGih1W3q9K12aulSsMlf1fw8WPNqcyr5ujFs4SE+WHuCe+nWWef+UaSUzP7zPF8dSsW7mCNrX21Ohzr5S7iKYhFK14EROyGoD+z8DBZ2hYTrekf1LypRFFZ2lvZNYGEXcHaH4dugwZBClxj283Rh9cvNGN6yEj/tv8SzU3Zz5LJldHwVxr30TF5bFs7kDaeoX8qeta82V3MkFOvm7A49Zmo1oq6GaV84I7fqHdU/qERRGAnXtW8AOz+DoN4wYheUDjLa7l0c7Xnv2VosHtaYtIwses3Yy7dbzpKRZXkTdvLiQmwy3X/Yw4Zj1xjfoTqj6jnj4aL6IxQbUa8/DN8B7qXgp57aJWwzmW+hEkVBRW7VMn/0IW0yTfeZ2jeDItCsii+/vd6KrsFl+X7bOXpN30NUjPUs5p6akcU3W87S/rs/uJmYyvwXG/FK60CEFS38oih5UqoGDNsGIYO0QTHzn4W7V/SOSiWKfEu6BevHahnfraR2fbH+gCJfzcrL1ZFvnqvHD/1DuHT7Hs9O+ZNFey8iLbR2DGh9Eb9H3ODJb3YxZds52tcuzaYxrWhVraTeoSmKfpyKQZcp0HMO3IzQvpAemKXr2YVauCiv0pJg7zRt9aqMFGg0Ep78SPulmtCzdcvQoGJx3lp5lA9+iWDLqVt0LGV5l6IuxCbz0boIdp2NoZqfO0uHN6FpFR+9w1IU8xHUC8rWh3WvaUUF9/1Xm9ldq6vJl1lViSI3WZlwZCHs+AySb0HNLtovyzdQt5D8PF1YOKQRi/Zd4rONp/nzbBZ7E48wum0gVf08dIsrL+6lZ/LDjkhm/XEBZwc7PuhUixeaVsDRXp3cKsq/+FSBwevh3O+wZSKsHAT+DeCpSVCxucnCUInicaSE0xu0DqW4c9oiJH0XQ7lGekcGaLO5X2hakWeCyvDh4l1sPXWTX49d45mgMoxuG2h2JbezsyW/nbjBpxtOci0+lR4h/rzdsQalPFQZDkXJkRDaMsmBT0L4EtjxKcx/Bqp11K5qlKpR5CGoRPEwKeHyPtg6Ea7sB99q0HcJVH/G5Kd7eeHr7kyf6k5MHtCMObvPs2DPJTYcu06H2qUZ3S6Q2mX1XcjnRnwqq8KusOJQNJdv36NWGU+m9KtPg4oldI1LUSyOnT2EDIQ6PWH/dNj9HUxvqvWRPvE2ePkX2aFVogAtOdw4DifXQsRauB0F7n7Q6TuoP1ArE2zmSrg5Ma59DYa3rMzc3ReY99dFNkXc4KlafoxoVZmQ8sVNNqs5PTOb7advsvzgFXadjSFbQpPKJRj7VDU6B5dVs6sVpTCcikHLNyFkMPzxFRycDYcXQYXmWmmQml3Aw8+oh9TlE1AI0Rv4CKgJNJJSHnrMdh2A7wF7YLaU8nOjBfGP5LAGbp8HYQ+VWkKz0VC3DzhZ3joH3sWcGPt0dYa2rMz8vy4yZ/d5tpy8iZerIy0CfWlVzZdW1UpSxsv45bkjbyWy/OAVfj58lbjkdPw8nXm5dRV6h5ajoq/l/V8qillz84GOn0OTlyB8qfZZtvEt2DgOKjSD2t2NljT0+qp8AugBzHzcBkIIe+AH4CkgGjgohFgnpTxZoCOmJUHCVYrfPgLb/ngoObSC5mOgRidw8y3Q7s2Nl6sjY56sypAWFdlxJoY/zmq3Dce18gDV/NxpVbUkraqVpFGlErg42ud531nZksu373HuZiLnbiVx9mYip68ncuZmIg52gnY1S/Fcw3K0qloSB9VJrShFq3hFaPOOdrt1+n9XRh5MGrW6QukgXFJuasNs7fM3kVWXRCGlPAXkNqGqERAppTxv2HYZ0BXIOVHcuw27voSEqxB/Vfs34SqkapVYg+Gh5NBZy8xWysPFkS7BZekSXBYpJadvJGpJ41wMC/deYvZubfSRn6cL7s4OeLhoN+1nR9wNPwOcu5nI2ZtJRMUkkZb5vyG5/t6uVPVzp2eoP93rB1DSQ5UAVxRdlKoBpd6G1m//M2n8Nh6AJgD7R2qzvz39tX4NT8MtB0LPCVtCiJ3AW4+69CSE6AV0kFIOM9wfCDSWUo56xLYjgBEAoWXsQg+NcCfd0Ys0Z1/SnH1JdfElzdmHNGdf7ma7ke1bjUxH8xoVVBhJSUm4u+d/VnhapuT0nSxOxWURnyZJyYSUzP/9m5opuZcJWYY/kRIugrLudvi7C/zd7fB3t6Osux2uDkXT51DQdpkz1SbLYG1tckm5gWvKdYi/iqdIwiU1Bue0WJzT4nBOi8UhKwXxcUKYlLLBo15fZGcUQoitwKNKfr4npfzFmMeSUv4I/AjQoF6Q5L2DODm64AQ8PKtg586dtG7d2piH111h2tQ+l+ellKRlZpMtJcWcTHsCqn5XlkG1yXLs3LmT4Ee1KzUePvZ+7OuK7J0vpXyykLu4CpR74H6A4bGcOTiDoxqbbyxCiHz1XyiKYoFyWRLBnHsaDwJVhRCVhBBOQF9gnc4xKYqi2BxdEoUQorsQIhpoCmwQQmw2PF5WCLERQEqZCYwCNgOngBVSygg94lUURbFleo16WgOsecTj14BnHri/EdhowtAURVGUh5jzpSdFURTFDKhEoSiKouRI13kURUEIEQNcymETXyDWROGYijW2CayzXapNlsEa2wQ5t6uClPKRq4ZZXaLIjRDi0OMmlVgqa2wTWGe7VJssgzW2CQreLnXpSVEURcmRShSKoihKjmwxUfyodwBFwBrbBNbZLtUmy2CNbYICtsvm+igURVGU/LHFMwpFURQlH2wyUQghPhFCHBNChAshfhdClNU7psISQnwlhDhtaNcaIYS33jEVlhCitxAiQgiRLYSw6BEoQogOQogzQohIIcTbesdjDEKIuUKIW0KIE3rHYixCiHJCiB1CiJOGv70xesdUWEIIFyHEASHEUUObPs73Pmzx0pMQwlNKmWD4+TWglpTyJZ3DKhQhxNPAdillphDiCwAp5QSdwyoUIURNIBttJcRHrltiCQyrNZ7lgdUagX4FXq3RTAghWgFJwEIpZR294zEGIUQZoIyU8rAQwgMIA7pZ8u9KaCvEuUkpk4QQjsBuYIyUcl9e92GTZxT3k4SBG2Dx2VJK+buhkCLAPrSy7BZNSnlKSnlG7ziM4O/VGqWU6cD91RotmpTyD+C23nEYk5TyupTysOHnRLSCpDkv/2bmpCbJcNfRcMvXZ55NJgoAIcSnQogrwPPAh3rHY2RDgN/0DkL5mz9w5YH70Vj4h48tEEJUBOoD+3UOpdCEEPZCiHDgFrBFSpmvNlltohBCbBVCnHjErSuAlPI9KWU5YDFaOXOzl1ubDNu8B2Sitcvs5aVNimJqQgh3YDXw+kNXICySlDJLSlkP7UpDIyFEvi4V6lJm3BTyscLeYrRS5hOLMByjyK1NQojBQCegnbSQzicjrIRoCQq2WqOiC8N1/NXAYinlz3rHY0xSyrtCiB1AByDPgxCs9owiJ0KIqg/c7Qqc1isWYxFCdADGA12klPf0jkf5B7Vao4UwdPzOAU5JKb/ROx5jEEKUvD8KUgjhijaoIl+febY66mk1UB1tRM0l4CUppUV/wxNCRALOQJzhoX1WMJKrOzAVKAncBcKllO11DaqAhBDPAN8B9sBcKeWn+kZUeEKIpUBrtIqkN4GJUso5ugZVSEKIFsCfwHG0zweAdw2LqFkkIURdYAHa354d2mqhk/K1D1tMFIqiKEre2eSlJ0VRFCXvVKJQFEVRcqQShaIoipIjlSgURVGUHKlEoSiKouRIJQpFURQlRypRKIqiKDlSiUJRipgQoqFhnRAXIYSbYU0AqyjLrdgGNeFOUUxACDEZcAFcgWgp5Wc6h6QoeaYShaKYgKHG00EgFWgmpczSOSRFyTN16UlRTMMHcAc80M4sFMViqDMKRTEBIcQ6tJXtKqEttWkRa6AoCljxehSKYi6EEC8AGVLKJYb1s/cIIdpKKbfrHZui5IU6o1AURVFypPooFEVRlBypRKEoiqLkSCUKRVEUJUcqUSiKoig5UolCURRFyZFKFIqiKEqOVKJQFEVRcqQShaIoipKj/wd9TXy632o1mQAAAABJRU5ErkJggg==\n",
"text/plain": [
"<Figure size 432x216 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"x = np.linspace(-np.pi, np.pi, 40)\n",
"y1, y2 = np.sin(x), np.cos(x)\n",
"\n",
"fig = plt.figure(figsize=(6,3))\n",
"\n",
"plt.plot(x, y1, label='sin')\n",
"plt.plot(x, y2, label='cos')\n",
"\n",
"plt.xlim(-np.pi, np.pi)\n",
"plt.ylim(None, None)\n",
"\n",
"plt.xlabel('x')\n",
"plt.ylabel('y')\n",
"plt.title('functions')\n",
"plt.grid()\n",
"plt.legend()\n",
"\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Histogram"
]
},
{
"cell_type": "code",
"execution_count": 90,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 432x216 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"x = np.random.beta(5, 5, size=1000)\n",
"\n",
"plt.figure(figsize=(6,3))\n",
"plt.hist(x, bins=50)\n",
"plt.xlim(0,1)\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 2d Data and Images"
]
},
{
"cell_type": "code",
"execution_count": 91,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 576x432 with 2 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"t = np.linspace(-np.pi, np.pi, 100)\n",
"data = np.sin(t)[:,None] * np.cos(t)[None,:]\n",
"\n",
"labels = [r'$-\\pi$', r'$-\\pi/2$', r'$0$', r'$\\pi/2$', '$\\pi$']\n",
"ticks = np.linspace(0,1,len(labels))*(len(t)-1)\n",
"\n",
"plt.figure(figsize=(8,6))\n",
"\n",
"plt.imshow(data)\n",
"\n",
"plt.title(r'$\\sin(t) \\cdot \\cos(t)$')\n",
"plt.colorbar(label='colorbar')\n",
"plt.xticks(ticks, labels)\n",
"plt.yticks(ticks, labels)\n",
"\n",
"# save plot as file\n",
"plt.savefig('./plot.pdf')\n",
"plt.savefig('./plot.png')\n",
"plt.savefig('./plot.jpg', pil_kwargs={ 'quality': 90, 'subsampling': 10})\n",
"\n",
"plt.show()\n",
"\n",
"from IPython.display import Image\n",
"#Image('plot.jpg')"
]
},
{
"cell_type": "code",
"execution_count": 92,
"metadata": {},
"outputs": [],
"source": [
"!rm plot.pdf plot.png plot.jpg"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"- You can use LaTeX in Matplotlib as shown in the example above\n",
"- More advanced examples can be found at \n",
"https://matplotlib.org/stable/gallery/index.html"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# TensorFlow\n",
"\n",
"- **Ubuntu** is an often used Linux distribution\n",
"- **APT** (Advanced Package Tool) is the package manager used by Linux distributions like Debian and Ubuntu\n",
"- **Anaconda** is a Python distribution often used under Windows (can also install system dependencies, not only python packages)\n",
"- **Conda** is the package manaer used by Anaconda\n",
"- **CUDA** (Compute Unified Device Architecture) is a parallel computing platform and library for Nvidia GPUs \n",
"- **cuDNN** (CUDA Deep Neural Network) low-level library for GPU-accelerated deep learning"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Tensorflow Setup \n",
"\n",
"- Latest TensorFlow at time of writing was version 2.5\n",
"- Official setup instructions \n",
"https://www.tensorflow.org/install\n",
"- The typical system dependencies for GPU support are the Nvidia Driver, CUDA and cuDNN\n",
"- See TensorFlow website for compatible versions of TensorFlow, cuDNN and CUDA \n",
"https://www.tensorflow.org/install/source_windows#gpu\n",
"\n",
"\n",
"### Windows 10\n",
"\n",
"1) Download and install Anaconda (Python distribution) \n",
"- https://www.anaconda.com/products/individual#Download\n",
"- Windows > Python 3.8 > 64-Bit Graphical Installer\n",
"\n",
"2) Open Anaconda Prompt\n",
"- Windows Start Menue > Anaconda Command Prompt\n",
"\n",
"3) Crate an environment (not necessarily required, but recommended)\n",
"- `conda create -n tf`\n",
"- `conda activate tf`\n",
"- default environment is `base`\n",
"\n",
"4) Install required Python packages\n",
"- `pip install -U numpy jupyter matplotlib pandas tqdm tensorflow`\n",
"\n",
"GPU Support\n",
"\n",
"1) Requires an adequate Nvidia GPU and installed Nvidia Driver\n",
"- https://en.wikipedia.org/wiki/CUDA#GPUs_supported\n",
"\n",
"2) Install Microsoft Visual Studio or at least Microsoft Visual C++ Redistributable\n",
"- Required by cuDNN, Community edition should be sufficient\n",
"- https://visualstudio.microsoft.com\n",
"- https://support.microsoft.com/en-us/topic/the-latest-supported-visual-c-downloads-2647da03-1eea-4433-9aff-95f26a218cc0\n",
"\n",
"3) Install Nvidia CUDA toolkit — 11.2.1\n",
"- https://developer.nvidia.com/cuda-11.2.1-download-archive?target_os=Windows&target_arch=x86_64&target_version=10&target_type=exelocal\n",
"\n",
"4) Install Nvidia cuDNN — 8.1.1\n",
"- https://developer.nvidia.com/rdp/cudnn-download\n",
"- You have to create a free account to access the files\n",
"\n",
"5) Create Anaconda environment `tf` and install Python packages as described above\n",
"\n",
"### Ubuntu 20.04 \n",
"\n",
"With GPU Support\n",
"\n",
"1) Add Nvidia Reopository\n",
"- `wget -O /etc/apt/preferences.d/cuda-repository-pin-600 https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64/cuda-ubuntu2004.pin`\n",
"- `apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64/7fa2af80.pub`\n",
"- `add-apt-repository \"deb https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64/ /\"`\n",
"\n",
"2) Remove old Dirver and CUDA if installed\n",
"- `apt remove nvidia*`\n",
"- `apt remove cuda*`\n",
"- `apt autoremove`\n",
"\n",
"3) Install Nvidia Driver, CUDA and cuDNN\n",
"- `apt update`\n",
"- `apt install nvidia-driver-465 cuda-11-2 nvidia-cuda-toolkit libcudnn8`\n",
"\n",
"4) Install Python\n",
"- `apt update`\n",
"- `apt install python3.8 python3.8-dev python3-pip python3-venv`\n",
"\n",
"5) Install PIP as user\n",
"- `python3.8 -m pip install pip`\n",
"- `ln -s /usr/bin/python3.8 ~/.local/bin/python`\n",
"- `ln -s /usr/bin/python3.8 ~/.local/bin/python3`\n",
"- logout and login\n",
"- alternatively you can use `venv` to create a virtual environment\n",
"\n",
"6) Install required Python packages as user\n",
"- `pip install -U numpy jupyter matplotlib pandas tqdm tensorflow keras`"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Import of Libraries "
]
},
{
"cell_type": "code",
"execution_count": 93,
"metadata": {},
"outputs": [],
"source": [
"import os, time\n",
"import numpy as np\n",
"import matplotlib.pyplot as plt\n",
"import pandas as pd\n",
"from tqdm.notebook import tqdm\n",
"#from tqdm import tqdm # use this in the terminal\n",
"\n",
"os.environ['CUDA_VISIBLE_DEVICES'] = '0' # 0=GPU1, 1=GPU2, ... -1=CPU\n",
"os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3' # 0=DEBUG, 1=INFO, 2=WARNING, 3=ERROR\n",
"os.environ['TF_FORCE_GPU_ALLOW_GROWTH'] = 'true'\n",
"\n",
"import tensorflow as tf\n",
"import keras"
]
},
{
"cell_type": "code",
"execution_count": 94,
"metadata": {},
"outputs": [],
"source": [
"tf.get_logger().setLevel('ERROR')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Tensors\n",
"\n",
"TensorFlow tensors most of the time behave like NumPy arrays, but are immutable and allow back-probagation."
]
},
{
"cell_type": "code",
"execution_count": 95,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[[ 0, 1, 2, 3],\n",
" [ 4, 5, 6, 7]],\n",
"\n",
" [[ 8, 9, 10, 11],\n",
" [12, 13, 14, 15]],\n",
"\n",
" [[16, 17, 18, 19],\n",
" [20, 21, 22, 23]]])"
]
},
"execution_count": 95,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"a = np.arange(24).reshape((3,2,4))\n",
"a"
]
},
{
"cell_type": "code",
"execution_count": 96,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"<tf.Tensor: shape=(3, 2, 4), dtype=float32, numpy=\n",
"array([[[ 0., 1., 2., 3.],\n",
" [ 4., 5., 6., 7.]],\n",
"\n",
" [[ 8., 9., 10., 11.],\n",
" [12., 13., 14., 15.]],\n",
"\n",
" [[16., 17., 18., 19.],\n",
" [20., 21., 22., 23.]]], dtype=float32)>"
]
},
"execution_count": 96,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"t = tf.convert_to_tensor(a, dtype='float32')\n",
"t"
]
},
{
"cell_type": "code",
"execution_count": 97,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[[ 0, 1, 2, 3],\n",
" [ 4, 5, 6, 7]],\n",
"\n",
" [[ 0, 0, 0, 0],\n",
" [ 0, 0, 0, 0]],\n",
"\n",
" [[16, 17, 18, 19],\n",
" [20, 21, 22, 23]]])"
]
},
"execution_count": 97,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"a[1,:,:] = 0.0\n",
"a"
]
},
{
"cell_type": "code",
"execution_count": 98,
"metadata": {},
"outputs": [
{
"ename": "TypeError",
"evalue": "'tensorflow.python.framework.ops.EagerTensor' object does not support item assignment",
"output_type": "error",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)",
"Cell \u001b[0;32mIn [98], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m t[\u001b[38;5;241m1\u001b[39m,:,:] \u001b[38;5;241m=\u001b[39m \u001b[38;5;241m0.0\u001b[39m\n\u001b[1;32m 2\u001b[0m t\n",
"\u001b[0;31mTypeError\u001b[0m: 'tensorflow.python.framework.ops.EagerTensor' object does not support item assignment"
]
}
],
"source": [
"t[1,:,:] = 0.0\n",
"t"
]
},
{
"cell_type": "code",
"execution_count": 99,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"<tf.Tensor: shape=(3, 2, 4), dtype=float32, numpy=\n",
"array([[[ 0., 1., 2., 3.],\n",
" [ 4., 5., 6., 7.]],\n",
"\n",
" [[ 0., 0., 0., 0.],\n",
" [ 0., 0., 0., 0.]],\n",
"\n",
" [[16., 17., 18., 19.],\n",
" [20., 21., 22., 23.]]], dtype=float32)>"
]
},
"execution_count": 99,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"tf.stack([t[0], tf.zeros_like(t[1]), t[2]], axis=0)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"https://www.tensorflow.org/api_docs/python/tf"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## MNIST Image Classification Dataset\n",
"\n",
"MNIST database (Modified National Institute of Standards and Technology database) \n",
"for handwritten digits classification\n",
"\n",
"<img src=\"https://upload.wikimedia.org/wikipedia/commons/2/27/MnistExamples.png\"> </img>"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Load Data Set"
]
},
{
"cell_type": "code",
"execution_count": 100,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"(60000, 28, 28, 1) (60000, 10)\n",
"(10000, 28, 28, 1) (10000, 10)\n"
]
}
],
"source": [
"from keras.datasets import mnist\n",
"from keras.utils import to_categorical\n",
"\n",
"input_shape = (28, 28, 1)\n",
"num_classes = 10\n",
"\n",
"# the data, split between train and test sets\n",
"(x_train, y_train), (x_test, y_test) = mnist.load_data()\n",
"\n",
"# normalize input data\n",
"x_train = x_train.astype('float32').reshape((-1, *input_shape)) / 255\n",
"x_test = x_test.astype('float32').reshape((-1, *input_shape)) / 255\n",
"\n",
"# convert class labels to one-hot encoding\n",
"y_train = to_categorical(y_train, num_classes)\n",
"y_test = to_categorical(y_test, num_classes)\n",
"\n",
"# input, output shape\n",
"print(x_train.shape, y_train.shape)\n",
"print(x_test.shape, y_test.shape)"
]
},
{
"cell_type": "code",
"execution_count": 101,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([1., 0., 0., 0., 0., 0., 0., 0., 0., 0.], dtype=float32)"
]
},
"execution_count": 101,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"y_train[1]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Some Samples"
]
},
{
"cell_type": "code",
"execution_count": 102,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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fr6Y+Dn2VqxYkXlPCF+/fv28+vjjj/fqrl27enXpeo34d82bmppq3B1QX8cdd1zL9W984xvefS+88IJXP/roo3XpCUgSPwfYxRdf7NXtWWNXSXzNXHx90rHHHpvZvlEc++23n1eXvs62ZsaMGVm2kyh+7sb4mtdly5Z5ddL5rvOGT+4AAAAAIABM7gAAAAAgAHwtsw5OOOEEr77++usTx0+YMMGrX3nllVq3hA5o/vz5Xt27d+/E8b/73e9arnPYaoRm9OjRLdd79erl3bdw4UKv3r59e116QscWPw1S3Be+8IU6dbInM/PqeK+Vev/hD3/o1RdeeGFN+kK+xJd3HHTQQV49Z86ceraTaODAgYn3F/m9N5/cAQAAAEAAmNwBAAAAQACY3AEAAABAAFhzVwdjx4716s6dO3v1Y4895tVPP/105j0hfGeccYZXH3300YnjFy1a5NU/+MEPat0SkBtDhw5tue6c8+6bN29evdtBB3TZZZd59e7duxvUSWXjxo3z6uHDh3t1vPd4HV9zhzBt3brVq1988UWvHjJkiFfH1ztv2rQpk74k6YADDvDqiRMnJo5/8sknM+sla3xyBwAAAAABYHIHAAAAAAFgcgcAAAAAAWDNXQb22Wcfrx4zZoxXf/TRR14dX9u0Y8eObBpD0OLnrfvud7/r1fG1nnHx78Y3NTXVpC8gDw488ECvHjVqVMv1FStWePfdd999dekJHVt8HVsj9enTx6sHDRrk1fH/n1Ty7rvvejXvazqGDz/80Kvj58g9++yzvfrBBx/06unTp7d534MHD/bqQw891KsHDBjg1fG11nF5XgNbCZ/cAQAAAEAAmNwBAAAAQACY3AEAAABAAFhzl4FrrrnGq+Png1m4cKFXP/XUU5n3hPBdffXVXn3ssccmjr///vu9mvPaIWQXXXSRV5ee8+iPf/xjnbsB8uWGG27w6qlTp6b6+TfffNOrJ0+e7NVr1qxpU18otvj7CjPz6q997WtePWfOnDbva+PGjV4dX1O3//77p9reHXfc0eZeGo1P7gAAAAAgAEzuAAAAACAATO4AAAAAIACsuauB+HeGv//973v1li1bvPrGG2/MvCd0PFdddVWq8ZdffrlXc147hKx///5l73v//ffr2AnQeA899JBXH3HEEe3a3tKlS736ySefbNf2EIbly5d79TnnnOPVw4YN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\n",
"text/plain": [
"<Figure size 1152x144 with 5 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"plt.figure(figsize=(16, 2))\n",
"for i in range(5):\n",
" plt.subplot(151+i)\n",
" plt.imshow(x_test[i,:,:,0], cmap='gray')\n",
" plt.title(str(np.int8(y_test[i,:])), y=-0.4)\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Keras Model\n",
"\n",
"Keras used to be an independent library. With TensorFlow 2.0 the complete Keras API was integrated in TensorFlow. "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Sequential API"
]
},
{
"cell_type": "code",
"execution_count": 103,
"metadata": {},
"outputs": [],
"source": [
"from keras.layers import Input, Dense, Conv2D, MaxPooling2D, Dropout, BatchNormalization, Flatten, Activation\n",
"from keras.models import Sequential\n",
"\n",
"model = Sequential()\n",
"\n",
"model.add(Input(input_shape))\n",
"model.add(Conv2D(32, kernel_size=(3, 3), activation='relu'))\n",
"model.add(Conv2D(64, (3, 3), activation='relu'))\n",
"model.add(MaxPooling2D(pool_size=(2, 2)))\n",
"model.add(Dropout(0.25))\n",
"model.add(Flatten())\n",
"model.add(Dense(128, activation='relu'))\n",
"model.add(Dropout(0.5))\n",
"model.add(Dense(num_classes, activation='softmax'))\n",
"\n",
"model.build()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Functional API"
]
},
{
"cell_type": "code",
"execution_count": 104,
"metadata": {},
"outputs": [],
"source": [
"from keras.layers import Input, Dense, Conv2D, MaxPooling2D, Dropout, BatchNormalization, Flatten, Activation\n",
"from keras.models import Model\n",
"\n",
"x = x_in = Input(input_shape)\n",
"x = Conv2D(32, kernel_size=(3, 3), activation='relu', name='foo')(x)\n",
"x = Conv2D(64, (3, 3), activation='relu')(x)\n",
"x = MaxPooling2D(pool_size=(2, 2))(x)\n",
"x = Dropout(0.25)(x)\n",
"x = Flatten()(x)\n",
"x = Dense(128)(x)\n",
"x = Activation('relu')(x)\n",
"x = Dropout(0.5)(x)\n",
"x = Dense(num_classes, activation='softmax')(x)\n",
"\n",
"model = Model(x_in, x)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"- Models can be used like layers in other models (nesting)\n",
"- It is much easier to build larger models using the functional API"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Model Info"
]
},
{
"cell_type": "code",
"execution_count": 105,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Model: \"model\"\n",
"_________________________________________________________________\n",
" Layer (type) Output Shape Param # \n",
"=================================================================\n",
" input_2 (InputLayer) [(None, 28, 28, 1)] 0 \n",
" \n",
" foo (Conv2D) (None, 26, 26, 32) 320 \n",
" \n",
" conv2d_2 (Conv2D) (None, 24, 24, 64) 18496 \n",
" \n",
" max_pooling2d_1 (MaxPoolin (None, 12, 12, 64) 0 \n",
" g2D) \n",
" \n",
" dropout_2 (Dropout) (None, 12, 12, 64) 0 \n",
" \n",
" flatten_1 (Flatten) (None, 9216) 0 \n",
" \n",
" dense_2 (Dense) (None, 128) 1179776 \n",
" \n",
" activation (Activation) (None, 128) 0 \n",
" \n",
" dropout_3 (Dropout) (None, 128) 0 \n",
" \n",
" dense_3 (Dense) (None, 10) 1290 \n",
" \n",
"=================================================================\n",
"Total params: 1199882 (4.58 MB)\n",
"Trainable params: 1199882 (4.58 MB)\n",
"Non-trainable params: 0 (0.00 Byte)\n",
"_________________________________________________________________\n"
]
}
],
"source": [
"model.summary()"
]
},
{
"cell_type": "code",
"execution_count": 106,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAPsAAALNCAYAAADpzhc/AAAABmJLR0QA/wD/AP+gvaeTAAAgAElEQVR4nOyde1xU5fb/PzsugoAoyAyCKZiFIMoX9RdQCpQoYBgGmoakWXbQLpKXcwjFSwkJ5PFSBy+nzBscMkg8lJ7hiIqKR61ExINCaSBy846ooAizfn94ZsfADDMDmxlgnvfrxevF7MvnWc+GNXs/z15rPRwRERgMRo/nKV0bwGAwtIOhECI1NTW4ePGiEFIMBqMF1tbWeO655zqsI4iznzhxAl9//TWef/55IeS6Lb/99hsePXoEV1dXXZuiMQ8ePMCJEycwceJEXZvCaIZUKsWZM2ewd+/eDmsJ4uwAEBAQgIiICKHkuiV79+5FbW0t3nrrLV2bojFVVVW4ceMGoqOjdW0KoxmNjY14/fXXBdFiY3YGQ09gzs5g6AldwtnHjh2LpqYmwXVtbW3b3N/Q0IDo6GhYWlpCLBZjxYoVgtvAYHQVBBuzd4Tc3FydtHvs2DHU1dWhqqoKpaWlGDduHIKDgzF69Gid2MNgdCY6v7OHh4eD4ziUlpbyv8fFxcHS0hJeXl548OABgCcTgBzHITY2FhYWFhg9ejSKi4vh5+cHQ8Mn31lr164Fx3E4deoUAgICcO3aNXAch6lTpyps28/PDxs3bkTv3r3h4uKCIUOGqHwaYDC6Kzp39uTkZHh4eMj9bmNjg+rqavTr1w+HDx8GAEgkEjg5OcHBwQHXr1/HpEmTsHjxYmRnZ6N///4AgCVLliA0NJQ/XiwWg4iQnp6u0o7du3dj/vz5sLe376Sedl8uXboEjuP4L2UiQmxsLK5du6Zr07odxcXF+OKLL/jPubm5/LW9f/9+p7atc2dXxIQJE2BqagoXFxfcvXtXbl9QUBBMTU0REhKCCxcutDq3PdG/W7duBRHh7bffbrfNmqKreYr2Mnr0aBARHBwckJiYCGdnZ4jFYsTExIDjOPj4+KChoQEAkJOTw/8D79u3r1PskaFq3uXvf/877OzsYGFhgddffx0PHz5sl5YmOjIKCwvxxhtvyD1ZOjk5gYiQkpIC4Mn/ARFp5SbTJZ2d4zil+zIzM1FfX4+9e/fCxcUFAGBmZobz58+jsrISBQUF/LGmpqYoLS3FpEmTlOrt3LkTIpEIs2bNQn5+Pnbs2CFYP9oiNzcXBgYGWmlLSKRSKbZt24bg4GAAQGxsLKKiolBQUIB58+YBAHx9fXHw4EGkpaVhypQpnWpP83mXI0eOICkpCWfOnAEAPHz4EAsXLoREIkF5eTmuX7+OPXv2aKylqY6MqqoqhUPIsLAwrF+/vv2dbic6d/bw8HCcPn0aw4YNw7x583D69Gl4enpi3759+Otf/4o333wTRUVF/PHV1dUQiUTYv38//vrXvwIAIiMj8cILL2D27NkYNmwYvLy8UFNTg/DwcLi6usLb21th2ydOnMCcOXMQEhICjuPg7u6utT6rmqfQdI4CgFrzFB2lsrIShoaGvA0y9uzZg++++w4JCQmtzvnkk08gFoshEon4u2Vb8zMrVqyAjY0N7OzssGnTpjbtaWvexdDQEFZWVnLHi0QijbU01Wmup+gL3cbGBiUlJWhsbFSpISgkAD/++CNt2bJFCKk2cXJyonv37nV6O+3l+++/p+3bt6t1rIeHB5WUlPC/b926lerq6igwMJAyMzOJ6El/d+/eTXV1dRQTE0OvvPIKERGJxWJeJzQ0lE6ePMl/br6PiGj8+PGUn5+v0p7Kykr605/+pHDfb7/9RqNHjyYionPnztGYMWPk9kdFRdGNGzcoMzOTDA0Nae/evXTw4EFKS0sjiURCw4cPp/LycqqoqCBXV1fav3+/0n5LJBLy8PCgsrIyqqqqohEjRtDly5dV2k9EtGvXLtq2bZvctrS0NLKwsCAANGvWLGpqamqXVnt1MjIyKDQ0tNV2e3t7un79utxnRf/bjx8/ptdee02ttlSh8zu7ugQEBKC4uBhDhw5t1/myMWTzn66EsnmKjs5RZGdnw83NTTA7rays+DtwSyZPnox169bhzTffxNmzZwEABQUF8PX1hb29Pezs7PDyyy/j3Llz/Dkt+11QUIDTp09j0KBBGDBgAM6fP88/ubSFonmXoqIiREdHo6CgAPfv34eJiQliY2M11mqvTlvU19ejX79+HdLQlG7j7BKJBESE6urqdp1PRK1+uhLKvnw0maMA1Jun6Ah2dnZobGxU+gj64YcfYu7cuXyMvZubGw4fPoyKigpUVlbi0KFDcl8+Lfvt5uYGX19f3Lx5k/87hYWFtWmTsnmX6upqNDY2yrVx9epVjbXao9MWN27cgKOjY6uhUKcjxOOBth7juzrqPsbPnDmTAFCvXr0oIiKCAJBYLKaMjAwCQADo4sWL5OTkRAkJCWRubk7u7u5UVFREREQbN24kc3Nz8vPzo6CgIAJAd+7cISKimJgYMjMzozVr1hARkZ+fn6CP8URE8fHxlJ6eTkREy5Yt422WPYY2NTVRcHAwpaWlERHRqlWryMbGhvr370/Lly8nImqz37LjTU1Nyd/fn27evElERMOHD6eKigo523Jzc4njOP58APzfQCqVUmRkJFlbW5OpqSn5+PjwQydNtNrSUaZFRPT+++/zOpaWlvz2DRs2UHJystyx2niM54g6fovbv38/cnJy8Morr3RUqltz/PhxDBw4EHPmzBFEb9iwYfjll19gbm4uiF5bVFVVYdWqVdi6dWurfZcuXcKzzz4LACgpKcHgwYMRFxeHd999F2KxuNNtA4B9+/ahpKQECxcu7NZaxcXFkEgkiIyMBPDkrcy4ceMAAPfu3Wv1t5ZlvXWpFNfy8nLk5eUJJdct+f333wV7X9p8jqK9QxehGDp0aKthT0xMjFZtEPIVni61nJyc4OTkxH+WvWfXBoI5u6+vL8tn/18+uxBIJBJBdBgMGd1mgo7BYHQM5uwMhp7Q6c4ui/LiOA5btmwRVLt5HHhntsNg9AQ6/UXfkiVLUFNTA3Nzcz52uju3w2B0V7T6GK/tfHUZ3377Lfr27YuRI0fiyJEjePjwIf8UkJycjPT0dHAcxxeKVBSbLbN9wYIFEIlE8PT07LwLxWB0AloN4UlOTsalS5f4fPXQ0FAcPnwYkydPhkQiwbBhw/h89c8++4zPV5c9ri9ZsoQPnZRIJLC1tVXrtdSMGTMwY8YMNDY2YuzYsTh16hR+/vlnLFy4EOHh4QCAefPmYfPmzcjKysK///1v5OXlwcjICBMnTkRAQABvu5eXF9avX680Y23nzp04fvy4QFdMe9TV1eHixYt45513dG0KoxlSqRR37twRREsnZanUzVeX5fw2R9N3kmVlZZgxYwby8vLw6NEjODg4AADGjBkDY2NjHD9+HI8ePcL48eMBQC42W8apU6cwZMgQAICXl1ebqamhoaGYPn26RjZ2Ba5du4bPP/8c8fHxujaF0YzGxkbMnz9fEC2dOLuqfPVp06YpjAW3trZWmK/+3nvv4cCBA620fvnlF4SFhcHJyQnV1dWorKyUixn/+OOP8dlnn8HBwQFJSUkA/ojNTk9Ph7W1tcZ9Mzc3h42Njcbn6ZrGxkaYmJh0S9t7Mo2NjXjqKYFG20LE3LYVG//555/LxRpDSTw0EWkcC948DlxROwDoz3/+M40cOZIsLS0pKiqKAMilHI4ePZp27twpZ7Oi2GxZLHdze1uiSYprV6Ot2HiG7hAyNr5LJcJoO1+9qamJPvroI3r8+LEgeszZGULTI/PZO5qvrilTp06FtbU1XnjhBe2nGjIYOqDL/JdrOxZcnYqzDEZPosvc2RldF1ZKWjh0WUpasDt7UVERsrKyhJLrluTn58PR0VEwPXXjCDrr/OaMHj0av/zyCwAgISFBrpR0XFwcvL29cfDgQRgbGyMnJwcvvfQSACAjI6NTK8w2NDRg5cqV2LRpE0xMTBAREYFPP/2U3//3v/8dq1atwr179xAYGIhdu3bBxMREYy1NdGQUFhYiNjYWjx8/5p8knZycIJFIkJKSgpkzZ/IprgMHDhToiihHMGe/efMmLl26JJRct6SqqkpQZ++KyEpJy+rhxcbGorGxEVu3bsW8efPwzTff8KWka2pqtFpKuuUSXrIS0CdPnsTgwYMRHByMPXv2YPbs2RppDR8+XCMdGbJS0qmpqXLbw8LCEBgYiJkzZwp2HdRCiFk+VpbqCapm41etWkUikYhsbGxo+fLlNH78eDIwMCCiP15RyirF+vv786/6QkND+c+rV68mc3NzGjVqFBUVFSnVaHm+KtQtS3X16lVydnaW2x8VFUVZWVlkZmZG8fHxRER8dVlF/Sb6ozRXbGws9enThzw9Pen+/ftERLR8+XLq378/DRgwgJKSklTa3pwxY8ZQeXk5ET2ZyR44cCCdO3eOampqyMfHhw4cOKCxVkd0lFWXtbKyknsLpI2yVF1mgq6nk5WVhbS0NOTl5YHjOPj7+yMhIQH//e9/AciHAgOKw4E7Gk7s5+eHv/71rx2qNnv79m2YmZm12j5q1CikpqYiJCQEzz33HCwsLJT229PTU2notLGxscJwZVkEY1u0XMLL0NAQ69evx9ixY3Hv3j3MmjUL/v7+avWzpVZ7dZRhamqKO3fuaDWIqctM0GVlZcHW1lau1HNnT1hoE1UllQH1QoE7UlpaiLLSrJQ0KyXdYdatW4fU1FS+fHDzOl2a0nK9s5SUFAwePBiWlpaYO3cuGhsbtb42u7KSypqWhRZ6+StNYaWk1dNpC70vJd18hRSijkXTNV8Vpb6+nnx8fOjWrVtUXV1Nw4YNo+zsbDp48CAtWLCAHjx4QIWFhWRlZUW//PJLh/qgzpi9ZUllTcpCdyScmKjtstKslHTPLyXdJZxdNlkDgCIjI4lI3tkVTfAQEaWmppKlpSWNGDGCDh8+TEStJ7ZkSKVSKikpoREjRsj9oWQ0n9hpL50dLtuZ4cSqnF12TUtKSkgqldLq1aupurq6U2xRREZGBq1bt67baxUVFdGGDRv4z8ePH2/1ZdmcHufsRMrv7G2tFSbj8ePH5OHhwX9uud4ZEdHs2bPJyMiI4uLiSCqVyu1TtEZYe+hMZ5d9iSnqmxCw2PiuSY+MjVeGsgmesrIyvPDCCzAxMYGRkZHKaK4dO3agsrISZ86c4dNZAd2szd4eOrr8FYPR5Z1d2QSPLN+8uroahYWFcrPQzSemcnNzERERgdraWhgaGsLIyAhXrlwBoLu12RkMXdAlnF22RrujoyOys7PlMuAmTpyI6dOnw93dHW5ubggJCcGkSZMwZcoUlJWVwcHBAbt27cKVK1f4WnTN12X38PCAra0tnJ2dMWjQINTW1mLx4sU6W5udwdAVgq31Vl5ezlaE+d+KMLLCld2JttZ6Y+gOIdd66xJ3dgaD0fkwZ2cw9ATm7AyGniBYvF5BQQEyMzOFkuuW/Pzzz6irq4OVlZWuTdGYO3fu4MqVK3r/N+xqSKVSwbQEmaC7evWq3heuAP74wwhW+reTyMjIQFBQEIyMjPhtRISmpiZWj68L4ujoyK9r0BEEcXZG9yIsLAxfffWVwlRVRs+la9+CGAyGYDBnZzD0BObsDIaewJydwdATmLMzGHoCc3YGQ09gzs5g6AnM2RkMPYE5O4OhJzBnZzD0BObsDIaewJydwdATmLMzGHoCc3YGQ09gzs5g6AnM2RkMPYEVr9AT7ty5gz/96U+or6/H1atXYW9vj6eeegpz587FlClTdG0eQwswZ9cjhg4disuXL/Of+/bti3/961/w9PTUoVUMbcEe4/UI2eo3MqytreHh4aFDixjahDm7HjFv3jyIxWL+s5+fn5zzM3o2zNn1iCFDhsDa2hoAIBKJ8MEHH+jYIoY2Yc6uZ8ycORMGBgawsrKCq6urrs1haBHm7HrGnDlzYGJiguDgYF2bwtAyaq8IEBkZifv373emLXrB7du3db5ijLm5OUpKSvDOO+9odF5XsJ3Rmvfffx+jRo1SeZzar94mTZqEnTt3dtgwfefNN9/E7t27dWrDhQsX4OLiovF5XcF2hjzffvst7O3tERISovJYte/shoaGsLGx6ZBhDMDY2Fjn19HHx6dd53UF2xnyWFhYqH1stxyzZ2VlwdbWFhzH4ccff9S1OQxGt6BbruK3bt06pKam4qWXXtK1KQxGt6Fb3tnv3r0LR0dHXZvBYHQrup2zh4eH4/Tp03B0dMRHH32ETz75BGKxGCKRCCtWrOCPU7adwdBXup2zJycnw8PDAyUlJQgMDERaWhry8vKQn5+PjIwMHDhwAFlZWQq3M7QDESE2NhbXrl3TtSndjuLiYnzxxRedot3tnL05BQUF8PX1hb29Pezs7PDyyy/j3LlzSrd3J8aOHYumpibBdW1tbQXXbEliYiKcnZ0hFosRExMDjuPg4+ODhoYGAEBOTg44jgPHcdi3b1+n2tLQ0IDo6GhYWlpCLBbLPeX9/e9/h52dHSwsLPD666/j4cOHWtMCgMLCQrzxxhuYOnUqv83JyQlEhJSUlHb0tm26tbO7ubnh8OHDqKioQGVlJQ4dOgQ3Nzel27sTubm5MDAw0LUZGiOVSrFt2zY+Qi82NhZRUVEoKCjAvHnzAAC+vr44ePAg0tLSOj2X/tixY6irq0NVVRWOHDmCpKQknDlzBg8fPsTChQshkUhQXl6O69evY8+ePVrTAoCqqio5R5cRFhaG9evXt7vPyuh2zt58zP7UU09h+vTpcHd3h5ubG0JCQjBp0iRMnDhR4fbuQnh4ODiOQ2lpKf97XFwcLC0t4eXlhQcPHiAgIAAcxyE2NhYWFhYYPXo0iouLATzJZjM0fPKiZe3ateA4DqdOnUJAQACuXbsGjuMU/pMJQWVlJQwNDfn2ZezZswffffcdEhISWp2jaH5FWb8BYMWKFbCxsYGdnR02bdrUpj1+fn7YuHEjevfuDRcXFwwZMgS2trYwNDRsFQ0oEom0piXTU/SFbmNjg5KSEjQ2NqrU0AhSk8mTJ6t7KKMN1L2OHh4eVFJSwv++detWqquro8DAQMrMzCQiIicnJ9q9ezfV1dVRTEwMvfLKK/z5YrGY/z00NJROnjzZajsR0fjx4yk/P18w28+dO0djxoyR2xYVFUU3btygzMxMMjQ0pL1799LBgwcpLS2NJBIJDR8+nMrLy6miooJcXV1p//79SvstkUjIw8ODysrKqKqqikaMGEGXL19Wy/5du3bRtm3b+M9paWlkYWFBAGjWrFnU1NSklo6QWhkZGRQaGtpqu729PV2/fl3l+du3b6fvv/9erba63Z1dX5kwYQJMTU3h4uKCu3fv8tuDgoJgamqKkJAQXLhwQeG51EZEdHZ2tqBDHCsrK/4O3JLJkydj3bp1ePPNN3H27FkAyuddZLTsd0FBAU6fPo1BgwZhwIABOH/+PE6dOqXSrq1bt4KI8PbbbwMAioqKEB0djYKCAty/fx8mJiaIjY1Vq49Caimjvr4e/fr165BGS5izdxOUFZnIzMxEfX099u7dKxfvbmZmhvPnz6OyshIFBQX8dlNTU5SWlnbasMbOzg6NjY1KH0E//PBDzJ07F9HR0QCUz7vIaNlvNzc3+Pr64ubNmyAiEBHCwsLatGnnzp0QiUSYNWsW8vPzsWPHDlRXV6OxsVFO/+rVqyr7J6SWMm7cuAFHR8dWQ6EOo9b9n9hjvFCocx1nzpxJAKhXr14UERFBAEgsFlNGRgYBIAB08eJFcnJyooSEBDI3Nyd3d3cqKiriNTZu3Ejm5ubk5+dHQUFBBIDu3LlDMTExZGZmRmvWrCEiIj8/P0Ef44mI4uPjKT09nYiIli1bxtt87949IiJqamqi4OBgSktLIyKiVatWkY2NDfXv35+WL19ORNRmv2XHm5qakr+/P928eZOIiIYPH04VFRVytuTm5hLHcfz5AGj79u0klUopMjKSrK2tydTUlHx8fPhhk5BainRkvP/++7yOpaUlv33Dhg2UnJys1rXW5DGeObuWEfI6Ojk58Q6kDdS1XSqV0urVq6m6urqTLfqDjIwMWrduXZfSao9OUVERbdiwQe3jNXF2tVNc3d3dMXz4cGEfK3RAQ0MDGhoaYG5urpP2S0tLkZub22GdgIAAZGVlQSwWo7q6WgDLVPPqq68iMzNTK20x1GPHjh3o06ePsCmu9vb2Kl9zdAf+85//4Oeff0ZkZKRO2lc1vlQXiUQiiA5Df1Db2Z966in06dOnM23RCmZmZjAxMdFZX556is2JMnQD+89rB7KAFlami9GdEMTZb9y4gTlz5mDgwIGwsbHBtGnT5F73dBRlMcmy6DCO42BsbIznnnsOixYtwp07dwRrWxESiQROTk6d2gaDITQdfpHX1NSEwMBAjB8/Hnl5eejTpw9yc3Mxf/58nDhxQggb5WKSS0tLMW7cOAQHB2PJkiWoqamBubk5Fi1ahN9++w0rVqyAj48Pzpw5AyMjI0HaZzB6Ah2+sx85cgR3795FfHw8RCIRTExM4Ofnxzu6unHPt27d4u/SycnJSE9PB8dxeOutt5TGJDfH2NgYw4cPR2pqKm7fvo2srCyN+yKza8GCBRCJRPD09FQZh60sDp3B6Gp0+M5+6dIlPPPMMwojvJrnlXMcB39/f3h6eiI5ORmXLl2CjY0NqqurERoays+SL1y4EOHh4QCeLFe0efNmOc3du3dj/vz5sLe3V2iPsbExnJ2dUVZWpnFfZHZ5eXlh/fr1yM7OxsqVK5GXlwcjIyNMnDgRAQEBGDJkCH9OdnY2/8WzZMkS5uiMLkuHnX3gwIG4fPkyiKiVwzePewbAxz3LQjVbxj1PnjwZpqamOH78OB49eoQJEybI6W3duhWmpqZ8TLIiGhoacPHixQ69WvPy8oKBgYFcHLaMU6dOyTl7S1SFLfz+++949dVX222bLvnvf//bbW3vqVRWVmLp0qVqHdthZ/f394eJiQmWLl2KRYsWwczMDHv37sXmzZuxcuVKbN++HRUVFeA4DocOHUJiYiJ/rqKngaVLl+Kzzz7DkCFD8Le//Y3fLotJfu2115Cfn4/8/Hy89dZb/P6GhgZ+zG5lZQV/f/+Odo2Pw05PT+fXSFOELA7d2tpa5cTkkCFDum1gCguq6Xrs2LFD/YPVDctrK1Ty+vXrNHv2bBKJRGRhYUGTJ0+m8vJyItI87pmI6MUXX6Tdu3fz+spikj///HP+s5GREQ0dOpQWLlxIt27dUmrrsWPHKDExUeE+mV3NbVEUh+3v78/bT6Q8Dl3T69jV6c6291Q6JVy2p3yrHz9+HKdOncKf//xnnbTfna9jd7a9p6JJuCwLqmEw9ATm7AyGnsCcncHQE5izMwSBWK14wRG6hrzar97Kysowbdo0wRrWFbW1tbh//z5++uknnbR/+/ZtwbRsbW07nMsuhAbQulZ8XFwcvL29cfDgQRgbGyMnJ4dfmy8jI6NTS0g3NDRg5cqV2LRpE0xMTBAREYFPP/0UAFBSUoKIiAj89NNPmDBhArZt29ZmBqSQWgCQkpKCpUuXoqamBtOmTcOWLVsglUoVtuHk5ASJRIKUlBTMnDmzw9dFbWd/+umnkZyc3OEG9Z3OKuGsS2S14mUFL2NjY9HY2IitW7di3rx5+Oabb/ha8TU1NVqtFd88l2LUqFGYOnUq/vKXv2Dfvn1ISEhAZmYmH7HZ2VoPHz7EV199hbNnz+Lx48fw9fXF0aNHQUQK2xg9ejTCwsIQGBgoiLOzslRapq3ruGrVKhKJRGRjY8PHJIwfP54MDAyIiPi4gpMnT/Lv+gFQaGgo/3n16tVkbm5Oo0aNoqKiIqXnE1ErjfbafvXqVXJ2dpbbFhUVRVlZWWRmZkbx8fFERHz5aGV9ldXei42NpT59+pCnpyfdv3+fiIiWL19O/fv3pwEDBlBSUpJKW5szZswYKi8vp/Pnz5O7uzsFBweTmZkZBQUFKY2H6EwtqVRKJSUlNGLECLm6dy3bkGFlZUWPHz9WqNVta9BJJBISi8WtChT2JJRdx7bqp6tbA15ZHXll5yvSaKuOvDLbu0ut+P3795OxsTEdO3aMamtrafr06fTxxx+rpSOk1uzZs8nIyIji4uJIKpUqbUNGWzXku23deNm660TUoXzxlhlxKSkpGDx4MCwtLTF37lw0Nja2uW6XLlB3fTpSEQOlqo68qvPbU0e+u9SKt7CwwIABAzBu3DhYWFggNDRUaa39ztTasWMHKisrcebMGSQlJSltQ4ZQNeS7lLN3xrrrzcdJv/76K06cOIGjR48qXbdLV7RVP12TGvCK6sgrO1+ZhqZ0l1rx7u7uePDgAXJycnDv3j18//33GDlypMr+CaWVm5uLiIgI1NbWwtDQEEZGRrhy5YrSNgCBa8irdf+nzn+Ml43XAFBkZKRcmWRF4zsiotTUVLK0tKQRI0bQ4cOHiUj5OFTTcVJnoWrM3jKPgEj9GvDK6si3FbuvSR35tmzvDrXiiYgOHDhAzz77LFlYWNDrr78uN1QUSktZrfiGhgZasWIF2dnZkYWFBQUGBlJVVVWbbaiqId9tx+zN1zeTOXtb4zsZjx8/Jg8PD/5zy3EokebjpM6iM69jZ9eRb8t2ViteWB0i9WrIa+LsAq8vIzzKcuJdXV0xY8YM5OXl4dGjR3BwcGhTZ8eOHVi7di0iIiKQlJSEDz74AIB6OfLdgYCAABQXF2Po0KFaqyPfHI7jEBMTo9U2hXyFJ5SWkDY5OTkJWuuwS43ZFaFsfCfLMa+urkZhYaHcxFPzcWh7xkndEYlEAiLSiaMzugddxtmbr7tuaGjI36WUrbU+ZcoUlJWVwcHBAbt27cKVK1f4gJXw8HC4urrC29sbHh4esLW1hbOzMwYNGoTa2losXrwYJ06cwJw5cxASEgKO4+Du7q7jK8BgdC56l8+ua7rzdezOtvdUWD47g8FoBXN2BkNPYM7OYOgJzNkZDD1B7Qm6Z599Fs7Ozp1tT4/n8uXLeOaZZ3Rqw6NHj/KFLskAACAASURBVNCrVy+Nz+sKtjPkuXr1KpYvX67WBJ3azs7oOYSFheGrr76CmZmZrk1haBH2GM9g6AnM2RkMPYE5O4OhJzBnZzD0BObsDIaewJydwdATmLMzGHoCc3YGQ09gzs5g6AnM2RkMPYE5O4OhJzBnZzD0BObsDIaewJydwdATmLMzGHoCc3YGQ09gzs5g6AnM2fWEO3fuwNLSEk8//TRycnIwbNgwWFlZYd26dbo2jaElWFkqPcLLy0tuXXM7Ozv8/PPPsLOz06FVDG3B7ux6xHvvvQdTU1P+84ABA5ij6xHM2fWI0NBQ9O/fHwBgZGTU7VeuZWgGc3Y9onfv3njuuecAAGKxGGFhYTq2iKFNmLPrGZGRkTAzM4ODgwP69u2ra3MYWoQ5u54REBAAAJg3b56OLWFoG7YijJbpCquqFBYWYtiwYTAwMNDovK5gO0MeTVaEMVRX1NnZma3NLQBdYY3zuro69O7dW+PzuoLtDHl27Nih9rHsMV4PaY+jM7o/eufsq1atAsdxyMnJ0bUpDIZW6VHO3tDQgOjoaFhaWkIsFmPFihWtjlm1ahWmT5/eIQ0GozvSo5z92LFjqKurQ1VVFY4cOYKkpCScOXNG6xoMRldEJ87+ySefQCwWw9HRESkpKXLbRCIRfzcNDw8Hx3GIi4uDpaUlvLy8cOvWLXAcB47jkJycjPT0dHAch7feegt+fn7YuHEjevfuDRcXFwwZMgS2trYgIsybNw99+vSBn58f6uvrldqmTIPB6O6oPRsvFFlZWdizZw/OnDmDXr168SGcaWlpyMvLA8dx8Pf3h6enJ5KTk3Hp0iXY2NiguroaoaGh+M9//oOff/4ZCxcuRHh4OIAn74w3b94s187u3bsxf/582NvbIzMzEydOnMCvv/6K+vp6jB8/Xi1bm2sw2oaIEBcXh3fffRdisVjX5vQIiouLkZWVhQULFgiip/U7e0FBAV5++WUMHDgQNjY2OHbsGAoKCuDr6wt7e3vY2dnh5Zdfxrlz5/hzJkyYAFNTU7i4uODu3bsYM2YMTE1Ncfz4cWRnZ2PChAlybWzduhVExMd+FxUVwcfHB7a2tnB0dMSoUaNU2tlSQ9uMHTsWTU1Ngut21lNKYmIinJ2dIRaLERMTA47j4OPjg4aGBgBATk4O/0S2b9++TrFBRlvzLiUlJZg4cSL69u2LadOmoba2VmtaAJCSkoLBgwfD0tISc+fORWNjo9I2nJycQET8029H0bqzu7m5IScnBxUVFXLbDh8+jIqKClRWVuLQoUNwc3Pj93Mc10pn6dKl+Oyzz5CRkYHXXnuN375z506IRCLMmjUL+fn52LFjB1xcXHD06FFUV1ejrKwMZ8+ebdNGRRraJjc3V+OgF10hlUqxbds2BAcHAwBiY2MRFRWFgoICPlLP19cXBw8eRFpaGqZMmdKp9iibdyEiTJ06Fe+88w4qKyvh4uKiMm5ASK2HDx/iq6++wtmzZ/Hrr7/ixIkTOHr0aJvzRGFhYVi/fr0wF4bUZPLkyeoeqpJVq1aRjY0NmZmZ0cyZM6mxsZHf1r9/f1q+fDkREUVERBAAEovFlJGRQQAIAF28eJGIiF588UXavXs3r5ubm0scx/HHAaDt27eTVCql9957jywsLMjHx4eCgoIIAF29erWVbco0hEKd6zhz5kwCQCUlJfzvsbGx1KdPH/L09KT79++Tv78/AaDVq1eTubk5jRo1ioqKioiIaPz48WRgYEBERJ9//jkBoJMnT/LnAKDQ0FDBbL969So5OzvLbYuKiqKsrCwyMzOj+Ph4IiI6ePAgpaWlEdGT/wGRSEQ2Njb831tZX4mIli9fTv3796cBAwZQUlKSRnaPGTOGysvL6fz58+Tu7k7BwcFkZmZGQUFBdOfOHa1rSaVSKikpoREjRlBJSYnSNmRYWVnR48ePFWpt376dvv/+e7Xa1Ymz6zPqXkcPDw/+H8HDw4O2bt1KdXV1FBgYSJmZmURE5OTkRLt376a6ujqKiYmhV155hT9fLBbzv4eGhtLJkydbbSd68sWQn5/fIdvPnTtHY8aMkdsWFRVFN27coMzMTDI0NKS9e/fyzi6RSGj48OFUXl5OFRUV5OrqSvv371faV4lEQh4eHlRWVkZVVVU0YsQIunz5slo279q1i7Zt20ZERPv37ydjY2M6duwY1dbW0vTp0+njjz9WS0dIrdmzZ5ORkRHFxcWRVCpV2oYMe3t7un79ukItTZy9R716aw+ycWTzn65Iy3kLGUFBQTA1NUVISAguXLig8FxqI/0hOztbbsjUHqysrPDgwQOF+yZPnox169bhzTff5IdPms7RFBQU4PTp0xg0aBAGDBiA8+fPy1XcUUbLeRcLCwsMGDAA48aNg4WFBUJDQ5Ves87U2rFjByorK3HmzBkkJSUpbUNGfX09+vXrp5Z2W+i9s9OTpxu5n66Isi+hzMxM1NfXY+/evXBxceG3m5mZ4fz586isrERBQQG/3dTUFKWlpZg0aZJgttnZ2aGxsRGNjY0K93/44YeYO3cuoqOjAWg+R+Pm5gZfX1/cvHmT/xupysVXNO/i7u6OBw8eICcnB/fu3cP333+PkSNHquyfUFq5ubmIiIhAbW0tDA0NYWRkhCtXrihtAwBu3LgBR0dHGBoK8OJMrfs/scd4odBkzN6rV6825y2cnJwoISGBzM3Nyd3dnR+zExFt3LiRzM3Nyc/Pj5+juHPnDsXExJCZmRmtWbOGiIj8/Pw6/BhPRBQfH0/p6elERLRs2TLeznv37hERUVNTEwUHB8uN2TWZo5Edb2pqSv7+/nTz5k0iIho+fDhVVFTI2dLWvMuBAwfo2WefJQsLC3r99dd5+4TUUqRDRNTQ0EArVqwgOzs7srCwoMDAQKqqqmqzjQ0bNlBycrLS667JY7zaKa6TJ09Genp6x79d9JypU6fihx9+EERr2LBh+OWXX2Bubi6IniraynojHbxn37dvH0pKSrBw4cIuoyWkTcXFxZBIJIiMjFR6zI4dO9CnTx+1UlzVdvb/+7//w7PPPqu+pV2U2tpa3L9/X2eFFquqqpCbm9thnYCAAGRlZUEsFqO6uloAy1TDUly7Hpo4u9oDgUGDBiEtLa1DhnUFjh8/jlOnTuHPf/6zTtp/9dVXBdGRSCSC6DD0B72foGMw9AXm7O0gICAAHMfh/v37ujaFwVAbQZz9xo0bmDNnDh/vPm3aNLnXPR1FWezw2rVr+XfjxsbGeO6557Bo0SLcuXNHsLYVIZFI4OTk1KltMBhC0+GXd01NTQgMDMT48eORl5eHPn36IDc3F/Pnz8eJEyeEsFEudri0tBTjxo1DcHAwlixZgpqaGpibm2PRokX47bffsGLFCvj4+ODMmTMwMjISpH0GoyfQ4Tv7kSNHcPfuXcTHx0MkEsHExAR+fn68o3dmnnpzjI2NMXz4cKSmpuL27dvIysrSuC8yuxYsWACRSARPT0+sWLECNjY2sLOzw6ZNm1qd4+fnxwc8yJ401InuYjC0TYfv7JcuXcIzzzyjMMIrKyurU/PUFWFsbAxnZ2eUlZVp3BeZXV5eXli/fj2ys7OxcuVK5OXlwcjICBMnTkRAQACGDBnCn5Odnc1/8SxZskSlo9+6dQtff/21xrZ1BSoqKrqt7T2VU6dOqR0N2WFnHzhwIC5fvgwiauXwzWOgAfAx0DLjWsZAT548mc9Tf/TokcI8dVNT0zZzzBsaGnDx4sU2AxFU4eXlBQMDA7mYbBmnTp2Sc/aWqApbMDQ0hEgkardtusTIyKjb2t5TsbCwUPvYDju7v78/TExMsHTpUixatAhmZmbYu3cvNm/ejJUrV2L79u2oqKgAx3E4dOgQEhMT+XPbylMfMmQI/va3v/HbZbHDr732GvLz85Gfn4+33nqL39/Q0MCP2a2srODv79/RrvEx2enp6bC2tlZ6nCwO3draWuXEpKWlpWDv2rXN119/3W1t76ncvn1b/YPVCqqltuOir1+/TrNnzyaRSEQWFhY0efJkPh+3M/PUZbnaAMjIyIiGDh1KCxcupFu3bim19dixY5SYmKhwn8yu5rYoismW5YXL0kWVxaFreh27Ot3Z9p5Kp8TG95RQya4QQdddr2N3tr2nokm4LAuqYTD0BObsDIaewJydwdAT1J6Nl0qlapXK7eo8ePAADx8+1FlfpFKpTtrtbIjVjRccoevGq+3sFRUVeO+99wRpVJc0NDSgoaFBZ32pqakRTMvW1rbDuexCaACt68bHxcXB29sbBw8ehLGxMXJycvDSSy8BADIyMjq1nHRDQwNWrlyJTZs2wcTEBBEREfj000/5/Y8ePcLzzz+PN954Ax9//LHWtIAnteYjIiLw008/YcKECdi2bRv69OmjUMvJyQkSiQQpKSmYOXNmO6/GH6jt7E8//TSSk5M73KC+0xPfU8vqxssKLsbGxqKxsRFbt27FvHnz8M033/B142tqarRaN755LsXo0aMBAF9++SWef/55rWvR/2rN/+Uvf8G+ffuQkJCAzMxMPmJUkVZYWBgCAwMFcXY2Zu9CKMojUBZ7HxAQgGvXroHjOEydOpVPu42NjYWFhQVGjx6N4uLiNmP3W2q0l8rKShgaGrYqirhnzx589913SEhIUKuvinImZFVrVeUoNKetXIpjx47B29tb7aGGkFqFhYUgIqSmpkIkEiEvLw9BQUFtatnY2KCkpERpMU9N6FLOnpWVBVtbWz4hRp/yxZvnEeTn5yMjIwMHDhxAdnY2+vfvD+BJ7H1oaCiAJ2m2YrEYRIT09HQ+7dbBwQHXr1/HpEmTsHjxYqXnK9IAnvxzNy/rrA63b9+GmZlZq+2jRo1CamoqYmJikJGRobKvycnJ8PDw4HMm+vXrh8OHDyMrKwv//ve/kZeXh7y8PGzZsgW///67WrY1z6W4ffs27t27p/adWGitsrIyFBYWYvHixaiqqoKZmRkSEhJUapmamgqStt2lnH3dunVITU0FEXUoX7xlRpwm62vpClW11GWoioFSVUde1fntqSPfXerGL126FEFBQfzTQ3R0NIYOHapWH4XQUlZrXpVWj6wbf/fuXTg6Ogqq2Z71tXRBW7XUNakBr6iOvLLzlWloSnepG79lyxb+/GXLlmHNmjW4dOmSyv4JpaWs1nxbWj2ybrysVjoAioyMJCcnJ74Ot6J1wYiIUlNTydLSkkaMGEGHDx8mIlK6npmm62t1Fm1dR0V5BETq14BXVke+rdh9TerI94S68UREwcHB/PaZM2fy24XSUlY3nqjtuvWKtISsG99lnJ1Ifn0zmbO3tS6YjMePH5OHhwf/ueV6ZkSar6/VWXTmdWz+BdkZtGW7VCql1atXU3V1dae135KMjAxat25dl9IS0qaioiLasGFDm8do4uwCPBt0Lspy4l1dXTFjxgzk5eXh0aNHcHBwaFNnx44dWLt2LSIiIpCUlIQPPvgAgHo58t2BgIAAFBcXY+jQoVqrI98cjuMQExOj1TaFfIUnlJaQNjk5OQla67BLjdkVoWx8J8sxr66u5l9pyGg+Dm3P+lrdEYlEAiLSiaMzugddxtnDw8Nx+vRpfjJCdpeaOHEipk+fDnd3d7i5uSEkJASTJk3ClClTUFZWBgcHB+zatQtXrlzh3xWHh4fD1dUV3t7e8PDwgK2tLZydnTFo0CDU1tZi8eLFOHHiBObMmYOQkBBwHAd3d3cdXwEGo3PRu3x2XdOdr2N3tr2nwvLZGQxGK5izMxh6AnN2BkNPUPvVW2NjI27cuNGZtugFDQ0N3fY6dmfbeyr37t3jU2RVofYEXWRkpF4lpnQWt2/fhpWVlU5t+P333+Hg4ICnntLswa4r2M5ozfvvv49Ro0apPE5tZ2f0HMLCwvDVV18pzFRj9FzYmJ3B0BOYszMYegJzdgZDT2DOzmDoCczZGQw9gTk7g6EnMGdnMPQE5uwMhp7AnJ3B0BOYszMYegJzdgZDT2DOzmDoCczZGQw9gTk7g6EnMGdnMPQE5uwMhp7Q5VeEYQhDTU0Ndu/ejaamJty4cQObNm2CkZERPDw84OXlpWvzGFqAVarRE6RSKezs7HDt2jV+m4mJCb799lsEBwfr0DKGtmCP8XrCU089BT8/P7ltIpEIgYGBOrKIoW2Ys+sRkZGR6N+/P/951KhRMDY21qFFDG3CnF2P+H//7//B0tISAGBpaYmPPvpIxxYxtAlzdj1j0qRJ4DgOVlZWGDdunK7NYWgR5ux6xvz582Fubg5vb2+N68Yzujf8q7eTJ0+isLBQl7boPVKpFAA63QlNTU3x9NNP4+uvvxZMk4jQ1NQEQ0P2NrcrYWRkhNmzZwNo9uptwYIFGDlyJEQikU6N02eOHTsGAPD29u7Udk6fPg0PDw9BNa9fv45//vOfePfddwXVZXSM+Ph4/Oc//wHQIqjGz88PDg4OurCJAeDBgwcAnqyD3pl0hn5paSkKCgo63XaGZjR/emODNgZDT+hxzh4QEACO47S2COWqVavAcRxycnK00h6D0V56nLNLJBI4OTnxn8eOHYumpiaNdRoaGhAdHQ1LS0uIxWKsWLFC4XGrVq3C9OnTleoUFhbijTfewNSpUzW2gcEQkh7n7C3Jzc2FgYGBxucdO3YMdXV1qKqqwpEjR5CUlIQzZ85orFNVVcUcndElUOns4eHh4DgOcXFxsLS0xNSpU/Gvf/0L/fv3x+jRo3H37l3+2G+//RZ9+/bFyJEjceTIETg4OIDjOGzYsAFBQUHgOA4//vijwnZkj9+xsbGwsLDA6NGjUVxcDAD45JNPIBaLIRKJ5O6wyra3tL20tLRVP7y8vPDgwQMQEebNm4c+ffrA19cXkydPBsdxGDZsGDZu3IjevXvDxcUFQ4YMga2tLQDInePn54f6+nql18/Pz69dXzY9DSJCbGysXCIOo2MUFxfjiy++UPt4lc6enJwMDw8PiMViVFZWoqKiAr/88guuXr2KZ555Bv/617/4Y2fMmIGamhrk5eUhOjoaxcXFePXVV2FnZwd/f3/k5+cjKChIYTuyx28HBwdcv34dkyZNwuLFi5GVlYW0tDTk5eUhPz8fGRkZOHDggNLtimxv/ruNjQ2qq6vRr18/HD58GD/88ANOnDiBX3/9FTt37sSFCxdw5MgRDBw4kNfZvXs35s+fD3t7ewCQO+err77C+fPn1b7gQtHe4YkqZF9oQpOYmAhnZ2d8+eWX4DgOPj4+aGhoAADk5OSA4zhwHId9+/Z1SvvNUTVEe/ToEdzc3BAfH98hHU20AKCkpAQTJ05E3759MW3aNNTW1rap4+TkBCJCSkqKSm1Ag8f48ePHw8zMDM888ww8PT1hamoKFxcX1NTUAADKysrwwgsvwMTEBEZGRrh27Rp69eqFPXv2YOnSpaitrYWbm5vKdoKCgmBqaoqQkBBcuHABBQUF8PX1hb29Pezs7PDyyy/j3LlzSrerYsKECbztd+/eRVFREXx8fGBra4vBgwfD3d1d7vitW7eCiPD222/z25qf4+joiFGjRql7GQWjvcMTXSCVSrFt2zYEBwcjNjYWUVFRKCgowLx58wAAvr6+OHjwINLS0jBlypROt0fVEO3LL7/E888/32EdTbSICFOnTsU777yDyspKuLi4IDMzU6VOWFgY1q9fr1If0MDZOY5T+LuM9PR0WFtbo7q6GoWFhSAiEBE2btyIH374AWfOnEFqaqrKdjIzM1FfX4+9e/fCxcUFbm5uOHz4MCoqKlBZWYlDhw7Bzc1N6XZN+gEALi4uOHr0KKqrq1FaWoqzZ8/y+3bu3AmRSIRZs2YhPz8fO3bsaHVOWVmZ3DnaQJ3hibJhkZ+fHx/ltnbtWnAch1OnTgF4MpS6du0aOI4TdJ6hsrIShoaGctF1e/bswXfffYeEhASF57Qcoinrp4wVK1bAxsYGdnZ22LRpU5v2+Pn5KR2iHTt2DN7e3hCLxSr71ZaOployn0lNTYVIJEJeXh7/FNyWjo2NDUpKStDY2KiyDdD/+PDDD6mkpIRaEhERQQBILBbTl19+SQAIAKWlpfG///zzz3T58mUaOXIkWVpaUlRUFL8PAJ09e5YGDx5MAGjZsmWt2pDh5ORECQkJZG5uTu7u7lRUVERERKtWrSIbGxvq378/LV++nD9e0XZ/f3/e3pkzZxIA6tWrl1w/MjIyeNsuXLhA7733HllYWND48ePplVdeodzcXMrNzSWO4+T6sX37diIikkql/Dk+Pj4UFBREAOjq1aut+vT+++/z51taWirtOxHRP/7xD/rHP/7R5jEyPDw8+L+Xh4cHbd26lerq6igwMJAyMzP567l7926qq6ujmJgYeuWVV4iISCwW8zqhoaF08uRJ/nPzfURE48ePp/z8fJX2lJSU0Icffqhw37lz52jMmDH856ioKLpx4wZlZmaSoaEh7d27lw4ePEhpaWlERCSRSGj48OFUXl5OFRUV5OrqSvv371faT4lEQh4eHlRWVkZVVVU0YsQIunz5skqbiYh27dpF27ZtIyKiW7du0Y8//khERMuWLaM1a9aopdFSpz1a+/fvJ2NjYzp27BjV1tbS9OnT6eOPP1ZLx97enq5fv65Qd/LkyfzvKp1dmzg5OdG9e/d01v6lS5do8ODBdO3aNZ203xFn//3334mIaPHixbR7924ienI979y5Q0REeXl55OjoSETyDh0SEtKms6tLW85+9epVcnZ25j/LnJ2I6IsvviAzMzNKTEzknT0xMZHef/99/vgFCxbQZ599prSfiYmJcl/KACglJUWlzVu2bKGdO3fyn2U3hOY/zzzzjMY67dE6duwYDR48mP/83Xff0auvvqqWjpWVFT1+/FihbnNn18mrN9lkTPOfgIAAFBcXY+jQoVq3Z/PmzbCzs4O3tzeWL1/e7vwARf3SFsraajksAgAzMzOcP38elZWVKCgokDve1NQUpaWlmDRpkmC22dnZobGxUeGj5ocffoi5c+ciOjqa39bWEE1RP93c3ODr64ubN2/yw8ewsLA2bVI0RNuyZQt//rJly7BmzRpcunRJYx0AGmu5u7vjwYMHyMnJwb179/D9999j5MiRKnVu3LgBR0dH9RKQZF7fFe7s+o66d3Z1hicXL15UOizauHEjmZubk5+fHz8EkT0BxMTEkJmZGf+46Ofn1+HHeCKi+Ph4Sk9Pp2XLlvE2yp7impqaKDg4mL+zE7UeorXVz+bHm5qakr+/P928eZOGDx9OFRUVrWxpa4hGRBQcHMxvnzlzJhGRQi1VOppoEREdOHCAnn32WbKwsKDXX39d7ilXkQ4R0YYNGyg5OVnpde+yj/H6jiaP8eqgzWGRKmeXSqW0evVqqq6u1oo9GRkZtG7duh6tVVRURBs2bGjzmObOzt/76+rqsGvXLlhbW6t+HGB0Cr/88gsmTpwoiFbzYVF1dbUgmh2B4zjExMRorT0hX+F1VS0nJye50HBV8M5uaGgIBwcHtV4TMDqH8vJywbQkEolgWoyeAe/sxsbG8Pb2ZvnsOuT27du6NoHRg+mxiTDaTnVlMLo6HXJ2WS73kCFD+DhnGVFRUeA4rtXCBOogi+yS/VhZWWHx4sUgDRavESrVFVAeA93cTmNjYzz33HNYtGgR7ty50652GIzOpEPVAVetWoXGxkZs3boVmzdvRmRkJACgoqIC3377LV588UVkZ2drrLtkyRLU1NTA3NwcH3/8MS5dugRvb28EBga268sDeBJL3l6ax0CXlpZi3LhxCA4OlrNz0aJF+O2337BixQr4+PjgzJkzMDIyanebDIbQCPIYn5iYiNjYWD5LJzY2FsuWLZM7pmX6KwC1U2CbV1ttT7pr81jy5p+FSHeVYWxsjOHDhyM1NRW3b99GVlZW+y8og9EJCFL3d/LkyfjnP/+JxMREzJw5E9bW1ny0lowZM2ZgxowZaGxsxNixY3Hq1CkUFxfj9ddf51Ng4+Li5JJZoqOjER0djX79+mHWrFlobGzk01o5joO/vz88PT1hYGCgcLuM5ORkuagj2WdZumtoaCgOHz4MIuJTVx89eoSXX35ZZbprS4yNjeHs7IyysjIhLi2DIRiCFfn+4osvMGbMGJSXl2PTpk3Iy8vj95WVlWHGjBnIy8vDo0eP+Bl/WQqsq6sr5syZ0yprbc2aNfj444/5z59//jmf1gqAT2s1NDRUuF0VLdNdKysr+dRVAArTXU1NTeXSXVvS0NCAixcv8kMaTVm7dq1a2YFdDdkwh1WX7VqUlJTwvwvm7IMGDUJSUhJEIhF69+4tt695+mtlZSUfd03NUmCXLVuG1NRUvPHGG0rbcHNzw/bt21FRUQGO43Do0CEkJibC0NBQ4XZVKEp33b17N6qrq/Hw4UOF6a6vvfYa8vPzkZ+fj7feeovf39DQwI/Zrays4O/vr85la8WSJUvavAZdldLSUqxbt06jyimMzkfuy1cWSteecNnPP/+cj9dtnnVz8eJFfntwcLDC9NfQ0FDy8PBQmALbXDciIkKuTXXTXZWluhKRYOmuze00MjKioUOH0sKFC+nWrVsaXUcZQofLahNV4bIM3cBi49VAF+muzNkZQqPzFNeujFDprgxGV4OtwteC+fPnY/78+bo2g8EQHHZnZzD0BObsDK1ArG684GhaN55/jH/w4AG+/vprWFlZdYphDNWcPXtW0HJQtra2Hcpl7+j5zWleNz4uLg7e3t44ePAgjI2NkZOTg5deegkAkJGRoZVy0oWFhYiNjcXjx4+Rnp4O4Mnr05UrV2LTpk0wMTFBREQEPv30U4112qtVUlKCiIgI/PTTT5gwYQK2bduGPn36AHhSN/7555/HG2+8wceeODk5QSKRICUlBTNnzlTZZ97ZjYyM4Orq2mmLBDBU01MTaGR14y9cuIDQ0FA+n2LevHn45ptv+LrxNTU1WnF04I9luZoHMCnLgRg9erRG+Am1aAAAIABJREFUOu3Rov/Vjf/LX/6Cffv2ISEhAZmZmQgPDwfQdt34wMBAtZydvXrrQqh69bZq1SoSiURkY2NDy5cvp/Hjx5OBgQER/RHzIKsUK4szwP9iGmSfV69eTebm5jRq1CgqKipSqtHyfFVoWl02KyuLzMzMKD4+nohIrpS0or7KYiViY2OpT58+5OnpSffv3+ePX758OfXv358GDBhASUlJKu0lelIiqq2+jRkzhsrLyzuso47W+fPnyd3dnYKDg8nMzIyCgoL4uoBHjx6l06dPKy0l3aWryyojKysLtra2fNooy0X/A0XLXS1atAj9+/cH8CTyLjQ0lD9eIpFALBaDiJCenq50ea3s7GyFGi3PB54siqBOGHJLbt++DTMzM7lto0aNQmpqKmJiYpCRkaGyr2FhYQqX75Id/+9//xt5eXnIy8vDli1b8Pvvv2tsZ3NU5UAIrVVWVobCwkIsXrwYVVVVMDMzQ0JCAm7fvo179+61uaqMqampWk+FXcrZ161bh9TUVBCRRrW1WtJyKJKSkoLBgwfD0tISc+fORWNjo9pLMncV1FnuitTI92+5vFZL2tLIzs5Wa9WdllhZWcmt3iJj8uTJWLduHd5880250OS2+toyn0F2/OnTpzFo0CAMGDAA58+f51e5aQ+KlvzqbC0LCwsMGDAA48aNg4WFBUJDQ3HhwgUsXbqUzwiNi4tDdHR0q3Lr9fX16Nevn0pbupSz3717F46OjoJqPnz4EF999RXOnj2LX3/9FSdOnMDRo0cFW5JZWyirpa5pDXhN6sgLVUO+K9aNV4ayOvCdraVXdeNlYzIAFBkZKVcGueX4TUZqaipZWlrSiBEj6PDhw0TUeqwqQyqVUklJCY0YMUJhP9Udn3Um6ozZW+YFaFIDXtM68prUkO9OdeOJFC/L1VYdeGVaypb3ao+WXtWNb76kkczZla371ZzHjx+Th4cH/1nREkazZ88mIyMjiouLI6lUKrev5TpduqKzY+M7s448qxuvfa12143vqjQfvwF/5Kq7uroqzJFXxo4dO7B27VpEREQgKSkJH3zwAQD1ctR7ArquI8/qxguvpWnd+C41ZleEsvGboiWiZTQfa+bm5iIiIgK1tbUwNDSEkZERrly5AkDY8VlXRyKRgIi6xIIRDN3QZZw9PDwcp0+f5icbZHehiRMnYvr06XB3d4ebmxtCQkIwadIkTJkyBWVlZXBwcMCuXbtw5coVfk3x8PBwuLq6wtvbGx4eHrC1tYWzszMGDRqE2tpaLF68GCdOnMCcOXMQEhICjuNaVaVhMHoaHP3vlrhgwQIsWrSILRKhQ2RRWKxSDUMoXn31VWRmZgLoQnd2BoPRuTBnZzD0BObsDIaewJydwdAT5N6zb968GX379tWVLXpPUVERAPAr13Qn7t69iwsXLmDNmjW6NoXRDNlrZqDZbHxpaSmqqqp0ZhRDe8THx+Ojjz6CiYmJrk1hdDIGBgZ8xhx/Z3dwcGCv3fQEMzMzPP/8863SThk9GzZmZzD0BObsDIaewJydwdATmLMzGHoCc3YGQ09gzs5g6AnM2RkMPYE5O4OhJzBnZzD0BObsDIaewJydwdATmLMzGHoCc3YGQ09gzs5g6AnM2RkMPYE5O4OhJ/CVahg9m1u3buHFF19EU1MTHjx4gN69e0MqlSI6Ohrvvvuurs1jaIEuv9YbQxisra1hZGSE4uJifptIJMKLL76oQ6sY2oQ9xusRb775ptw63lZWVvwa7YyeD3N2PWLOnDkQiUQAnqyqGhoaqmOLGNqEObseYWNjgwEDBgAAbG1tMXfuXB1bxNAmzNn1jD/96U/o1asXbGxsWDVhPYM5u54xY8YMGBgYIDw8XNemMLSM4K/eZsyYgbq6OiEluzxSqRS3bt2CjY2Nrk1Ri59//hlubm4wNjYGAFy7dg1isVjHVjGaU19fj8TERLi7uwumKfirt7q6On49aH2htrYW7733HpKTk3VtilqUl5dj4MCB/Ofma3gzugbr1q3D3bt3BdVkj/F6SHNHZ+gPOnH2VatWgeM45OTk6KJ5BkMv0ZmzT58+XRdN89ja2ra5v6GhAdHR0bC0tIRYLMaKFSu0ZBmD0Tmwx3glHDt2DHV1daiqqsKRI0eQlJSEM2fO6NosBqPdaM3ZiQjz5s1Dnz594Ofnh/r6egBAeHg4OI7DggULIBKJ4OnpCQD45JNPIBaLIRKJ+LtqQEAAOI5DbGwsLCwsMHr0aD7WW9Hxfn5+fHjo2rVrwXEcTp06hYCAAFy7dg0cx2Hq1KkK7fXz88PGjRvRu3dvuLi4YMiQISqfBhiMrozWEmF++OEHnDhxAr/++ivq6+sxfvx4AEBycjIuXboELy8vrF+/HgYGBsjKykJaWhry8vLAcRz8/f3h6ekJiUSCYcOGwcHBAdevX8dnn32GxYsX48MPP1R4fHZ2Nu+gS5YswalTpwAAEokEtra2qK6uVsv23bt3Y/78+bC3t++ci9OFISLExcXh3XffZa/nBKK4uBhZWVlYsGCBVtvV2p29qKgIPj4+sLW1haOjI0aNGiW338vLCwYGBgCAgoIC+Pr6wt7eHnZ2dnj55Zdx7tw5/tigoCCYmpoiJCQEFy5cUHm8jPaEFGzduhVEhLffflvjcxUxduxYNDU1CaLVnM566khMTISzszPEYjFiYmLAcRx8fHzQ0NAAAMjJyQHHceA4Dvv27esUG5pTWFiIN954Q+6JrL3zK0JqlZSUYOLEiejbty+mTZuG2tpaft+jR4/g5uaG+Ph4AICTkxOICCkpKWppC4XWnN3FxQVHjx5FdXU1ysrKcPbsWaXHurm54fDhw6ioqEBlZSUOHToENzc3fn9mZibq6+uxd+9euLi4tHm8mZkZzp8/j8rKShQUFPAapqamKC0txaRJk5TasXPnTohEIsyaNQv5+fnYsWNHh69Dbm4u/6XW1ZFKpdi2bRuCg4MBALGxsYiKikJBQQHmzZsHAPD19cXBgweRlpaGKVOmdLpNVVVVrYZe7Z1fEUqLiDB16lS88847qKyshIuLi1zcwpdffonnn39e7pywsDCsX79epY1CojVnf+WVV+Dt7Y3nnnsOs2bNgouLC1566SUEBQXh9OnTcHR0RFFREQBg4sT/z965R0V1Jfv/eyKgLWAr0jRCRsVRW0BkUCeAPwWMKGhQHDDRIOo4cS4kjhI1a9SIhijExyg+Jno1XidG5RKFiIsZXU1ARQevkkREDArGBCQCLT5AUEBe9fvD2+fS0M3z9AN6f9bqtbrPo3bt01199q5TVXsG5s+fDzc3N7i6uiIoKEjFKBUKBWxsbHD27Fns2rWrzeMjIiIwadIkLFmyBGPGjIGnpycqKioQGhqKsWPHwsvLS62+V65cwdKlSxEUFASO4wSJZFL6JwoLC/n3MTExEIvF8PT0xIsXL9r0S3THB9EVSkpKYGJiopIWCwAnT57EqVOnsH379lbnqPOdaOorAGzatAkSiQR2dnY4cOBAuzr5+vq2+rPsqn9FKFm5ubkgIsTHx8PGxgZZWVkICAgA8OrPw8vLq9UUSCKRoKCgAA0NDe3qKRgkMLNnzxZapAoymYyqqqq02kZnefbsGS1cuLBDx7q7u1NBQQH//tChQ1RdXU0zZ86k5ORkInrVx+PHj1N1dTVFRkbSW2+9xZ8vlUr598HBwXT16tVW24mIpk2bRtnZ2R3SSdN3dvPmTZo4caLKtrVr19KjR48oOTmZTExM6PTp05SamkoJCQkkl8vJ2dmZHjx4QMXFxTR27Fg6e/asxr7K5XJyd3enoqIiKi0tJRcXF/r555/b1TcpKYmCg4PV7jt27BgdOXKkQ/0WStbZs2fJzMyMLl++TJWVlTR//nxat24dPXnyhP71r38REdGGDRto69atKufZ29tTWVmZWpm7du2iixcvdrgfHaFHPXrz9/dHfn4+Ro4cKahc5Zyz+UtXTJ8+HSKRCE5OTirhkS39EuqgNnwQaWlpKlOfrmBlZcXfgVsye/ZsxMbGYtGiRfyUrD3fScu+5uTkIDMzE0OHDsWQIUNw69Yt3onaFYT0r3RGlqWlJYYMGYIpU6bA0tISwcHBuH37Nj7++GMEBATwo5r169er/HZramowaNCgbuvaUXqUscvlchBRh73oHYWIWr10haY/lpZ+CSXd8UF0Fjs7OzQ0NGgcaq5YsQLLli3D+vXrAbTva2nZV1dXV/j4+ODx48f8dQ8JCemSrkL6Vzory83NDS9evEB6ejqqqqrwzTffYNy4cTh48CDfrw0bNmDr1q24d+8eAODRo0dwcHBoNUXSKoKOE0j7w3hDpKPD+IULFxIA6tu3L4WFhREAkkqllJSURAAIAN25c4dkMhlt376dLCwsyM3NjfLy8ngZe/fuJQsLC/L19aWAgAACQOXl5RQZGUnm5ub8UNHX17fbw3giom3btlFiYiIRvRqKKvVUTqUaGxspMDCQEhISiIgoKiqKJBIJWVtb08aNG4mI2uyr8niRSER+fn70+PFjIiJydnam4uLiVvosX76cP18sFhMRUUZGBnEcx28HQF9++SV/jlCyNMkhIjp37hyNGjWKLC0t6Z133lGZagYGBvKylL+TPXv20IkTJzRed20M45mxC0Bn5uwdQdd+iba+s6amJtqyZQspFAqd6ZOUlESxsbEGJUtInfLy8mjPnj1tHqMNYxd8DFFcXIw5c+YILdagaWhoEGzo39wvIfR0pStwHIfIyEidtinkIzyhZAmpk0wmg0wmE0xeRxHc2O3t7Y0uN1qZzy4EcrlcEDkMRkt6lIOOwWB0HWbsDIaRoFdjV0aBcRwHMzMzjB49GqtXr0Z5ebnedGKZbYzeil6Xf/roo49QUVEBCwsLrF69Gj/99BM2bdoEb29vXL9+HaampvpUj8HoVRjMMN7MzAzOzs6Ij4/H06dPkZKSojbXXd957gxGT8XgFnY0MzODo6MjioqKWuW6p6WlYc2aNQaT596cFy9eIDc3V9BroSueP3/eY3XvrTx69EhwmQZn7HV1dbhz5w4iIiL4bcpc9+ax1wD42GtliGjzePK4uLh2j1cixDPyhw8f9phS0i3pybr3VnJycuDn5yeoTIMx9rq6On7ObmVlpbajrq6u+PLLL1FcXAyO43D+/Hns2LGD35+cnIy3335bJc9d0/HKGPPBgwerjTH/4IMPcO7cuQ7rP2LECGzdurUbV0B/5Obm9ljdeyuxsbGCy9Srse/cuRMxMTEAXuU1Dxs2DLNnz8bhw4dhamqK8PBwPtf9zp07KnnrRIT3339fbZ77qFGjEB8fD5lMpvF4ZZ67h4cHn+deXl7O57nrOmqMwdA6ggbfkv5i4/WZ5y50bLyuMcZ8BkPH6PPZNaGtPHcGozdhMHP27sDiyRmM9ukVd3YGg9E+zNgZbUJEiI6OxsOHD/WtSq8hPz8f+/bt03m7LJ9dAITMZwfQ5cAeoc5vTsu68TExMfDy8kJqairMzMyQnp6OqVOnAgCSkpK0Xk46NzcX0dHRqK+vR2JiIoBXj20/+eQTHDhwAP369UNYWBg2b96sU1kFBQUICwvDd999h+nTp+PIkSMYMGAAgFd149944w28++67WLduHWQyGeRyOeLi4rBw4cJuXI3OwfLZBUDIfHZDQlk3XlnwMjo6Gg0NDTh06BDCw8Pxj3/8g68bX1FRodO68fHx8fy25rXeCwsLMWXKFAQGBmLChAk6kUX/Wzf+r3/9K86cOYPt27cjOTkZoaGhADTXjZ85c6ZOjZ0N43VAd+LzNcX96yK+n9WN71114w3K2FNSUmBra8unvT5//lzfKnWb5uvWZWdnIykpCefOnUNaWhqsra0BvIrPDw4OBvDqyYJUKgURITExEXK5HDKZjI/7nzVrFtasWdPh85X4+vqqXRKrLZ4+fQpzc/NW28ePH4/4+HhERkYiKSmp3b6eOHEC7u7ukEgkUCgUGDRoEC5cuICUlBR8++23yMrKQlZWFg4ePIhffvmlcxe4BUKuy9dRWUVFRcjNzcWaNWtQWloKc3NzbN++HU+fPkVVVVWru7oSkUik03RugzL22NhYxMfHg4i6VaOr5T9xXFwchg0bBrFYjGXLlqGhoUFn668LtQ5de3Xk2zu/K3XkWd14Vjdeazx79gwODg6CyqytrcXhw4dx48YN3L17F1euXMGlS5d0tv66UOvQqasjr+0a8qxuPKsb3yZdDb1U1lQHQBERESrhr1FRUWRjY0MSiYSvRU5EFB8fT2KxmFxcXOjChQtEROTn58fLab6sT1NTExUUFJCLiwu//FJzJk6cSA8ePOiS7u2Fy6qrpU7U8RrwmurId/R8orbryLO68axufJfoTpx183XQlMbe1vphSurr68nd3Z3/3HLdMyKiJUuWkKmpKcXExFBTU5PKvs6uD9YSbcfGazvun9WN150col5UN15oNOWkjx07FgsWLEBWVhZevnyJ4cOHtynn6NGj2LlzJ8LCwrB//3785S9/AfBqbiYSiQRbf11o9F1HntWNF1YOoL+68QY1Z1eHpnlgYmIiBg8eDIVCwT/6UNJ8zpqRkYGwsDBUVlbCxMQEpqamuH//PgDtrL8uNNpa345hfBiMsYeGhvK56yYmJvzdTNPa63PnzkVRURGGDx+OY8eO4f79+/xz5eZrr7u7u8PW1haOjo4YOnQoKisrsWbNGq2sv85gGDIckbBLls6ZM8doI+h6amknY/zODJ3Y2FiMHz8ePj4+gsk0mDs7g8HQLszYGQwjgRk7g2EkMGNnMIwErTxnN7Z89qamJpSVlfWYfpeXl2PgwIF8+GpJSUmP0d1YePbsGaZMmSKoTMG98QzDJyQkBIcPH1ab0cbovbBhPINhJDBjZzCMBGbsDIaRwIydwTASmLEzGEYCM3YGw0hgxs5gGAnM2BkMI4EZO4NhJDBjZzCMBGbsDIaRwIydwTASmLEzGEYCM3YGw0hgxs5gGAnM2BkMI8HgV4RhCEN1dTXu3LkD4NVSzDdu3IBIJIJEIsHQoUP1rB1DF7BKNUZCTU0N7O3t0bdvXxAROI5DbW0tdu7ciffee0/f6jF0ABvGGwkikQi///3voVAo8PDhQygUClhYWPCr6DB6P8zYjYiIiAgMGDCA/+zg4ACxWKxHjRi6hBm7ETFjxgxYWVkBAPr374/ly5frWSOGLmHGbkSYmJhgwoQJAABra2tWPtrIYMZuZHz44YcYMGAAnJ2dIRKJ9K0OQ4do9dHb/fv38fz5c202wegkysUhAgMDkZubq291GC0YPXo0TE1NtSJbq4/eZs6cid/97nfaEq9XysvL8csvv/DD4p7Ed999h4qKCsyYMUPfqjCakZqaisTERAwfPlwr8rV6Zzc1NcXWrVu12YTeyMnJwalTpxAdHa1vVTpNU1MT5s6d22u/m57KixcvtCqfzdmNkNdeY1+7MaK3bz0lJQW2trbgOI5/sfk9g6E99GbssbGxiI+PBxGBiCCTydo9x9bWts3PQpCbm4t3332XRZYxeh16M/Znz57BwcFBX81rpLS0lBk6o1eiF2MPDQ1FZmYmHBwc8OGHH7ba//XXX2PgwIEYN24cLl68CADw9/fHw4cPwXEc5s2b1+ozAGzatAkSiQR2dnY4cOAA3xbHcYiJiYFYLIanp2ebjhBfX1/06dNHC71mMPSLXoz9xIkTcHd3R0FBAfbs2dNq/4IFC1BRUYGsrCysX78eACCXyyGVSkFESExMbPU5JSUF3377LbKyspCVlYWDBw/il19+4duSSCRQKBQYNGgQLly4oOsu9yiICNHR0Xj48KG+Vek15OfnY9++fXrVweDcskVFRZg0aRL69esHU1PTDv/gcnJykJmZiaFDh2LIkCG4desWrl27xu+fPn06RCIRnJyc8OzZM22pr5bJkyejsbFRcLna8FkAwI4dO+Do6AipVIrIyEhwHAdvb2/U1dUBANLT03mn6pkzZ7SiQ3PU+VHq6uqwfv16iMViSKVSbNq0SaeyCgoKMGPGDAwcOBBvv/02KisrVfa/fPkSrq6u2LZtGwBAJpOBiBAXF9chPbWBwRl7YmIiBg8eDIVCgdzcXDSP+RGJRCgsLMSsWbNafXZ1dYWPjw8eP37MO/1CQkL4czmO03lflGRkZPSYqUFTUxOOHDmCwMBAAEB0dDTWrl2LnJwchIeHAwB8fHyQmpqKhIQEzJ07V+s6qfOjXL58GdXV1SgtLcXFixexf/9+XL9+XSeyiAjz5s3De++9h5KSEjg5OSE5OVnlmL///e944403VLaFhIRg9+7d7eqoLfQ+Z09LS4O/vz/y8/MxcuRIzJ07F0VFRRg+fDiOHTuG+/fv819OaGgoxo4dCy8vr1afZ8yYAR8fHzg6OqJ///7w9/fHkydPEB4ejszMTHh4eODMmTPYtWsXFi1ahLy8PLW6/eUvf8Ef/vAHfPPNNxg4cKAgfeU4DoWFhRr9B/7+/uA4DtHR0bC0tMSECROQn58PX19fmJi8invauXMnOI7jRyvqfBZCUFJSAhMTE75dJSdPnsSpU6ewffv2Vud8+umnkEqlsLGx4e+KbflK1PlW2kKdH8XX1xd79+5F//794eTkhBEjRnRopCOELOVNKD4+HjY2NsjKykJAQAC///Lly/Dy8oJUKlU5TyKRoKCgAA0NDe3qqRVIi8yePVub4vXKzZs3acOGDR061t3dnQoKCvj3hw4dourqapo5cyYlJycTEZFMJqPjx49TdXU1RUZG0ltvvUVERFKplJcTHBxMV69e5T8330dENG3aNMrOzu6QTpq+m5s3b9LEiRNVtq1du5YePXpEycnJZGJiQqdPn6bU1FRKSEgguVxOzs7O9ODBAyouLqaxY8fS2bNnNfZVLpeTu7s7FRUVUWlpKbm4uNDPP//crr5JSUkUHBysdt+xY8foyJEjHeq3ELLOnj1LZmZmdPnyZaqsrKT58+fTunXriIjoyZMn9K9//YuIiDZs2EBbt25VOdfe3p7KysrUyl2xYgX/O9EGBjeM1xXNg3mUL12hyX8QEBAAkUiEoKAg3L59u9V51E4aQ1paGlxdXbulm5WVlcanFbNnz0ZsbCwWLVqEGzduAHjlK/Hx8YG9vT3s7Ozw5ptv4ubNm/w5Lfvanm+lsxw6dAhEhD/96U9dltFZWZaWlhgyZAimTJkCS0tLBAcH89/Xxx9/jICAAH5Us379eowcOZI/t6amBoMGDeq2rl3BaI2d/nde3/ylKzT9sSQnJ6OmpganT5+Gk5MTAMDc3By3bt1CSUkJcnJyVI5v6cMQAjs7OzQ0NGgcaq5YsQLLli3jn5K4urriwoULKC4uRklJCc6fP6/yh9Oyr+35VjrDV199BRsbGyxevBjZ2dk4evRol+R0VpabmxtevHiB9PR0VFVV4ZtvvsG4ceMAAAcPHuT7tWHDBmzduhX37t0DADx69AgODg6tpkg6Q2tjBmLDeCKihQsXEgDq27cvhYWFEQCSSqWUlJREAAgA3blzh2QyGW3fvp0sLCzIzc2N8vLyiIho7969ZGFhQb6+vhQQEEAAqLy8nIiIIiMjydzcnB8q+vr6dnsYT0S0bds2SkxMJKJXQ1GlnlVVVURE1NjYSIGBgZSQkEBERFFRUSSRSMja2po2btxIRNRmX5XHi0Qi8vPzo8ePHxMRkbOzMxUXF7fSZ/ny5fz5YrGYiIgyMjKI4zh+OwD68ssv25QjpKxz587RqFGjyNLSkt555x3+2igJDAzkZS1cuJCIiPbs2UMnTpzQeN21PYzXaoqrv78/PvvsM22J1ys//fQTbty4wT9a6S5jxozBDz/8AAsLC0HktcecOXNaeZCVEBFiYmLw5z//uZWTSVucOXMGBQUFWLVqlUHIEVpWfn4+5HI5IiIiNB6zcuVKrF69umemuNbU1Gj8QfV0Hj58KFill+ZPIxQKhSAyuwPHcYiMjNRpm0I9whPyUaCQsmQyWYfyP7SJVo1dLBYjKipKm03oDWU+uxDI5XJB5DAYbWG0DjoGw9gweGNXBpywXHcGo3sYhLEro8NaviIjIyGXyw0m153B6MkYhLF/9NFH/DNJ+t9nlI8ePdK3WgxGr8IgjF0d1tbWaos56jPXncHoyRjUks3r16/nI7MiIiI05rovWLAADQ0NmDx5Mq5duwa5XA5bW1uVx1bNPzfPdTc1NcWMGTPg7++PEydO4N69e3yue3BwMC5cuIDZs2d3SN+rV69i9erVAvRc9/z00089VvfeSvMwY21gUMa+detWrFu3TuP+oqIiLFiwAFlZWXj58mWHgw+ax2MruXbtGkaMGAGg67nuzs7O+OCDDzp8vCGRk5PTY3XvrWg7AM2gjL09mue6l5SUqMSEK+PEP/jgA5w7d07l84cffggfHx/+/JZ0NQlmwIABKkkOPYn+/fv3WN17K9qOnjSIOfvOnTv5DKHQ0FCVfYaU685g9Gi0FnVPLBHGkOnN301PheWzMxgMQWDGzmAYCczYGQwjQave+JcvX+Lq1avabEJv3Lt3T3+FAw0M0kP+uz7Jz89HSkoKVq5cqW9VOoXWjT09PV2bTegNhUIhaHnolkFBuj6/O7SsMx8TEwMvLy+kpqbCzMwM6enpmDp1KgAgKSlJ6+WnDx48iOjoaLx8+RJLly7F9u3bwXEc6urq8Mknn+DAgQPo168fwsLCsHnzZgCvKsZGR0ejvr4eiYmJvKyCggKEhYXhu+++w/Tp03HkyBHIZDLI5XLExcVh4cKFWu2LoGjN9Ue92+MrtDe+ZaVYbZ8v1HfT2NhIo0aNovr6en7b2rVraeDAgbR06VJ+m7Iarba5ffs2DRkyhO7evUulpaX0u9/9ji+xlZqaSitXrqQXL15Qbm4uWVlZ0Q8//MDvS0xMVKk629TUROPHj6evv/6aXrx4QZs2baLjx48TEVFZWRlNmDDUUPpSAAAgAElEQVRBUN2ZN76H0rKWemdqwHe2jry2ash3BEOrM3/r1i288cYbGDVqFGxtbTFr1iykpaUBaLs+vLp68m3Vh9d7DfguYFDG3nLN9p6aw56SkoKEhARkZWUhOzsbSUlJWL16NaytrQG8yvILDg7mj1e3jp1MJsPw4cNRVlaGWbNmYc2aNUhLS1Mro+X5Snx9fbUeb/306VOYm5u32j5+/HjEx8cjMjISSUlJ/HZ11+bcuXMa1+TTtIafJhwdHZGZmYmffvoJZWVlOH/+vNoQ6OPHj+P999+Hvb29RllFRUXIzc3FmjVrUFpaCnNzc5U/L5FIhPLy8o5eKr1jUMbefM327tTrapnLHhcXh2HDhkEsFmPZsmVoaGjo8lphHaG9WupA+zXgAcOoI98ehlZn3sXFBREREZg0aRLc3d3h5OSEYcOGqRwjRH14QL814LuCQRm7NtZsr62txeHDh3Hjxg3cvXsXV65cwaVLl7q8VlhH0FRLvbM14DtTR14bNeQ7giHWmf/mm2/w448/Qi6XIzMzUyUEW6j68HqvAd8VtOYNoM45gZT11QFQREQEyWQyvhZ3VFQU2djYkEQi4euSExHFx8eTWCwmFxcXunDhAhER+fn58XJaOlsKCgrIxcVFrRNk4sSJ9ODBgw7r256DTl0t9c7UgO9sHfmW5xO1XUdeSOepodWZ//zzz8na2ppkMhmdOnWK395WfXh19eSJNNeHb68GfFfQtoPOYIydSHVNNKWxt7WWmJL6+npyd3fnP6vzTC9ZsoRMTU0pJiaGmpqaVPZ1dq0wIu3Hxjf/s9MGQhp7U1MTbdmyhRQKhWAy2yMpKYliY2N11l5z8vLyaM+ePYLLNXpvvKY5XmfXcT969ChKSkpw/fp17N+/n98u5FphQtE8068noKwXqMuAmrlz5wqyeENXkMlkbS72YKgYvLFrmuN1dB33jIwMhIWFobKyEiYmJjA1NcX9+/cBCLtWmJDI5XIQkUEsGMHoPRiMsTdfs93ExIS/s82YMQPz58+Hm5sbXF1dERQUhFmzZnU4t93d3R22trZwdHTE0KFDUVlZiTVr1uDKlStYunQpgoKCwHEc3Nzc9HwFGAwto7UJArEIOkOmN383PRWjn7MzGAxhYMbOYBgJzNgZDCNBq+E/TU1NvTbF9ZdffsH9+/d7bP+ePHnSY3XvrRQXF2tVPkfUgSDtLpKYmIiioiJtidcrTU1NqK+vR9++ffWtSqc5f/483njjDVhaWupbFUYLli1bhgEDBmhFtlaNnWGYhISE4PDhw2qz1Ri9FzZnZzCMBGbsDIaRwIydwTASmLEzGEYCM3YGw0hgxs5gGAnM2BkMI4EZO4NhJDBjZzCMBGbsDIaRwIydwTASmLEzGEYCM3YGw0hgxs5gGAnM2BkMI4EZO4NhJLDiFUZCRUUF1q1bh9raWty5cwejR49Gnz59sGDBAvj7++tbPYYOYMZuRAwfPpxfDQcABgwYgH/+85/w8vLSo1YMXcGG8UZEYGCgypLI1tbWmDx5sh41YugSZuxGxIoVK2BjY8N/9vHxwWuvsZ+AscC+aSNi5MiRGDRoEABAIpFgxYoVetaIoUuYsRsZ8+fPx2uvvQaxWIzf/e53+laHoUOYsRsZy5YtQ//+/REQEKBvVRg6Rmsrwuzbtw+FhYXaEm80NDY2orq6WtAFHczNzfHs2TOsXr1aMJmaqKiowMCBA7XeTm9i7dq1kEqlgsvVmrF/++232LNnj7bEGw33799HXFwcPvjgA8FkTp48GePGjRNMXluEhYXh448/1klbvYGdO3fi8ePHPcvYX3vtNYwcOVJb4o2KgQMHCnotdfm9mJubs99BJ1A6ULVBj56zR0VFgeM4tkAhg9EBeryxz58/Xy9t19XVYf369RCLxZBKpdi0aZNe9GAwOkqPNnZ9cvnyZVRXV6O0tBQXL17E/v37cf36dX2rxWBopMcZOxEhPDwcAwYMgK+vL2pqavh9mzZtgkQigZ2dHQ4cOAAACA0NBcdxiImJgVgshqenJ168eAGFQgEPDw+YmpqC4zh8/fXXGmWow9fXF3v37kX//v3h5OSEESNGwNbWVrudZzC6gdYcdNrin//8J65cuYK7d++ipqYG06ZNAwCkpKTg22+/RVZWFkxNTTFjxgz4+/vjxIkTuHfvHiQSCRQKBYKDg3HhwgU8ffoUEokEP//8M4YOHdqmjBEjRrSp0/Hjx/H+++/D3t5e6/3vTRARYmJi8Oc//1kr3mdDIz8/HykpKVi5cqVe2u9xd/a8vDx4e3vD1tYWDg4OGD9+PAAgJycHmZmZGDp0KIYMGYJbt27h2rVr/HnTp0+HSCSCk5MTnj17hqCgIAwZMgSOjo7w9fXF3bt325WhjkOHDoGI8Kc//Umr/e4IkydPRmNjo+BytTVi2bFjBxwdHSGVShEZGQmO4+Dt7Y26ujoAQHp6OjiOA8dxOHPmjFZ0aM7Bgwfx+uuvQyKR4K9//SuIqE3fTG5uLt59913MmzevlayCggLMmDEDAwcOxNtvv43KykrIZDIQEeLi4rTeF3X0OGN3cnLCpUuXoFAoUFRUhBs3bgAAXF1d4ePjg8ePH4OIQEQICQnhz2ue7QUAlpaW+OKLL6BQKCCTyfD555+3K6MlX331FWxsbLB48WJkZ2fj6NGjWulzR8nIyECfPn30qkNHaWpqwpEjRxAYGAgAiI6Oxtq1a5GTk4Pw8HAArxJ1UlNTkZCQgLlz52pVnzt37mDz5s24ePEibt26hdTUVJw+fbpN30xpaalaQycizJs3D++99x5KSkrg5OSE5ORkAEBISAh2796t1b5ooscZ+1tvvQUvLy+MHj0aixcvhpOTE6ZOnQonJyf4+PjA0dER/fv3h7+/P548eYLw8HBkZmbCw8MDZ86cwa5du7Bo0SKEh4eD4zgMGjQIly5dwh//+EfMmDFDrQx1XLlyBUuXLkVQUBA4joObm5uOr4QqSt9EYWGhRj+Fv78/OI5DdHQ0LC0tMWHCBOTn5wN45YMwMXk1q9u5cyc4jsO1a9fg7++Phw8fguM4tT/srlJSUgITExO+TSUnT57EqVOnsH379lbnfPrpp5BKpbCxseHvsJr6CnTc/wIAt27dwhtvvIFRo0bB1tYWs2bNQlpaWpu+GV9fX7V/rrm5uSAixMfHw8bGBllZWXx4skQiQUFBARoaGjp/0boLaYnZs2drS7RR8dNPP9GqVas6dKy7uzsVFBTw7w8dOkTV1dU0c+ZMSk5OJiIimUxGx48fp+rqaoqMjKS33nqLP18qlfLvg4OD6erVq622ExFNmzaNsrOzO6STpt/BzZs3aeLEiSrb1q5dS48ePaLk5GQyMTGh06dPU2pqKiUkJJBcLidnZ2d68OABFRcX09ixY+ns2bMa+yqXy8nd3Z2KioqotLSUXFxc6Oeff9aoZ05ODtna2tLdu3fp4cOH5O7uTu+++67KMceOHaMjR46obEtKSqLg4GCVbWfPniUzMzO6fPkyVVZW0vz582ndunX8fnt7eyorK1Orx7p16+jHH3/UqGd36HF3dn2gnDc2f/UEWvoplAQEBEAkEiEoKAi3b99Wey61UcAoLS0Nrq6u3dLNysqKvwO3ZPbs2YiNjcWiRYv4aVpOTg58fHxgb28POzs7vPnmm7h58yZ/Tsu+dtb/4uLigoiICEyaNAnu7u5wcnLCsGHD+P2d8c1YWlpiyJAhmDJlCiwtLREcHKxynWtqarQaKacJZuwdgP53/t781RPQ9KeUnJyMmpoanD59Gk5OTvx2c3Nz3Lp1CyUlJcjJyeG3i0QiFBYWYtasWYLpZmdnh4aGBo3D2RUrVmDZsmVYv349gFc+mQsXLqC4uBglJSU4f/68yh9Oy7521v8CAN988w1+/PFHyOVyZGZmIjQ0FEDnfTNubm548eIF0tPTUVVVhW+++YbPRXj06BEcHBxaTV90glbGC8SG8ULR0WH8woULCQD17duXwsLCCABJpVJKSkoiAASA7ty5QzKZjLZv304WFhbk5uZGeXl5vIy9e/eShYUF+fr6UkBAAAGg8vJyioyMJHNzc9q6dSsREfn6+nZ7GE9EtG3bNkpMTCQiog0bNvB6VlVVERFRY2MjBQYGUkJCAhERRUVFkUQiIWtra9q4cSMRUZt9VR4vEonIz8+PHj9+TEREzs7OVFxc3Eqfzz//nKytrUkmk9GpU6eIiCgjI4M4juPlAqAvv/ySiIiWL1/ObxOLxSqyzp07R6NGjSJLS0t65513+D7t2bOHTpw4ofGaaHMYz4zdwOnMnL0jyGQy/oenC9r6HTQ1NdGWLVtIoVDoTJ+kpCSKjY3VWXvNycvLoz179rR5jDaNXWtjiSdPnmD58uXaEi8Y1dXV6NOnD/r27atvVdTy7NkziEQiQWT5+/sjPz8fI0eOhEKhEERmd+A4DpGRkTptU9uP8NpCJpNBJpPprX2tGbtYLMa6deu0JV4wvvrqKwwfPhze3t76VkUthYWFSExMFESWXC4XRA6jZ6I1YzcxMcFvfvMbbYkXjEGDBkEikRisri9fvuwxgTIMw4Z54zWgDEB5/vy5vlVhMARB58aujM7iOA5mZmYYPXo0Vq9ejfLycl2r0iZyubzV/EpbsecMhi7Q+cO+jz76CBUVFbCwsMDq1avx008/YdOmTfD29sb169dhamqqa5U6TEZGhr5VYDC6jF6H8WZmZnB2dkZ8fDyePn2KlJQUALrNS+8oHYk9b6vdr7/+GgMHDsS4ceNw8eJFXsbKlSthY2MDDw+PbuvIYLSFQeSzm5mZwdHREUVFRXrNS28LZfvN37fUxczMTGO7CxYswIIFC9DQ0IDJkyfj2rVruHfvHjw9PbF7927mhGNoHYMw9rq6Oty5cwcREREqMc1Krl27xhuqurz0K1euwNHREZ6enjhw4EC7MoSipS6lpaVq2zUxMcGCBQuQlZWFly9fYvjw4fx+T0/Pdg398uXLmDNnjqC664off/yxx+quD0pKSvgwXaHRq7HX1dXxc3YrKyv4+fnBzMwMPj4+SExMxODBg1udoykvfdeuXVi3bh0+//xzBAQEtClDKDTFY7dsNzY2FoMHD4ZCoUBJSUmnY8y9vLwQGxsriM66Zs6cOXwuN6N9lLkAWkErcXmkOUzyb3/7Gx9PbGpqSiNHjqRVq1bRkydP+GPUxTRrioFWbu/Tpw85OzvT9evXNcpQx+eff05yubzVdj8/P749oo7Hnqtr9+eff6Zx48aRWCymtWvXqsRZK8/ThNDhsrqGhU13DhYbr0U0GbuhwIzduGD57AwGo9swY2cwjARm7AyGkcCMnWEQEBGio6Px8OFDfasiKPn5+di3b5++1QCgxUdvjx8/xnvvvact8YJRVFSE/v3749SpU/pWRS2VlZUQi8WCybO1te1WLnt3z9dEyxryMTEx8PLyQmpqKszMzJCeno6pU6cCAJKSkrSel56bm4vo6GjU19fzKcZ1dXX45JNPcODAAfTr1w9hYWHYvHkzf84XX3yBqKgoVFVVYebMmTh27BhkMhnkcjni4uKwcOFCrercHloz9kGDBmHbtm3aEm80FBQU4L//+7/1rYZWUdaQVxZljI6ORkNDAw4dOoTw8HD84x//4GvIV1RU6KQAhbImfHx8PL+teQ35wsJCTJkyBYGBgZgwYQJqa2uxatUqXL16FcOGDUNgYCBOnjyJJUuWICQkBDNnztS7sRv9ozdDp71Hb1FRUWRjY0MSiYQ2btxI06ZNoz59+hDR/8U0KEtCK2MHAFBwcDD/ecuWLWRhYUHjx4+nvLw8jTJant8ROvI7+PXXX8nR0VFl29q1ayklJYXMzc1p27ZtRER8WWl1/Sb6v1iI6OhoGjBgAHl4eNDz58+JiGjjxo1kbW1NQ4YMof3793dId3VlopszceJEevDgARER1dfX0+uvv043b96kiooK8vb2pnPnzvHHWllZUX19fbtt9siyVLogJSUFS5YsUZnnVVVVwcLCQo9a6Y6UlBQkJCQgKysLHMfBz88P27dvx48//gjgVYZh8/LJcrm81TB8zJgxGD58OMrKyvDZZ59hzZo1SEtL4xdCaC5D3fnAq8USdu3a1eXy0k+fPoW5uXmr7ePHj0d8fDyCgoIwevRoWFpaauy3h4dHl3IWukrL9f1MTEywe/duTJ48GVVVVVi8eDH8/Pz440UiEcrLyyGRSLrcZnfp0Q662NhYxMfH86WCu1rfS91aZnFxcRg2bBjEYjGWLVuGhoYGg1uTvb1a6kDb9d+VtFdHvj0Z3a0jb2g15NtDXQ35vLw8rF+/Hjk5OXj+/Dn69euH6Ohofr++asU3p0cb+7Nnz+Dg4CC43NraWhw+fBg3btzA3bt3ceXKFVy6dMng1mTXVEtdU/13QH0NeHV15I29hrwmNNWQVygUaGhoUGn7119/BaDnWvHN0crkgLQ/Z1fOzwBQREQEEamWSVY3pyMiio+PJ7FYTC4uLnThwoU256FNTU1UUFBALi4u/LJKzWk+Z9MWHZmzt6ylrqn+OxG1qgGvqY58R2vIE7VdR76jvwNDqyGvriZ8WzXkm5qaKCIiggYPHkwikYi8vb3530x7teKbw2LjNdB8bTOi/zP2ttYFU1JfX0/u7u5E1HotMyVLliwhU1NTiomJoaamJpV96tb90gbajo3Xdh35jv4OemsN+Y7Uim8Oi43vJJrmdEVFRZg0aRL69esHU1PTdgM4jh49ipKSEly/fh379+/ntxvSmuzdoXkdeX2jrCEvlUp11ubcuXOxatUqrbYhk8kQERGh1TY6Sq80dk1zOmWeuUKh4JfVBVrPQzMyMhAWFobKykqYmJjA1NQU9+/fB2B4a7J3B7lcDiIyiAUjGNqnxxp7aGgoMjMz4eDggLS0NJW71IwZMzB//ny4ubnB1dUVQUFBmDVrFubOnYuioiIMHz4cx44dw/379zFv3jyEhoZi7Nix8PLyAgC4u7vD1tYWjo6OGDp0KCorK7FmzRqDW5OdwegUWpkcEAuqEQqWz25csDk7g8HoNszYGQwjgRk7g2EkMGNnMIwEjqgDwdNdYOrUqXySAKPr1NTUoLi4WNBn4bW1tejXr59g8tri1q1bcHFx0UlbvYHs7GycPHkSzs7OgsvWmrFXV1drjHVm6Jf33nsPf//739G/f399q8JQg4WFBV57TfhBt9Yi89kPyXAxNTWFpaWl2rRSRu+FzdkZDCOBGTuDYSQwY2cwjARm7AyGkcCMncEwEpixMxhGAjN2BsNIYMbOYBgJzNgZDCOBGTuDYSQwY2cwjARm7AyGkcCMncEwEpixMxhGAjN2BsNIYMbOYBgJzNiNhPLyckilUvz2t7/Fv//9b4wbNw62trb4/PPP9a0aQ0foeQ1Zhq4YNGgQhg0bhu+//57fNmTIEMydO1ePWjF0CbuzGxFhYWEqhSalUilef/11PWrE0CXM2I2Id955BxKJBABgYmKCxYsX61kjhi5hxm5EWFpawsHBAcCruzozduOCGbuRsXLlSvTv3x9Dhw7F4MGD9a0OQ4cwYzcyAgICwHEc/vznP+tbFYaOEXyRiEmTJsHa2lpIkYx2KCwsxPDhwzt8/K1bt+Do6AgTE/0/jCkuLoaNjQ1MTU31rYpB8eDBA+zbtw+TJ08WTKbg37a1tTWSk5OFFstogzlz5nTqmldWVmLAgAFa1KjjLF++HOvWrcNvfvMbfatiUMTGxgq+ohIbxhshhmLoDN3CjJ3BMBJ6rbHb2tqqfJ48eTIaGxv1LovB0Bf699DoiIyMDIOUxWDoih51Z//6668xcOBAjBs3DhcvXuS3f/rpp5BKpXBwcEBcXBz8/f3x8OFDcByHefPmITQ0FBzHobCwELW1teA4DhzH4cSJE0hMTATHcfjjH/+oVn5bspq3bWNjg02bNgEAf0xMTAzEYjE8PT3x4sULnV8vBkMFEpjZs2cLLbIV9fX15O7uTkREcrmcHB0d6ddff6WysjKaMmUKERFJpVKVc9zd3amgoICIiL7//nuaPHkyvy88PFyj/LZkyeVycnZ2pgcPHlBxcTGNHTuWzp49yx9z6NAhqq6uppkzZ1JycrIwnVeDLq65tvjggw+oqKhI7b6mpibasmULKRQKHWulXfLy8mjv3r1tHrNr1y66ePGioO32mDt7UVERJk2ahH79+sHU1BQPHz4EAOTk5ODNN9/E66+/DolEgsuXL7cra+LEiRCJRPj3v/+NtLQ0TJ8+XaP8tsjJyYGPjw/s7e1hZ2eHN998Ezdv3uT3T58+HSKRCE5OTnj27FnXOy8Q2vI1tPRpCMWOHTvg6OgIqVSKyMhIcBwHb29v1NXVAQDS09P5UdqZM2e0okNzcnNz8e6772LevHkq2+vq6rB+/XqIxWJIpVJ+hAcAX3zxBezs7GBpaYl33nkHtbW1kMlkICLExcVpXefm9BhjT0xMxODBg6FQKJCbmwv631ggV1dXpKeno7i4WOV4kUiEwsJCzJo1S628jz/+GJ999hmSkpLwhz/8QaP8tmS5urriwoULKC4uRklJCc6fPw9XV1d+P8dxQnVfEDIyMtCnTx99q9EhmpqacOTIEQQGBgIAoqOjsXbtWuTk5CA8PBwA4OPjg9TUVCQkJOgkVbe0tLSVoQPA5cuXUV1djdLSUly8eBH79+/H9evXUVtbi1WrVkEul+PBgwcoKyvDyZMnAQAhISHYvXu31nVuTo8x9rlz56KoqAjDhw/HsWPHcP/+fcybNw8zZszA22+/DTc3N1hYWCA0NBSNjY0IDQ3F2LFj4eXlhdDQUGRmZmLMmDG8PB8fH1RVVcHT0xMcx2mUD0CjrBkzZmD+/Plwc3ODq6srgoKCMGvWLISHhyMzMxMeHh44c+YMdu3ahUWLFiEvL09fl0/F19CWT8Hf3x8cxyE6OhqWlpaYMGEC8vPz4evry0fc7dy5ExzH4dq1a618GkJRUlICExOTVlF+J0+exKlTp7B9+/ZW53TWf7Jp0yZIJBLY2dnhwIED7erk6+ur9s/S19cXe/fuRf/+/eHk5IQRI0bA1tYWJiYmsLKyUjnWxsYGACCRSFBQUCB44EybCDopoJ49f+ypdPSaN/dbtOVTkMlkdPz4caqurqbIyEh66623iEjVdxEcHExXr15ttZ2IaNq0aZSdnd0hnTTN2W/evEkTJ05U2bZ27Vp69OgRJScnk4mJCZ0+fZpSU1MpISGh0/4TuVxO7u7uVFRURKWlpeTi4kI///xzu/omJSVRcHCwxv3Hjh2jI0eO8J8TEhLI0tKSANDixYupsbGR32dvb09lZWVq5Rj1nJ0hPG35FAICAiASiRAUFITbt2+3OpfaSKlIS0tTmc50BSsrK41PMGbPno3Y2FgsWrQIN27cANB5/0lOTg4yMzMxdOhQDBkyBLdu3cK1a9e6pfOhQ4dARPjTn/4EAMjLy8P69euRk5OD58+fo1+/foiOjuaPr6mpwaBBg7rVZmdgxm7EtOVTSE5ORk1NDU6fPg0nJycAgLm5OW7duoWSkhLk5OTwx7bnH+kKdnZ2aGho0DjMXbFiBZYtW4b169cD6Lz/xNXVFT4+Pnj8+DGICESEkJCQLuv71VdfwcbGBosXL0Z2djaOHj0KhUKBhoYGlbZ//fVXAMCjR4/g4OCg22QkQccJxIbx+qAj13zhwoUEgPr27UthYWEEgKRSKSUlJREAAkB37twholfD+O3bt5OFhQW5ublRXl4eERHt3buXLCwsyNfXlwICAggAlZeXU2RkJJmbm9PWrVuJiMjX17fbw3giom3btlFiYiIREW3YsIHXs6qqioiIGhsbKTAwkBISEoiIKCoqiiQSCVlbW9PGjRuJiNrsq/J4kUhEfn5+9PjxYyIicnZ2puLi4lb6LF++nD9fLBbz2zMyMojjOH4fAPryyy+pqamJIiIiaPDgwSQSicjb25ufRu3Zs4dOnDih8bpoYxjPjL0XIPQ1l8lkvEFpG0N7zp6UlESxsbFabSMvL4/27NnT5jHaMHbBxxDFxcWYM2eO0GINmqamJvz6668YNmyYXtpXDg2FwN/fH/n5+Rg5ciQUCoVgcrsCx3GIjIzUaZu6eIQnk8kgk8m03k5LBDd2e3t7o8tnr6ysxAcffIATJ07opX0h/1zlcrlgshiGBXPQMRhGAjN2A0EZzPL8+XN9q8Lopejc2B8/fgyRSITMzMx2jzWmnHS5XK6XeRzDeNC5sR85cgTLli3D3r17O32ukLHdPSlOnMEQAp0ae0NDA0pLS/HZZ5/h22+/RUlJCb+voznpeXl5GvPRAfU57/rMSVfKWblyJWxsbODh4QGg7bhsTXHoDEZ30GmlmsTERMyfPx+WlpZYsmQJ9u/fj5iYGKSkpODkyZO4fv06+vbti+DgYFy+fBm2trYqj3/u3buHfv364fvvv8eqVasQGhoKAAgPD8d//ud/AgAWLFiABQsWoKGhAZMnT8a1a9cgl8vVygKAlJQUJCQkICsrCxzHwc/PDx4eHjhx4gTu3bsHiUQChUKB4OBgXLhwAbNnz+5Un5VyPD09sXv3bvTp0wcpKSn49ttvkZWVBVNTU8yYMQP+/v78OWlpafy046OPPmrX0F+8eIGEhIRO6WUoFBQU4OzZs2zBihbcvn0b48ePF1SmTo193759uHr1Kv/Z2toaGzduVMlJB9BuTnrzfPSXL19i+vTpAF7lvC9YsABZWVl4+fJlh2qpN4+pBsDHVCtDP4XKSff09OSnDc3jspW0ZdDUTmn/pqYm1NbWdlk3fdLY2IiXL1/2WP21hTay4XRm7D/88ANmzpyJ//mf/wHw6kv+/e9/jxMnTsDV1RVfffUViouLeaMD/i/m+oMPPsC5c+dU5Cnz0UeMGMGvMd48J72kpEQlVluTLFdXV3z55ZcoLi4Gx3E4f/48duzYweVOjzcAACAASURBVO/XRk66Mi5bqa+SzZs38++VceiDBw9WiUNXh6WlJRYtWiS4nrrg2rVrCAoKYnXjW/Do0SPhhQoaj0fqQzfLy8v5mGElCQkJ/LakpCQ+Ttnc3JwWLlxIDQ0NKjHXzWO7lfy///f/6Pjx4/znn3/+mcaNG0disZjWrl1LAPh0xLZkdTamuiXPnj2jhQsXqr0eSjktz20Zlz1x4kS+PSLNcegdveY9hbbCZY0ZFhtvoLRl7LqgJ19zZuzqYfnsDAajyzBjZzCMBGbsDIaRwIydYbAQEaKjoztU1rsnkZ+fj3379um8XZbPLgBEhIqKCr31W8h89pbBR/qSAbSuGx8TEwMvLy+kpqbCzMwM6enpmDp1KgAgKSlJ67noubm5iI6ORn19PRITE/ntdXV1+OSTT3DgwAH069cPYWFh/GPUL774AlFRUaiqqsLMmTNx7NgxyGQyyOVyxMXFYeHChVrVWQVB3X3Usz3DPRUhr3nLSrHalqHJG9/Y2EijRo2i+vp6ftvatWtp4MCBtHTpUn6bsrqsLkhNTaXExMRW1WVTU1Np5cqV9OLFC8rNzSUrKyv64YcfqKamhvr37083b96kiooK8vb2pqNHjxIRUVlZGU2YMEFjW8wbz+g06uL+O1oDvrM15IHWeQhdhdWNF55es4prSkoKlixZojK/q6qqgoWFhR610i+a4v41xd6ryyEYM2YMhg8fjrKyMnz22WdYs2ZNm7H76mT4+vpi165dnSov/fTpU5ibm7faPn78eMTHxyMoKAijR4+GpaVlm33VlONgZmamNj9hxIgRnbjCrTl+/Djef/99PhJ09+7dmDx5MqqqqrB48WL4+fnxx4pEIpSXl0MikXSrzY7Sa+7ssbGxiI+P58sCdyc3vGXue1xcHIYNGwaxWIxly5ahoaGhzfW9DIX2aqkroXZi77tTQx7oWh15VjdeeHqNsT979gwODg6Cy62trcXhw4dx48YN3L17F1euXMGlS5c0ru9lSLRVS70zNeA7U0Nek4zOwurGawFBPQCkHwedMtYdAEVERBCRajnkqKgosrGxIYlEwse+ExHFx8eTWCwmFxcXunDhAhER+fn58bKaO2KampqooKCAXFxc+NrfzZk4cSI9ePBAi73UTFvXXF3cP1HHa8B3toY8EXWqjjyrG68eFhvfBs3XMSP6P2Nvaw0wJe2tx05EtGTJEjI1NaWYmBhqampS2ddyfS9do81rru0a8qxuvHqYN74LaJrLdXY99qNHj6KkpATXr1/H/v37+e0t52m9ieY15PWBsm68VCrVWZtz587FqlWrtNqGTCZDRESEVttQR683dk1zuY6ux56RkYGwsDBUVlbCxMQEpqamuH//PgD187TehFwuBxHpfbEIhjD0CmNXrpnu4OCAtLQ0lTuSpjXUO7oeu7u7O2xtbeHo6IihQ4eisrISa9aswZUrV7B06VIEBQWB4zi4ubnp+SowGG3DEbXz3KSTzJkzx+hWhNE3PfmaL1++HOvWrWOValoQGxuL8ePHw8fHRzCZveLOzmAw2ocZO4NhJDBjZzCMBMHDd4gIL1++FFosow2ampp67DVvbGxEXV1dj9VfW2hjaTLBHXQrVqxgj2p0zJMnTzq1yEJJSQlsbW3x2mv6H9g9e/YMFhYWbCkuNXz66ad8eLIQCG7sDMMnJCQEhw8fVptVxui96P+vncFg6ARm7AyGkcCMncEwEpixMxhGAjN2BsNIYMbOYBgJzNgZDCOBGTuDYSQwY2cwjARm7AyGkcCMncEwEpixMxhGAjN2BsNIYMbOYBgJzNgZDCOBGTuDYST0miWbGW1TWVmJlJQUAK+qw5w5cwZmZmYYPXp0p1dYZfRMWKUaI6GhoQFDhgzB48eP+W1mZmY4ceIE3n77bT1qxtAVbBhvJJiYmGDq1Kkq26RSKWbPnq0njRi6hhm7EfHhhx/CysqK/zxu3Dj069dPjxoxdAkzdiPC09MTYrEYADBgwACsXLlSzxoxdAkzdiOC4zhMnz4dAGBlZYVp06bpWSOGLmHGbmT85S9/gaWlJTw8PFitdiPDoB69PX78GBcvXtS3Gr2evn37wsXFBQkJCfpWpVczfPhw/P73v9e3GjwGZex37tzB6dOnMWvWLH2rolNSU1Nhb28v6OofbfHOO+/g9ddfR21tbbdlFRQU4NatW5gzZ44AmvUeXrx4gbNnz+Lo0aP6VoXHoIwdAMaPH49FixbpWw2dUl5eDicnJ/j6+uqkPSGv7/fffw+O44zuO2uPp0+f4tq1a/pWQwU2Z2cwjIQeaexRUVHgOA7p6en6VoXB6DH0WGOfP3++XnWwtbVtc39cXByGDRsGsViMZcuWoaGhQUeaMRjq6ZHGbujU1tbi8OHDuHHjBu7evYsrV67g0qVL+laLYeT0GGMnIoSHh2PAgAHw9fVFTU0NACA0NBQcx2HlypWwsbGBh4cHgFdrW0ulUtjY2GDTpk3w9/cHx3GIjo6GpaUlJkyYgPz8fF5+y+N9fX1hYvLKf7lz505wHMc7XPz9/fHw4UNwHId58+a10rVfv35IT0/HoEGDUFNTA1NTU/z2t7/V9iUySIgI0dHRePjwob5VEYz8/Hzs27dP32p0mh5j7P/85z9x5coV3L17F4cPH8atW7cAACdOnIC7uzs8PT1RWlqKa9euISUlBQkJCcjKykJ2djaSkpKwcuVKyGQyDB8+HGVlZZg1axbWrFkDAGqPX716NaytrQEAH330EYKDg3ld5HI5pFIpiAiJiYkadV66dClGjx6NBQsWYNiwYYJch8mTJ6OxsVEQWUram5J0hx07dsDR0RF///vfwXEcvL29UVdXBwBIT08Hx3HgOA5nzpzRmg7Nyc3NxbvvvqvyJ11XV4f169dDLBZDKpVi06ZN/L4vvvgCdnZ2sLS0xDvvvIPa2lrIZDIQEeLi4nSis1D0GGPPy8uDt7c3bG1t4eDggPHjx6vs9/T05CPCcnJy4OPjA3t7e9jZ2eHNN9/EzZs3AQABAQEQiUQICgrC7du32z1eSVcygY8ePYqSkhJcv34d+/fv70q3W5GRkdFjIt+amppw5MgRBAYGIjo6GmvXrkVOTg7Cw8MBAD4+PkhNTUVCQgLmzp2rE51KS0tbjcYuX76M6upqlJaW4uLFi9i/fz+uX7+O2tparFq1CnK5HA8ePEBZWRlOnjwJAAgJCcHu3bt1orNQ9Bhjd3JywqVLl6BQKFBUVIQbN25oPNbV1RUXLlxAcXExSkpKcP78eb5AQ3JyMmpqanD69Gk+iEXT8ebm5rh16xZKSkqQk5Oj0oZIJEJhYaHaAKCMjAyEhYWhsrISJiYmMDU1xf3797t9DZRTlsLCQv59TEwMxGIxPD098eLFC43TFU3TkvamJN2hpKQEJiYmfLsAcPLkSZw6dQrbt29Xe07L6ZSmfirZtGkTJBIJ7OzscODAgXZ18vX1bfVn6evri71796J///5wcnLCiBEjYGtrCxMTE5UsQQCwsbEBAEgkEhQUFPQox2uPMfa33noLXl5eGD16NBYvXgwnJydMnToVAQEByMzMhIODA/Ly8gAAM2bMwPz58+Hm5gZXV1cEBQXxRqlQKGBjY4OzZ89i165dbR4fERGBSZMmYcmSJRgzZgw8PT1RUVEB4JXhjR07Fl5eXq10dXd3h62tLRwdHTF06FBUVlbyU4buoJyyNH8vkUigUCgwaNAgXLhwAXK5XO10JS0tTe20RNOUxNfXt9XoprM8ffoU5ubmKtvGjx+P+Ph4REZGIikpSWWfuulUSEiI2n4qj//222+RlZWFrKwsHDx4EL/88ku3dD5+/Djef/992Nvbw8TEBLt378bkyZMxcOBADBs2DH5+fvyxIpEI5eXl3WpPp5ABcfnyZdqxY4fW5MtkMqqqqtKa/K6yd+9eSk1N7dCx7u7uVFBQwL//5ZdfiIhozZo1dPz4cSJ61c/y8nIiIsrKyiIHBwciIpJKpbycoKAgunr1aqvtneW7776jzZs3q93366+/kqOjI/957dq19OjRIyIi2rdvH5mbm9OOHTsoISGBiIh27NhBy5cv549fuXIlffbZZxr7uWPHDgKg8oqLi2tX56SkJAoODm61/eDBg/TVV1/xn+/cuUMjR46kgoICev78Of3Hf/wHffrpp/x+Kysrqq+vV9vGkydPaMmSJe3qokt6zJ29u/j7+yM/Px8jR44UXLbSydT8pSs0taVuuqJpWtLWlKQ72NnZoaGhQe1Qd8WKFVi2bBnWr1/Pb2tr+qWun66urvDx8cHjx49BRCAihISEdEnXr776CjY2Nli8eDGys7Nx9OhRKBQKNDQ0qLT966+/AgAePXoEBwcHlSmKwaPvf5vmaPvObqh09M6+cOFCAkB9+/alsLAwAkBSqZSSkpL4O9udO3dIJpPR9u3bycLCgtzc3CgvL49vx8LCgnx9fSkgIIAAUHl5OUVGRpK5uTlt3bqVb8vX15eys7Pb1amtOzsR0bZt2ygxMZE2bNjA66gcXTU2NlJgYCB/ZyciioqKIolEQtbW1rRx48Y2+9n8eJFIRH5+fvT48WNydnam4uJitfosX76clyEWi4mIKCMjgziOUxkhfPnll9TU1EQRERE0ePBgEolE5O3tzY+q9uzZQydOnNDYb0O8szNjNwA6M4zvCLqcrrRn7E1NTbRlyxZSKBQ60ScpKYliY2O12kZeXh7t2bOnzWMM0dgNbgzy448/4vjx4/pWQ6dkZ2cLlt7afLqiUCgEkdkdOI5DZGSkztrTxSM8mUwGmUym9XaExuCMvU+fPkZXBFHIeZ9cLhdMFqN3YXDG7ujoaHR1zEtLS/WtAsMIMBpvPINh7DBjZzCMhB5t7MqwT47j+HXLVq9erdeoJm0mlTAY3cHg5uyd4aOPPkJFRQUsLCywevVq/PTTT9i0aRO8vb1x/fp1mJqa6ltFBsNg6NF39uaYmZnB2dkZ8fHxePr0KSQSSYfy3AG0meuu7nh9JJUwGN2lR9/Z1WFmZgZHR0f84Q9/wLFjx+Dp6Yndu3ejT58+KokWHMfBz88PHh4ekMvlGDNmDJ888tlnn2HNmjVYsWKF2uPT0tL44fpHH33EF7WQy+WwtbXt9PPt2tpabNy4sUcWRKioqEBlZSW+//57fatiUNTX1xvcyLLXGXtdXR3u3LmDiIgIAJrz3AHweevKmPDmue5xcXHtHq+Eurnqdb9+/bBlyxadlZIWku+//x5yuRwbN27UtyoGxdOnT7F69Wp9q6FCrxnG19XV8VVIrKysVFIRlbSVaAG0Th5p63hdJ5UwGN2lR9/Zd+7ciZiYGACvihgMGzYMs2fPxuHDh7FixQo+z/3OnTsYM2aMSt46EeH9999XMUplrvuoUaMQHx8PmUym8XhlrruHhwef615eXs7nuesyRJTB6BB6js1XQZ+JMPrMdRc6EUaXtJcIY6wYYiJMrxnGdwdt5rozGIZCjx7GCwVLHmEYA+zOztAqxOrGGwwGd2fPzs7Gf/3Xf+lbDZ3yww8/CJbP3pXn/NqQoaR53fiYmBh4eXkhNTUVZmZmSE9Px9SpUwEASUlJOslFz83NRXR0NOrr6/kCm3V1dfjkk09w4MAB9OvXD2FhYdi8eTOAV3Xjo6KiUFVVhZkzZ+LYsWOQyWSQy+WIi4vDwoULta6zUBicsZubm/Pleo0FCwsLfaugFZR142/fvo3g4GA0NDTg0KFDCA8Pxz/+8Q++bnxFRYXO68bHx8fz25rXjS8sLMSUKVMQGBgIZ2dnrFq1ClevXsWwYcMQGBiIkydPYsmSJQgJCcHMmTN7lLEzb7wB0JY3PioqimxsbEgikdDGjRuJiGjatGnUp08fIiL629/+RgDo6tWr5Ofnx9dQU1ZPVW7bsmULWVhY0Pjx4ykvL69TMtqis9VlU1JSyNzcnLZt20ZERKmpqa1q0DXvr7LuXnR0NA0YMIA8PDzo+fPn/PEbN24ka2trGjJkCO3fv79dfYk0V5dVMnHiRHrw4AHV19fT66+/Tjdv3qSKigry9vamc+fO8cex6rIMwVBXR/3cuXOdqgEvRB35rtaQZ3XjDYteY+wpKSmwtbVVKef8/PlzfavVLTqyLBXQsXBddctedVRGWlqaSqRhR7GyslJZvUXJ7NmzERsbi0WLFqms7NNWf6dPnw6RSAQnJyc8e/aMPz7z/7d35zFRnV8fwL83MiMIdARktUFcwsimRU1AawXbUVBwCRjFlUqMEptKURtLtIS20FasqLhENC6lGrQQMVjrUBBXWqiCikHFqiiyjCiKGygC5/3Dd+5vBmdYZBaYeT4JiTPcee65mDNz753znKewEM7OznB0dMTVq1f5eQrvIyUlBUSEiIgIAG+XHIuJiUFJSQlevHgBU1NTxMfH89s3NjbCysrqvfenawaT7ElJSUhLS+P7h3enIWDbOemq1lpvbzFATdFkua4++sizvvE9jN4uIFTozjW74kopRN2riFNcIaWxsZH8/Pyorq6OZDIZDR8+nHJzcyknJ4dWrFhBL1++pNLSUrK2tqaLFy++1/46umZX7KOu+JrO9oDvbh/59nrIs77xqvXEa3aDSHb5TRwAFBUVRUTKya7qJhcRUVpaGolEIvLy8qK8vDwiIrU3qFpbW6m8vJy8vLyU3lTk5Dd13oe2y2W1WQrM+sarxpK9A9r4ZJdKpeTh4UGVlZVUVVVFnp6edPz4caXXvnnzhnx8fPjHqtY+Cw8PJ4FAQAkJCdTa2qr0u9TUVNqzZ897xU2k3WSXv3l1Zz239rDaeNV6YrIbzDW7Oupu+lRUVGDcuHEwNTWFQCDosMJL3VrrbW/q9DRSqRRE1CMWjGD0y+CTXd1Nn4yMDNjY2EAmk6G0tFTpbrTiDar21lpXdVOHYXoqg0j2BQsW8HPXc3NzlWaxqVt7febMmaioqICLiwtSU1Nx7949vm+c4trr6tZaz8/Px+LFixESEgKO4+Dt7a3nvwLDtI8j6mZPJQ06d+4cCgoK8PXXX+s7FJ1KTk6Gu7s7a0tlQORtqXrS2Z5BfLIzDNMxluwMYyRYsjOMkehxtX5///230ldbxqCgoAB37tzhF6boTSorK1FWVmZ0/2cdaWho0HcI7+hRN+jq6+tRWFio7zAM3s6dOxEREQGhUKjvUAzawIED4enpqe8weD0q2RndmDdvHnbv3v3O9FPGsLFrdoYxEizZGcZIsGRnGCPBkp1hjARLdoYxEizZGcZIsGRnGCPBkp1hjARLdoYxEizZGcZIsGRnGCPBkp1hjARLdoYxEizZGcZIsGRnGCPBkp1hjARrXmEkHj9+jClTpqClpQX19fUQiURoaWlBdHQ0wsPD9R0eowM9rgcdox3W1tZ4/vw5rl+/zj9na2uLUaNG6TEqRpfYabwRmTt3Lvr06cM/7t+/P7y8vPQYEaNLLNmNyJIlS2Bvbw8A4DgOM2bM0HNEjC6xZDcijo6OsLOzAwDY29tj2bJleo6I0SWW7EZG3kJ6wIABGDZsmL7DYXSIJbuRWbBgAUxMTBAWFqbvUBgd0+hXbzdv3kR0dLTSTSBG+54/fw6hUIi+fft2avvCwkJ89NFHnd5em16/fo2mpiZYWlrqO5QeRyKRYMWKFRobT6NfvT19+hS+vr5s+V4d27BhA3x9ffHJJ590avvy8nIMHjxYy1F1jrEu092RmpoaxMXFaXRMdhpvhHpKojO6ZTDJHhcXB47jcPr0aX2HwjA9kkEl+5w5c/S2/4MHD2LQoEEQiURYsmQJmpub9RYLw6hiMMmuT69evcLu3btx6dIl3Lx5E/n5+Thz5oy+w2IYJb062YkIkZGR+OCDDyCRSNDY2Mj/LjY2Fra2tnBycsKOHTsAvP3aieM4JCQkQCQSYezYsXj58iVkMhl8fX0hEAjAcRwOHTqkdgxVTE1Ncfr0aVhZWaGxsRECgQBDhw7V7sEzTBf16mQ/duwY8vPzcfPmTezevRtXr14FAGRnZ+Ovv/5CcXExiouLsXPnTty5cwcHDhyAj48PbG1tIZPJYGVlhby8PGRnZ8PW1ha3b98GESEsLEztGO1ZvHgxXF1dERYWhkGDBuniT2DwiAjx8fF48OCBvkPRmLKyMiQnJ+t8v7062W/cuAE/Pz84ODhg8ODB/AyukpISFBYWwtnZGY6Ojrh69SoKCgr4102aNAlmZmZwd3fH06dPERISAkdHR7i5uUEikeDmzZsdjqHK/v37UV1djaKiImzfvl2rx/6+xo8fj5aWFo2O6eDgoNHxFCUmJsLNzQ1bt24Fx3Hw8/NDU1MTAOD06dPgOA4cx+Ho0aNai0FRaWkp5s6di1mzZvHPNTU1ISYmBiKRCPb29oiNjeV/t2vXLjg5OcHS0hKzZ8/Gq1evIBaLQUQ4ePCgTmKW69XJ7u7ujjNnzkAmk6GiogKXLl0CAIwcORL+/v549OgRiAhEhHnz5vGv4zhOaRxLS0vs2rULMpkMYrEY27Zt63AMRefPn8eyZcvw7NkzmJiYQCAQ4N69e9o78G44f/58ryl6am1txZ49ezBjxgzEx8djzZo1KCkpQWRkJADA398fOTk5SE9Px8yZM3USU01NjVKiA8DZs2fR0NCAmpoanDp1Ctu3b0dRURFevXqF6OhoSKVSVFZWora2FocPHwYAzJs3D5s2bdJJzHK9OtmDgoIwYcIEuLq6YtGiRXB3d8fEiRPh7u4Of39/uLm5oV+/fggMDERdXR0iIyNRWFgIX19fHD16FBs3bsTChQsRGRkJjuNgZWWFM2fO4PPPP8fkyZNVjqGKj48PHBwc4ObmBmdnZzx79gyrVq3S8V+jY/J7Fnfv3lV7/yIwMBAcxyE+Ph6WlpYYPXo0ysrKIJFIYGLytgbrl19+AcdxKCgoQGBgIB48eACO495Jgu6qrq6GiYkJv18AOHz4MH7//XesX79e5Wu+++472Nvbw87ODrGxsWqPU66z92XkJBLJO2+WEokEW7ZsQb9+/eDu7o4hQ4bAwcEBJiYmsLa2VtpWPhHJ1tYW5eXluv3WhjTo33//pe+//16TQzKdkJiYSGfPnu3Utj4+PlReXs7/OyUlhRoaGmjKlCmUlZVFRERisZh+++03amhooHXr1lFQUBAREdnb2/PjhIaG0j///PPO83KfffYZXb58ucN4zp49S4mJiSp/d+XKFRozZgz/eM2aNfTw4UPKysoiExMTOnLkCOXk5FB6ejoREUmlUvLw8KDKykqqqqoiT09POn78uNrjlEql5OPjQxUVFVRTU0NeXl50+/btDmPOzMyk0NBQlb9LTU2lPXv28I/T09PJ0tKSANCiRYuopaWF/93AgQOptrZW5TjV1dW0dOnSDmPpil79ya4P8mtExZ/erO39C7ng4GCYmZkhJCQE165de+d11MGUitzcXIwcObJbsVlbWyt9CstNmzYNSUlJWLhwIX/pBry9V+Pv74+BAwfCyckJn376Ka5cuQJA9XG+z32Z9qSkpICIEBERAeDtPaWYmBiUlJTgxYsXMDU1RXx8PL99Y2MjrKys3nt/XcWSvYvo/6/fFX96M3VvVllZWWhsbMSRI0fg7u4OADA3N8fVq1dRXV2NkpISflszMzPcvXsXU6dO1WhsTk5OaG5uVnmq++WXX2LJkiWIiYnhnxs5ciTy8vJQVVWF6upqnDx5kn/DUXWcXbkv05Fff/0VdnZ2WLRoES5fvoz9+/dDJpOhublZad/3798HADx8+BCDBw9WukTROk2eJrDTeP3o7Gn8/PnzCQD17duXli1bRgDI3t6eMjMzCQABoOvXr5NYLKb169eThYUFeXt7040bN4iIaMuWLWRhYUESiYSCg4MJAD158oTWrVtH5ubm9NNPP/H7kkgk3T6NJyL6+eefKSMjg9auXcvH+Pz5cyIiamlpoRkzZvCn8UREcXFxZGtrSwMGDKBvv/223eNU3N7MzIwCAgLo0aNH5OHhQVVVVSrj+eKLL/gxRCIRERGdP3+eOI7jnwdA+/bto9bWVoqKiiIbGxsyMzMjPz8//hJq8+bNdODAAbXHrY3TeJbsBqAr1+ydIRaL+YTSto6SvbW1lX744QeSyWQ6iSczM5OSkpK0uo8bN27Q5s2b291GG8mu8XOIY8eO4cKFC5oeVuMePnwIW1tbfYehETU1NfD19dXIWIGBgSgrK8OwYcMgk8k0MmZ3cByHdevW6Wx/uvgKTywWQywWa30/bWk82adNm9Yr5rNPnz4dWVlZ+g5DIzZs2KCxsaRSqcbGYnoWdoOOYYwES/Zuys7OhoODAziOwx9//KHvcBhGLZ0lu7zqiuM4CIVCuLq6YuXKlXjy5ImuQtCKpKQkpKWlgYgQHBys1TpxhukOnX3Jt3r1atTX18PCwgIrV67Ef//9h9jYWPj5+aGoqAgCgUBXoWjU06dPWZsnplfQy2m8UCiEh4cH0tLS8PjxY2RnZwN4t065q/PPVY3RVerGbltzDbytNS8sLMTgwYPx1VdfvVMn3jb+WbNm4cSJExgwYABGjx7NV3IdOnQI/fv3x4gRI3Dq1CkAgIuLCziOw+bNmxEcHMwuE5hu0+vCjkKhEG5ubqioqFCaPy4QCDB58mQcPXoUt27d4uefh4aGIi8vD48fP+bnnzs7O/PjqRojMDAQQ4YM6XRMinPb5WNnZ2cjPT0dxcXF4DgOAQEB8PX1xYEDB3Dr1i0cOnQILi4uAN5O91T8yurWrVuwt7dHdXU1JBIJLl68iPv37yM8PBwnTpxAWFgY/9Pc3Izx48ejoKAAZWVlmD17NpycnBAQEICEhAS15aetra2ora3lq7N6k9raWjx9+rRXxq5NtbW1Gp+KrNdkb2pqwvXr1xEVFaVUpywnr1NWNf88Pz8fbm5uGDt2LHbs2AFXV1e1Y3Ql2VWNrVhzDYCvue5seehnn30Gc3NzDB06FL6+EgifgAAABbJJREFUvvyx1NfXo6KiAmFhYSguLsbr16/5N42+ffvi8OHD8PT0xOLFi9utM3/9+jUOHjyIvLy8Th9nT1FTU4O6urpef+9G0xoaGpQ6L2mCXpK9qamJv2a3trZGQEAAhEIh/P39kZGRARsbG37b5ORktfPPN27ciG+++Qbbtm1DcnIyX+vcdoyuUDV2cHAw9u3bh6qqKnAch5MnTyIxMVHl6+V14suXL8eff/4JQLkuu+2xyGOVyWSorq7m30CICFu2bMGxY8ewdu1apKWlYe7cuWr3GR0d3em+8T0J6xuvmjb6xuusXHbDhg183bBAIKBhw4ZRdHQ01dXV8du0rVOeNWuWyrpmeb1znz59yMPDg4qKitSO8ejRI5XxTJs2TeXzmzZtUjl225prov/VmgOgnJwcIiKlOnHFuuytW7fy26anp/P/Pnz4MI0YMYJEIhGtWbOGAFBoaCj5+PgQALp06RINGjSIANDatWtVxqzpclld6qhc1lix2ngNUpfsvRFLdsPD5rMzDPPeWLIzjJFgyc4wRoIlO9NrUC/uIa+vXvGKjHY++7179zB9+nR9h6ERmpzP3rYoSF9jqKLYQz4hIQETJkxATk4OhEIhTp8+jYkTJwIAMjMzdTIvvbS0FPHx8Xjz5g0yMjL45/Py8rB8+XI8evQIS5cuRUJCAsRiMaRSKQ4ePIj58+drPTZVjHY+uyHR5Hz2nkreQ/7atWsIDQ1Fc3MzUlJSEBkZib179/I95Ovr63XeQz4tLY1/7tWrV5g/fz5SU1Ph5eWFgIAAfPzxxwgKCsK8efMwZcoUvSU7O403cKpq+rvSA76n9JHXRA95QP16f4BmesgXFRXhww8/xKRJk+Dg4ICIiAgcP34cgJ56xSvQa7msJmVnZyM8PFzpeu758+ewsLDQY1T6pa6mPzc3l5+Ku3r1ar4sWSqVvnMKLpVKMXz4cLi4uKC2thY//vgjVq1a1aUxJBIJNm7c2K3W0o8fP4a5ubnSc6NGjUJaWhpCQkLg6uoKS0vLDo9dPp+h7XwLoVDY7XkVwNuadvlCEMDbRSHOnTvHPzYzM8OTJ0/00hLNYD7ZFeeVE1G3eny1nZOuau319tb36ina66OuiDrRDrs7feR7Wg954N35FprqIW9nZ4fa2lr+cdvk13WveEUGk+zamleubu11det79STt9VHvag94ffeR12QPeeDdOQqa6iE/evRo3L9/Hzk5OZDJZNi7dy+CgoIA6KlXvCJNluPpq1xWsUY9KiqKiJTbIcfFxZGdnR3Z2tryde1ERGlpaSQSicjLy4vy8vKIiCggIIAfS3GJn9bWViovLycvLy++97eiMWPGUGVlpRaPUr32ymVV1fQTda0HfHf7yLfXQ74r5bLd7SFPRO32kddED3kiopMnT5KrqyvZ2NhQTEwMtba2ElHHveIVsdr4diiuYUb0v2RXt/6Xojdv3pCPjw//WNXaZeHh4SQQCCghIYH/z5Nru76Xrmm7Nl6bfeS7kuy9uYd8Z3rFK2K18e9B3bVbRUUFxo0bB1NTUwgEgg4LNdStvd52fS9Do9hHXt/kPeTt7e11sr+ZM2ciOjpaI2OJxWJERUVpZKz3ZfDJru7aTXEeeWlpqdINJsVrzvbWXle1vpehkUqlIKIesWAE0z0GkeyKveByc3OVPo0mT56MOXPmwNvbGyNHjkRISAimTp2KmTNnoqKiAi4uLkhNTcW9e/f474UXLFgAT09PTJgwQe3a6/n5+Vi8eDFCQkLAcRy8vb31/FdgmPZxRJpbhvTChQuQSqWsgk7HNmzYAF9fX9apxoDIO9WkpKRobEyD+GRnGKZjLNkZxkiwZGcYI8GSnWGMhEbr9oRCYa+Zz25I6urqkJ2djX79+uk7lC6T90dXnCzCAM3NzRgxYoRGx9To3XiGYXoudhrPMEbCBEC6voNgGEb7/g+Iqlg2qnO+WQAAAABJRU5ErkJggg==\n",
"text/plain": [
"<IPython.core.display.Image object>"
]
},
"execution_count": 106,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from keras.utils import plot_model\n",
"\n",
"plot_model(model, to_file='/tmp/model.png', dpi=50,\n",
" #expand_nested=False, show_shapes=False, show_dtype=False, show_layer_names=False)\n",
" expand_nested=True, show_shapes=True, show_dtype=True, show_layer_names=True, show_layer_activations=True)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Show Image in Jupyter Notebook"
]
},
{
"cell_type": "code",
"execution_count": 107,
"metadata": {},
"outputs": [],
"source": [
"from IPython.display import Image\n",
"#display(Image('/tmp/model.png'))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Layer properties"
]
},
{
"cell_type": "code",
"execution_count": 108,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"conv2d_2\n",
"Conv2D\n",
"(None, 26, 26, 32)\n",
"(None, 24, 24, 64)\n",
"(3, 3)\n"
]
}
],
"source": [
"layer = model.layers[2]\n",
"print(layer.name)\n",
"print(layer.__class__.__name__)\n",
"print(layer.input_shape)\n",
"print(layer.output_shape)\n",
"print(layer.kernel_size)"
]
},
{
"cell_type": "code",
"execution_count": 109,
"metadata": {
"scrolled": true
},
"outputs": [
{
"data": {
"text/plain": [
"<tf.Variable 'conv2d_2/kernel:0' shape=(3, 3, 32, 64) dtype=float32, numpy=\n",
"array([[[[ 0.07392616, 0.05897463, 0.04968441, ..., -0.0455512 ,\n",
" -0.00312725, -0.01189327],\n",
" [ 0.06458876, -0.00118212, 0.04812177, ..., -0.08073562,\n",
" -0.04055898, 0.02988011],\n",
" [ 0.06744681, -0.00906464, 0.00525299, ..., 0.07085413,\n",
" -0.00105768, -0.03691113],\n",
" ...,\n",
" [-0.01403499, 0.01666423, -0.05948063, ..., 0.01153425,\n",
" 0.08192829, -0.04761424],\n",
" [ 0.03789053, 0.01478174, -0.01809818, ..., -0.03452279,\n",
" 0.04054334, 0.06721445],\n",
" [ 0.07536777, -0.07170765, -0.02936218, ..., -0.07434559,\n",
" -0.01121459, -0.01228831]],\n",
"\n",
" [[ 0.00344393, 0.04033232, 0.06591376, ..., -0.02594455,\n",
" 0.07471987, -0.05644137],\n",
" [-0.01417746, 0.00655898, -0.06519489, ..., -0.04890823,\n",
" -0.07608249, -0.06318065],\n",
" [ 0.05507209, 0.02108941, 0.06897409, ..., 0.06794032,\n",
" -0.02156945, 0.02551601],\n",
" ...,\n",
" [-0.03969721, -0.06882465, -0.00486624, ..., -0.00946134,\n",
" -0.02923667, -0.04103416],\n",
" [ 0.02110001, -0.05052809, -0.06788548, ..., 0.04236891,\n",
" -0.06427556, -0.04927043],\n",
" [-0.0562337 , 0.03159621, 0.07773713, ..., -0.04253594,\n",
" -0.04399868, -0.07729679]],\n",
"\n",
" [[ 0.01139722, -0.00358748, 0.03489912, ..., 0.069658 ,\n",
" 0.02839579, 0.07847973],\n",
" [-0.03488904, -0.00723841, -0.01276386, ..., 0.06423827,\n",
" 0.07649962, 0.04928001],\n",
" [ 0.06156036, 0.02683914, 0.05261984, ..., 0.01718625,\n",
" -0.06848353, 0.05728152],\n",
" ...,\n",
" [ 0.03452259, 0.05460794, -0.01687666, ..., -0.06430485,\n",
" -0.0517382 , -0.03655916],\n",
" [ 0.05500526, -0.00139461, 0.07912637, ..., 0.01222374,\n",
" -0.04431931, -0.03392563],\n",
" [-0.07562419, -0.04461138, 0.06622294, ..., -0.08071842,\n",
" -0.01734072, 0.05444152]]],\n",
"\n",
"\n",
" [[[ 0.08163739, 0.03329792, -0.05387783, ..., 0.03243566,\n",
" -0.05663822, -0.06609654],\n",
" [-0.03964476, 0.05167504, -0.03705239, ..., 0.03073332,\n",
" -0.01282489, -0.02002183],\n",
" [ 0.07020213, -0.04631933, 0.01006152, ..., 0.01340751,\n",
" 0.05104215, 0.03420544],\n",
" ...,\n",
" [ 0.06263543, -0.06552911, 0.06739414, ..., -0.05585275,\n",
" -0.01314118, -0.02200633],\n",
" [-0.08218686, -0.03454296, 0.01571459, ..., 0.03957848,\n",
" -0.00015584, -0.06693747],\n",
" [-0.08287965, 0.05243791, -0.08287891, ..., -0.05746832,\n",
" -0.07408945, -0.05849048]],\n",
"\n",
" [[ 0.02399319, -0.00512457, 0.00241736, ..., -0.06734904,\n",
" -0.03077799, 0.08113173],\n",
" [-0.00199936, 0.03415968, -0.0593672 , ..., 0.06185544,\n",
" -0.00810111, 0.01138005],\n",
" [ 0.01792803, 0.05233272, -0.03303105, ..., 0.05906246,\n",
" -0.00343293, -0.03315067],\n",
" ...,\n",
" [-0.04259716, 0.07056428, 0.07492622, ..., 0.0719193 ,\n",
" -0.00050122, -0.01861551],\n",
" [ 0.00745847, -0.04687272, -0.00141376, ..., 0.05851782,\n",
" 0.06248834, -0.04763667],\n",
" [ 0.04928681, -0.03322685, 0.0743498 , ..., -0.03609191,\n",
" 0.05196067, -0.08227509]],\n",
"\n",
" [[-0.04533831, -0.03183993, 0.02125774, ..., -0.0704821 ,\n",
" -0.02897469, -0.04510488],\n",
" [-0.02222808, 0.02822765, 0.07305918, ..., 0.03029899,\n",
" 0.07977099, 0.08030296],\n",
" [-0.06619543, -0.01775233, 0.00226285, ..., 0.03881399,\n",
" 0.00015604, 0.06537708],\n",
" ...,\n",
" [-0.04773736, -0.03549961, 0.0791334 , ..., 0.00954012,\n",
" 0.01867858, -0.05642649],\n",
" [ 0.04523314, -0.0399521 , -0.04405596, ..., -0.03965686,\n",
" 0.04838005, 0.05863587],\n",
" [ 0.06894801, 0.08142091, -0.04733662, ..., 0.00100783,\n",
" 0.07689931, -0.03838267]]],\n",
"\n",
"\n",
" [[[ 0.01219052, 0.03763232, -0.059853 , ..., -0.0158759 ,\n",
" -0.07053721, 0.07573316],\n",
" [ 0.00370731, -0.07976317, -0.00681963, ..., 0.00305321,\n",
" 0.0224764 , -0.05613937],\n",
" [-0.07609402, 0.04107988, -0.07612132, ..., -0.06555452,\n",
" -0.01805212, 0.05727597],\n",
" ...,\n",
" [-0.03267926, -0.02257494, 0.03633495, ..., -0.04978675,\n",
" 0.06224672, 0.00213486],\n",
" [-0.06492041, 0.02107257, 0.07801457, ..., 0.02030947,\n",
" -0.01508149, 0.06499388],\n",
" [-0.02290231, -0.07525271, -0.07470787, ..., 0.05211665,\n",
" -0.03059761, -0.0679888 ]],\n",
"\n",
" [[ 0.07628367, 0.00798508, -0.0554226 , ..., 0.04131905,\n",
" -0.0780226 , -0.00302058],\n",
" [-0.01404077, -0.00742888, 0.07992122, ..., 0.00120495,\n",
" 0.06674764, -0.02014116],\n",
" [ 0.05755738, -0.08066897, -0.08020439, ..., -0.0479699 ,\n",
" -0.07831752, 0.00455568],\n",
" ...,\n",
" [-0.05726717, 0.06313581, 0.08204878, ..., -0.03842795,\n",
" -0.03812677, 0.00559088],\n",
" [-0.06713472, 0.00766458, 0.02291628, ..., 0.03953478,\n",
" 0.03032293, 0.02527332],\n",
" [-0.06528276, -0.05520594, 0.00080454, ..., 0.01782525,\n",
" -0.03008225, -0.06209364]],\n",
"\n",
" [[ 0.0721959 , -0.05849358, 0.04600904, ..., -0.07617873,\n",
" 0.07763012, -0.04406613],\n",
" [ 0.07573051, -0.04088753, 0.02174252, ..., 0.02465854,\n",
" 0.06322337, -0.00175079],\n",
" [-0.04267456, -0.06360577, -0.0369525 , ..., -0.07599541,\n",
" -0.06914755, -0.05564191],\n",
" ...,\n",
" [-0.0824463 , -0.02448761, 0.04148344, ..., 0.00488967,\n",
" 0.03705265, -0.03312838],\n",
" [-0.07874157, -0.03456581, 0.04561617, ..., -0.07850891,\n",
" 0.07190693, -0.02480898],\n",
" [ 0.0294311 , 0.02178317, -0.03215762, ..., 0.03795793,\n",
" -0.03892611, -0.04893148]]]], dtype=float32)>"
]
},
"execution_count": 109,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"layer.kernel"
]
},
{
"cell_type": "code",
"execution_count": 110,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"<tf.Variable 'conv2d_2/bias:0' shape=(64,) dtype=float32, numpy=\n",
"array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,\n",
" 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,\n",
" 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,\n",
" 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], dtype=float32)>"
]
},
"execution_count": 110,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"layer.bias"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"get weight values as numpy arrays"
]
},
{
"cell_type": "code",
"execution_count": 111,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[(3, 3, 32, 64), (64,)]\n"
]
},
{
"data": {
"text/plain": [
"[array([[[[ 0.07392616, 0.05897463, 0.04968441, ..., -0.0455512 ,\n",
" -0.00312725, -0.01189327],\n",
" [ 0.06458876, -0.00118212, 0.04812177, ..., -0.08073562,\n",
" -0.04055898, 0.02988011],\n",
" [ 0.06744681, -0.00906464, 0.00525299, ..., 0.07085413,\n",
" -0.00105768, -0.03691113],\n",
" ...,\n",
" [-0.01403499, 0.01666423, -0.05948063, ..., 0.01153425,\n",
" 0.08192829, -0.04761424],\n",
" [ 0.03789053, 0.01478174, -0.01809818, ..., -0.03452279,\n",
" 0.04054334, 0.06721445],\n",
" [ 0.07536777, -0.07170765, -0.02936218, ..., -0.07434559,\n",
" -0.01121459, -0.01228831]],\n",
" \n",
" [[ 0.00344393, 0.04033232, 0.06591376, ..., -0.02594455,\n",
" 0.07471987, -0.05644137],\n",
" [-0.01417746, 0.00655898, -0.06519489, ..., -0.04890823,\n",
" -0.07608249, -0.06318065],\n",
" [ 0.05507209, 0.02108941, 0.06897409, ..., 0.06794032,\n",
" -0.02156945, 0.02551601],\n",
" ...,\n",
" [-0.03969721, -0.06882465, -0.00486624, ..., -0.00946134,\n",
" -0.02923667, -0.04103416],\n",
" [ 0.02110001, -0.05052809, -0.06788548, ..., 0.04236891,\n",
" -0.06427556, -0.04927043],\n",
" [-0.0562337 , 0.03159621, 0.07773713, ..., -0.04253594,\n",
" -0.04399868, -0.07729679]],\n",
" \n",
" [[ 0.01139722, -0.00358748, 0.03489912, ..., 0.069658 ,\n",
" 0.02839579, 0.07847973],\n",
" [-0.03488904, -0.00723841, -0.01276386, ..., 0.06423827,\n",
" 0.07649962, 0.04928001],\n",
" [ 0.06156036, 0.02683914, 0.05261984, ..., 0.01718625,\n",
" -0.06848353, 0.05728152],\n",
" ...,\n",
" [ 0.03452259, 0.05460794, -0.01687666, ..., -0.06430485,\n",
" -0.0517382 , -0.03655916],\n",
" [ 0.05500526, -0.00139461, 0.07912637, ..., 0.01222374,\n",
" -0.04431931, -0.03392563],\n",
" [-0.07562419, -0.04461138, 0.06622294, ..., -0.08071842,\n",
" -0.01734072, 0.05444152]]],\n",
" \n",
" \n",
" [[[ 0.08163739, 0.03329792, -0.05387783, ..., 0.03243566,\n",
" -0.05663822, -0.06609654],\n",
" [-0.03964476, 0.05167504, -0.03705239, ..., 0.03073332,\n",
" -0.01282489, -0.02002183],\n",
" [ 0.07020213, -0.04631933, 0.01006152, ..., 0.01340751,\n",
" 0.05104215, 0.03420544],\n",
" ...,\n",
" [ 0.06263543, -0.06552911, 0.06739414, ..., -0.05585275,\n",
" -0.01314118, -0.02200633],\n",
" [-0.08218686, -0.03454296, 0.01571459, ..., 0.03957848,\n",
" -0.00015584, -0.06693747],\n",
" [-0.08287965, 0.05243791, -0.08287891, ..., -0.05746832,\n",
" -0.07408945, -0.05849048]],\n",
" \n",
" [[ 0.02399319, -0.00512457, 0.00241736, ..., -0.06734904,\n",
" -0.03077799, 0.08113173],\n",
" [-0.00199936, 0.03415968, -0.0593672 , ..., 0.06185544,\n",
" -0.00810111, 0.01138005],\n",
" [ 0.01792803, 0.05233272, -0.03303105, ..., 0.05906246,\n",
" -0.00343293, -0.03315067],\n",
" ...,\n",
" [-0.04259716, 0.07056428, 0.07492622, ..., 0.0719193 ,\n",
" -0.00050122, -0.01861551],\n",
" [ 0.00745847, -0.04687272, -0.00141376, ..., 0.05851782,\n",
" 0.06248834, -0.04763667],\n",
" [ 0.04928681, -0.03322685, 0.0743498 , ..., -0.03609191,\n",
" 0.05196067, -0.08227509]],\n",
" \n",
" [[-0.04533831, -0.03183993, 0.02125774, ..., -0.0704821 ,\n",
" -0.02897469, -0.04510488],\n",
" [-0.02222808, 0.02822765, 0.07305918, ..., 0.03029899,\n",
" 0.07977099, 0.08030296],\n",
" [-0.06619543, -0.01775233, 0.00226285, ..., 0.03881399,\n",
" 0.00015604, 0.06537708],\n",
" ...,\n",
" [-0.04773736, -0.03549961, 0.0791334 , ..., 0.00954012,\n",
" 0.01867858, -0.05642649],\n",
" [ 0.04523314, -0.0399521 , -0.04405596, ..., -0.03965686,\n",
" 0.04838005, 0.05863587],\n",
" [ 0.06894801, 0.08142091, -0.04733662, ..., 0.00100783,\n",
" 0.07689931, -0.03838267]]],\n",
" \n",
" \n",
" [[[ 0.01219052, 0.03763232, -0.059853 , ..., -0.0158759 ,\n",
" -0.07053721, 0.07573316],\n",
" [ 0.00370731, -0.07976317, -0.00681963, ..., 0.00305321,\n",
" 0.0224764 , -0.05613937],\n",
" [-0.07609402, 0.04107988, -0.07612132, ..., -0.06555452,\n",
" -0.01805212, 0.05727597],\n",
" ...,\n",
" [-0.03267926, -0.02257494, 0.03633495, ..., -0.04978675,\n",
" 0.06224672, 0.00213486],\n",
" [-0.06492041, 0.02107257, 0.07801457, ..., 0.02030947,\n",
" -0.01508149, 0.06499388],\n",
" [-0.02290231, -0.07525271, -0.07470787, ..., 0.05211665,\n",
" -0.03059761, -0.0679888 ]],\n",
" \n",
" [[ 0.07628367, 0.00798508, -0.0554226 , ..., 0.04131905,\n",
" -0.0780226 , -0.00302058],\n",
" [-0.01404077, -0.00742888, 0.07992122, ..., 0.00120495,\n",
" 0.06674764, -0.02014116],\n",
" [ 0.05755738, -0.08066897, -0.08020439, ..., -0.0479699 ,\n",
" -0.07831752, 0.00455568],\n",
" ...,\n",
" [-0.05726717, 0.06313581, 0.08204878, ..., -0.03842795,\n",
" -0.03812677, 0.00559088],\n",
" [-0.06713472, 0.00766458, 0.02291628, ..., 0.03953478,\n",
" 0.03032293, 0.02527332],\n",
" [-0.06528276, -0.05520594, 0.00080454, ..., 0.01782525,\n",
" -0.03008225, -0.06209364]],\n",
" \n",
" [[ 0.0721959 , -0.05849358, 0.04600904, ..., -0.07617873,\n",
" 0.07763012, -0.04406613],\n",
" [ 0.07573051, -0.04088753, 0.02174252, ..., 0.02465854,\n",
" 0.06322337, -0.00175079],\n",
" [-0.04267456, -0.06360577, -0.0369525 , ..., -0.07599541,\n",
" -0.06914755, -0.05564191],\n",
" ...,\n",
" [-0.0824463 , -0.02448761, 0.04148344, ..., 0.00488967,\n",
" 0.03705265, -0.03312838],\n",
" [-0.07874157, -0.03456581, 0.04561617, ..., -0.07850891,\n",
" 0.07190693, -0.02480898],\n",
" [ 0.0294311 , 0.02178317, -0.03215762, ..., 0.03795793,\n",
" -0.03892611, -0.04893148]]]], dtype=float32),\n",
" array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,\n",
" 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,\n",
" 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,\n",
" 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], dtype=float32)]"
]
},
"execution_count": 111,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"weights = layer.get_weights()\n",
"print([w.shape for w in weights])\n",
"weights"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Save and Load Weights"
]
},
{
"cell_type": "code",
"execution_count": 112,
"metadata": {},
"outputs": [],
"source": [
"model.save_weights('weights.keras')\n",
"\n",
"model.load_weights('weights.keras')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Classical API\n",
"\n",
"- The classical API for training, evaluation, prediction is inspired by scikit-learn"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Training"
]
},
{
"cell_type": "code",
"execution_count": 113,
"metadata": {
"scrolled": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Epoch 1/10\n",
"469/469 [==============================] - 7s 9ms/step - loss: 0.2383 - accuracy: 0.9282 - val_loss: 0.0562 - val_accuracy: 0.9814\n",
"Epoch 2/10\n",
"469/469 [==============================] - 4s 8ms/step - loss: 0.0833 - accuracy: 0.9747 - val_loss: 0.0387 - val_accuracy: 0.9871\n",
"Epoch 3/10\n",
"469/469 [==============================] - 4s 8ms/step - loss: 0.0628 - accuracy: 0.9811 - val_loss: 0.0319 - val_accuracy: 0.9887\n",
"Epoch 4/10\n",
"469/469 [==============================] - 4s 8ms/step - loss: 0.0506 - accuracy: 0.9843 - val_loss: 0.0305 - val_accuracy: 0.9896\n",
"Epoch 5/10\n",
"469/469 [==============================] - 4s 8ms/step - loss: 0.0430 - accuracy: 0.9869 - val_loss: 0.0298 - val_accuracy: 0.9902\n",
"Epoch 6/10\n",
"469/469 [==============================] - 4s 8ms/step - loss: 0.0378 - accuracy: 0.9878 - val_loss: 0.0281 - val_accuracy: 0.9908\n",
"Epoch 7/10\n",
"469/469 [==============================] - 4s 8ms/step - loss: 0.0353 - accuracy: 0.9888 - val_loss: 0.0321 - val_accuracy: 0.9894\n",
"Epoch 8/10\n",
"469/469 [==============================] - 4s 7ms/step - loss: 0.0310 - accuracy: 0.9897 - val_loss: 0.0315 - val_accuracy: 0.9898\n",
"Epoch 9/10\n",
"469/469 [==============================] - 4s 8ms/step - loss: 0.0285 - accuracy: 0.9910 - val_loss: 0.0346 - val_accuracy: 0.9900\n",
"Epoch 10/10\n",
"469/469 [==============================] - 4s 8ms/step - loss: 0.0258 - accuracy: 0.9918 - val_loss: 0.0268 - val_accuracy: 0.9912\n"
]
}
],
"source": [
"from tensorflow.keras.optimizers import SGD, Adam\n",
"from keras.callbacks import ModelCheckpoint\n",
"from keras.losses import categorical_crossentropy\n",
"\n",
"optimizer = Adam(learning_rate=0.001)\n",
"\n",
"callbacks = [\n",
" ModelCheckpoint('/tmp/weights-{epoch:02d}.keras')\n",
"]\n",
"\n",
"model.compile(loss=categorical_crossentropy, optimizer=optimizer, metrics=['accuracy'])\n",
"\n",
"history = model.fit(x_train, y_train, batch_size=128, epochs=10, verbose=1, \n",
" validation_data=(x_test, y_test), callbacks=callbacks)"
]
},
{
"cell_type": "code",
"execution_count": 114,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"-rw-rw-r-- 1 mvoe mvoe 14442849 Apr 30 17:01 /tmp/weights-01.keras\r\n",
"-rw-rw-r-- 1 mvoe mvoe 14442849 Apr 30 17:01 /tmp/weights-02.keras\r\n",
"-rw-rw-r-- 1 mvoe mvoe 14442849 Apr 30 17:02 /tmp/weights-03.keras\r\n",
"-rw-rw-r-- 1 mvoe mvoe 14442849 Apr 30 17:02 /tmp/weights-04.keras\r\n",
"-rw-rw-r-- 1 mvoe mvoe 14442849 Apr 30 17:02 /tmp/weights-05.keras\r\n",
"-rw-rw-r-- 1 mvoe mvoe 14442849 Apr 30 17:02 /tmp/weights-06.keras\r\n",
"-rw-rw-r-- 1 mvoe mvoe 14442849 Apr 30 17:02 /tmp/weights-07.keras\r\n",
"-rw-rw-r-- 1 mvoe mvoe 14442849 Apr 30 17:02 /tmp/weights-08.keras\r\n",
"-rw-rw-r-- 1 mvoe mvoe 14442849 Apr 30 17:02 /tmp/weights-09.keras\r\n",
"-rw-rw-r-- 1 mvoe mvoe 14442849 Apr 30 17:02 /tmp/weights-10.keras\r\n"
]
}
],
"source": [
"!ls -l /tmp/weights*"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Plot Training History"
]
},
{
"cell_type": "code",
"execution_count": 115,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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gV+a2WfxLtR0rdPQIBERSXAdCq5ycoYMSKN4UD8Wl5bz/84f7Xc5IiLSB3Tgy+Z1wKzurktERKQzuvSqwvJOFxYXsHJHFdWH6/0uRUREREREpEdScD3F5hUVEHXw3EadPiQiIiIiInIyFFxPsclDB5CXmcKi0r1+lyIiIiIiItIjKbieYoGAMa8on+c2VtAQifpdjoiIiIiISI+j4NoN5hUVcqg2zKvb+8ydgERERERERLqMgms3mD02j+RggMWl5X6XIiIiIiIi0uMouHaDjJQQ54zOZXHpXnSrPBERERERkROj4NpNSooL2F55hC0Vh/0uRUREREREpEdRcO0m84oKAFiyXlcXFhEREREROREKrt1kaHY6RQOzWKTzXEVERERERE6Igms3urC4kFU7qtl/pN7vUkRERERERHoMBdduNK+4gEjU8dzGCr9LERERERER6TEUXLvRlKEDyMtM1nBhERERERGRE6Dg2o0CAeOC8QU8u6GchkjU73JERERERER6BAXXblZSXMCh2jArt1f7XYqIiIiIiEiPoODazWaPzSc5GGBxqW6LIyIiIiIi0hEKrt0sIyXEzNG5LF6v81xFREREREQ6QsHVBxcWF7Bt32G2VNT4XYqIiIiIiEjCU3D1wbyiAgCW6OrCIiIiIiIi7VJw9cHQ7HSKBmaxSOe5ioiIiIiItEvB1SclxQWs3FHNgSMNfpciIiIiIiKS0BRcfTKvqJBI1PHsRg0XFhEREREROR4FV59MGTaA3IxkFus8VxERERERkeNScPVJMGBcUFTAsxvKaYhE/S5HREREREQkYSm4+qikqICDtWFWbq/2uxQREREREZGEpeDqo9nj8kkOBliyXlcXFhERERERORYFVx9lpoQ4e1SOznMVERERERE5DgVXn11YXMjWfYfZWlHjdykiIiIiIiIJScHVZ/OKCgBYsl5HXUVERERERNqi4OqzYTnpjC/MYlGpznMVERERERFpi4JrAigpLuDV7dUcONLgdykiIiIiIiIJR8E1AZQUFxCJOp7bVOF3KSIiIiIiIglHwTUBTBmWTU5GMos1XFhEREREROQdFFwTQDBgXDC+gGc3VBCORP0uR0REREREJKF0KLia2Xwz22Bmm83stjbWzzGz1WYWNrMPtloXMbM1sceTXVV4b1NSXMCBow2s3FHtdykiItKDtddnx9pc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\n",
"text/plain": [
"<Figure size 1152x288 with 2 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"n = len(history.history['loss'])\n",
"x = list(range(1, n+1))\n",
"\n",
"plt.figure(figsize=(16, 4))\n",
"plt.subplot(121)\n",
"plt.plot(x, history.history['loss'], label='loss')\n",
"plt.plot(x, history.history['val_loss'], label='val_loss')\n",
"plt.xlim(0, n); plt.ylim(0, None); plt.xticks(x); plt.legend()\n",
"plt.subplot(122)\n",
"plt.plot(x, history.history['accuracy'], label='accuracy')\n",
"plt.plot(x, history.history['val_accuracy'], label='val_accuracy')\n",
"plt.xlim(0, n); plt.ylim(0, 1); plt.xticks(x); plt.legend()\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Evaluate"
]
},
{
"cell_type": "code",
"execution_count": 116,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Test loss: 0.026757806539535522\n",
"Test accuracy: 0.9911999702453613\n"
]
}
],
"source": [
"score = model.evaluate(x_test, y_test, verbose=0)\n",
"\n",
"print('Test loss:', score[0])\n",
"print('Test accuracy:', score[1])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Prediction"
]
},
{
"cell_type": "code",
"execution_count": 117,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"1/1 [==============================] - 0s 156ms/step\n"
]
},
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAA3EAAAClCAYAAADyM3ToAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/bCgiHAAAACXBIWXMAAAsTAAALEwEAmpwYAAAd/ElEQVR4nO3deZRU5bnv8d8jkyJGZRDREFCIUUIYhRgFMziGiKBCNLJcGD1B78JojooSTW4iSdSDa5ETo8HLPYcjGg8SAQ1GQ/RyRcOKI3GmUYHFFEFAHGiRK8N7/6jdnX433TV0V9Xe7+7vZ61a7qf27tpPd/8o6+1db73mnBMAAAAAIAwHJN0AAAAAAKB4DOIAAAAAICAM4gAAAAAgIAziAAAAACAgDOIAAAAAICAM4gAAAAAgIC0axJnZ2Wb2lpmtMrOp5WoKSAsyjqwj48gy8o2sI+OtlzV3nTgzayPpbUlnSNoo6UVJ33POrShfe0ByyDiyjowjy8g3so6Mt25tW/C1wyWtcs6tkSQze1DSGElNBsfMWFk8PNucc92SbiIhZLwVcM5Z0j0kqKSMk+8g8RzOc3jWkXEynmlNvU5pydspj5a0oUG9MboP2bIu6QYSRMaRdWQ8+3gO/yfynU1k/J/IeCvSkitxRTGzSZImVfo8QFLIOLKMfCPryDiyjoxnU0sGcf+Q1LNB/fnoPo9zbpakWRKXcBEcMo6sK5hx8o2A8RyOrCPjrVhL3k75oqQvmtkxZtZe0kWSFpWnLSAVyDiyjowjy8g3so6Mt2LNvhLnnNtjZldJ+oukNpJmO+feLFtnQMLIOLKOjCPLyDeyjoy3bs1eYqBZJ+MSboiWO+dOTLqJUJDx8LTyT6csCfkOEs/hJSDjQSLjJSDj4anEp1MCAAAAAKqMQRwAAAAABIRBHAAAAAAEhEEcAAAAAASk4ot9A0iH66+/3qsPOuggrx4wYIBXjxs3rsnHmjlzplc/++yzXn3//fc3p0UAAAAUgStxAAAAABAQBnEAAAAAEBAGcQAAAAAQEBb7RiEsolmCNGV83rx5Xp1vjltLrV692qtPP/10r16/fn3Fzt1SLPZdvDTlu5qOO+44r165cqVXX3PNNV7929/+tuI9lYDn8BKEnPGDDz7Yq++444767SuuuMLbt3z5cq8eP368V69bt67M3VUUGS9ByBlvrVjsGwAAAAAygEEcAAAAAASEJQaAjGjp2yfjbxH7y1/+Ur997LHHevtGjx7t1X369PHqCRMmePVtt91WUi9AmgwePNir9+3b59UbN26sZjtAo3r06OHVP/jBD+q345kdOnSoV59zzjlefffdd5e5O6CwIUOGePXChQu9unfv3lXr5cwzz/Tqmpoar96wYUPVemkKV+IAAAAAICAM4gAAAAAgIAziAAAAACAgzIkDAnXiif4nKp933nl5j3/zzTe9+txzz/Xqbdu2eXVtbW39dvv27b19zz33nFcPHDjQq7t06ZK3FyAkgwYN8upPPvnEqx9++OEqdgPkdOvWzavnzJmTUCdAeZx11lle3aFDh4Q62X/u/2WXXebVF110UTXbaRRX4gAAAAAgIAziAAAAACAgDOIAAAAAICCZmRMXXxOr4fookvTuu+969a5du7z6gQce8OrNmzd79apVq1raIlBW8TWBzMyr43Pg4u8137RpU9Hnuu6667y6X79+eY9/7LHHin5sIG369+/v1VdddZVX33///dVsB5AkXX311V49duxYrx4+fHizH/vUU0/16gMO8P/G/+qrr3r1M8880+xzAXXatvWHIaNGjUqok/0tX77cq6+99lqvPvjgg706Ple6GrgSBwAAAAABYRAHAAAAAAFhEAcAAAAAAcnMnLjp06d7de/evUv6+iuuuMKrd+zY4dXx+UXVtHHjRq+Of68vvfRSNdtBSjz66KNe3bdvX6+OZ3j79u3NPld8PZR27do1+7GAtDv++OO9Oj73Yd68edVsB5Ak/frXv/bqffv2le2xzz///Lz1unXrvPrCCy/06vj8IaAY3/zmN736a1/7mlfHX+9W0+GHH+7V8c8C6Nixo1czJw4AAAAAkBeDOAAAAAAICIM4AAAAAAhIZubExdeFGzBggFfX1NR49QknnODVQ4YM8epvfOMbXn3SSSd59YYNG+q3e/bsWVKve/bs8eqtW7d6dXz9r7j169d7NXPiIO0/Z6GlpkyZUr993HHH5T32+eefz1sDIbnhhhu8Ov5vi+dcVMPjjz/u1fG121ri/fff9+ra2lqv7tWrl1cfc8wxXv3CCy94dZs2bcrWG7Irvgbn3LlzvXr16tVefeutt1a8p6aMGTMmsXMXiytxAAAAABAQBnEAAAAAEJCCgzgzm21mW8zsjQb3dTazJ83snei/h+d7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\n",
"text/plain": [
"<Figure size 1152x144 with 5 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"x, y = x_test[:5], y_test[:5]\n",
"\n",
"y_pred = model.predict(x)\n",
"\n",
"c_pred = np.argmax(y_pred, axis=-1)\n",
"\n",
"plt.figure(figsize=(16, 2))\n",
"for i, c in enumerate(c_pred):\n",
" plt.subplot(151+i)\n",
" plt.imshow(x[i,:,:,0], cmap='gray')\n",
" plt.title('conf %.2f, class %i' % (y_pred[i,c], c), y=-0.4)\n",
"plt.show()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Advanced Training Loop"
]
},
{
"cell_type": "code",
"execution_count": 118,
"metadata": {},
"outputs": [],
"source": [
"from keras.layers import Input, Dense, Conv2D, MaxPooling2D, Dropout, BatchNormalization, Flatten, Activation\n",
"from keras.models import Model\n",
"\n",
"x = x_in = Input(input_shape)\n",
"x = Conv2D(32, kernel_size=(3, 3))(x)\n",
"x = Activation('relu')(x)\n",
"x = Conv2D(64, (3, 3))(x)\n",
"x = Activation('relu')(x)\n",
"x = MaxPooling2D(pool_size=(2, 2))(x)\n",
"x = Dropout(0.25)(x)\n",
"x = Flatten()(x)\n",
"x = Dense(128)(x)\n",
"x = Activation('relu')(x)\n",
"x = Dropout(0.5)(x)\n",
"x = Dense(num_classes)(x)\n",
"x = Activation('softmax')(x)\n",
"\n",
"model = Model(x_in, x)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"TensorFlow 2.x Eager API\n",
"- TensorFlow 1.x was the compiler approach. The model has to be defined and compiled as computation graph before training. This was not always intuitive and often difficult to debug.\n",
"- Eager Execution is the just-in-time compiler approach, as in PyTorch. Variables intuitively evaluate to their values, as they do in NumPy.\n",
"- Graph execution is often faster and more optimized."
]
},
{
"cell_type": "code",
"execution_count": 119,
"metadata": {},
"outputs": [
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"total: 0%| | 0/10 [00:00<?, ?it/s]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"epoch 1/10\n"
]
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"training: 0%| | 0/468 [00:00<?, ?it/s]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"validation: 0%| | 0/78 [00:00<?, ?it/s]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"loss 0.41495 accuracy 0.92632 val_loss 0.09675 val_accuracy 0.98237 \n",
"0.2 minutes/epoch 41.21 iter/sec\n",
"\n",
"epoch 2/10\n"
]
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"training: 0%| | 0/468 [00:00<?, ?it/s]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"validation: 0%| | 0/78 [00:00<?, ?it/s]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"loss 0.15423 accuracy 0.97434 val_loss 0.06839 val_accuracy 0.98738 \n",
"0.2 minutes/epoch 47.82 iter/sec\n",
"\n",
"epoch 3/10\n"
]
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"training: 0%| | 0/468 [00:00<?, ?it/s]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"validation: 0%| | 0/78 [00:00<?, ?it/s]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"loss 0.11541 accuracy 0.98102 val_loss 0.06802 val_accuracy 0.98798 \n",
"0.2 minutes/epoch 47.93 iter/sec\n",
"\n",
"epoch 4/10\n"
]
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"training: 0%| | 0/468 [00:00<?, ?it/s]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"validation: 0%| | 0/78 [00:00<?, ?it/s]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"loss 0.09661 accuracy 0.98381 val_loss 0.05533 val_accuracy 0.99038 \n",
"0.2 minutes/epoch 48.19 iter/sec\n",
"\n",
"epoch 5/10\n"
]
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"training: 0%| | 0/468 [00:00<?, ?it/s]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"validation: 0%| | 0/78 [00:00<?, ?it/s]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"loss 0.08086 accuracy 0.98656 val_loss 0.05228 val_accuracy 0.99008 \n",
"0.2 minutes/epoch 48.34 iter/sec\n",
"\n",
"epoch 6/10\n"
]
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"training: 0%| | 0/468 [00:00<?, ?it/s]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"validation: 0%| | 0/78 [00:00<?, ?it/s]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"loss 0.07205 accuracy 0.98753 val_loss 0.05336 val_accuracy 0.99099 \n",
"0.2 minutes/epoch 48.34 iter/sec\n",
"\n",
"epoch 7/10\n"
]
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"training: 0%| | 0/468 [00:00<?, ?it/s]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"validation: 0%| | 0/78 [00:00<?, ?it/s]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"loss 0.06375 accuracy 0.98933 val_loss 0.04448 val_accuracy 0.99209 \n",
"0.2 minutes/epoch 48.41 iter/sec\n",
"\n",
"epoch 8/10\n"
]
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"training: 0%| | 0/468 [00:00<?, ?it/s]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"validation: 0%| | 0/78 [00:00<?, ?it/s]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"loss 0.05746 accuracy 0.99008 val_loss 0.04860 val_accuracy 0.99189 \n",
"0.2 minutes/epoch 48.42 iter/sec\n",
"\n",
"epoch 9/10\n"
]
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"training: 0%| | 0/468 [00:00<?, ?it/s]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"validation: 0%| | 0/78 [00:00<?, ?it/s]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"loss 0.05362 accuracy 0.99092 val_loss 0.04444 val_accuracy 0.99269 \n",
"0.2 minutes/epoch 48.30 iter/sec\n",
"\n",
"epoch 10/10\n"
]
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"training: 0%| | 0/468 [00:00<?, ?it/s]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"validation: 0%| | 0/78 [00:00<?, ?it/s]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"loss 0.04605 accuracy 0.99197 val_loss 0.06555 val_accuracy 0.99139 \n",
"0.2 minutes/epoch 50.80 iter/sec\n"
]
}
],
"source": [
"from tensorflow.keras.optimizers import SGD, Adam\n",
"from keras.metrics import Mean\n",
"from tensorflow.keras import backend as K\n",
"\n",
"\n",
"def generator(x, y, batch_size):\n",
" # loads the data batchwise\n",
" num_batches = x.shape[0] // batch_size\n",
" num_samples = num_batches * batch_size\n",
" \n",
" indices = np.arange(num_samples)\n",
" \n",
" while True:\n",
" for i in range(num_batches):\n",
" idxs = indices[i*batch_size:(i+1)*batch_size]\n",
" batch = tf.convert_to_tensor(x[idxs], dtype='float32'), tf.convert_to_tensor(y[idxs], dtype='float32')\n",
" yield batch\n",
" np.random.shuffle(indices) # randomize sample order\n",
"\n",
"\n",
"@tf.function # indicates TensorFlow to compile the function as graph\n",
"def calc_metrics(y_true, y_pred):\n",
" # shape y: (batch_size, num_classes)\n",
" \n",
" eps = K.epsilon()\n",
" input_shape = K.shape(y_true)\n",
" num_samples = input_shape[0]\n",
" \n",
" # categorical crossentropy loss for classification\n",
" y_pred = K.clip(y_pred, eps, 1-eps)\n",
" loss = - y_true*K.log(y_pred) - (1-y_true)*K.log(1-y_pred)\n",
" loss = K.sum(loss, axis=-1)\n",
" # equivalent to\n",
" #loss = categorical_crossentropy(y_true, y_pred)\n",
" \n",
" loss = tf.reduce_mean(loss)\n",
" \n",
" # true and predicted class\n",
" c_true = tf.reshape(tf.argmax(y_true, axis=-1), shape=(-1,))\n",
" c_pred = tf.reshape(tf.argmax(y_pred, axis=-1), shape=(-1,))\n",
" \n",
" # count correct classifications\n",
" TP = tf.reduce_sum(tf.cast(tf.equal(c_true, c_pred), 'float32'))\n",
" \n",
" accuracy = TP / tf.cast(num_samples, 'float32')\n",
" \n",
" return eval('{'+' '.join(['\"'+n+'\": '+n+',' for n in metric_names])+'}')\n",
"\n",
"\n",
"batch_size = 128\n",
"epochs = 10\n",
"\n",
"optimizer = Adam(learning_rate=0.001)\n",
"\n",
"steps_per_epoch = x_train.shape[0] // batch_size\n",
"validation_steps = x_test.shape[0] // batch_size\n",
"\n",
"iterator = generator(x_train, y_train, batch_size)\n",
"iterator_val = generator(x_test, y_test, batch_size)\n",
"\n",
"t0 = time.time()\n",
"iteration = 0\n",
"metric_names = ['loss', 'accuracy',]\n",
"history = {n: [] for n in metric_names}\n",
"history.update({'val_'+n: [] for n in metric_names})\n",
"\n",
"# taining loop\n",
"for epoch in tqdm(range(1, epochs+1), 'total', leave=False):\n",
" print('\\nepoch %i/%i' % (epoch, epochs))\n",
" \n",
" t1 = time.time()\n",
" metrics = {n: Mean() for n in metric_names}\n",
" \n",
" for i in tqdm(range(steps_per_epoch), 'training', leave=False):\n",
" iteration += 1\n",
" \n",
" # training step\n",
" x, y_true = next(iterator)\n",
" #s = slice(i*batch_size, (i+1)*batch_size)\n",
" #x, y_true = x_train[s], y_train[s]\n",
" \n",
" with tf.GradientTape() as tape:\n",
" y_pred = model(x, training=True)\n",
" metric_values = calc_metrics(y_true, y_pred)\n",
" loss = metric_values['loss']\n",
"\n",
" gradients = tape.gradient(loss, model.trainable_variables)\n",
" optimizer.apply_gradients(zip(gradients, model.trainable_variables))\n",
" \n",
" for n, v in metric_values.items():\n",
" metrics[n].update_state(v)\n",
" \n",
" for n, m in metrics.items(): \n",
" history[n].append(float(m.result()))\n",
" \n",
" t2 = time.time()\n",
" metrics = {n: Mean() for n in metric_names}\n",
" \n",
" for i in tqdm(range(validation_steps), 'validation', leave=False):\n",
" # validation step\n",
" x, y_true = next(iterator_val)\n",
" #s = slice(i*batch_size, (i+1)*batch_size)\n",
" #x, y_true = x_test[s], y_test[s]\n",
" \n",
" y_pred = model(x, training=False)\n",
" metric_values = calc_metrics(y_true, y_pred)\n",
" \n",
" for n, v in metric_values.items():\n",
" metrics[n].update_state(v)\n",
" \n",
" for n, m in metrics.items():\n",
" history['val_'+n].append(float(m.result()))\n",
" \n",
" t3 = time.time()\n",
" for n, v in history.items():\n",
" print('%s %5.5f ' % (n, v[-1]), end='')\n",
" print('\\n%.1f minutes/epoch %.2f iter/sec' % ((t3-t1)/60, steps_per_epoch/(t2-t1)))\n",
" \n",
" #model.save_weights('weights_%03i.h5' % (epoch,))\n",
" #pd.DataFrame.from_dict(history).to_csv('history.csv', index=False)"
]
},
{
"cell_type": "code",
"execution_count": 120,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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mXH22Wfz3//93+zatYvbb7+dTZs2AfCb3/yGfv36ceWVV7JixQoAfvrTn3Lo0CEeeOABLrnkEsaPH88bb7zB9ddfz4gRI3jooYeoqamhZ8+ePPXUUxQWFnLo0CHuuusuSktLMTO++93vcuDAAZYtW8YvfvELAH73u9+xatUqfv7zn5/qt3tCCq4JEAoZl48qZPbSbVTXRUhPCQddkohIwlx77bX8y7/8S0MH/Nxzz/HSSy9x9913k5uby549e7jgggu46qqrMLO4z/vII49gZixfvpw1a9Ywbdo01q1bx29/+1vuuecebrjhBmpqaohEIrz44ov069ePv/3tbwAcOHCgTT6riIjI6Upkv5mRkcELL7xw3HGrVq3ioYceYuHChfTq1Yt9+/YBcPfddzNlyhReeOEFIpEIhw4doqKi4oQ/o6amhtLSUgAqKipYtGgRZsbvf/97fvzjH/Pv//7vfP/73ycvL4/ly5c3tEtNTeUHP/gBP/nJT0hNTeXxxx/n0UcfPd2vr0UKrgkyraiQP729hYUb93LpWb2DLkdEOquT/CtvW5gwYQK7d+9m+/btlJeXk5+fT58+ffjKV77CggULCIVCbNu2jV27dtGnT5+4z/vGG29w1113ATBy5EgGDx7MunXrmDRpEj/4wQ8oKyvjE5/4BMOHD2fs2LF87Wtf45vf/CZXXnklF198cVt9XBER6SwC6DMhsf2mc45//dd/Pe64uXPncs0119CrVy8AevToAcDcuXN58sknAQiHw+Tl5Z00uMaOYCorK+Paa69lx44d1NTUMHToUABeeeUVnnnmmYZ2+fn5AFx22WX89a9/ZdSoUdTW1jJ27NhWflvx0z2uCTJpWE+y08K8vFKzC4tI53PNNdcwa9Ysnn32Wa699lqeeuopysvLWbJkCUuXLqWwsJCqqqqE/KzPfOYzzJ49m8zMTD7ykY8wd+5cRowYwTvvvMPYsWO5//77efDBBxPys0RERNpCovrNRPS3KSkpRKPRhvWmx2dnZzcs33XXXdx5550sX76cRx999KQ/69Zbb+WJJ57g8ccf5+abb25VXa2l4JogGalhppxVwCurdxGNuqDLERFJqGuvvZZnnnmGWbNmcc0113DgwAF69+5Namoq8+bN44MPPmj1OS+++GKeeuopANatW8eWLVs466yz2LRpE2eccQZ33303M2bM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\n",
"text/plain": [
"<Figure size 1152x288 with 2 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"n = len(history['loss'])\n",
"x = list(range(1, n+1))\n",
"\n",
"plt.figure(figsize=(16, 4))\n",
"plt.subplot(121)\n",
"plt.plot(x, history['loss'], label='loss')\n",
"plt.plot(x, history['val_loss'], label='val_loss')\n",
"plt.xlim(0, n); plt.ylim(0, None); plt.xticks(x); plt.legend()\n",
"plt.subplot(122)\n",
"plt.plot(x, history['accuracy'], label='accuracy')\n",
"plt.plot(x, history['val_accuracy'], label='val_accuracy')\n",
"plt.xlim(0, n); plt.ylim(0, 1); plt.xticks(x); plt.legend()\n",
"plt.show()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.10"
},
"toc": {
"base_numbering": 1,
"nav_menu": {},
"number_sections": true,
"sideBar": true,
"skip_h1_title": false,
"title_cell": "Table of Contents",
"title_sidebar": "Contents",
"toc_cell": false,
"toc_position": {
"height": "calc(100% - 180px)",
"left": "10px",
"top": "150px",
"width": "336px"
},
"toc_section_display": true,
"toc_window_display": true
},
"varInspector": {
"cols": {
"lenName": 16,
"lenType": 16,
"lenVar": 40
},
"kernels_config": {
"python": {
"delete_cmd_postfix": "",
"delete_cmd_prefix": "del ",
"library": "var_list.py",
"varRefreshCmd": "print(var_dic_list())"
},
"r": {
"delete_cmd_postfix": ") ",
"delete_cmd_prefix": "rm(",
"library": "var_list.r",
"varRefreshCmd": "cat(var_dic_list()) "
}
},
"types_to_exclude": [
"module",
"function",
"builtin_function_or_method",
"instance",
"_Feature"
],
"window_display": false
}
},
"nbformat": 4,
"nbformat_minor": 4
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment