From dc28cbe2b4ed77be92ee8b2b69a20689c3bf02a4 Mon Sep 17 00:00:00 2001 From: aktersnurra Date: Sun, 8 Nov 2020 14:54:44 +0100 Subject: new updates --- src/notebooks/Untitled.ipynb | 893 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 893 insertions(+) create mode 100644 src/notebooks/Untitled.ipynb (limited to 'src/notebooks/Untitled.ipynb') diff --git a/src/notebooks/Untitled.ipynb b/src/notebooks/Untitled.ipynb new file mode 100644 index 0000000..f114ed9 --- /dev/null +++ b/src/notebooks/Untitled.ipynb @@ -0,0 +1,893 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "%load_ext autoreload\n", + "%autoreload 2\n", + "\n", + "import importlib\n", + "import cv2\n", + "import yaml\n", + "\n", + "%matplotlib inline\n", + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "import torch\n", + "from torch import nn\n", + "from importlib.util import find_spec\n", + "if find_spec(\"text_recognizer\") is None:\n", + " import sys\n", + " sys.path.append('..')" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "def convert_y_label_to_string(y, dataset):\n", + " return ''.join([dataset.mapper(int(i)) for i in y])" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "from text_recognizer.models import VisionTransformerModel, TransformerEncoderModel\n", + "from text_recognizer.datasets import IamLinesDataset\n", + "from text_recognizer.datasets.transforms import Compose, AddTokens" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [], + "source": [ + "target_transform = Compose([torch.tensor, AddTokens(init_token=\"\", pad_token=\"_\", eos_token=\"\")])\n", + "dataset = IamLinesDataset(train=False, init_token=\"\", pad_token=\"_\", eos_token=\"\", target_transform=target_transform)\n", + "dataset.load_or_generate_data()" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "config_path = \"../training/experiments/VisionTransformerModel_IamLinesDataset_CNNTransformer/1102_221553/config.yml\"\n", + "with open(config_path, \"r\") as f:\n", + " experiment_config = yaml.safe_load(f)" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "dataset_args = experiment_config.get(\"dataset\", {})\n", + "datasets_module = importlib.import_module(\"text_recognizer.datasets\")\n", + "dataset_ = getattr(datasets_module, dataset_args[\"type\"])\n", + "\n", + "network_module = importlib.import_module(\"text_recognizer.networks\")\n", + "network_fn_ = getattr(network_module, experiment_config[\"network\"][\"type\"])" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2020-11-03 07:32:07.256 | DEBUG | text_recognizer.models.base:load_weights:457 - Loading network with pretrained weights.\n" + ] + } + ], + "source": [ + "model = VisionTransformerModel(network_fn=network_fn_, dataset=dataset_, dataset_args=dataset_args)" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2020-11-03 07:32:10.285 | DEBUG | text_recognizer.models.base:load_from_checkpoint:404 - Loading checkpoint...\n" + ] + } + ], + "source": [ + "checkpoint_path = \"../training/experiments/VisionTransformerModel_IamLinesDataset_CNNTransformer/1102_221553/model/last.pt\"\n", + "model.load_from_checkpoint(checkpoint_path)" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [ + "model.eval()" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [], + "source": [ + "data, target = dataset[0]\n", + "sentence = convert_y_label_to_string(target, dataset) " + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "torch.Size([98])" + ] + }, + "execution_count": 25, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "target.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "([], [])" + ] + }, + "execution_count": 26, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plt.figure(figsize=(20, 20))\n", + "plt.title(sentence)\n", + "plt.imshow(data.squeeze(0).numpy(), cmap='gray')\n", + "plt.xticks([])\n", + "plt.yticks([])" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": {}, + "outputs": [], + "source": [ + " def make_len_mask(inp):\n", + " return (inp == 79).transpose(0, 1)" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "torch.Size([98, 1])" + ] + }, + "execution_count": 34, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "make_len_mask(target.unsqueeze(0)).shape" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "('to stel mire of a thar chishirchit', 0.20226626098155975)" + ] + }, + "execution_count": 27, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "model.predict_on_image(data)" + ] + }, + { + "cell_type": "code", + "execution_count": 103, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2020-10-31 16:35:40.255 | DEBUG | text_recognizer.models.base:load_weights:457 - Loading network with pretrained weights.\n", + "2020-10-31 16:35:40.837 | DEBUG | text_recognizer.models.base:load_from_checkpoint:404 - Loading checkpoint...\n" + ] + } + ], + "source": [ + "target_transform = Compose([torch.tensor, AddTokens(pad_token=\"_\", eos_token=\"\")])\n", + "dataset = IamLinesDataset(train=False, pad_token=\"_\", eos_token=\"\", target_transform=target_transform)\n", + "dataset.load_or_generate_data()\n", + "\n", + "\n", + "config_path = \"../training/experiments/TransformerEncoderModel_IamLinesDataset_CNNTransformerEncoder/1031_150630/config.yml\"\n", + "with open(config_path, \"r\") as f:\n", + " experiment_config = yaml.safe_load(f)\n", + "\n", + "\n", + "dataset_args = experiment_config.get(\"dataset\", {})\n", + "datasets_module = importlib.import_module(\"text_recognizer.datasets\")\n", + "dataset_ = getattr(datasets_module, dataset_args[\"type\"])\n", + "\n", + "network_module = importlib.import_module(\"text_recognizer.networks\")\n", + "network_fn_ = getattr(network_module, experiment_config[\"network\"][\"type\"])\n", + "\n", + "\n", + "checkpoint_path = \"../training/experiments/TransformerEncoderModel_IamLinesDataset_CNNTransformerEncoder/1031_150630/model/last.pt\"\n", + "\n", + "\n", + "model = TransformerEncoderModel(network_fn=network_fn_, dataset=dataset_, dataset_args=dataset_args)\n", + "model.load_from_checkpoint(checkpoint_path)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 92, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "===============================================================================================\n", + "Layer (type:depth-idx) Output Shape Param #\n", + "===============================================================================================\n", + "├─WideResidualNetwork: 1-1 [-1, 256, 2, 60] --\n", + "| └─Sequential: 2-1 [-1, 256, 2, 60] --\n", + "| | └─Conv2d: 3-1 [-1, 8, 28, 952] 72\n", + "| | └─Sequential: 3-2 [-1, 16, 28, 952] --\n", + "| | | └─WideBlock: 4-1 [-1, 16, 28, 952] 3,632\n", + "| | └─Sequential: 3-3 [-1, 32, 14, 476] --\n", + "| | | └─WideBlock: 4-2 [-1, 32, 14, 476] 14,432\n", + "| | └─Sequential: 3-4 [-1, 64, 7, 238] --\n", + "| | | └─WideBlock: 4-3 [-1, 64, 7, 238] 57,536\n", + "| | └─Sequential: 3-5 [-1, 128, 4, 119] --\n", + "| | | └─WideBlock: 4-4 [-1, 128, 4, 119] 229,760\n", + "| | └─Sequential: 3-6 [-1, 256, 2, 60] --\n", + "| | | └─WideBlock: 4-5 [-1, 256, 2, 60] 918,272\n", + "├─Conv2d: 1-2 [-1, 97, 2, 60] 24,929\n", + "├─Linear: 1-3 [-1, 97, 96] 11,616\n", + "├─PositionalEncoding: 1-4 [-1, 97, 96] --\n", + "| └─Dropout: 2-2 [-1, 97, 96] --\n", + "├─TransformerEncoder: 1-5 [-1, 2, 96] --\n", + "| └─ModuleList: 2 [] --\n", + "| | └─TransformerEncoderLayer: 3-7 [-1, 2, 96] --\n", + "| | | └─MultiheadAttention: 4-6 [-1, 2, 96] 37,248\n", + "| | | └─Dropout: 4-7 [-1, 2, 96] --\n", + "| | | └─LayerNorm: 4-8 [-1, 2, 96] 192\n", + "| | | └─Linear: 4-9 [-1, 2, 2048] 198,656\n", + "| | | └─Dropout: 4-10 [-1, 2, 2048] --\n", + "| | | └─Linear: 4-11 [-1, 2, 96] 196,704\n", + "| | | └─Dropout: 4-12 [-1, 2, 96] --\n", + "| | | └─LayerNorm: 4-13 [-1, 2, 96] 192\n", + "| | └─TransformerEncoderLayer: 3-8 [-1, 2, 96] --\n", + "| | | └─MultiheadAttention: 4-14 [-1, 2, 96] 37,248\n", + "| | | └─Dropout: 4-15 [-1, 2, 96] --\n", + "| | | └─LayerNorm: 4-16 [-1, 2, 96] 192\n", + "| | | └─Linear: 4-17 [-1, 2, 2048] 198,656\n", + "| | | └─Dropout: 4-18 [-1, 2, 2048] --\n", + "| | | └─Linear: 4-19 [-1, 2, 96] 196,704\n", + "| | | └─Dropout: 4-20 [-1, 2, 96] --\n", + "| | | └─LayerNorm: 4-21 [-1, 2, 96] 192\n", + "| | └─TransformerEncoderLayer: 3-9 [-1, 2, 96] --\n", + "| | | └─MultiheadAttention: 4-22 [-1, 2, 96] 37,248\n", + "| | | └─Dropout: 4-23 [-1, 2, 96] --\n", + "| | | └─LayerNorm: 4-24 [-1, 2, 96] 192\n", + "| | | └─Linear: 4-25 [-1, 2, 2048] 198,656\n", + "| | | └─Dropout: 4-26 [-1, 2, 2048] --\n", + "| | | └─Linear: 4-27 [-1, 2, 96] 196,704\n", + "| | | └─Dropout: 4-28 [-1, 2, 96] --\n", + "| | | └─LayerNorm: 4-29 [-1, 2, 96] 192\n", + "| | └─TransformerEncoderLayer: 3-10 [-1, 2, 96] --\n", + "| | | └─MultiheadAttention: 4-30 [-1, 2, 96] 37,248\n", + "| | | └─Dropout: 4-31 [-1, 2, 96] --\n", + "| | | └─LayerNorm: 4-32 [-1, 2, 96] 192\n", + "| | | └─Linear: 4-33 [-1, 2, 2048] 198,656\n", + "| | | └─Dropout: 4-34 [-1, 2, 2048] --\n", + "| | | └─Linear: 4-35 [-1, 2, 96] 196,704\n", + "| | | └─Dropout: 4-36 [-1, 2, 96] --\n", + "| | | └─LayerNorm: 4-37 [-1, 2, 96] 192\n", + "| | └─TransformerEncoderLayer: 3-11 [-1, 2, 96] --\n", + "| | | └─MultiheadAttention: 4-38 [-1, 2, 96] 37,248\n", + "| | | └─Dropout: 4-39 [-1, 2, 96] --\n", + "| | | └─LayerNorm: 4-40 [-1, 2, 96] 192\n", + "| | | └─Linear: 4-41 [-1, 2, 2048] 198,656\n", + "| | | └─Dropout: 4-42 [-1, 2, 2048] --\n", + "| | | └─Linear: 4-43 [-1, 2, 96] 196,704\n", + "| | | └─Dropout: 4-44 [-1, 2, 96] --\n", + "| | | └─LayerNorm: 4-45 [-1, 2, 96] 192\n", + "| | └─TransformerEncoderLayer: 3-12 [-1, 2, 96] --\n", + "| | | └─MultiheadAttention: 4-46 [-1, 2, 96] 37,248\n", + "| | | └─Dropout: 4-47 [-1, 2, 96] --\n", + "| | | └─LayerNorm: 4-48 [-1, 2, 96] 192\n", + "| | | └─Linear: 4-49 [-1, 2, 2048] 198,656\n", + "| | | └─Dropout: 4-50 [-1, 2, 2048] --\n", + "| | | └─Linear: 4-51 [-1, 2, 96] 196,704\n", + "| | | └─Dropout: 4-52 [-1, 2, 96] --\n", + "| | | └─LayerNorm: 4-53 [-1, 2, 96] 192\n", + "| └─LayerNorm: 2-3 [-1, 2, 96] 192\n", + "├─Linear: 1-6 [-1, 97, 81] 7,857\n", + "===============================================================================================\n", + "Total params: 3,866,250\n", + "Trainable params: 3,866,250\n", + "Non-trainable params: 0\n", + "Total mult-adds (M): 18.78\n", + "===============================================================================================\n", + "Input size (MB): 0.10\n", + "Forward/backward pass size (MB): 2.06\n", + "Params size (MB): 14.75\n", + "Estimated Total Size (MB): 16.91\n", + "===============================================================================================\n" + ] + } + ], + "source": [ + "model.summary(experiment_config[\"train_args\"][\"input_shape\"], 4)" + ] + }, + { + "cell_type": "code", + "execution_count": 110, + "metadata": {}, + "outputs": [], + "source": [ + "data, target = dataset[110]\n", + "sentence = convert_y_label_to_string(target, dataset) " + ] + }, + { + "cell_type": "code", + "execution_count": 111, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "([], [])" + ] + }, + "execution_count": 111, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plt.figure(figsize=(20, 20))\n", + "plt.title(sentence)\n", + "plt.imshow(data.squeeze(0).numpy(), cmap='gray')\n", + "plt.xticks([])\n", + "plt.yticks([])" + ] + }, + { + "cell_type": "code", + "execution_count": 112, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "('Boyis cheed iitrincy- tarisaing one', 0.3990435302257538)" + ] + }, + "execution_count": 112, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "model.predict_on_image(data)" + ] + }, + { + "cell_type": "code", + "execution_count": 95, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[[1, 28, 952], [92]]" + ] + }, + "execution_count": 95, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "experiment_config[\"train_args\"][\"input_shape\"]" + ] + }, + { + "cell_type": "code", + "execution_count": 99, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "=========================================================================================================\n", + "Layer (type:depth-idx) Output Shape Param #\n", + "=========================================================================================================\n", + "├─Sequential: 1-1 [-1, 158, 1, 28, 6] --\n", + "| └─Unfold: 2-1 [-1, 168, 158] --\n", + "| └─Rearrange: 2-2 [-1, 158, 1, 28, 6] --\n", + "├─Linear: 1-2 [-1, 158, 512] 86,528\n", + "├─PositionalEncoding: 1-3 [-1, 158, 512] --\n", + "| └─Dropout: 2-3 [-1, 158, 512] --\n", + "├─Embedding: 1-4 [-1, 92, 512] 41,984\n", + "├─PositionalEncoding: 1-5 [-1, 92, 512] --\n", + "| └─Dropout: 2-4 [-1, 92, 512] --\n", + "├─Transformer: 1-6 [-1, 92, 512] --\n", + "| └─Encoder: 2-5 [-1, 158, 512] --\n", + "| | └─ModuleList: 3 [] --\n", + "| | | └─EncoderLayer: 4-1 [-1, 158, 512] 3,150,848\n", + "| | | └─EncoderLayer: 4-2 [-1, 158, 512] 3,150,848\n", + "| | | └─EncoderLayer: 4-3 [-1, 158, 512] 3,150,848\n", + "| | | └─EncoderLayer: 4-4 [-1, 158, 512] 3,150,848\n", + "| | └─LayerNorm: 3-1 [-1, 158, 512] 1,024\n", + "| └─Decoder: 2-6 [-1, 92, 512] --\n", + "| | └─ModuleList: 3 [] --\n", + "| | | └─DecoderLayer: 4-5 [-1, 92, 512] 4,200,960\n", + "| | | └─DecoderLayer: 4-6 [-1, 92, 512] 4,200,960\n", + "| | | └─DecoderLayer: 4-7 [-1, 92, 512] 4,200,960\n", + "| | | └─DecoderLayer: 4-8 [-1, 92, 512] 4,200,960\n", + "| | └─LayerNorm: 3-2 [-1, 92, 512] 1,024\n", + "├─Sequential: 1-7 [-1, 92, 82] --\n", + "| └─LayerNorm: 2-7 [-1, 92, 512] 1,024\n", + "| └─Linear: 2-8 [-1, 92, 512] 262,656\n", + "| └─GELU: 2-9 [-1, 92, 512] --\n", + "| └─Dropout: 2-10 [-1, 92, 512] --\n", + "| └─Linear: 2-11 [-1, 92, 82] 42,066\n", + "=========================================================================================================\n", + "Total params: 29,843,538\n", + "Trainable params: 29,843,538\n", + "Non-trainable params: 0\n", + "Total mult-adds (M): 118.22\n", + "=========================================================================================================\n", + "Input size (MB): 0.10\n", + "Forward/backward pass size (MB): 2.73\n", + "Params size (MB): 113.84\n", + "Estimated Total Size (MB): 116.68\n", + "=========================================================================================================\n" + ] + } + ], + "source": [ + "model.summary(experiment_config[\"train_args\"][\"input_shape\"], 4)" + ] + }, + { + "cell_type": "code", + "execution_count": 61, + "metadata": {}, + "outputs": [], + "source": [ + "t=[12,1,1,1,1,1,4,4,4,4,4]" + ] + }, + { + "cell_type": "code", + "execution_count": 62, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "1" + ] + }, + "execution_count": 62, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "t[t!=79]" + ] + }, + { + "cell_type": "code", + "execution_count": 63, + "metadata": {}, + "outputs": [], + "source": [ + "x = torch.arange(10)\n", + "value = 5\n", + "x = x[x!=value]" + ] + }, + { + "cell_type": "code", + "execution_count": 64, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "tensor([0, 1, 2, 3, 4, 6, 7, 8, 9])" + ] + }, + "execution_count": 64, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "x" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "t = torch.rand(98)" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "tensor(1.7656e-43)" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "t.cumprod(dim=0)[-1]" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [], + "source": [ + "pred_tokens = torch.Tensor([1,2,21,31, 89, 89])" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [], + "source": [ + "pred_tokens = torch.stack([pred_tokens, pred_tokens])" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "tensor([[ 1., 2., 21., 31., 89., 89.],\n", + " [ 1., 2., 21., 31., 89., 89.]])" + ] + }, + "execution_count": 26, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pred_tokens" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [], + "source": [ + "eos_token_index = torch.nonzero(\n", + " pred_tokens == 89, as_tuple=False,\n", + " )" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0\n" + ] + } + ], + "source": [ + "if eos_token_index.nelement():\n", + " print(eos_token_index[0][0].item())" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "tensor([[0, 4],\n", + " [0, 5],\n", + " [1, 4],\n", + " [1, 5]])" + ] + }, + "execution_count": 32, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "eos_token_index" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "8" + ] + }, + "execution_count": 29, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "eos_token_index.nelement()" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "metadata": {}, + "outputs": [], + "source": [ + "from text_recognizer.models import accuracy" + ] + }, + { + "cell_type": "code", + "execution_count": 44, + "metadata": {}, + "outputs": [], + "source": [ + "pred = torch.Tensor([1,2,21,31, 80, 80]).unsqueeze(0)\n", + "target = torch.Tensor([1,2,1,31, 80, 80]).unsqueeze(0)" + ] + }, + { + "cell_type": "code", + "execution_count": 57, + "metadata": {}, + "outputs": [], + "source": [ + "pred = torch.stack([pred, pred])\n", + "target = torch.stack([target, target])" + ] + }, + { + "cell_type": "code", + "execution_count": 115, + "metadata": {}, + "outputs": [], + "source": [ + "target = torch.tensor([0, 1, 2, 3])\n", + "pred = torch.tensor([0, 2, 1, 3])" + ] + }, + { + "cell_type": "code", + "execution_count": 116, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0.5" + ] + }, + "execution_count": 116, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "accuracy(pred, target)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 53, + "metadata": {}, + "outputs": [], + "source": [ + "acc = (target.argmax(-1) == pred.argmax(-1)).float()\n", + "\n", + "# return float(100 * acc.sum() / len(acc))" + ] + }, + { + "cell_type": "code", + "execution_count": 54, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "tensor([[1.],\n", + " [1.]])" + ] + }, + "execution_count": 54, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "acc" + ] + }, + { + "cell_type": "code", + "execution_count": 58, + "metadata": {}, + "outputs": [], + "source": [ + "train_acc = (pred == target).sum().item()/target.shape[-1]" + ] + }, + { + "cell_type": "code", + "execution_count": 59, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "3.3333333333333335" + ] + }, + "execution_count": 59, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "train_acc" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "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.7.4" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} -- cgit v1.2.3-70-g09d2