Created
May 18, 2022 19:25
-
-
Save remi-or/3214590e57eba9278b9ccf6b444df879 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| { | |
| "nbformat": 4, | |
| "nbformat_minor": 0, | |
| "metadata": { | |
| "colab": { | |
| "name": "Untitled4.ipynb", | |
| "provenance": [], | |
| "collapsed_sections": [] | |
| }, | |
| "kernelspec": { | |
| "name": "python3", | |
| "display_name": "Python 3" | |
| }, | |
| "language_info": { | |
| "name": "python" | |
| }, | |
| "accelerator": "GPU" | |
| }, | |
| "cells": [ | |
| { | |
| "cell_type": "code", | |
| "source": [ | |
| "!pip install torch==1.9.0+cu111 torchvision==0.10.0+cu111 -f https://download.pytorch.org/whl/torch_stable.html\n", | |
| "!pip install mmcv-full -f https://download.openmmlab.com/mmcv/dist/cu111/torch1.9.0/index.html\n", | |
| "!git clone https://github.com/lzh420202/FCOSR\n", | |
| "!sudo apt install swig -y\n", | |
| "!pip install shapely\n", | |
| "%cd FCOSR/DOTA_devkit\n", | |
| "!swig -c++ -python polyiou.i\n", | |
| "!python setup.py build_ext --inplace\n", | |
| "import polyiou\n", | |
| "%cd ..\n", | |
| "!pip install -r requirements/build.txt\n", | |
| "!python setup.py develop" | |
| ], | |
| "metadata": { | |
| "id": "acruC-8k2W7r" | |
| }, | |
| "execution_count": null, | |
| "outputs": [] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "source": [ | |
| "import torch\n", | |
| "import numpy as np\n", | |
| "from mmcv import Config\n", | |
| "from mmdet.apis import set_random_seed \n", | |
| "from mmdet.models import build_detector\n", | |
| "\n", | |
| "cfg = Config.fromfile('configs/fcosrbox/fcosr_mobilenetv2_fpn_3x_dota10_single.py')\n", | |
| "\n", | |
| "if cfg.get('cudnn_benchmark', False):\n", | |
| " torch.backends.cudnn.benchmark = True\n", | |
| "\n", | |
| "cfg.gpu_ids = range(1)\n", | |
| "distributed = False\n", | |
| "\n", | |
| "set_random_seed(42, deterministic=True)\n", | |
| "cfg.seed = 42\n", | |
| "\n", | |
| "Model = build_detector(\n", | |
| " cfg.model,\n", | |
| " train_cfg=cfg.get('train_cfg'),\n", | |
| " test_cfg=cfg.get('test_cfg'))\n", | |
| "Model.load_state_dict(torch.load('fcosr-s-single-74.05-0a0a310f.pth')['state_dict'])\n", | |
| "Model.train().cuda()" | |
| ], | |
| "metadata": { | |
| "colab": { | |
| "base_uri": "https://localhost:8080/" | |
| }, | |
| "id": "-Vh0PqFC3s5X", | |
| "outputId": "0af9cbd3-d245-41f3-d793-a01a68296d4e" | |
| }, | |
| "execution_count": null, | |
| "outputs": [ | |
| { | |
| "output_type": "execute_result", | |
| "data": { | |
| "text/plain": [ | |
| "FCOSR(\n", | |
| " (backbone): MobileNetV2(\n", | |
| " (conv1): ConvModule(\n", | |
| " (conv): Conv2d(3, 32, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)\n", | |
| " (bn): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", | |
| " (activate): LeakyReLU(negative_slope=0.1, inplace=True)\n", | |
| " )\n", | |
| " (layer1): Sequential(\n", | |
| " (0): InvertedResidual(\n", | |
| " (depthwise_conv): ConvModule(\n", | |
| " (conv): Conv2d(32, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=32, bias=False)\n", | |
| " (bn): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", | |
| " (activate): LeakyReLU(negative_slope=0.1, inplace=True)\n", | |
| " )\n", | |
| " (linear_conv): ConvModule(\n", | |
| " (conv): Conv2d(32, 16, kernel_size=(1, 1), stride=(1, 1), bias=False)\n", | |
| " (bn): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", | |
| " )\n", | |
| " )\n", | |
| " )\n", | |
| " (layer2): Sequential(\n", | |
| " (0): InvertedResidual(\n", | |
| " (expand_conv): ConvModule(\n", | |
| " (conv): Conv2d(16, 96, kernel_size=(1, 1), stride=(1, 1), bias=False)\n", | |
| " (bn): BatchNorm2d(96, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", | |
| " (activate): LeakyReLU(negative_slope=0.1, inplace=True)\n", | |
| " )\n", | |
| " (depthwise_conv): ConvModule(\n", | |
| " (conv): Conv2d(96, 96, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), groups=96, bias=False)\n", | |
| " (bn): BatchNorm2d(96, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", | |
| " (activate): LeakyReLU(negative_slope=0.1, inplace=True)\n", | |
| " )\n", | |
| " (linear_conv): ConvModule(\n", | |
| " (conv): Conv2d(96, 24, kernel_size=(1, 1), stride=(1, 1), bias=False)\n", | |
| " (bn): BatchNorm2d(24, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", | |
| " )\n", | |
| " )\n", | |
| " (1): InvertedResidual(\n", | |
| " (expand_conv): ConvModule(\n", | |
| " (conv): Conv2d(24, 144, kernel_size=(1, 1), stride=(1, 1), bias=False)\n", | |
| " (bn): BatchNorm2d(144, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", | |
| " (activate): LeakyReLU(negative_slope=0.1, inplace=True)\n", | |
| " )\n", | |
| " (depthwise_conv): ConvModule(\n", | |
| " (conv): Conv2d(144, 144, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=144, bias=False)\n", | |
| " (bn): BatchNorm2d(144, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", | |
| " (activate): LeakyReLU(negative_slope=0.1, inplace=True)\n", | |
| " )\n", | |
| " (linear_conv): ConvModule(\n", | |
| " (conv): Conv2d(144, 24, kernel_size=(1, 1), stride=(1, 1), bias=False)\n", | |
| " (bn): BatchNorm2d(24, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", | |
| " )\n", | |
| " )\n", | |
| " )\n", | |
| " (layer3): Sequential(\n", | |
| " (0): InvertedResidual(\n", | |
| " (expand_conv): ConvModule(\n", | |
| " (conv): Conv2d(24, 144, kernel_size=(1, 1), stride=(1, 1), bias=False)\n", | |
| " (bn): BatchNorm2d(144, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", | |
| " (activate): LeakyReLU(negative_slope=0.1, inplace=True)\n", | |
| " )\n", | |
| " (depthwise_conv): ConvModule(\n", | |
| " (conv): Conv2d(144, 144, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), groups=144, bias=False)\n", | |
| " (bn): BatchNorm2d(144, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", | |
| " (activate): LeakyReLU(negative_slope=0.1, inplace=True)\n", | |
| " )\n", | |
| " (linear_conv): ConvModule(\n", | |
| " (conv): Conv2d(144, 32, kernel_size=(1, 1), stride=(1, 1), bias=False)\n", | |
| " (bn): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", | |
| " )\n", | |
| " )\n", | |
| " (1): InvertedResidual(\n", | |
| " (expand_conv): ConvModule(\n", | |
| " (conv): Conv2d(32, 192, kernel_size=(1, 1), stride=(1, 1), bias=False)\n", | |
| " (bn): BatchNorm2d(192, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", | |
| " (activate): LeakyReLU(negative_slope=0.1, inplace=True)\n", | |
| " )\n", | |
| " (depthwise_conv): ConvModule(\n", | |
| " (conv): Conv2d(192, 192, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=192, bias=False)\n", | |
| " (bn): BatchNorm2d(192, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", | |
| " (activate): LeakyReLU(negative_slope=0.1, inplace=True)\n", | |
| " )\n", | |
| " (linear_conv): ConvModule(\n", | |
| " (conv): Conv2d(192, 32, kernel_size=(1, 1), stride=(1, 1), bias=False)\n", | |
| " (bn): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", | |
| " )\n", | |
| " )\n", | |
| " (2): InvertedResidual(\n", | |
| " (expand_conv): ConvModule(\n", | |
| " (conv): Conv2d(32, 192, kernel_size=(1, 1), stride=(1, 1), bias=False)\n", | |
| " (bn): BatchNorm2d(192, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", | |
| " (activate): LeakyReLU(negative_slope=0.1, inplace=True)\n", | |
| " )\n", | |
| " (depthwise_conv): ConvModule(\n", | |
| " (conv): Conv2d(192, 192, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=192, bias=False)\n", | |
| " (bn): BatchNorm2d(192, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", | |
| " (activate): LeakyReLU(negative_slope=0.1, inplace=True)\n", | |
| " )\n", | |
| " (linear_conv): ConvModule(\n", | |
| " (conv): Conv2d(192, 32, kernel_size=(1, 1), stride=(1, 1), bias=False)\n", | |
| " (bn): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", | |
| " )\n", | |
| " )\n", | |
| " )\n", | |
| " (layer4): Sequential(\n", | |
| " (0): InvertedResidual(\n", | |
| " (expand_conv): ConvModule(\n", | |
| " (conv): Conv2d(32, 192, kernel_size=(1, 1), stride=(1, 1), bias=False)\n", | |
| " (bn): BatchNorm2d(192, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", | |
| " (activate): LeakyReLU(negative_slope=0.1, inplace=True)\n", | |
| " )\n", | |
| " (depthwise_conv): ConvModule(\n", | |
| " (conv): Conv2d(192, 192, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), groups=192, bias=False)\n", | |
| " (bn): BatchNorm2d(192, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", | |
| " (activate): LeakyReLU(negative_slope=0.1, inplace=True)\n", | |
| " )\n", | |
| " (linear_conv): ConvModule(\n", | |
| " (conv): Conv2d(192, 64, kernel_size=(1, 1), stride=(1, 1), bias=False)\n", | |
| " (bn): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", | |
| " )\n", | |
| " )\n", | |
| " (1): InvertedResidual(\n", | |
| " (expand_conv): ConvModule(\n", | |
| " (conv): Conv2d(64, 384, kernel_size=(1, 1), stride=(1, 1), bias=False)\n", | |
| " (bn): BatchNorm2d(384, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", | |
| " (activate): LeakyReLU(negative_slope=0.1, inplace=True)\n", | |
| " )\n", | |
| " (depthwise_conv): ConvModule(\n", | |
| " (conv): Conv2d(384, 384, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=384, bias=False)\n", | |
| " (bn): BatchNorm2d(384, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", | |
| " (activate): LeakyReLU(negative_slope=0.1, inplace=True)\n", | |
| " )\n", | |
| " (linear_conv): ConvModule(\n", | |
| " (conv): Conv2d(384, 64, kernel_size=(1, 1), stride=(1, 1), bias=False)\n", | |
| " (bn): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", | |
| " )\n", | |
| " )\n", | |
| " (2): InvertedResidual(\n", | |
| " (expand_conv): ConvModule(\n", | |
| " (conv): Conv2d(64, 384, kernel_size=(1, 1), stride=(1, 1), bias=False)\n", | |
| " (bn): BatchNorm2d(384, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", | |
| " (activate): LeakyReLU(negative_slope=0.1, inplace=True)\n", | |
| " )\n", | |
| " (depthwise_conv): ConvModule(\n", | |
| " (conv): Conv2d(384, 384, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=384, bias=False)\n", | |
| " (bn): BatchNorm2d(384, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", | |
| " (activate): LeakyReLU(negative_slope=0.1, inplace=True)\n", | |
| " )\n", | |
| " (linear_conv): ConvModule(\n", | |
| " (conv): Conv2d(384, 64, kernel_size=(1, 1), stride=(1, 1), bias=False)\n", | |
| " (bn): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", | |
| " )\n", | |
| " )\n", | |
| " (3): InvertedResidual(\n", | |
| " (expand_conv): ConvModule(\n", | |
| " (conv): Conv2d(64, 384, kernel_size=(1, 1), stride=(1, 1), bias=False)\n", | |
| " (bn): BatchNorm2d(384, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", | |
| " (activate): LeakyReLU(negative_slope=0.1, inplace=True)\n", | |
| " )\n", | |
| " (depthwise_conv): ConvModule(\n", | |
| " (conv): Conv2d(384, 384, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=384, bias=False)\n", | |
| " (bn): BatchNorm2d(384, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", | |
| " (activate): LeakyReLU(negative_slope=0.1, inplace=True)\n", | |
| " )\n", | |
| " (linear_conv): ConvModule(\n", | |
| " (conv): Conv2d(384, 64, kernel_size=(1, 1), stride=(1, 1), bias=False)\n", | |
| " (bn): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", | |
| " )\n", | |
| " )\n", | |
| " )\n", | |
| " (layer5): Sequential(\n", | |
| " (0): InvertedResidual(\n", | |
| " (expand_conv): ConvModule(\n", | |
| " (conv): Conv2d(64, 384, kernel_size=(1, 1), stride=(1, 1), bias=False)\n", | |
| " (bn): BatchNorm2d(384, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", | |
| " (activate): LeakyReLU(negative_slope=0.1, inplace=True)\n", | |
| " )\n", | |
| " (depthwise_conv): ConvModule(\n", | |
| " (conv): Conv2d(384, 384, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=384, bias=False)\n", | |
| " (bn): BatchNorm2d(384, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", | |
| " (activate): LeakyReLU(negative_slope=0.1, inplace=True)\n", | |
| " )\n", | |
| " (linear_conv): ConvModule(\n", | |
| " (conv): Conv2d(384, 96, kernel_size=(1, 1), stride=(1, 1), bias=False)\n", | |
| " (bn): BatchNorm2d(96, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", | |
| " )\n", | |
| " )\n", | |
| " (1): InvertedResidual(\n", | |
| " (expand_conv): ConvModule(\n", | |
| " (conv): Conv2d(96, 576, kernel_size=(1, 1), stride=(1, 1), bias=False)\n", | |
| " (bn): BatchNorm2d(576, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", | |
| " (activate): LeakyReLU(negative_slope=0.1, inplace=True)\n", | |
| " )\n", | |
| " (depthwise_conv): ConvModule(\n", | |
| " (conv): Conv2d(576, 576, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=576, bias=False)\n", | |
| " (bn): BatchNorm2d(576, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", | |
| " (activate): LeakyReLU(negative_slope=0.1, inplace=True)\n", | |
| " )\n", | |
| " (linear_conv): ConvModule(\n", | |
| " (conv): Conv2d(576, 96, kernel_size=(1, 1), stride=(1, 1), bias=False)\n", | |
| " (bn): BatchNorm2d(96, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", | |
| " )\n", | |
| " )\n", | |
| " (2): InvertedResidual(\n", | |
| " (expand_conv): ConvModule(\n", | |
| " (conv): Conv2d(96, 576, kernel_size=(1, 1), stride=(1, 1), bias=False)\n", | |
| " (bn): BatchNorm2d(576, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", | |
| " (activate): LeakyReLU(negative_slope=0.1, inplace=True)\n", | |
| " )\n", | |
| " (depthwise_conv): ConvModule(\n", | |
| " (conv): Conv2d(576, 576, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=576, bias=False)\n", | |
| " (bn): BatchNorm2d(576, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", | |
| " (activate): LeakyReLU(negative_slope=0.1, inplace=True)\n", | |
| " )\n", | |
| " (linear_conv): ConvModule(\n", | |
| " (conv): Conv2d(576, 96, kernel_size=(1, 1), stride=(1, 1), bias=False)\n", | |
| " (bn): BatchNorm2d(96, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", | |
| " )\n", | |
| " )\n", | |
| " )\n", | |
| " (layer6): Sequential(\n", | |
| " (0): InvertedResidual(\n", | |
| " (expand_conv): ConvModule(\n", | |
| " (conv): Conv2d(96, 576, kernel_size=(1, 1), stride=(1, 1), bias=False)\n", | |
| " (bn): BatchNorm2d(576, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", | |
| " (activate): LeakyReLU(negative_slope=0.1, inplace=True)\n", | |
| " )\n", | |
| " (depthwise_conv): ConvModule(\n", | |
| " (conv): Conv2d(576, 576, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), groups=576, bias=False)\n", | |
| " (bn): BatchNorm2d(576, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", | |
| " (activate): LeakyReLU(negative_slope=0.1, inplace=True)\n", | |
| " )\n", | |
| " (linear_conv): ConvModule(\n", | |
| " (conv): Conv2d(576, 160, kernel_size=(1, 1), stride=(1, 1), bias=False)\n", | |
| " (bn): BatchNorm2d(160, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", | |
| " )\n", | |
| " )\n", | |
| " (1): InvertedResidual(\n", | |
| " (expand_conv): ConvModule(\n", | |
| " (conv): Conv2d(160, 960, kernel_size=(1, 1), stride=(1, 1), bias=False)\n", | |
| " (bn): BatchNorm2d(960, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", | |
| " (activate): LeakyReLU(negative_slope=0.1, inplace=True)\n", | |
| " )\n", | |
| " (depthwise_conv): ConvModule(\n", | |
| " (conv): Conv2d(960, 960, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=960, bias=False)\n", | |
| " (bn): BatchNorm2d(960, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", | |
| " (activate): LeakyReLU(negative_slope=0.1, inplace=True)\n", | |
| " )\n", | |
| " (linear_conv): ConvModule(\n", | |
| " (conv): Conv2d(960, 160, kernel_size=(1, 1), stride=(1, 1), bias=False)\n", | |
| " (bn): BatchNorm2d(160, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", | |
| " )\n", | |
| " )\n", | |
| " (2): InvertedResidual(\n", | |
| " (expand_conv): ConvModule(\n", | |
| " (conv): Conv2d(160, 960, kernel_size=(1, 1), stride=(1, 1), bias=False)\n", | |
| " (bn): BatchNorm2d(960, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", | |
| " (activate): LeakyReLU(negative_slope=0.1, inplace=True)\n", | |
| " )\n", | |
| " (depthwise_conv): ConvModule(\n", | |
| " (conv): Conv2d(960, 960, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=960, bias=False)\n", | |
| " (bn): BatchNorm2d(960, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", | |
| " (activate): LeakyReLU(negative_slope=0.1, inplace=True)\n", | |
| " )\n", | |
| " (linear_conv): ConvModule(\n", | |
| " (conv): Conv2d(960, 160, kernel_size=(1, 1), stride=(1, 1), bias=False)\n", | |
| " (bn): BatchNorm2d(160, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", | |
| " )\n", | |
| " )\n", | |
| " )\n", | |
| " (layer7): Sequential(\n", | |
| " (0): InvertedResidual(\n", | |
| " (expand_conv): ConvModule(\n", | |
| " (conv): Conv2d(160, 960, kernel_size=(1, 1), stride=(1, 1), bias=False)\n", | |
| " (bn): BatchNorm2d(960, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", | |
| " (activate): LeakyReLU(negative_slope=0.1, inplace=True)\n", | |
| " )\n", | |
| " (depthwise_conv): ConvModule(\n", | |
| " (conv): Conv2d(960, 960, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=960, bias=False)\n", | |
| " (bn): BatchNorm2d(960, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", | |
| " (activate): LeakyReLU(negative_slope=0.1, inplace=True)\n", | |
| " )\n", | |
| " (linear_conv): ConvModule(\n", | |
| " (conv): Conv2d(960, 320, kernel_size=(1, 1), stride=(1, 1), bias=False)\n", | |
| " (bn): BatchNorm2d(320, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", | |
| " )\n", | |
| " )\n", | |
| " )\n", | |
| " (conv2): ConvModule(\n", | |
| " (conv): Conv2d(320, 1280, kernel_size=(1, 1), stride=(1, 1), bias=False)\n", | |
| " (bn): BatchNorm2d(1280, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", | |
| " (activate): LeakyReLU(negative_slope=0.1, inplace=True)\n", | |
| " )\n", | |
| " )\n", | |
| " init_cfg={'type': 'Pretrained', 'checkpoint': 'open-mmlab://mmdet/mobilenet_v2'}\n", | |
| " (neck): FPN(\n", | |
| " (lateral_convs): ModuleList(\n", | |
| " (0): ConvModule(\n", | |
| " (conv): Conv2d(32, 128, kernel_size=(1, 1), stride=(1, 1))\n", | |
| " )\n", | |
| " (1): ConvModule(\n", | |
| " (conv): Conv2d(96, 128, kernel_size=(1, 1), stride=(1, 1))\n", | |
| " )\n", | |
| " (2): ConvModule(\n", | |
| " (conv): Conv2d(1280, 128, kernel_size=(1, 1), stride=(1, 1))\n", | |
| " )\n", | |
| " )\n", | |
| " (fpn_convs): ModuleList(\n", | |
| " (0): ConvModule(\n", | |
| " (conv): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n", | |
| " )\n", | |
| " (1): ConvModule(\n", | |
| " (conv): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n", | |
| " )\n", | |
| " (2): ConvModule(\n", | |
| " (conv): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n", | |
| " )\n", | |
| " (3): ConvModule(\n", | |
| " (conv): Conv2d(128, 128, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1))\n", | |
| " )\n", | |
| " (4): ConvModule(\n", | |
| " (conv): Conv2d(128, 128, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1))\n", | |
| " )\n", | |
| " )\n", | |
| " )\n", | |
| " init_cfg={'type': 'Xavier', 'layer': 'Conv2d', 'distribution': 'uniform'}\n", | |
| " (rbbox_head): FCOSRboxHead(\n", | |
| " (cls_loss_function): QualityFocalLoss()\n", | |
| " (cls_convs): ModuleList(\n", | |
| " (0): ConvModule(\n", | |
| " (conv): Conv2d(128, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n", | |
| " (gn): GroupNorm(32, 256, eps=1e-05, affine=True)\n", | |
| " (activate): ReLU(inplace=True)\n", | |
| " )\n", | |
| " (1): ConvModule(\n", | |
| " (conv): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n", | |
| " (gn): GroupNorm(32, 256, eps=1e-05, affine=True)\n", | |
| " (activate): ReLU(inplace=True)\n", | |
| " )\n", | |
| " (2): ConvModule(\n", | |
| " (conv): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n", | |
| " (gn): GroupNorm(32, 256, eps=1e-05, affine=True)\n", | |
| " (activate): ReLU(inplace=True)\n", | |
| " )\n", | |
| " (3): ConvModule(\n", | |
| " (conv): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n", | |
| " (gn): GroupNorm(32, 256, eps=1e-05, affine=True)\n", | |
| " (activate): ReLU(inplace=True)\n", | |
| " )\n", | |
| " )\n", | |
| " (reg_convs): ModuleList(\n", | |
| " (0): ConvModule(\n", | |
| " (conv): Conv2d(128, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n", | |
| " (gn): GroupNorm(32, 256, eps=1e-05, affine=True)\n", | |
| " (activate): ReLU(inplace=True)\n", | |
| " )\n", | |
| " (1): ConvModule(\n", | |
| " (conv): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n", | |
| " (gn): GroupNorm(32, 256, eps=1e-05, affine=True)\n", | |
| " (activate): ReLU(inplace=True)\n", | |
| " )\n", | |
| " (2): ConvModule(\n", | |
| " (conv): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n", | |
| " (gn): GroupNorm(32, 256, eps=1e-05, affine=True)\n", | |
| " (activate): ReLU(inplace=True)\n", | |
| " )\n", | |
| " (3): ConvModule(\n", | |
| " (conv): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n", | |
| " (gn): GroupNorm(32, 256, eps=1e-05, affine=True)\n", | |
| " (activate): ReLU(inplace=True)\n", | |
| " )\n", | |
| " )\n", | |
| " (fcos_cls): Conv2d(256, 15, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n", | |
| " (fcos_xy_reg): Conv2d(256, 2, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n", | |
| " (fcos_wh_reg): Conv2d(256, 2, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n", | |
| " (fcos_angle_reg): Conv2d(256, 1, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n", | |
| " (scales): ModuleList(\n", | |
| " (0): Scale()\n", | |
| " (1): Scale()\n", | |
| " (2): Scale()\n", | |
| " (3): Scale()\n", | |
| " (4): Scale()\n", | |
| " )\n", | |
| " )\n", | |
| " init_cfg={'type': 'Normal', 'layer': 'Conv2d', 'std': 0.01, 'override': {'type': 'Normal', 'name': 'fcos_cls', 'std': 0.01, 'bias_prob': 0.01}}\n", | |
| ")" | |
| ] | |
| }, | |
| "metadata": {}, | |
| "execution_count": 111 | |
| } | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "source": [ | |
| "Nboxes = 10\n", | |
| "Seed = 67\n", | |
| "\n", | |
| "Gen = np.random.default_rng(Seed)\n", | |
| "\n", | |
| "Img = torch.tensor(Gen.random((1, 3, 512, 512)), device='cuda', dtype=torch.float)\n", | |
| "\n", | |
| "Boxes = torch.tensor(Gen.random((Nboxes, 5)), device='cuda', dtype=torch.float)\n", | |
| "Boxes[:, :2] *= 256\n", | |
| "Boxes[:, :2] += 100\n", | |
| "Boxes[:, 2:4] *= 64\n", | |
| "Boxes[:, -1] %= np.pi/2\n", | |
| "\n", | |
| "Labels = torch.tensor(Gen.random((Nboxes)) * 5, device='cuda', dtype=torch.float).int().float()" | |
| ], | |
| "metadata": { | |
| "id": "TU_c2tSx6sVI" | |
| }, | |
| "execution_count": null, | |
| "outputs": [] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "source": [ | |
| "#COMPARAISON START" | |
| ], | |
| "metadata": { | |
| "id": "l3hVV5t0DXuV" | |
| } | |
| }, | |
| { | |
| "cell_type": "code", | |
| "source": [ | |
| "Fms = Model.extract_feat(Img)\n", | |
| "Fmshapes = [fm.shape[2:4] for fm in Fms]\n", | |
| "print(\n", | |
| " Fms[0][0, 34, 29, 3].item(),\n", | |
| " Fms[1][0, 4].sum().item(),\n", | |
| " Fms[2][0, 4].mean().item(),\n", | |
| " Fms[3][0, 1, -1, 4].item(),\n", | |
| " Fmshapes,\n", | |
| " sep='\\n',\n", | |
| ")" | |
| ], | |
| "metadata": { | |
| "colab": { | |
| "base_uri": "https://localhost:8080/" | |
| }, | |
| "id": "yJOYs_SHUZPX", | |
| "outputId": "381a70ab-d60a-4b69-f1ed-424a8af2b3e0" | |
| }, | |
| "execution_count": null, | |
| "outputs": [ | |
| { | |
| "output_type": "stream", | |
| "name": "stdout", | |
| "text": [ | |
| "0.8811362981796265\n", | |
| "-676.8612060546875\n", | |
| "-0.40830639004707336\n", | |
| "-1.0962724685668945\n", | |
| "[torch.Size([64, 64]), torch.Size([32, 32]), torch.Size([16, 16]), torch.Size([8, 8]), torch.Size([4, 4])]\n" | |
| ] | |
| } | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "source": [ | |
| "ClsLogits = torch.cat([cls_logits.flatten(2) for cls_logits in Model.rbbox_head.forward(Fms)[0]], dim=-1)\n", | |
| "RegLogits = torch.cat([reg_logits.flatten(2) for reg_logits in Model.rbbox_head.forward(Fms)[1]], dim=-1)\n", | |
| "\n", | |
| "print(\n", | |
| " ClsLogits.shape,\n", | |
| " ClsLogits[0, 3, 2903].item(),\n", | |
| " ClsLogits[0, 7, 28].item(),\n", | |
| " RegLogits.shape,\n", | |
| " RegLogits[0, 3, 2903].item(),\n", | |
| " RegLogits[0, 4, 28].item(),\n", | |
| " sep='\\n'\n", | |
| ")" | |
| ], | |
| "metadata": { | |
| "colab": { | |
| "base_uri": "https://localhost:8080/" | |
| }, | |
| "id": "r9ri5AFdenX8", | |
| "outputId": "6f1e6dc4-18dc-458f-d9af-a6d2c1d3857b" | |
| }, | |
| "execution_count": null, | |
| "outputs": [ | |
| { | |
| "output_type": "stream", | |
| "name": "stdout", | |
| "text": [ | |
| "torch.Size([1, 15, 5456])\n", | |
| "-7.740866184234619\n", | |
| "-5.994778633117676\n", | |
| "torch.Size([1, 5, 5456])\n", | |
| "46.02573776245117\n", | |
| "-0.07694123685359955\n" | |
| ] | |
| } | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "source": [ | |
| "Points, Strides = Model.rbbox_head.get_points([fm.shape[2:4] for fm in Fms], torch.float, 'cuda') \n", | |
| "ConcatPoints = torch.cat(Points, dim=0)\n", | |
| "\n", | |
| "xs = ConcatPoints[:, 0][:, None].repeat((1, Nboxes))\n", | |
| "ys = ConcatPoints[:, 1][:, None].repeat((1, Nboxes))\n", | |
| "boxes = Boxes[None].repeat(xs.size(0), 1, 1)\n", | |
| "Ngds = Model.rbbox_head.get_ngds_score(xs, ys, boxes, mode='shrink', version='v2')\n", | |
| "\n", | |
| "print(\n", | |
| " Ngds.shape,\n", | |
| " Ngds.sum(),\n", | |
| " Ngds.sum(0),\n", | |
| " sep='\\n'\n", | |
| ")" | |
| ], | |
| "metadata": { | |
| "colab": { | |
| "base_uri": "https://localhost:8080/" | |
| }, | |
| "id": "9yjI7VTrpHby", | |
| "outputId": "53d7b0e7-cd46-48ed-e0a0-ce1f08c9f8e4" | |
| }, | |
| "execution_count": null, | |
| "outputs": [ | |
| { | |
| "output_type": "stream", | |
| "name": "stdout", | |
| "text": [ | |
| "torch.Size([5456, 10])\n", | |
| "tensor(80.1257, device='cuda:0')\n", | |
| "tensor([7.1336e+00, 4.2219e+00, 3.5291e+00, 2.0138e-02, 2.4661e-04, 1.1857e+01,\n", | |
| " 1.4028e+01, 1.9670e+01, 7.0453e-01, 1.8961e+01], device='cuda:0')\n" | |
| ] | |
| } | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "source": [ | |
| "Points, Strides = Model.rbbox_head.get_points([fm.shape[2:4] for fm in Fms], torch.float, 'cuda') \n", | |
| "ConcatPoints = torch.cat(Points, dim=0)\n", | |
| "\n", | |
| "xs = ConcatPoints[:, 0][:, None].repeat((1, Nboxes))\n", | |
| "ys = ConcatPoints[:, 1][:, None].repeat((1, Nboxes))\n", | |
| "boxes = Boxes[None].repeat(xs.size(0), 1, 1)\n", | |
| "Rgds = Model.rbbox_head.get_gds_score(xs, ys, boxes, mode='shrink', refined=True) * 100000\n", | |
| "\n", | |
| "print(\n", | |
| " Rgds.shape,\n", | |
| " Rgds.sum(),\n", | |
| " Rgds.sum(dim=0),\n", | |
| " sep='\\n'\n", | |
| ")" | |
| ], | |
| "metadata": { | |
| "colab": { | |
| "base_uri": "https://localhost:8080/" | |
| }, | |
| "id": "T0I1ZfZZEguy", | |
| "outputId": "644d2f32-859e-4dd6-dcbb-e8a5ab232258" | |
| }, | |
| "execution_count": null, | |
| "outputs": [ | |
| { | |
| "output_type": "stream", | |
| "name": "stdout", | |
| "text": [ | |
| "torch.Size([5456, 10])\n", | |
| "tensor(467617.0625, device='cuda:0')\n", | |
| "tensor([5.2169e+04, 4.2096e+04, 3.6243e+04, 1.0744e+03, 1.6754e+01, 6.8975e+04,\n", | |
| " 7.4833e+04, 8.7638e+04, 1.8392e+04, 8.6179e+04], device='cuda:0')\n" | |
| ] | |
| } | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "source": [ | |
| "#UP TO HERE, EVERYTHING IS OK" | |
| ], | |
| "metadata": { | |
| "id": "mMM3D7g1COTA" | |
| } | |
| }, | |
| { | |
| "cell_type": "code", | |
| "source": [ | |
| "Model.forward_train(Img, [{}], [Boxes], [Labels])" | |
| ], | |
| "metadata": { | |
| "colab": { | |
| "base_uri": "https://localhost:8080/" | |
| }, | |
| "id": "g0L_DrxpydR0", | |
| "outputId": "dcbb78f7-1f8f-4b2a-c9b0-0a4e743d21e4" | |
| }, | |
| "execution_count": null, | |
| "outputs": [ | |
| { | |
| "output_type": "execute_result", | |
| "data": { | |
| "text/plain": [ | |
| "{'IOU_mean': tensor([0.3040], device='cuda:0'),\n", | |
| " 'loss_ProbiouLoss': tensor([0.4779], device='cuda:0', grad_fn=<DivBackward0>),\n", | |
| " 'loss_QualityFocalLoss': tensor([0.3024], device='cuda:0', grad_fn=<UnsqueezeBackward0>)}" | |
| ] | |
| }, | |
| "metadata": {}, | |
| "execution_count": 135 | |
| } | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "source": [ | |
| "LvlTargetLabels, LvlTargetBoxes, LvlGscores, LvlIds = Model.rbbox_head.fcos_target(Points, [Boxes], [Labels], Strides)\n", | |
| "TargetLabels = torch.cat(LvlTargetLabels)" | |
| ], | |
| "metadata": { | |
| "id": "M1xev6snaWtl" | |
| }, | |
| "execution_count": null, | |
| "outputs": [] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "source": [ | |
| "print(\n", | |
| " TargetLabels.shape,\n", | |
| " TargetLabels.sum(),\n", | |
| " sep='\\n',\n", | |
| ")" | |
| ], | |
| "metadata": { | |
| "colab": { | |
| "base_uri": "https://localhost:8080/" | |
| }, | |
| "id": "NTiqKRWmb2ck", | |
| "outputId": "df491e98-c075-426e-c21e-f4622d87daf6" | |
| }, | |
| "execution_count": null, | |
| "outputs": [ | |
| { | |
| "output_type": "stream", | |
| "name": "stdout", | |
| "text": [ | |
| "torch.Size([5456])\n", | |
| "tensor(81343., device='cuda:0')\n" | |
| ] | |
| } | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "source": [ | |
| "import matplotlib.pyplot as plt\n", | |
| "from math import sqrt\n", | |
| "\n", | |
| "for lvl_target_labels in LvlTargetLabels:\n", | |
| " side = int(sqrt(lvl_target_labels.size(0)))\n", | |
| " plt.imshow((lvl_target_labels != 15).view((side, side)).cpu().numpy())\n", | |
| " plt.show()" | |
| ], | |
| "metadata": { | |
| "colab": { | |
| "base_uri": "https://localhost:8080/", | |
| "height": 1000 | |
| }, | |
| "id": "nOA9Su17i3FB", | |
| "outputId": "2e7dc39a-47e6-4cae-f5a5-80040ca315e4" | |
| }, | |
| "execution_count": null, | |
| "outputs": [ | |
| { | |
| "output_type": "display_data", | |
| "data": { | |
| "text/plain": [ | |
| "<Figure size 432x288 with 1 Axes>" | |
| ], | |
| "image/png": "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\n" | |
| }, | |
| "metadata": { | |
| "needs_background": "light" | |
| } | |
| }, | |
| { | |
| "output_type": "display_data", | |
| "data": { | |
| "text/plain": [ | |
| "<Figure size 432x288 with 1 Axes>" | |
| ], | |
| "image/png": "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\n" | |
| }, | |
| "metadata": { | |
| "needs_background": "light" | |
| } | |
| }, | |
| { | |
| "output_type": "display_data", | |
| "data": { | |
| "text/plain": [ | |
| "<Figure size 432x288 with 1 Axes>" | |
| ], | |
| "image/png": "iVBORw0KGgoAAAANSUhEUgAAAP8AAAD4CAYAAAAjDTByAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4yLjIsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+WH4yJAAAMnklEQVR4nO3df6wl5V3H8fdHFljZIiyilAIRaAgJNipkg7Q22LiKCxK2Jv1jiVUoTTaNomBqyFYS2/hXa7X+bNogoFQJNFKwpAHLSts0JrJ2WZefS8uCCKwLi2KgthFY+/WPM2vuXu7dvZwzM9z1eb+SkzNn5jlnvvc593Pnx53Mk6pCUnu+780uQNKbw/BLjTL8UqMMv9Qowy81asWYKzsiR9ZKVo25Sqkp/813eLVeyVLajhr+laziJ7N2zFVKTdlS9y65rbv9UqMMv9SomcKfZF2SbybZmWRTX0VJGt7U4U9yGPBp4ELgLODSJGf1VZikYc2y5T8X2FlVT1bVq8CtwPp+ypI0tFnCfxLwzJzXz3bz9pNkY5KtSba+xiszrE5SnwY/4VdV11XVmqpaczhHDr06SUs0S/h3AafMeX1yN0/SIWCW8H8DOCPJaUmOADYAd/ZTlqShTX2FX1XtTXIl8GXgMODGqnqkt8okDWqmy3ur6i7grp5qkTQir/CTGmX4pUYZfqlRhl9qlOGXGmX4pUYZfqlRhl9qlOGXGmX4pUYZfqlRhl9qlOGXGmX4pUYZfqlRhl9qlOGXGmX4pUbNMmLPKUm+muTRJI8kuarPwiQNa5Z7+O0FPlxV25IcDdyfZHNVPdpTbZIGNPWWv6p2V9W2bvrbwA4WGLFH0vI0091790lyKnA2sGWBZRuBjQArOaqP1Unqwcwn/JK8BfgCcHVVvTx/ucN1ScvTTOFPcjiT4N9cVbf3U5KkMcxytj/ADcCOqvpUfyVJGsMsW/6fAn4Z+Jkk27vHRT3VJWlgs4zV9w9AeqxF0oi8wk9qlOGXGmX4pUYZfqlRhl9qlOGXGmX4pUYZfqlRhl9qlOGXGmX4pUYZfqlRhl9qlOGXGmX4pUYZfqlRhl9qlOGXGtXHrbsPS/LPSb7UR0GSxtHHlv8qJqP1SDqEzHrf/pOBXwCu76ccSWOZdcv/R8A1wPd6qEXSiGYZtONiYE9V3X+QdhuTbE2y9TVemXZ1kno266AdlyR5CriVyeAdfz2/kWP1ScvTLEN0f6SqTq6qU4ENwFeq6v29VSZpUP6fX2rU1MN1zVVVXwO+1sdnSRqHW36pUYZfapThlxpl+KVGGX6pUYZfapThlxpl+KVGGX6pUYZfapThlxpl+KVGGX6pUYZfapThlxpl+KVGGX6pUYZfapThlxo164g9xya5LcljSXYkeWdfhUka1qw38Pxj4O+q6n1JjgCO6qEmSSOYOvxJjgHOBy4HqKpXgVf7KUvS0GbZ7T8NeAH4i26I7uuTrJrfyOG6pOVplvCvAM4BPlNVZwPfATbNb+RwXdLyNEv4nwWeraot3evbmPwxkHQImGWsvueAZ5Kc2c1aCzzaS1WSBjfr2f5fB27uzvQ/CXxg9pIkjWGm8FfVdmBNT7VIGpFX+EmNMvxSowy/1CjDLzXK8EuNMvxSowy/1CjDLzXK8EuNMvxSowy/1CjDLzXK8EuNMvxSowy/1CjDLzXK8EuNMvxSo2Ydrus3kzyS5OEktyRZ2VdhkoY1dfiTnAT8BrCmqt4BHAZs6KswScOadbd/BfD9SVYwGafv32YvSdIYZrlv/y7g94Gngd3AS1V1z/x2DtclLU+z7PavBtYzGbPvbcCqJO+f387huqTlaZbd/p8F/qWqXqiq14DbgXf1U5akoc0S/qeB85IclSRMhuva0U9ZkoY2yzH/FiaDc24DHuo+67qe6pI0sFmH6/oo8NGeapE0Iq/wkxpl+KVGGX6pUYZfapThlxpl+KVGGX6pUYZfapThlxpl+KVGGX6pUYZfapThlxpl+KVGGX6pUYZfapThlxpl+KVGHTT8SW5MsifJw3PmHZdkc5LHu+fVw5YpqW9L2fL/JbBu3rxNwL1VdQZwb/da0iHkoOGvqq8DL86bvR64qZu+CXhvz3VJGti0d+89oap2d9PPAScs1jDJRmAjwEqOmnJ1kvo28wm/qiqgDrDc4bqkZWja8D+f5ESA7nlPfyVJGsO04b8TuKybvgz4Yj/lSBrLUv7Vdwvwj8CZSZ5N8kHg48DPJXmcyYCdHx+2TEl9O+gJv6q6dJFFa3uuRdKIvMJPapThlxpl+KVGGX6pUYZfapThlxpl+KVGGX6pUYZfapThlxpl+KVGGX6pUYZfapThlxpl+KVGGX6pUYZfapThlxo17XBdn0zyWJIHk9yR5Nhhy5TUt2mH69oMvKOqfgz4FvCRnuuSNLCphuuqqnuqam/38j7g5AFqkzSgPo75rwDuXmxhko1JtibZ+hqv9LA6SX2YKfxJrgX2Ajcv1sbhuqTladqBOklyOXAxsLYbr0/SIWSq8CdZB1wD/HRVfbffkiSNYdrhuv4MOBrYnGR7ks8OXKeknk07XNcNA9QiaURe4Sc1yvBLjTL8UqMMv9Qowy81yvBLjTL8UqMMv9Qowy81yvBLjTL8UqMMv9Qowy81yvBLjTL8UqMMv9Qowy81yvBLjZpquK45yz6cpJIcP0x5koYy7XBdJDkFuAB4uueaJI1gquG6On/I5Pbd3rNfOgRNdcyfZD2wq6oeWEJbh+uSlqE3PGhHkqOA32ayy39QVXUdcB3AD+Q49xKkZWKaLf/bgdOAB5I8xWSE3m1J3tpnYZKG9Ya3/FX1EPDD+153fwDWVNW/91iXpIFNO1yXpEPctMN1zV1+am/VSBqNV/hJjTL8UqMMv9Qowy81yvBLjTL8UqMMv9Qowy81yvBLjTL8UqMMv9Qowy81yvBLjTL8UqMMv9SoVI13W70kLwD/usji44HlcDcg69ifdexvudfxI1X1Q0v5gFHDfyBJtlbVGuuwDusYpw53+6VGGX6pUcsp/Ne92QV0rGN/1rG//zd1LJtjfknjWk5bfkkjMvxSo0YNf5J1Sb6ZZGeSTQssPzLJ57vlW5KcOkANpyT5apJHkzyS5KoF2rwnyUtJtneP3+m7jjnreirJQ916ti6wPEn+pOuTB5Oc0/P6z5zzc25P8nKSq+e1Gaw/ktyYZE+Sh+fMOy7J5iSPd8+rF3nvZV2bx5NcNkAdn0zyWNfvdyQ5dpH3HvA77KGOjyXZNaf/L1rkvQfM1+tU1SgP4DDgCeB04AjgAeCseW1+FfhsN70B+PwAdZwInNNNHw18a4E63gN8aaR+eQo4/gDLLwLuBgKcB2wZ+Dt6jsmFIqP0B3A+cA7w8Jx5vwds6qY3AZ9Y4H3HAU92z6u76dU913EBsKKb/sRCdSzlO+yhjo8Bv7WE7+6A+Zr/GHPLfy6ws6qerKpXgVuB9fParAdu6qZvA9YmSZ9FVNXuqtrWTX8b2AGc1Oc6erYe+FxN3Accm+TEgda1Fniiqha7CrN3VfV14MV5s+f+HtwEvHeBt/48sLmqXqyq/wQ2A+v6rKOq7qmqvd3L+5gMSjuoRfpjKZaSr/2MGf6TgGfmvH6W14fu/9p0nf4S8INDFdQdVpwNbFlg8TuTPJDk7iQ/OlQNQAH3JLk/ycYFli+l3/qyAbhlkWVj9QfACVW1u5t+DjhhgTZj9gvAFUz2wBZysO+wD1d2hx83LnIY9Ib7o9kTfkneAnwBuLqqXp63eBuTXd8fB/4U+NsBS3l3VZ0DXAj8WpLzB1zXopIcAVwC/M0Ci8fsj/3UZJ/2Tf1/dJJrgb3AzYs0Gfo7/AzwduAngN3AH/TxoWOGfxdwypzXJ3fzFmyTZAVwDPAffReS5HAmwb+5qm6fv7yqXq6q/+qm7wIOT3J833V0n7+re94D3MFk922upfRbHy4EtlXV8wvUOFp/dJ7fd2jTPe9ZoM0o/ZLkcuBi4Je6P0Svs4TvcCZV9XxV/U9VfQ/480U+/w33x5jh/wZwRpLTuq3MBuDOeW3uBPadtX0f8JXFOnxa3TmEG4AdVfWpRdq8dd+5hiTnMumnIf4IrUpy9L5pJieYHp7X7E7gV7qz/ucBL83ZJe7TpSyyyz9Wf8wx9/fgMuCLC7T5MnBBktXdbvAF3bzeJFkHXANcUlXfXaTNUr7DWeuYe47nFxf5/KXka399nKF8A2cyL2Jydv0J4Npu3u8y6VyAlUx2O3cC/wScPkAN72ayG/kgsL17XAR8CPhQ1+ZK4BEmZ0zvA941UH+c3q3jgW59+/pkbi0BPt312UPAmgHqWMUkzMfMmTdKfzD5g7MbeI3JceoHmZznuRd4HPh74Liu7Rrg+jnvvaL7XdkJfGCAOnYyOY7e93uy7z9RbwPuOtB32HMdf9V99w8yCfSJ8+tYLF8Henh5r9SoZk/4Sa0z/FKjDL/UKMMvNcrwS40y/FKjDL/UqP8Fv8yiAydROuQAAAAASUVORK5CYII=\n" | |
| }, | |
| "metadata": { | |
| "needs_background": "light" | |
| } | |
| }, | |
| { | |
| "output_type": "display_data", | |
| "data": { | |
| "text/plain": [ | |
| "<Figure size 432x288 with 1 Axes>" | |
| ], | |
| "image/png": "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\n" | |
| }, | |
| "metadata": { | |
| "needs_background": "light" | |
| } | |
| }, | |
| { | |
| "output_type": "display_data", | |
| "data": { | |
| "text/plain": [ | |
| "<Figure size 432x288 with 1 Axes>" | |
| ], | |
| "image/png": "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\n" | |
| }, | |
| "metadata": { | |
| "needs_background": "light" | |
| } | |
| } | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "source": [ | |
| "" | |
| ], | |
| "metadata": { | |
| "id": "fhrSoL1-lH1p" | |
| }, | |
| "execution_count": null, | |
| "outputs": [] | |
| } | |
| ] | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment