number-plate-study/test-viva.ipynb

456 lines
345 KiB
Plaintext
Raw Permalink Normal View History

2024-11-28 18:44:43 +01:00
{
"cells": [
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [],
"source": [
"import os\n",
"import torch\n",
"import torch.nn as nn\n",
"import torch.optim as optim\n",
"from torch.utils.data import DataLoader, Dataset\n",
"from torchvision import transforms\n",
"from PIL import Image\n",
"\n",
"DATASET_DIR = \"dataset\"\n",
"SAVE_PATH = \"best_model_2.pth\"\n",
"BATCH_SIZE = 32\n",
"EPOCHS = 10\n",
"LEARNING_RATE = 0.001\n",
"DEVICE = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n",
"\n",
"CLASSES = \"ABEKMHOPCTYX0123456789\"\n",
"NUM_CLASSES = len(CLASSES)\n",
"CLASS_TO_IDX = {char: idx for idx, char in enumerate(CLASSES)}\n",
"IDX_TO_CLASS = {idx: char for char, idx in CLASS_TO_IDX.items()}"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Weights loaded successfully from best_model_2.pth\n",
"Model set to evaluation mode\n"
]
}
],
"source": [
"import torch\n",
"import torch.nn as nn\n",
"import torch.nn.functional as F\n",
"\n",
"# Определение модели\n",
"class SimpleCNN(nn.Module):\n",
" def __init__(self, num_classes):\n",
" super(SimpleCNN, self).__init__()\n",
" self.conv_layers = nn.Sequential(\n",
" nn.Conv2d(1, 32, kernel_size=3, padding=1), # Увеличиваем количество фильтров\n",
" nn.LeakyReLU(negative_slope=0.1), # Используем LeakyReLU вместо ReLU\n",
" nn.BatchNorm2d(32), # Нормализация\n",
" nn.MaxPool2d(kernel_size=2, stride=2),\n",
" \n",
" nn.Conv2d(32, 64, kernel_size=3, padding=1),\n",
" nn.ELU(), # Используем ELU вместо ReLU\n",
" nn.BatchNorm2d(64),\n",
" nn.MaxPool2d(kernel_size=2, stride=2),\n",
" \n",
" nn.Conv2d(64, 128, kernel_size=3, padding=1),\n",
" nn.SiLU(), # Используем SiLU (Swish) вместо ReLU\n",
" nn.BatchNorm2d(128),\n",
" nn.MaxPool2d(kernel_size=2, stride=2)\n",
" )\n",
" self.fc_layers = nn.Sequential(\n",
" nn.Linear(128 * 3 * 3, 256),\n",
" nn.GELU(), # Используем GELU для полносвязного слоя\n",
" nn.Dropout(0.5),\n",
" nn.Linear(256, num_classes)\n",
" )\n",
"\n",
" def forward(self, x):\n",
" x = self.conv_layers(x)\n",
" x = x.view(x.size(0), -1)\n",
" x = self.fc_layers(x)\n",
" return x\n",
"\n",
"# Создание модели и загрузка весов\n",
"model = SimpleCNN(len(CLASSES)).to(DEVICE)\n",
"\n",
"# Загрузка весов модели\n",
"model.load_state_dict(torch.load(\"best_model_2.pth\", map_location=DEVICE))\n",
"print(\"Weights loaded successfully from best_model_2.pth\")\n",
"\n",
"# Перевод модели в режим оценки\n",
"model.eval()\n",
"print(\"Model set to evaluation mode\")\n"
]
},
{
"cell_type": "code",
"execution_count": 26,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAABKUAAAGZCAYAAABYPYI6AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8hTgPZAAAACXBIWXMAAA9hAAAPYQGoP6dpAAEAAElEQVR4nOy9eZxsVXnu/1b36T6HSTCE0YExIkgABxwTAQdQME7BCERFEocrBjWJ88AQFRONCqIYR1RE41WM5JoYnDDxOpJEjYr4Mwo4EAcIEuHA6T7d+/fHuU/1U0+/a+1dw6lzkOf7+dSnqnbtvfYa3vVOe+1dvaZpmjDGGGOMMcYYY4wxZorMbOkKGGOMMcYYY4wxxpjbH05KGWOMMcYYY4wxxpip46SUMcYYY4wxxhhjjJk6TkoZY4wxxhhjjDHGmKnjpJQxxhhjjDHGGGOMmTpOShljjDHGGGOMMcaYqeOklDHGGGOMMcYYY4yZOk5KGWOMMcYYY4wxxpip46SUMcYYY4wxxhhjjJk6TkoZY4wxZqtg7733jqc+9albuhpDc+aZZ0av14vrrrtuYmUeeeSRceSRR06krJ/97Gdx/PHHx8477xy9Xi/OOeeciZS7pen1enHmmWdu6WoYY4wxZgyclDLGGGM2E+95z3ui1+sVX1/+8peHKu/aa6+NM888M77+9a9vngp34B//8R+3eCLgpptuijPOOCMOPvjg2G677WLnnXeOww47LJ773OfGtddeu0XrtjXyp3/6p3HppZfGS17ykrjwwgvjEY94xJauUpGrr756YI7Mzs7GXe9613jc4x43Mbm/4oor4swzz4yrr756IuUZY4wxZnTWbOkKGGOMMb/u/MVf/EXss88+q7bvv//+Q5Vz7bXXxllnnRV77713HHbYYROq3XD84z/+Y7zlLW/ZYompxcXFePCDHxxXXnllnHzyyXHaaafFTTfdFN/+9rfjAx/4QDzucY+LPffcc4vUbWvls5/9bDzmMY+J5z//+Vu6Kp058cQT49hjj42lpaX4zne+E29961vjE5/4RHz5y18eW/avuOKKOOuss+LII4+MvffeeyL1NcYYY8xoOClljDHGbGYe+chHxn3uc5+pn3f9+vWx7bbbTv28m5OPfexj8bWvfS0uuuiiOOmkkwZ+u/XWW2NhYWEL1Wzr5ec//3nstNNOrfvdfPPNsd12223+CnXgXve6VzzpSU/qf3/Qgx4Uj370o+Otb31rvO1tb9uCNTPGGGPMJPHte8YYY8wW5owzzoiZmZn4zGc+M7D9Gc94RszPz8c3vvGN+NznPheHH354RESccsop/dub3vOe90TEpmcQHXzwwfFv//Zv8eAHPzi23XbbeOlLXxoREZdcckkcd9xxseeee8batWtjv/32i1e+8pWxtLS0qi5f+cpX4thjj4073vGOsd1228UhhxwS5557bkREPPWpT423vOUtEREDt1iB5eXlOOecc+Ie97hHrFu3Lnbbbbd45jOfGTfccMPAOZqmiVe96lVx5zvfObbddts46qij4tvf/nanvvr+978fEZuSFMq6deviDne4Q0REXHDBBdHr9eJrX/vaqv3OPvvsmJ2djZ/85CcDffcf//EfccQRR8S2224b+++/f3zkIx+JiIh//ud/jvvd736xzTbbxAEHHBCf/vSn07pdd9118Qd/8AdxhzvcIXbeeed47nOfG7feeuvAPhs3boxXvvKVsd9++8XatWtj7733jpe+9KWxYcOG1rafd955cY973CO23XbbuOMd7xj3uc994gMf+EBxf9w+2jRNvOUtbxkYL/z2z//8z3HqqafGrrvuGne+8537x55//vlxj3vcI9auXRt77rlnPPvZz45f/vKXA+VPqt+68JCHPCQiIq666qriPtdcc02ceuqpccABB8Q222wTO++8czzhCU8YuE3vPe95TzzhCU+IiIijjjqq3yef+9zn+vt84hOfiN/93d+N7bbbLnbYYYc47rjjOsunMcYYY4bDSSljjDFmM3PjjTfGddddN/C6/vrr+7+//OUvj8MOOyz++I//OH71q19FRMSll14a73jHO+L000+PQw89NA488MD4i7/4i4jYlKy68MIL48ILL4wHP/jB/XKuv/76eOQjHxmHHXZYnHPOOXHUUUdFxKZAfPvtt48/+7M/i3PPPTfufe97x+mnnx4vfvGLB+r5qU99Kh784AfHFVdcEc997nPj9a9/fRx11FHx8Y9/PCIinvnMZ8bDH/7wiIj++S+88ML+8c985jPjBS94QTzoQQ+Kc889N0455ZS46KKL4phjjonFxcX+fqeffnq84hWviEMPPTRe97rXxb777htHH3103Hzzza19uddee0VExPve975omqa43/HHHx/bbLNNXHTRRat+u+iii+LII4+MO93pTv1tN9xwQzzqUY+K+93vfvHa17421q5dGyeccEJ86EMfihNOOCGOPfbY+Mu//Mu4+eab4/jjj++PE/MHf/AHceutt8ZrXvOaOPbYY+NNb3pTPOMZzxjY52lPe1qcfvrpca973Sve+MY3xhFHHBGvec1r4oQTTqi2+x3veEc85znPiYMOOijOOeecOOuss+Kwww6Lr3zlK8VjHvzgB/fH5+EPf/iq8YqIOPXUU+OKK64YkIczzzwznv3sZ8eee+4Zr3/96+P3f//3421ve1scffTRA+M4qX7rApKRO++8c3Gfyy+/PL74xS/GCSecEG9605vif/2v/xWf+cxn4sgjj4z169f3++Q5z3lORES89KUv7ffJgQceGBGb5Pq4446L7bffPv7qr/4qXvGKV8QVV1wRv/M7v+NnUBljjDGbg8YYY4wxm4ULLrigiYj0tXbt2oF9v/nNbzbz8/PN0572tOaGG25o7nSnOzX3uc99msXFxf4+l19+eRMRzQUXXLDqXEcccUQTEc3f/M3frPpt/fr1q7Y985nPbLbddtvm1ltvbZqmaTZu3Njss88+zV577dXccMMNA/suLy/3Pz/72c9uMvfh85//fBMRzUUXXTSw/Z/+6Z8Gtv/85z9v5ufnm+OOO26g3Je+9KVNRDQnn3zyqrK1LQcccEATEc1ee+3VPPWpT23e9a53NT/72c9W7XviiSc2e+65Z7O0tNTf9u///u+r+hB994EPfKC/7corr2wiopmZmWm+/OUv97dfeumlq44/44wzmohoHv3oRw+c/9RTT20iovnGN77RNE3TfP3rX28ionna0542sN/zn//8JiKaz372swN1OuKII/rfH/OYxzT3uMc9qn1TIiKaZz/72QPbIJu/8zu/02zcuLG/HeNz9NFHD/Tbm9/85iYimne/+90DdRyn3zKuuuqqJiKas846q/nFL37R/PSnP20+97nPNfe85z2biGguvvjigXadccYZ/e+ZnH/pS19qIqJ53/ve19/24Q9/uImI5rLLLhvY91e/+lWz0047NU9/+tMHtv/0pz9tdtxxx1XbjTHGGDM+XilljDHGbGbe8pa3xKc+9amB1yc+8YmBfQ4++OA466yz4p3vfGccc8wxcd1118V73/veWLOm++Mf165dG6eccsqq7dtss03/869+9au47rrr4nd/93dj/fr1ceWVV0ZExNe+9rW46qqr4nnPe96q5w/xLXolPvzhD8eOO+4YD3/4wwdWhN373veO7bffPi677LKIiPj0pz8dCwsLcdpppw2U+7znPa9TG7fZZpv4yle+Ei94wQsiYtMqsD/+4z+OPfbYI0477bSB2+Ce8pSnxLXXXts/d8SmVVLbbLNN/P7v//5Audtvv/3AaqUDDjggdtpppzjwwAPjfve7X387Pv/gBz9YVbdnP/vZA99PO+20iNj0cHh+/7M/+7OB/f78z/88IiL+4R/+odjunXbaKX784x/H5ZdfXtxnFJ7+9KfH7Oxs/zvG53nPe17MzMwM7HeHO9xhVR0n0W8ZZ5xxRuyyyy6x++67x5FHHhnf//7346/+6q/i8Y9/fPEYlvPFxcW4/vrrY//994+ddtop/v3f/731nJ/61Kfil7/8ZZx44okDMjw7Oxv3u9/9BuT
"text/plain": [
"<Figure size 1200x600 with 8 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"import cv2\n",
"import numpy as np\n",
"import matplotlib.pyplot as plt\n",
"\n",
"# Загрузка изображения в чёрно-белом формате\n",
"rotated = cv2.imread(\"img/plate-viva.jpg\", cv2.IMREAD_GRAYSCALE)\n",
"\n",
"# Увеличиваем изображение для лучшей обработки\n",
"resized = cv2.resize(rotated, None, fx=4, fy=4, interpolation=cv2.INTER_CUBIC)\n",
"img_conf = cv2.GaussianBlur(resized, (3, 3), 0)\n",
"\n",
"# Настройки вырезания\n",
"start_x = 25 # начальная координата X\n",
"start_y = 25 # начальная координата Y\n",
"symbol_width = 55 # базовая ширина символа\n",
"symbol_height = 110 # высота символа\n",
"spacing = 0 # промежуток между символами\n",
"\n",
"# Настройки для регулировки ширины и высоты\n",
"left_adjustment = 4 # Сдвиг с левой стороны (уменьшение ширины: отрицательное, увеличение: положительное)\n",
"right_adjustment = 4 # Сдвиг с правой стороны (уменьшение ширины: отрицательное, увеличение: положительное)\n",
"top_adjustment = 10 # Сдвиг сверху (уменьшение высоты: отрицательное, увеличение: положительное)\n",
"bottom_adjustment = -30 # Сдвиг снизу (уменьшение высоты: отрицательное, увеличение: положительное)\n",
"\n",
"# Последовательность символов на номерном знаке: 1 буква, 3 цифры, 2 буквы, 2 цифры\n",
"symbol_sequence = ['буква', 'цифра', 'цифра', 'цифра', 'буква', 'буква', 'цифра', 'цифра']\n",
"\n",
"# Список для сохранения вырезанных символов\n",
"chars1 = []\n",
"\n",
"# Вырезаем каждый символ\n",
"for i, symbol_type in enumerate(symbol_sequence):\n",
" # Координаты текущего символа с учетом регулировки ширины и высоты\n",
" crop_start_x = start_x + i * (symbol_width + spacing) + left_adjustment\n",
" crop_end_x = start_x + i * (symbol_width + spacing) + symbol_width + right_adjustment\n",
"\n",
" # Если это последние 2 цифры, поднимаем их выше\n",
" if i >= len(symbol_sequence) - 2: # Последние два символа\n",
" crop_start_y = start_y + top_adjustment - 11 # Поднимаем символ выше на 10 пикселей\n",
" crop_end_y = start_y + symbol_height + bottom_adjustment - 11\n",
" crop_start_x -=5\n",
" crop_end_x -=5\n",
" else:\n",
" crop_start_y = start_y + top_adjustment\n",
" crop_end_y = start_y + symbol_height + bottom_adjustment\n",
"\n",
" # Проверяем, что координаты в пределах изображения\n",
" crop_start_x = max(0, crop_start_x)\n",
" crop_end_x = min(img_conf.shape[1], crop_end_x)\n",
" crop_start_y = max(0, crop_start_y)\n",
" crop_end_y = min(img_conf.shape[0], crop_end_y)\n",
"\n",
" # Вырезаем символ\n",
" crop = img_conf[crop_start_y:crop_end_y, crop_start_x:crop_end_x]\n",
"\n",
" # Добавляем символ в список\n",
" chars1.append(crop)\n",
"\n",
"# Отображаем все символы с помощью matplotlib\n",
"plt.figure(figsize=(12, 6))\n",
"for i, char in enumerate(chars1):\n",
" plt.subplot(1, len(chars1), i + 1) # Создаем сетку для отображения символов\n",
" plt.imshow(char, cmap='gray')\n",
" plt.title(f\"Symbol {i}\")\n",
" plt.axis('off')\n",
"\n",
"plt.suptitle(\"Extracted Symbols from Plate\")\n",
"plt.tight_layout()\n",
"plt.show()\n",
"\n",
"# Теперь все символы находятся в списке `chars1`\n"
]
},
{
"cell_type": "code",
"execution_count": 37,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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",
"text/plain": [
"<Figure size 1000x200 with 7 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"import cv2\n",
"import matplotlib.pyplot as plt\n",
"\n",
"# Загрузка изображения номерного знака\n",
"image_path = \"img/plate3_original.jpg\" # Замените на путь к вашему изображению\n",
"plate_image = cv2.imread(image_path)\n",
"\n",
"# Преобразование в оттенки серого\n",
"gray = cv2.cvtColor(plate_image, cv2.COLOR_BGR2GRAY)\n",
"\n",
"# Бинаризация изображения\n",
"_, binary = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)\n",
"\n",
"# Определение размеров изображения\n",
"height, width = binary.shape\n",
"\n",
"# Предполагаемые ширины символов (в процентах от ширины изображения)\n",
"symbol_widths = [0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1] # 7 символов\n",
"\n",
"# Предполагаемые отступы между символами (в процентах от ширины изображения)\n",
"symbol_gaps = [0.02, 0.02, 0.02, 0.02, 0.02, 0.02] # 6 промежутков\n",
"\n",
"# Вычисление абсолютных позиций символов\n",
"positions = []\n",
"current_x = 0\n",
"for i in range(len(symbol_widths)):\n",
" symbol_w = int(symbol_widths[i] * width)\n",
" positions.append((current_x, current_x + symbol_w))\n",
" current_x += symbol_w\n",
" if i < len(symbol_gaps):\n",
" current_x += int(symbol_gaps[i] * width)\n",
"\n",
"# Извлечение и отображение каждого символа\n",
"plt.figure(figsize=(10, 2))\n",
"for idx, (start_x, end_x) in enumerate(positions):\n",
" symbol = binary[:, start_x:end_x]\n",
" plt.subplot(1, len(positions), idx + 1)\n",
" plt.imshow(symbol, cmap='gray')\n",
" plt.axis('off')\n",
"plt.show()\n"
]
},
{
"cell_type": "code",
"execution_count": 27,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAtkAAAGGCAYAAACufZ0hAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8hTgPZAAAACXBIWXMAAA9hAAAPYQGoP6dpAABDf0lEQVR4nO3deXwV1f3/8XeALEhIENkrgggWRRZFsdQiqFFA3FpXtEqKRev6a4uI1GpEW8HlUfWLFDcWt2pRqXWhVEWollLBBa1CEWi0oKIiEjbJQs7vDx+55Z4cMifDubkheT0fjzx05s6cOTP3hnsY3p85GcYYIwAAAADBNEl3BwAAAICGhkE2AAAAEBiDbAAAACAwBtkAAABAYAyyAQAAgMAYZAMAAACBMcgGAAAAAmOQDQAAAATGIBsAAAAIjEE2AAAAEBiD7Dq2Zs0aXXrpperWrZtycnKUl5enY445Rvfcc4+++eabdHcvLZYsWaLLL79c/fv3V2ZmpjIyMtLdJQANREZGhtfPwoUL67Rfn376qX784x/ru9/9rlq2bKlWrVppwIABevjhh2WMqdO+AEiNZunuQGPy4osv6uyzz1Z2drYuuugiHXbYYSorK9Pf//53jRs3Th988IEeeOCBdHezzs2dO1cPPfSQ+vTpo27duunDDz9Md5cANBCPPvpo0vIjjzyil19+udr6Qw45pC67pQ0bNmjdunU666yzdMABB6i8vFwvv/yyCgsLtXLlSt1666112h8A4WUY/spcJ4qLi9WnTx/tv//+evXVV9WxY8ek11evXq0XX3xR/+///b809TB9Pv/8c+Xl5al58+a68sorNXXqVO7kAEiJ+v5nzKmnnqoFCxaopKRETZs2TXd3AOwB4iJ15Pbbb9fWrVs1ffr0agNsSerevXvSADsjI0M33XRT0jZ33HGHMjIyNGTIkMS6hQsXJv65c9myZUnbf/LJJ2ratKkyMjL09NNPJ9YXFhYm/TPpvvvuqyFDhuj111+v1q/f//736tWrl7Kzs9WpUyddccUV2rRpU7XtPvroo93+M2yU9u3bq3nz5pHbAUCqffHFF7r44ovVvn175eTkqG/fvnr44YeTtqnpzzv7z+ja6tq1q7Zv366ysrIat7vppptq7MOsWbMS2xYWFio3N1f/+c9/NHToULVo0UKdOnXSzTffXO0vG5WVlbr77rvVq1cv5eTkqH379rr00kv19ddfV+tDTdfho48+Stp206ZN+sUvfqGuXbsqOztb+++/vy666CJt2LBB0v++y3aN7Xz66afq2rWrjjzySG3dulWSVFZWphtvvFH9+/dXfn6+WrRooUGDBmnBggVJx1u5cqWOP/54dejQQdnZ2ercubN+9rOfaePGjYltfNuqOs8777yz2jU47LDDnN/JdvxoxIgRzu/1BQsWaNCgQdp3332Trt+VV15Z7VjY+xAXqSPPP/+8unXrpu9///ux9t+0aZMmTZq029dzcnI0c+ZM3XPPPYl1Dz/8sLKysrRjx45q27dp00Z33XWXJGndunW65557dPLJJ2vt2rVq1aqVpG//EJ84caIKCgp02WWXaeXKlZo2bZqWLl2qRYsWKTMzs1q7l1xyiQYNGiRJmjNnjv70pz/FOl8AqGvffPONhgwZotWrV+vKK6/UgQceqKeeekqFhYXatGlTtX9pHDlypE4++eSkdRMmTKj1Mbdt26atW7fqb3/7m2bOnKmBAwd633iYNm2acnNzE8vFxcW68cYbq223c+dODRs2TN/73vd0++23a968eSoqKlJFRYVuvvnmxHaXXnqpZs2apZ/85Ce6+uqrVVxcrHvvvVfvvPPObv/c3/U6zJ07V0888UTS61u3btWgQYO0YsUKjR49WkcccYQ2bNig5557TuvWrVObNm2qtVlSUqLhw4crMzNTc+fOTZzj5s2b9dBDD2nkyJEaM2aMtmzZounTp2vo0KFasmSJ+vXrJ0natm2b9t9/f5166qnKy8vT+++/r6lTp+qTTz7R888/X6u29tRrr72muXPnVltfXFysESNGqGPHjrrxxhvVtm1bSdKFF14Y5LioBwxSrqSkxEgyp59+uvc+kkxRUVFi+dprrzXt2rUz/fv3N4MHD06sX7BggZFkRo4cafbbbz9TWlqaeK1Hjx7m/PPPN5LMU089lVg/atQo06VLl6TjPfDAA0aSWbJkiTHGmC+++MJkZWWZk046yezcuTOx3b333mskmRkzZiTtv2rVKiPJPPzww4l1RUVFprYfsSuuuKLW+wCAr5r+jLn77ruNJPPYY48l1pWVlZmBAwea3Nxcs3nzZmOMMcXFxUaSueOOO6q10atXr6Q/o6NMmjTJSEr8nHDCCea///1v5H5Vf75++eWXSeuXLl1qJJmZM2cm1o0aNcpIMldddVViXWVlpRkxYoTJyspKtPH6668bSebxxx9PanPevHnO9R9++KGRZO68887EujvuuMNIMsXFxYl1N954o5Fk5syZU+08KisrjTH/+y5bsGCB2bFjhxkyZIhp166dWb16ddL2FRUVSd9zxhjz9ddfm/bt25vRo0fv7nIZY4y5/PLLTW5ubq3bqs37vet5VDn66KPN8OHDq32v33///UaSWbx4cVKbkswVV1xR47lg70BcpA5s3rxZktSyZctY+3/yySeaMmWKbrjhhqQ7Frs69dRTlZGRoeeee06S9Prrr2vdunU699xzndtXVlZqw4YN2rBhg5YtW6ZHHnlEHTt2TBT/vPLKKyorK9PPf/5zNWnyv4/JmDFjlJeXpxdffDGpvap/2szOzo51jgCQbnPnzlWHDh00cuTIxLrMzExdffXViTvNoY0cOVIvv/yy/vCHP+j888+XpJQ9aWrXCEJVJKGsrEyvvPKKJOmpp55Sfn6+TjzxxMT3w4YNG9S/f3/l5uZWi1FU/StpTk5Ojcd95pln1LdvX/3whz+s9podKaysrNRFF12kf/7zn5o7d64OOuigpNebNm2qrKysxLYbN25URUWFjjzySL399tvV2i8pKdHnn3+u+fPn68UXX9Sxxx4bu63t27cnXZcNGzZo586dNZ77nDlztHTpUk2ePLnaa1u2bJEk7bfffjW2gb0Xg+w6kJeXJ+l/v1C1VVRUpE6dOunSSy/d7TaZmZn68Y9/rBkzZkiSZsyYoTPPPDNxbNvatWvVtm1btW3bVocffrjWrFmjZ555JjGI//jjjyVJ3/3ud5P2y8rKUrdu3RKvV6nKae/uLwEAUN99/PHH6tGjR9KNBel/Tx6x/9zzsX79+qQfewDdpUsXFRQUaOTIkXr88cfVrVs3FRQUBB9oN2nSRN26dUtad/DBB0tSIj+9atUqlZSUqF27donvh6qfrVu36osvvkjavypPnZ+fX+Ox16xZo8MOO8yrn9dff71mz56t0tJSbd++3bnNww8/rD59+ignJ0f77bef2rZtqxdffFElJSXVth06dKg6dOiggoICHXLIIfrjH/8Yu62ioqJq1+Xf//73bs9l586d+tWvfqULLrhAffr0qfb6wIEDJUnjxo3TihUrEgN3NBxksutAXl6eOnXqpPfff7/W+65YsUKzZs3SY4895szC7Wr06NE6/PDDtXLlSj311FOJu9ou7du312OPPSbp27/pz5gxQ8OGDdPf//539e7du9b9XL9+vSSpQ4cOtd4XABoqu9B95syZKiws3O32Z511lh588EG99tprGjp0aIp7l6yyslLt2rXT448/7ny9KjNcpWpw3rVr12B9eOONNzRr1izde++9uuSSS7Rs2bKkfyF97LHHVFhYqDPOOEPjxo1Tu3bt1LRpU02aNElr1qyp1t6UKVO0YcMGLV++XJMmTdLPfvazxHdfbdu65JJLdPbZZyetGzNmzG7PZfr06froo4/017/+1fn697//fd1xxx2aOHGiDj30UK/rg70Lg+w6csopp+iBBx7Q4sWLE3979TFhwgT169dvt7GPXfXu3VuHH364zjnnHLVt21bHHXfcbv95MycnRwUFBYnl0047Ta1bt9a9996r+++/X126dJH0bYX2rnc/ysrKVFx
"text/plain": [
"<Figure size 800x400 with 2 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAtYAAAGGCAYAAABfdsasAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8hTgPZAAAACXBIWXMAAA9hAAAPYQGoP6dpAABLAElEQVR4nO3deXhV1fn+/zsMSYCQgDJXBBksigwKQqlFqEYBcWydcCJgEQf02xYRrdWIVsHhUvyABScGR0Sl1oFSEaFaSp3BKhSRogUVFFHmJED27w9/nHKes8he2ezkhPB+XVeu9uyzh3XW2ZLF5n7WygiCIBAAAACAfVIj3Q0AAAAAqgMG1gAAAEAMGFgDAAAAMWBgDQAAAMSAgTUAAAAQAwbWAAAAQAwYWAMAAAAxYGANAAAAxICBNQAAABADBtYAAABADBhYV7KVK1dq+PDhatOmjbKzs5Wbm6vjjjtO999/v7Zv357u5lW60tJSTZs2TaeffrpatmypevXq6aijjtIf/vAHFRUVpbt5AKqZjIwMr58FCxZUaru+/PJLXXTRRfrxj3+s+vXrq0GDBurRo4emT5+uIAgqtS0AoquV7gYcSF555RWdc845ysrK0iWXXKKjjjpKJSUl+vvf/65Ro0bp448/1kMPPZTuZlaqbdu2aciQIfrJT36iyy+/XE2aNNGiRYtUWFioefPm6fXXX1dGRka6mwmgmnj88ceTXj/22GOaO3duyvYjjjiiMpul9evXa82aNTr77LN16KGHaseOHZo7d64KCgq0fPly3XHHHZXaHgDRZAT8VbhSrFq1Sp07d9Yhhxyi119/Xc2bN096/9NPP9Urr7yi//f//l+aWpgeJSUlevfdd/XTn/40afutt96qwsJCzZ07V/n5+WlqHYDqbsSIEXrggQeq7FPh0047TfPnz9fGjRtVs2bNdDcHQAiiIJXkrrvu0pYtW/Too4+mDKolqV27dkmD6oyMDN1yyy1J+9x9993KyMhQ3759E9sWLFiQ+KfLxYsXJ+3/xRdfqGbNmsrIyNBzzz2X2F5QUJD0T54NGzZU37599eabb6a0649//KM6duyorKwstWjRQldddZW+//77lP0+++yzvf6TalkyMzNTBtWSdNZZZ0mSli1bVubxAFCRvv76a1166aVq2rSpsrOz1aVLF02fPj1pn7L+/LN/ZpdX69attW3bNpWUlJS53y233FJmG6ZNm5bYt6CgQDk5OfrPf/6jfv36qV69emrRooVuvfXWlL9glJaWavz48erYsaOys7PVtGlTDR8+XN99911KG8rqh88++yxp3++//16/+c1v1Lp1a2VlZemQQw7RJZdcovXr10v63++2PSM5X375pVq3bq3u3btry5Ytkn54OHPzzTerW7duysvLU7169dS7d2/Nnz8/6XrLly/XCSecoGbNmikrK0stW7bU5Zdfrg0bNiT28T3X7s95zz33pPTBUUcd5fwdbaNFAwcOdP6enz9/vnr37q2GDRsm9d+IESNSroWqiShIJXnppZfUpk0b5yDSx/fff6+xY8fu9f3s7GxNnTpV999/f2Lb9OnTlZmZ6cwqN2rUSPfdd58kac2aNbr//vt1yimnaPXq1WrQoIGkH/6gHjNmjPLz83XFFVdo+fLlmjRpkt555x0tXLhQtWvXTjnvZZddpt69e0uSZs2apT/96U+RPu/atWsT7QSAdNi+fbv69u2rTz/9VCNGjNBhhx2mZ599VgUFBfr+++9T/oVx0KBBOuWUU5K23XDDDeW+5tatW7Vlyxb97W9/09SpU9WrVy/VqVPH6/hJkyYpJycn8XrVqlW6+eabU/bbtWuX+vfvr5/85Ce66667NGfOHBUWFmrnzp269dZbE/sNHz5c06ZN05AhQ3TNNddo1apVmjhxoj744IO9/h7Ysx9mz56tp59+Oun9LVu2qHfv3lq2bJmGDh2qY445RuvXr9eLL76oNWvWOP/c37hxowYMGKDatWtr9uzZic+4adMmPfLIIxo0aJCGDRumzZs369FHH1W/fv309ttvq2vXrpKkrVu36pBDDtFpp52m3NxcffTRR3rggQf0xRdf6KWXXirXufbVG2+8odmzZ6dsX7VqlQYOHKjmzZvr5ptvVuPGjSVJF198cSzXRSUJUOE2btwYSArOOOMM72MkBYWFhYnX1113XdCkSZOgW7duQZ8+fRLb58+fH0gKBg0aFBx88MFBcXFx4r327dsHF1xwQSApePbZZxPbBw8eHLRq1Srpeg899FAgKXj77beDIAiCr7/+OsjMzAxOPvnkYNeuXYn9Jk6cGEgKpkyZknT8ihUrAknB9OnTE9sKCwuDqLdYfn5+kJubG3z33XeRjgcAH1ddddVe/5waP358ICl44oknEttKSkqCXr16BTk5OcGmTZuCIAiCVatWBZKCu+++O+UcHTt2TPozO8zYsWMDSYmfE088Mfjvf/8betzuP2+/+eabpO3vvPNOICmYOnVqYtvgwYMDScHVV1+d2FZaWhoMHDgwyMzMTJzjzTffDCQFTz75ZNI558yZ49z+ySefBJKCe+65J7Ht7rvvDiQFq1atSmy7+eabA0nBrFmzUj5HaWlpEAT/+902f/78oKioKOjbt2/QpEmT4NNPP03af+fOnUm/94IgCL777rugadOmwdChQ/fWXUEQBMGVV14Z5OTklPtc5fm+9/wcu/Xs2TMYMGBAyu/5Bx98MJAULFq0KOmckoKrrrqqzM+CqoMoSCXYtGmTJKl+/fqRjv/iiy80YcIE3XTTTUlPIvZ02mmnKSMjQy+++KIk6c0339SaNWt03nnnOfcvLS3V+vXrtX79ei1evFiPPfaYmjdvnijYee2111RSUqJf//rXqlHjf7fJsGHDlJubq1deeSXpfLv/mTIrKyvSZ9zTHXfcoddee03jxo1LPD0HgMo2e/ZsNWvWTIMGDUpsq127tq655prEE+W4DRo0SHPnztVTTz2lCy64QJIqbMaoPeMFu+MGJSUleu211yRJzz77rPLy8nTSSSclfl+sX79e3bp1U05OTkpEYve/jmZnZ5d53eeff15dunRJRP72ZOODpaWluuSSS/TPf/5Ts2fPVtu2bZPer1mzpjIzMxP7btiwQTt37lT37t31/vvvp5x/48aNWrdunebNm6dXXnlFxx9/fORzbdu2Lalf1q9fr127dpX52WfNmqV33nlH48aNS3lv8+bNkqSDDz64zHOgamNgXQlyc3Ml/e8/mvIqLCxUixYtNHz48L3uU7t2bV100UWaMmWKJGnKlCn65S9/mbi2tXr1ajVu3FiNGzfW0UcfrZUrV+r5559PDNw///xzSdKPf/zjpOMyMzPVpk2bxPu77c5d723g7+uZZ57R73//e1166aW64oor9ulcALAvPv/8c7Vv3z7p4YL0vxlD7J+DPtauXZv0YwfNrVq1Un5+vgYNGqQnn3xSbdq0UX5+fuyD6xo1aqhNmzZJ2w4//HBJSuShV6xYoY0bN6pJkyaJ3xe7f7Zs2aKvv/466fjd+ei8vLwyr71y5UodddRRXu288cYbNXPmTBUXF2vbtm3OfaZPn67OnTsrOztbBx98sBo3bqxXXnlFGzduTNm3X79+atasmfLz83XEEUfomWeeiXyuwsLClH7597//vdfPsmvXLv3ud7/ThRdeqM6dO6e836tXL0nSqFGjtGzZssRgHfsXMtaVIDc3Vy1atNBHH31U7mOXLVumadOm6YknnnBm2fY0dOhQHX300Vq+fLmeffbZxNNrl6ZNm+qJJ56Q9MPf4KdMmaL+/fvr73//uzp16lTudu7ORDdr1qzcx+42d+5cXXLJJRo4cKAmT54c+TwAUFXZ4vWpU6eqoKBgr/ufffbZevjhh/XGG2+oX79+Fdy6ZKWlpWrSpImefPJJ5/u7M8C77R6Qt27dOrY2vPXWW5o2bZomTpyoyy67TIsXL076l9EnnnhCBQUFOvPMMzVq1Cg1adJENWvW1NixY7Vy5cqU802YMEHr16/X0qVLNXbsWF1++eWJ34XlPddll12mc845J2nbsGHD9vpZHn3
"text/plain": [
"<Figure size 800x400 with 2 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 800x400 with 2 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAtUAAAGGCAYAAAC0QX2vAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8hTgPZAAAACXBIWXMAAA9hAAAPYQGoP6dpAABIlklEQVR4nO3deZQU1f3+8WdYZmE2lB0lEBZFEVxQDCqKOgqIWxLFYKKMKG6gvxhFJEYRNYLLSTSCuLFFjEYE/SoQ3IlKSCQaXCJBRVRQUQn7NjMw9fvDQ4f+9IW6UzXTPQzv1zlzjlVzq/p2dUFfi+dzb1YQBIEAAAAARFYv0x0AAAAA9nQMqgEAAICYGFQDAAAAMTGoBgAAAGJiUA0AAADExKAaAAAAiIlBNQAAABATg2oAAAAgJgbVAAAAQEwMqgEAAICYGFSn2dKlS3XZZZepffv2ys3NVVFRkY499ljdd9992rJlS6a7l3EVFRU6+OCDlZWVpXvuuSfT3QFQh2RlZXn9zJs3L639+uqrr/SLX/xCBx54oAoLC9W4cWP16NFDU6dOVRAEae0LgOgaZLoDe5PZs2fr3HPPVU5Oji688EIdcsghKi8v15tvvqnhw4fr3//+tx5++OFMdzOj7r//fn3xxReZ7gaAOuixxx5L2v7jH/+ol156KWX/QQcdlM5uadWqVVqxYoXOOecc/eAHP1BFRYVeeukllZaWasmSJbrjjjvS2h8A0WQF/G9wWixbtkzdunXT/vvvr1dffVWtWrVK+v0nn3yi2bNn6//9v/+XoR5m3rfffqsDDjhA1157rW6++Wbdfffduu666zLdLQB11LBhwzR+/Pha+zT4jDPO0GuvvaZ169apfv36me4OgBDEP9Lkrrvu0saNGzVx4sSUAbUkdezYMWlAnZWVpVtuuSWpzd13362srCz17t07sW/evHmJf7JctGhRUvsvv/xS9evXV1ZWlp5++unE/tLS0qR/6txnn33Uu3dvvfHGGyn9euCBB9SlSxfl5OSodevWGjp0qNauXZvS7rPPPtvlP6X6uuGGG3TggQfqF7/4hfcxAFBTvv32W1188cVq0aKFcnNzdeihh2rq1KlJbXb3d5/9+7qq2rVrp82bN6u8vHy37W655Zbd9mHKlCmJtqWlpSooKNCnn36qPn36KD8/X61bt9att96a8j8XlZWVuvfee9WlSxfl5uaqRYsWuuyyy7RmzZqUPuzuOnz22WdJbdeuXatrrrlG7dq1U05Ojvbff39deOGFWrVqlaT/fa/tHMP56quv1K5dOx155JHauHGjJKm8vFw333yzunfvruLiYuXn56tXr1567bXXkl5vyZIlOumkk9SyZUvl5OSoTZs2uvzyy7V69epEG99z7XifrnjiIYcc4vx+tnGi/v37O7/jX3vtNfXq1Uv77LNP0vUbNmxYymuhdiL+kSbPP/+82rdvr2OOOSbS8WvXrtWYMWN2+fvc3FxNnjxZ9913X2Lf1KlTlZ2dra1bt6a0b9q0qX7/+99LklasWKH77rtPp512mpYvX67GjRtL+v4v6tGjR6ukpERXXHGFlixZogkTJmjhwoWaP3++GjZsmHLeSy+9VL169ZIkzZw5U88884zX+3vrrbc0depUvfnmm1UaiANATdiyZYt69+6tTz75RMOGDdMPf/hDTZ8+XaWlpVq7dm3KvyoOHDhQp512WtK+kSNHVvk1N23apI0bN+qvf/2rJk+erJ49eyovL8/r+AkTJqigoCCxvWzZMt18880p7bZv366+ffvqRz/6ke666y7NnTtXo0aN0rZt23Trrbcm2l122WWaMmWKLrroIl199dVatmyZxo0bp3/961+7/A7Y+TrMmTNHTzzxRNLvN27cqF69emnx4sUaPHiwjjjiCK1atUrPPfecVqxYoaZNm6acc926derXr58aNmyoOXPmJN7j+vXr9eijj2rgwIEaMmSINmzYoIkTJ6pPnz566623dNhhh0mSNm3apP33319nnHGGioqK9MEHH2j8+PH68ssv9fzzz1fpXHG9/vrrmjNnTsr+ZcuWqX///mrVqpVuvvlmNWvWTJJ0wQUXVMvrIk0C1Lh169YFkoKzzjrL+xhJwahRoxLb119/fdC8efOge/fuwQknnJDY/9prrwWSgoEDBwZNmjQJysrKEr/r1KlTcP755weSgunTpyf2Dxo0KGjbtm3S6z388MOBpOCtt94KgiAIvv322yA7Ozs49dRTg+3btyfajRs3LpAUTJo0Ken4jz/+OJAUTJ06NbFv1KhRgc8tVllZGfTo0SMYOHBgEARBsGzZskBScPfdd4ceCwBRDR06dJd/R917772BpGDatGmJfeXl5UHPnj2DgoKCYP369UEQ7P7vqy5duiT9fR1mzJgxgaTEz8knnxx88cUXocft+Lv2u+++S9q/cOHCQFIwefLkxL5BgwYFkoKrrroqsa+ysjLo379/kJ2dnTjHG2+8EUgKHn/88aRzzp0717n/o48+CiQF99xzT2Lf3XffHUgKli1blth38803B5KCmTNnpryPysrKIAj+97322muvBVu3bg169+4dNG/ePPjkk0+S2m/bti3pOy8IgmDNmjVBixYtgsGDB+/qcgVBEARXXnllUFBQUOVzVeXz3vl97HD00UcH/fr1S/mOf+ihhwJJwYIFC5LOKSkYOnTobt8Lag/iH2mwfv16SVJhYWGk47/88kvdf//9uummm5KeQuzsjDPOUFZWlp577jlJ0htvvKEVK1bovPPOc7avrKzUqlWrtGrVKi1atEh//OMf1apVq0SBzssvv6zy8nL98pe/VL16/7tNhgwZoqKiIs2ePTvpfDv+eTInJ6fK72/KlCl6//33deedd1b5WACoCXPmzFHLli01cODAxL6GDRvq6quvTjxJrm4DBw7USy+9pD/96U86//zzJanGZoXaOVKwI2JQXl6ul19+WZI0ffp0FRcX65RTTkl8V6xatUrdu3dXQUFBSixix7+I5ubm7vZ1Z8yYoUMPPVQ//vGPU35n/5WysrJSF154of7+979rzpw56tChQ9Lv69evr+zs7ETb1atXa9u2bTryyCP1zjvvpJx/3bp1+uabb/TKK69o9uzZOv744yOfa/PmzUnXZdWqVdq+fftu3/vMmTO1cOFCjR07NuV3GzZskCQ1adJkt+dA7cagOg2Kiook/e8PTVWNGjVKrVu31mWXXbbLNg0bNtQvfvELTZo0SZI0adIk/fSnP028trV8+XI1a9ZMzZo10+GHH66lS5dqxowZiUH7559/Lkk68MADk47Lzs5W+/btE7/fYUfOeleD/l1Zv369Ro4cqeHDh6tNmzZVOhYAasrnn3+uTp06JT1UkP43M4j9O9DHypUrk37sgLlt27YqKSnRwIED9fjjj6t9+/YqKSmp9oF1vXr11L59+6R9BxxwgCQl8s8ff/yx1q1bp+bNmye+K3b8bNy4Ud9++23S8Tvy0MXFxbt97aVLl+qQQw7x6ueNN96op556SmVlZdq8ebOzzdSpU9WtWzfl5uaqSZMmatasmWbPnq1169altO3Tp49atmypkpISHXTQQfrzn/8c+VyjRo1KuS7/+c9/dvletm/frl//+tf6+c9/rm7duqX8vmfPnpKk4cOHa/HixYmBOvYsZKrToKioSK1bt9YHH3xQ5WMXL16sKVOmaNq0ac782s4GDx6sww8/XEuWLNH06dMTT61dWrRooWnTpkn6/v/eJ02apL59++rNN99U165dq9zPlStXSpJatmxZpePuuecelZeX67zzzkv8Zb5ixQpJ0po1a/TZZ5+pdevWiScIALCnskXqkydPVmlp6S7bn3POOXrkkUf0+uuvq0+fPjXcu2SVlZVq3ry5Hn/8cefvd2R+d9jx93e7du2qrQ//+Mc/NGXKFI0bN06XXnqpFi1alPSvodOmTVNpaanOPvtsDR8+XM2bN1f9+vU1ZswYLV26NOV8999/v1atWqUPP/xQY8aM0eWXX574HqzquS699FKde+65SfuGDBmyy/cyceJEffbZZ3rhhRecvz/mmGN0991
"text/plain": [
"<Figure size 800x400 with 2 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAtYAAAGGCAYAAABfdsasAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8hTgPZAAAACXBIWXMAAA9hAAAPYQGoP6dpAABFUUlEQVR4nO3deXwV1f3/8fcFkpuQhX1VhLJYEEERxSJFUaOguLaK4kZEQQto61cRKV9FtAouj1a/orixqbix1K8CxQXhq1JcqkWrUERECypWBEIIkIRkfn/4y6333EPmZJx7bwiv5+ORx8OZO8uZM0PucfL5nE/E8zxPAAAAAH6SeuluAAAAAFAXMLAGAAAAQsDAGgAAAAgBA2sAAAAgBAysAQAAgBAwsAYAAABCwMAaAAAACAEDawAAACAEDKwBAACAEDCwBgAAAELAwDrF1q9fr6uuukodO3ZUVlaW8vPz1a9fP91///3avXt3upuXFoWFhYpEIgk/Xbt2TXfTANQxtt81tp/ly5entF1ff/21LrnkEv385z9XXl6eGjdurD59+mj27NnyPC+lbQEQXIN0N+BAsmjRIp1//vmKRqO67LLLdPjhh6usrExvvfWWxo4dq08++USPPvpoupuZFtFoVI8//njcukaNGqWpNQDqqieffDJu+YknntCrr76asL5bt26pbJa2bNmiTZs26bzzztMhhxyi8vJyvfrqqyosLNTatWt15513prQ9AIKJePyvcEps2LBBPXv21MEHH6zXX39dbdq0ifv8s88+06JFi/Tb3/42TS1Mn8LCQs2bN087d+5Md1MAHGDGjBmjBx98sNa+FT7zzDO1bNkyFRUVqX79+uluDgAfhIKkyN13362dO3dq+vTpCYNqSercuXPcoDoSiejWW2+N2+aee+5RJBLRgAEDYuuWL18e+9PlqlWr4rb/6quvVL9+fUUiEc2bNy+23gy9aNKkiQYMGKA333wzoV0PPfSQunfvrmg0qrZt22r06NHavn17wnZffPHFPv+k6qqiokI7duxw3h4Aku3f//63rrjiCrVq1UpZWVk64ogjNHv27Lhtqvv9Z/7OrqkOHTpo165dKisrq3a7W2+9tdo2zJo1K7ZtYWGhcnNz9fnnn2vgwIHKyclR27ZtddtttyX8D0ZlZaXuu+8+de/eXVlZWWrVqpWuuuoqbdu2LaEN1fXDF198Ebft9u3bdd1116lDhw6KRqM6+OCDddlll2nLli2S/vPd9uOQnK+//lodOnTQ0UcfHXsRU1ZWpltuuUW9e/dWo0aNlJOTo/79+2vZsmVx51u7dq1OOukktW7dWtFoVO3atdPVV1+trVu3xrZxPVbVdd57770JfXD44Ydbv6PN0KLBgwdbv+eXLVum/v37q0mTJnH9N2bMmIRzoXYiFCRFXnrpJXXs2FHHHXdcoP23b9+uyZMn7/PzrKwszZw5U/fff39s3ezZs5WZmak9e/YkbN+8eXP96U9/kiRt2rRJ999/v04//XRt3LhRjRs3lvTDL+pJkyapoKBAv/nNb7R27VpNmzZN7733nlasWKGMjIyE444cOVL9+/eXJC1YsEB//vOfna5v165dys/P165du9SkSRMNHTpUd911l3Jzc532B4Cw7d69WwMGDNBnn32mMWPG6Gc/+5nmzp2rwsJCbd++PeEvjEOHDtXpp58et278+PE1PmdJSYl27typ//u//9PMmTPVt29fZWdnO+0/bdq0uN+bGzZs0C233JKwXUVFhQYNGqRf/OIXuvvuu7VkyRJNnDhRe/fu1W233Rbb7qqrrtKsWbN0+eWX69prr9WGDRs0depU/f3vf9/n98CP+2Hx4sV65pln4j7fuXOn+vfvrzVr1mj48OE66qijtGXLFr344ovatGmTmjdvnnDMoqIinXbaacrIyNDixYtj17hjxw49/vjjGjp0qEaMGKHi4mJNnz5dAwcO1LvvvqsjjzxSklRSUqKDDz5YZ555pvLz8/Xxxx/rwQcf1FdffaWXXnqpRsf6qd544w0tXrw4Yf2GDRs0ePBgtWnTRrfccotatGghSbr00ktDOS9SxEPSFRUVeZK8s88+23kfSd7EiRNjyzfeeKPXsmVLr3fv3t4JJ5wQW79s2TJPkjd06FCvWbNmXmlpaeyzLl26eBdddJEnyZs7d25s/bBhw7z27dvHne/RRx/1JHnvvvuu53me9+9//9vLzMz0Tj31VK+ioiK23dSpUz1J3owZM+L2X7dunSfJmz17dmzdxIkTPZdH7KabbvLGjRvnPffcc94zzzzjDRs2zJPk9evXzysvL/fdHwCCGj169D5/T913332eJO+pp56KrSsrK/P69u3r5ebmejt27PA8z/M2bNjgSfLuueeehGN079497ne2n8mTJ3uSYj8nn3yy969//ct3v6rft999913c+vfee8+T5M2cOTO2rup37DXXXBNbV1lZ6Q0ePNjLzMyMHePNN9/0JHlz5syJO+aSJUus6z/99FNPknfvvffG1t1zzz2eJG/Dhg2xdbfccosnyVuwYEHCdVRWVnqe95/vtmXLlnl79uzxBgwY4LVs2dL77LPP4rbfu3dv3Pee53netm3bvFatWnnDhw/fV3d5nud5o0aN8nJzc2t8rJrc7x9fR5Vjjz3WO+200xK+5x955BFPkrdy5cq4Y0ryRo8eXe21oPYgFCQFqsIb8vLyAu3/1Vdf6YEHHtDNN9+8zze4Z555piKRiF588UVJ0ptvvqlNmzbpggsusG5fWVmpLVu2aMuWLVq1apWeeOIJtWnTJpaw89prr6msrEy/+93vVK/efx6TESNGKD8/X4sWLYo7XtWfKaPRaI2vb/LkyZoyZYqGDBmiCy+8ULNmzdIdd9yhFStWxIWwAEAqLV68WK1bt9bQoUNj6zIyMnTttdfG3iiHbejQoXr11Vf19NNP66KLLpKkpM0Y9ePwgqpwg7KyMr322muSpLlz56pRo0Y65ZRTYt8XW7ZsUe/evZWbm5sQIlH119GsrKxqzzt//nwdccQROvfccxM+M8MHKysrddlll+ntt9/W4sWL1alTp7jP69evr8zMzNi2W7du1d69e3X00Ufrgw8+SDh+UVGRvv32Wy1dulSLFi3S8ccfH/hYu3btiuuXLVu2qKKiotprX7Bggd577z1NmTIl4bPi4mJJUrNmzao9Bmo3BtYpkJ+fL+k//2hqauLEiWrbtq2uuuqqfW6TkZGhSy65RDNmzJAkzZgxQ7/+9a9j5zZt3LhRLVq0UIsWLdSrVy+tX79e8+fPjw3cv/zyS0nSz3/+87j9MjMz1bFjx9jnVarirsMK3bjuuutUr1692C94AEi1L7/8Ul26dIl7uSD9Z8YQ8/egi82bN8f9mIPm9u3bq6CgQEOHDtWcOXPUsWNHFRQUhD64rlevnjp27Bi37tBDD5WkWDz0unXrVFRUpJYtW8a+L6p+du7cqX//+99x+1fFR/vN6LR+/XodfvjhTu2cMGGCnn/+eZWWlmrXrl3WbWbPnq2ePXsqKytLzZo1U4sWLbRo0SIVFRUlbDtw4EC1bt1aBQUF6tatm5577rnAx5o4cWJCv/zzn//c57VUVFTo97//vS6++GL17Nkz4fO+fftKksaOHas1a9bEBuvYvxBjnQL5+flq27atPv744xrvu2bNGs2aNUtPPfWUNZbtx4YPH65evXpp7dq1mjt3buzttU2rVq301FNPSfrh/+BnzJihQYMG6a233lKPHj1q3M7NmzdLklq3bl3jfW2ys7PVrFmzuMQSANjfmcnrM2fOVGFh4T63P++88/TYY4/pjTfe0MCBA5PcuniVlZVq2bKl5syZY/28Kga4StWAvEOHDqG14Z133tGsWbM0depUjRw5UqtWrYr7y+hTTz2lwsJCnXPOORo7dqxatmyp+vXra/LkyVq/fn3C8R544AFt2bJFq1ev1uTJk3X11VfHvgtreqyRI0fq/PPPj1s3YsSIfV7L9OnT9cUXX+jll1+2fn7cccfpnnvu0aRJk3TYYYc59Q9qHwbWKXLGGWfo0Ucf1cqVK2P/V+pi/Pj
"text/plain": [
"<Figure size 800x400 with 2 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 800x400 with 2 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAtwAAAGGCAYAAABIVFZlAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8hTgPZAAAACXBIWXMAAA9hAAAPYQGoP6dpAABH00lEQVR4nO3dd5RV1f3+8WcoU5gGSFcEKYoiRbGEGAR1pIgtsWJjRLGiv0TEEqOIJoLiihoxWAHFFhViVAgWhKh8iWJBoyACGRUUVETKAFNg9u8P19xw993M2XO4Z+4w836tNUvPuafsc+4d7ubwfPZOM8YYAQAAAIhEg1Q3AAAAAKjL6HADAAAAEaLDDQAAAESIDjcAAAAQITrcAAAAQITocAMAAAARosMNAAAARIgONwAAABAhOtwAAABAhOhwAwAAABGiw13DVq5cqUsvvVSdOnVSZmam8vLydNRRR+m+++7Ttm3bUt28lEhLS9vlz/HHH5/q5gHYQ1X1Z8vOP/Pnz6/Rdn377bc677zzdMABByg3N1dNmzbVEUccoccff1zGmBptC4Ca0SjVDahPZs2apTPOOEMZGRm64IILdPDBB6usrEzvvPOOxowZo88++0wPP/xwqptZ46ZPn56w7v3339d9992ngQMHpqBFAOoC+8+WJ554Qq+//nrC+gMPPLAmm6V169Zp9erVOv3007XvvvuqvLxcr7/+ugoLC7Vs2TLdcccdNdoeANFLM/x1ukYUFRWpZ8+e2mefffTmm2+qbdu2ca+vWLFCs2bN0v/7f/8vRS2sXS6++GJNmTJFX3/9tfbZZ59UNwdAHTBq1Cg98MADtfYp8kknnaR58+Zp48aNatiwYaqbAyCJiJTUkLvuukvFxcV67LHHEjrbktSlS5e4znZaWppuvfXWuG0mTpyotLQ0DRgwILZu/vz5sX8WXbx4cdz233zzjRo2bKi0tDS98MILsfWFhYVx/5zarFkzDRgwQG+//XZCu/7617+qe/fuysjIULt27XTllVdqw4YNCdt9+eWXu/zn2uoqLS3VjBkz1L9/fzrbAGrM999/r4suukitW7dWZmamevXqpccffzxum6r+rLP/fK6ujh07auvWrSorK6tyu1tvvbXKNkybNi22bWFhoXJycvTf//5XgwYNUnZ2ttq1a6fbbrst4S8eFRUVuvfee9W9e3dlZmaqdevWuvTSS/XTTz8ltKGq+/Dll1/Gbbthwwb97ne/U8eOHZWRkaF99tlHF1xwgdatWyfpf99jO0d7vv32W3Xs2FGHHXaYiouLJUllZWW65ZZb1KdPH+Xn5ys7O1v9+vXTvHnz4s63bNkyHXvssWrTpo0yMjLUvn17XXbZZVq/fn1sG99jVV7n3XffnXAPDj74YOf3sR1RGjp0qPM7fd68eerXr5+aNWsWd/9GjRqVcC7s+YiU1JCXX35ZnTp10i9/+ctQ+2/YsEHjx4/f5euZmZmaOnWq7rvvvti6xx9/XOnp6SopKUnYvkWLFrrnnnskSatXr9Z9992nE044QatWrVLTpk0l/fyH+rhx41RQUKDLL79cy5Yt0+TJk7Vo0SItWLBAjRs3TjjuJZdcon79+kmSZs6cqb///e/VvtbZs2drw4YNOvfcc6u9LwCEsW3bNg0YMEArVqzQqFGjtN9+++n5559XYWGhNmzYkPCvj8OGDdMJJ5wQt+7GG2+s9jm3bNmi4uJi/etf/9LUqVPVt29fZWVlee0/efJk5eTkxJaLiop0yy23JGy3Y8cODR48WL/4xS901113ac6cORo7dqy2b9+u2267LbbdpZdeqmnTpunCCy/U1VdfraKiIk2aNEkfffTRLv/M3/k+zJ49W88880zc68XFxerXr5+WLl2qESNG6NBDD9W6dev00ksvafXq1WrRokXCMTdu3KghQ4aocePGmj17duwaN23apEcffVTDhg3TyJEjtXnzZj322GMaNGiQ3nvvPfXu3VuStGXLFu2zzz466aSTlJeXp08//VQPPPCAvvnmG7388svVOtbueuuttzR79uyE9UVFRRo6dKjatm2rW265RS1btpQknX/++Uk5L2ohg8ht3LjRSDKnnHKK9z6SzNixY2PL1113nWnVqpXp06eP6d+/f2z9vHnzjCQzbNgws9dee5nS0tLYa127djXnnHOOkWSef/752Prhw4ebDh06xJ3v4YcfNpLMe++9Z4wx5vvvvzfp6elm4MCBZseOHbHtJk2aZCSZKVOmxO2/fPlyI8k8/vjjsXVjx441YT5ip512msnIyDA//fRTtfcFgF258sord/ln0r333mskmSeffDK2rqyszPTt29fk5OSYTZs2GWOMKSoqMpLMxIkTE47RvXv3uD+fg4wfP95Iiv0cd9xx5uuvvw7cr/LP1h9++CFu/aJFi4wkM3Xq1Ni64cOHG0nmqquuiq2rqKgwQ4cONenp6bFjvP3220aSeeqpp+KOOWfOHOf6L774wkgyd999d2zdxIkTjSRTVFQUW3fLLbcYSWbmzJkJ11FRUWGM+d/32Lx580xJSYkZMGCAadWqlVmxYkXc9tu3b4/7jjPGmJ9++sm0bt3ajBgxYle3yxhjzBVXXGFycnKqfazqvN87X0elI4880gwZMiThO/2hhx4ykszChQvjjinJXHnllVVeC/ZMREpqwKZNmyRJubm5ofb/5ptvdP/99+vmm2+Oe5qxs5NOOklpaWl66aWXJElvv/22Vq9erbPOOsu5fUVFhdatW6d169Zp8eLFeuKJJ9S2bdtY8dAbb7yhsrIy/fa3v1WDBv/7mIwcOVJ5eXmaNWtW3PEq/wk0IyMj1DVW2rRpk2bNmqUTTjgh9qQdAKI2e/ZstWnTRsOGDYuta9y4sa6++urYE+hkGzZsmF5//XU9/fTTOueccyQpstGqdo4pVMYWysrK9MYbb0iSnn/+eeXn5+v444+PfTesW7dOffr0UU5OTkLUovJfTjMzM6s874wZM9SrVy/9+te/TnjNjhxWVFToggsu0L///W/Nnj1bnTt3jnu9YcOGSk9Pj227fv16bd++XYcddpg+/PDDhONv3LhR3333nebOnatZs2bp6KOPDn2srVu3xt2XdevWaceOHVVe+8yZM7Vo0SJNmDAh4bXNmzdLkvbaa68qj4G6gw53DcjLy5P0v1+w6ho7dqzatWunSy+9dJfbNG7cWOedd56mTJkiSZoyZYpOO+202Lltq1atUsuWLdWyZUsdcsghWrlypWbMmBHr0H/11VeSpAMOOCBuv/T0dHXq1Cn2eqXKXPeu/kLga8aMGSopKSFOAqBGffXVV+ratWvcAwbpfyOY2H/m+Vi7dm3cj92Z7tChgwoKCjRs2DA99dRT6tSpkwoKCpLe6W7QoIE6deoUt27//feXpFjeevny5dq4caNatWoV+26o/CkuLtb3338ft39l/jo/P7/Kc69cuVIHH3ywVztvuukmPffccyotLdXWrVud2zz++OPq2bOnMjMztddee6lly5aaNWuWNm7cmLDtoEGD1KZNGxUUFOjAAw/U3/72t9DHGjt2bMJ9+fzzz3d5LTt27NDvf/97nXvuuerZs2fC63379pUkjRkzRkuXLo114lF3keGuAXl5eWrXrp0+/fTTau+7dOlSTZs2TU8++aQzP7ezESNG6JBDDtGyZcv0/PPPx552u7Ru3VpPPvmkpJ+fAkyZMkWDBw/WO++8ox49elS7nWvXrpUktWnTptr77uypp55Sfn6+TjzxxN06DgCkml0gP3XqVBUWFu5y+9NPP12PPPKI3nrrLQ0aNCji1sWrqKhQq1at9NRTTzlfr8wYV6rsqHfs2DFpbXj33Xc1bdo0TZo0SZdccokWL14c96+mTz75pAoLC3XqqadqzJgxatWqlRo2bKjx48dr5cqVCce7//77tW7dOi1ZskTjx4/XZZddFvveq+6xLrnkEp1xxhlx60aOHLnLa3nsscf05Zdf6tVXX3W+/stf/lITJ07UuHHjdNBBB3ndH+zZ6HDXkBNPPFEPP/ywFi5cGPubrY8bb7xRvXv33mU0ZGc9evTQIYccojP
"text/plain": [
"<Figure size 800x400 with 2 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAtUAAAGGCAYAAAC0QX2vAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8hTgPZAAAACXBIWXMAAA9hAAAPYQGoP6dpAABE40lEQVR4nO3deXgV5f3//1eAbCQk7JAogiyKIouiUGoRlMgiWq07WiViwarot60iUi8F7AIWP60WLG5silXZal0oVREqpYhURWulCBgVEFREErYskPn94Y8j5z43mTsz5+SE+HxcVy6dObPcM+eQczO83ved4nmeJwAAAACB1Ut2AwAAAICjHZ1qAAAAICQ61QAAAEBIdKoBAACAkOhUAwAAACHRqQYAAABColMNAAAAhESnGgAAAAiJTjUAAAAQEp1qAAAAICQ61TVs06ZNuuGGG9S+fXtlZGQoJydHZ555ph588EHt378/2c1Lmnnz5ul73/ueGjdurGbNmqlfv3566aWXkt0sAHVESkqK08/y5ctrtF2fffaZfvzjH+vEE09Uo0aN1LhxY/Xq1Utz5syR53k12hYA4TRIdgO+S1566SVddtllSk9P17XXXqtTTjlF5eXl+uc//6kxY8bov//9rx599NFkN7PGTZ06VbfeequGDh2qyZMnq7S0VLNnz9b555+vhQsX6uKLL052EwEc5Z588smo5SeeeEKvvPJKzPqTTjqpJpulHTt2aMuWLbr00kt13HHHqaKiQq+88ooKCwu1fv16/fa3v63R9gAILsXjr8I1oqioSN26ddOxxx6r1157TXl5eVGvb9y4US+99JL+3//7f0lqYfKccMIJaty4sVavXq2UlBRJUklJiY455hidc845+utf/5rkFgKoa0aPHq2HHnqo1j4NvuCCC7Rs2TIVFxerfv36yW4OAAfEP2rI7373O+3Zs0czZsyI6VBLUseOHaM61CkpKZowYULUNlOmTFFKSor69+8fWbd8+fLIP1uuXbs2avutW7eqfv36SklJ0YIFCyLrCwsLo/65s0mTJurfv79WrFgR064//elP6tKli9LT05Wfn6+bb75Zu3btitnu448/PuI/p/opKSlRy5Yto7bNyclRdna2MjMzffcHgHj74osvdP3116tVq1bKyMhQ9+7dNWfOnKhtqvq9Z/6urq527dpp3759Ki8vr3K7CRMmVNmG2bNnR7YtLCxUdna2PvroIw0aNEhZWVnKz8/XvffeG/OXi8rKSj3wwAPq0qWLMjIy1KpVK91www36+uuvY9pQ1X34+OOPo7bdtWuXfv7zn6tdu3ZKT0/Xscceq2uvvVY7duyQ9O132uExnM8++0zt2rXT6aefrj179kiSysvLdc8996hnz57Kzc1VVlaW+vbtq2XLlkWdb/369TrnnHPUunVrpaenq02bNvrpT3+qnTt3RrZxPdah67z//vtj7sEpp5xi/W4240RDhw61fr8vW7ZMffv2VZMmTaLu3+jRo2POhdqL+EcNeeGFF9S+fXt9//vfD7T/rl27NGnSpCO+npGRoVmzZunBBx+MrJszZ47S0tJUWloas33z5s31hz/8QZK0ZcsWPfjggzrvvPO0efNmNW7cWNI3v6wnTpyogoIC3XjjjVq/fr2mT5+uNWvWaOXKlUpNTY057qhRo9S3b19J0qJFi/SXv/zF99r69++vBQsWaOrUqbrgggtUWlqqqVOnqri4+Dv55B5Acu3fv1/9+/fXxo0bNXr0aB1//PGaP3++CgsLtWvXrpjfS8OGDdN5550XtW7cuHHVPufevXu1Z88e/eMf/9CsWbPUp08f5wcL06dPV3Z2dmS5qKhI99xzT8x2Bw8e1ODBg/W9731Pv/vd77RkyRKNHz9eBw4c0L333hvZ7oYbbtDs2bN13XXX6dZbb1VRUZGmTZumd95554i//w+/D4sXL9bTTz8d9fqePXvUt29frVu3TiNGjNBpp52mHTt26Pnnn9eWLVvUvHnzmGMWFxdryJAhSk1N1eLFiyPXWFJSoscff1zDhg3TyJEjtXv3bs2YMUODBg3Sm2++qR49ekiS9u7dq2OPPVYXXHCBcnJy9P777+uhhx7S1q1b9cILL1TrWGG9/vrrWrx4ccz6oqIiDR06VHl5ebrnnnvUokULSdI111wTl/OiBnlIuOLiYk+Sd+GFFzrvI8kbP358ZPmOO+7wWrZs6fXs2dPr169fZP2yZcs8Sd6wYcO8Zs2aeWVlZZHXOnXq5F111VWeJG/+/PmR9cOHD/fatm0bdb5HH33Uk+S9+eabnud53hdffOGlpaV5AwcO9A4ePBjZbtq0aZ4kb+bMmVH7b9iwwZPkzZkzJ7Ju/PjxnstH7PPPP/cGDBjgSYr8NG/e3PvXv/7luy8ABHHzzTcf8ffTAw884Eny5s6dG1lXXl7u9enTx8vOzvZKSko8z/O8oqIiT5I3ZcqUmGN06dIl6ne1n0mTJkX9DhwwYID36aef+u536Pfsl19+GbV+zZo1niRv1qxZkXXDhw/3JHm33HJLZF1lZaU3dOhQLy0tLXKMFStWeJK8p556KuqYS5Yssa7/8MMPPUne/fffH1k3ZcoUT5JXVFQUWXfPPfd4krxFixbFXEdlZaXned9+py1btswrLS31+vfv77Vs2dLbuHFj1PYHDhyI+r7zPM/7+uuvvVatWnkjRow40u3yPM/zbrrpJi87O7vax6rO+334dRzSu3dvb8iQITHf74888ognyVu1alXUMSV5N998c5XXgtqF+EcNKCkpkSQ1atQo0P5bt27V1KlTdffdd0c9iTjcBRdcoJSUFD3//POSpBUrVmjLli264oorrNtXVlZqx44d2rFjh9auXasnnnhCeXl5kSKdV199VeXl5frZz36mevW+/ZiMHDlSOTk5MSNzHPonyvT09GpfX8OGDXXiiSdq+PDhmj9/vmbOnKm8vDxdfPHF2rhxY7WPBwBhLF68WK1bt9awYcMi61JTU3XrrbdGniTH27Bhw/TKK6/oz3/+s6666ipJStiIUIdHCg5FDMrLy/Xqq69KkubPn6/c3Fyde+65ke+JHTt2qGfPnsrOzo6JRRz619CMjIwqz7tw4UJ1795dP/rRj2JeM6OClZWVuvbaa/XGG29o8eLF6tChQ9Tr9evXV1paWmTbnTt36sCBAzr99NP19ttvxxy/uLhYn3/+uZYuXaqXXnpJZ511VuBj7du3L+q+7NixQwcPHqzy2hctWqQ1a9Zo8uTJMa/t3r1bktSsWbMqj4Haj/hHDcjJyZH07R+c6ho/frzy8/N1ww03RGWjD5eamqof//jHmjlzpi699FLNnDlTl1xySeTcps2bN0f+iUmS8vLytHDhwkin/ZNPPpEknXjiiVH7paWlqX379pHXDzmUsz5Sp78ql112mRo0aBD5pzhJuvDCC9WpUyfdddddevbZZ6t9TAAI6pNPPlGnTp2iHihI344MYv7+c7F9+/ao5dzc3KhoR9u2bdW2bVtJ33SwR40apYKCAq1fvz6utSX16tVT+/bto9adcMIJkhTJP2/YsEHFxcVq2bKl9RhffPFF1PKhPHRubm6V5960aZMuueQSp3beddddeuONN5SSkqJ9+/ZZt5kzZ47+7//+T//73/9UUVERWX/88cfHbDto0CCtXr1akjR48OCY75XqHGv8+PEaP358zPpWrVpZ23nw4EH98pe/1NVXX61u3brFvN6nTx9J0pgxYzRp0qSo72YcXehU14CcnBzl5+fr/fffr/a+69at0+zZszV37lxrhu1wI0aM0Kmnnqr169dr/vz5kafWNq1atdLcuXMlffM3+JkzZ2rw4MH65z//qa5du1a7nYe+MFq3bl2t/T766CMtWbIkZijBpk2b6gc/+IFWrlxZ7bYAQG1jFqjPmjVLhYWFR9z+0ksv1WOPPabXX39dgwYNSnDrolVWVqply5Z66qmnrK+bnb5DnfF27drFrQ2rV6/W7NmzNW3aNI0aNUpr166N+pfQuXPnqrCwUBdddJHGjBmjli1bqn79+po0aZI2bdoUc7ypU6dqx44d+uC
"text/plain": [
"<Figure size 800x400 with 2 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"import torch\n",
"import torch.nn as nn\n",
"import torchvision.transforms as transforms\n",
"import numpy as np\n",
"import matplotlib.pyplot as plt\n",
"\n",
"transform = transforms.Compose([\n",
" transforms.Resize((28, 28)), # Изменяем размер до 28x28\n",
" transforms.ToTensor(), \n",
" transforms.ColorJitter(brightness=0.5), # Преобразуем в тензор\n",
" transforms.Normalize(mean=[0.5], std=[0.5]) # Нормализация: среднее 0.5, стандартное отклонение 0.5\n",
" ])\n",
"\n",
"# Функция для получения топ-3 предсказаний\n",
"def get_top_predictions(output, top_k=3):\n",
" probabilities = torch.softmax(output, dim=1).squeeze() # Преобразование в вероятности\n",
" top_probs, top_indices = torch.topk(probabilities, top_k)\n",
" return top_probs.tolist(), [CLASSES[idx] for idx in top_indices.tolist()]\n",
"\n",
"from PIL import Image\n",
"\n",
"# Функция распознавания символов с выводом графиков\n",
"def recognize_and_plot_characters(characters, model, device=\"cpu\"):\n",
" \"\"\"\n",
" Распознает символы из списка изображений characters и строит графики топ-3 предсказаний.\n",
"\n",
" :param characters: Список символов (массивы numpy 28x28).\n",
" :param model: Загруженная модель для распознавания.\n",
" :param device: Устройство для вычислений (\"cpu\" или \"cuda\").\n",
" \"\"\"\n",
" for i, char in enumerate(characters):\n",
" # Преобразование символа в объект PIL.Image\n",
" char_image = Image.fromarray(char)\n",
" \n",
" # Преобразование символа в тензор\n",
" char_tensor = transform(char_image).unsqueeze(0).to(device) # Добавляем batch размерности\n",
" \n",
" # Прогон через модель\n",
" with torch.no_grad():\n",
" output = model(char_tensor)\n",
" top_probs, top_classes = get_top_predictions(output)\n",
"\n",
" # Вывод символа и графика топ-3 предсказаний\n",
" plt.figure(figsize=(8, 4))\n",
"\n",
" # Символ\n",
" plt.subplot(1, 2, 1)\n",
" plt.imshow(char, cmap='gray')\n",
" plt.axis('off')\n",
" plt.title(f\"Символ {i + 1}\")\n",
"\n",
" # Топ-3 предсказания\n",
" plt.subplot(1, 2, 2)\n",
" plt.barh(top_classes, top_probs, color='blue')\n",
" plt.xlabel(\"Вероятность\")\n",
" plt.ylabel(\"Класс\")\n",
" plt.title(\"Топ-3 предсказания\")\n",
" plt.gca().invert_yaxis() # Инвертируем ось, чтобы лучший класс был сверху\n",
"\n",
" plt.tight_layout()\n",
" plt.show()\n",
"\n",
"\n",
"# Использование функции\n",
"if len(chars1) > 0:\n",
" recognize_and_plot_characters(chars1, model, device=DEVICE)\n",
"else:\n",
" print(\"Список characters пуст.\")\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[156, 157, 157, ..., 153, 153, 153],\n",
" [156, 157, 158, ..., 155, 155, 155],\n",
" [156, 157, 158, ..., 158, 157, 157],\n",
" ...,\n",
" [174, 174, 175, ..., 183, 183, 183],\n",
" [172, 173, 174, ..., 180, 180, 180],\n",
" [171, 172, 172, ..., 177, 177, 177]], dtype=uint8)"
]
},
"execution_count": 13,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"chars1[0]"
]
}
],
"metadata": {
"kernelspec": {
"display_name": ".venv",
"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.9.13"
}
},
"nbformat": 4,
"nbformat_minor": 2
}