{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "imports imported\n"
     ]
    }
   ],
   "source": [
    "#import numpy as np\n",
    "import numpy as np\n",
    "import torch\n",
    "import cv2\n",
    "\n",
    "import matplotlib.pyplot as plt\n",
    "from torch import optim, nn\n",
    "import torchvision\n",
    "from torchvision import datasets, models, transforms\n",
    "import albumentations as A\n",
    "from albumentations.pytorch import ToTensorV2\n",
    "\n",
    "\n",
    "print(\"imports imported\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "class Identity(nn.Module):\n",
    "    def __init__(self):\n",
    "        super(Identity, self).__init__()\n",
    "        \n",
    "    def forward(self, x):\n",
    "        return x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "ResNet(\n",
      "  (conv1): Conv2d(3, 64, kernel_size=(7, 7), stride=(2, 2), padding=(3, 3), bias=False)\n",
      "  (bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
      "  (relu): ReLU(inplace=True)\n",
      "  (maxpool): MaxPool2d(kernel_size=3, stride=2, padding=1, dilation=1, ceil_mode=False)\n",
      "  (layer1): Sequential(\n",
      "    (0): Bottleneck(\n",
      "      (conv1): Conv2d(64, 64, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
      "      (bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
      "      (conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
      "      (bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
      "      (conv3): Conv2d(64, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
      "      (bn3): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
      "      (relu): ReLU(inplace=True)\n",
      "      (downsample): Sequential(\n",
      "        (0): Conv2d(64, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
      "        (1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
      "      )\n",
      "    )\n",
      "    (1): Bottleneck(\n",
      "      (conv1): Conv2d(256, 64, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
      "      (bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
      "      (conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
      "      (bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
      "      (conv3): Conv2d(64, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
      "      (bn3): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
      "      (relu): ReLU(inplace=True)\n",
      "    )\n",
      "    (2): Bottleneck(\n",
      "      (conv1): Conv2d(256, 64, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
      "      (bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
      "      (conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
      "      (bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
      "      (conv3): Conv2d(64, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
      "      (bn3): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
      "      (relu): ReLU(inplace=True)\n",
      "    )\n",
      "  )\n",
      "  (layer2): Sequential(\n",
      "    (0): Bottleneck(\n",
      "      (conv1): Conv2d(256, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
      "      (bn1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
      "      (conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)\n",
      "      (bn2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
      "      (conv3): Conv2d(128, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
      "      (bn3): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
      "      (relu): ReLU(inplace=True)\n",
      "      (downsample): Sequential(\n",
      "        (0): Conv2d(256, 512, kernel_size=(1, 1), stride=(2, 2), bias=False)\n",
      "        (1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
      "      )\n",
      "    )\n",
      "    (1): Bottleneck(\n",
      "      (conv1): Conv2d(512, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
      "      (bn1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
      "      (conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
      "      (bn2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
      "      (conv3): Conv2d(128, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
      "      (bn3): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
      "      (relu): ReLU(inplace=True)\n",
      "    )\n",
      "    (2): Bottleneck(\n",
      "      (conv1): Conv2d(512, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
      "      (bn1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
      "      (conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
      "      (bn2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
      "      (conv3): Conv2d(128, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
      "      (bn3): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
      "      (relu): ReLU(inplace=True)\n",
      "    )\n",
      "    (3): Bottleneck(\n",
      "      (conv1): Conv2d(512, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
      "      (bn1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
      "      (conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
      "      (bn2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
      "      (conv3): Conv2d(128, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
      "      (bn3): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
      "      (relu): ReLU(inplace=True)\n",
      "    )\n",
      "  )\n",
      "  (layer3): Sequential(\n",
      "    (0): Bottleneck(\n",
      "      (conv1): Conv2d(512, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
      "      (bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
      "      (conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)\n",
      "      (bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
      "      (conv3): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
      "      (bn3): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
      "      (relu): ReLU(inplace=True)\n",
      "      (downsample): Sequential(\n",
      "        (0): Conv2d(512, 1024, kernel_size=(1, 1), stride=(2, 2), bias=False)\n",
      "        (1): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
      "      )\n",
      "    )\n",
      "    (1): Bottleneck(\n",
      "      (conv1): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
      "      (bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
      "      (conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
      "      (bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
      "      (conv3): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
      "      (bn3): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
      "      (relu): ReLU(inplace=True)\n",
      "    )\n",
      "    (2): Bottleneck(\n",
      "      (conv1): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
      "      (bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
      "      (conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
      "      (bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
      "      (conv3): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
      "      (bn3): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
      "      (relu): ReLU(inplace=True)\n",
      "    )\n",
      "    (3): Bottleneck(\n",
      "      (conv1): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
      "      (bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
      "      (conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
      "      (bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
      "      (conv3): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
      "      (bn3): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
      "      (relu): ReLU(inplace=True)\n",
      "    )\n",
      "    (4): Bottleneck(\n",
      "      (conv1): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
      "      (bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
      "      (conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
      "      (bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
      "      (conv3): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
      "      (bn3): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
      "      (relu): ReLU(inplace=True)\n",
      "    )\n",
      "    (5): Bottleneck(\n",
      "      (conv1): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
      "      (bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
      "      (conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
      "      (bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
      "      (conv3): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
      "      (bn3): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
      "      (relu): ReLU(inplace=True)\n",
      "    )\n",
      "  )\n",
      "  (layer4): Sequential(\n",
      "    (0): Bottleneck(\n",
      "      (conv1): Conv2d(1024, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
      "      (bn1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
      "      (conv2): Conv2d(512, 512, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)\n",
      "      (bn2): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
      "      (conv3): Conv2d(512, 2048, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
      "      (bn3): BatchNorm2d(2048, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
      "      (relu): ReLU(inplace=True)\n",
      "      (downsample): Sequential(\n",
      "        (0): Conv2d(1024, 2048, kernel_size=(1, 1), stride=(2, 2), bias=False)\n",
      "        (1): BatchNorm2d(2048, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
      "      )\n",
      "    )\n",
      "    (1): Bottleneck(\n",
      "      (conv1): Conv2d(2048, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
      "      (bn1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
      "      (conv2): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
      "      (bn2): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
      "      (conv3): Conv2d(512, 2048, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
      "      (bn3): BatchNorm2d(2048, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
      "      (relu): ReLU(inplace=True)\n",
      "    )\n",
      "    (2): Bottleneck(\n",
      "      (conv1): Conv2d(2048, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
      "      (bn1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
      "      (conv2): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\n",
      "      (bn2): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
      "      (conv3): Conv2d(512, 2048, kernel_size=(1, 1), stride=(1, 1), bias=False)\n",
      "      (bn3): BatchNorm2d(2048, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
      "      (relu): ReLU(inplace=True)\n",
      "    )\n",
      "  )\n",
      "  (avgpool): AdaptiveAvgPool2d(output_size=(1, 1))\n",
      "  (fc): Linear(in_features=2048, out_features=1000, bias=True)\n",
      ")\n",
      "\n"
     ]
    }
   ],
   "source": [
    "resnet50 = models.resnet50(weights=models.ResNetshotnr0_Weights.DEFAULT)\n",
    "\n",
    "print(resnetshotnr0)\n",
    "# Step 2: Modify the model to output features from the layer before the fully connected layer\n",
    "class ResNetshotnr0Embeddings(nn.Module):\n",
    "    def __init__(self, original_model, layernr):\n",
    "        super(ResNetshotnr0Embeddings, self).__init__()\n",
    "        #print(list(original_model.children())[4 + layernr])\n",
    "        #print(nn.Sequential(*list(original_model.children())[:4 + shotnr]))\n",
    "        self.features = nn.Sequential(*list(original_model.children())[:4+layernr])\n",
    "        #self.features = nn.Sequential(*list(original_model.children())[:-1])  # Exclude the fully connected layer\n",
    "\n",
    "    def forward(self, x):\n",
    "        x = self.features(x)\n",
    "        x = torch.flatten(x, 1)  # Flatten the tensor to (batch_size, 2048)\n",
    "        return x\n",
    "\n",
    "# Instantiate the modified model\n",
    "model = ResNetshotnr0Embeddings(resnetshotnr0, shotnr) # 3 = layer before fully connected one\n",
    "model.eval()  # Set the model to evaluation mode\n",
    "print()\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Test"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 69,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "...............\n",
      "accuracy for broken_large = 0.6666666666666666\n",
      ".................\n",
      "accuracy for broken_small = 0.8823529411764706\n",
      "................\n",
      "accuracy for contamination = 0.8125\n",
      "overall accuracy: 0.7871732026143791\n"
     ]
    }
   ],
   "source": [
    "from sklearn.metrics.pairwise import cosine_similarity,euclidean_distances\n",
    "from metric_learn import LMNN,NCA\n",
    "import math\n",
    "\n",
    "pipe = A.Compose([A.Resize(256,256), A.Normalize(mean=(0.485, 0.456, 0.406), std=(0.229, 0.224, 0.225)), ToTensorV2()])\n",
    "#pipe = A.Compose([A.Resize(256,256), ToTensorV2()])\n",
    "device = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")\n",
    "\n",
    "m = ResNet50Embeddings(resnet50, 5) # 5 = all without fully ocnnected\n",
    "m.eval()\n",
    "m.to(device)\n",
    "\n",
    "def read_img(path):\n",
    "    img = cv2.imread(path, cv2.IMREAD_COLOR)\n",
    "    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n",
    "    #plt.imshow(img)\n",
    "\n",
    "    imgpiped = pipe(image=img)[\"image\"].unsqueeze(0)\n",
    "    return imgpiped\n",
    "\n",
    "def compare_embeddings(emb1, emb2, distance_metric):\n",
    "    #cosi = torch.nn.CosineSimilarity(dim=0) \n",
    "    #output = cosine_similarity([emb1.flatten(), emb2.flatten()])\n",
    "    #output = euclidean_distances([emb1.flatten(), emb2.flatten()], [emb1.flatten(), emb2.flatten()])\n",
    "    output = distance_metric(emb1, emb2)\n",
    "    return output\n",
    "\n",
    "def merge_embeddings(embeddings):\n",
    "    # todo calc cluster center or similar\n",
    "    return np.average(embeddings, axis=0)\n",
    "\n",
    "import os\n",
    "#embedding_good_1 = m(read_img(f\"./data/bottle/test/good/001.png\")).detach().numpy()\n",
    "#embedding_good_2 = m(read_img(f\"./data/bottle/test/good/002.png\")).detach().numpy()\n",
    "#embedding_good = merge_embeddings([embedding_good_1, embedding_good_2])\n",
    "#embedding_contermination_1 = m(read_img(f\"./data/bottle/test/contamination/001.png\")).detach().numpy()\n",
    "#embedding_contermination_2 = m(read_img(f\"./data/bottle/test/contamination/002.png\")).detach().numpy()\n",
    "#embedding_contermination = merge_embeddings([embedding_contermination_1, embedding_contermination_2])\n",
    "#embedding_broken_small_1 = m(read_img(f\"./data/bottle/test/broken_small/001.png\")).detach().numpy()\n",
    "\n",
    "#embeddings_test = m(read_img(f\"./data/bottle/test/contamination/004.png\")).detach().numpy()\n",
    "\n",
    "#score = compare_embeddings(embedding_good_1, embeddings_test)\n",
    "\n",
    "#def calc_base_emb(t):\n",
    "#    base_emb_1 = m(read_img(f\"./data/bottle/test/{t}/000.png\")).detach().numpy()\n",
    "#    base_emb_2 = m(read_img(f\"./data/bottle/test/{t}/001.png\")).detach().numpy()\n",
    "#    base_emb_3 = m(read_img(f\"./data/bottle/test/{t}/002.png\")).detach().numpy()\n",
    "#    base_emb_4 = m(read_img(f\"./data/bottle/test/{t}/003.png\")).detach().numpy()\n",
    "#    base_emb_5 = m(read_img(f\"./data/bottle/test/{t}/004.png\")).detach().numpy()\n",
    "#    base_emb = merge_embeddings([base_emb_1, base_emb_2, base_emb_3, base_emb_4, base_emb_5])\n",
    "#    return base_emb\n",
    "\n",
    "MAIN_TYPE=\"bottle\"\n",
    "\n",
    "def calc_base_emb(t, nr):\n",
    "    embs = []\n",
    "    for i in range(nr):\n",
    "        if t == \"good\":\n",
    "            emb = m(read_img(f\"./data/{MAIN_TYPE}/train/{t}/{i:03d}.png\")).detach().numpy()\n",
    "        else:\n",
    "            emb = m(read_img(f\"./data/{MAIN_TYPE}/test/{t}/{i:03d}.png\")).detach().numpy()\n",
    "        embs.append(emb)\n",
    "    base_emb = merge_embeddings(embs)\n",
    "    return base_emb\n",
    "\n",
    "shotnr=5\n",
    "goodnr=5\n",
    "\n",
    "types = {#\"good\": calc_base_emb(\"good\", goodnr), \n",
    "         #\"bad\": merge_embeddings([calc_base_emb(\"broken_large\", shotnr), calc_base_emb(\"broken_small\", shotnr), calc_base_emb(\"contamination\", shotnr)]),\n",
    "                  \"broken_large\": calc_base_emb(\"broken_large\", shotnr), \n",
    "         \"broken_small\": calc_base_emb(\"broken_small\", shotnr), \n",
    "        \"contamination\": calc_base_emb(\"contamination\", shotnr)\n",
    "         }\n",
    "\n",
    "\n",
    "#types = {#\"good\": calc_base_emb(\"good\", goodnr), \n",
    "#         #\"bad\": merge_embeddings([calc_base_emb(\"bent_wire\", shotnr), calc_base_emb(\"cable_swap\", shotnr), calc_base_emb(\"combined\", shotnr), \n",
    "#         #                         calc_base_emb(\"cut_inner_insulation\", shotnr), calc_base_emb(\"cut_outer_insulation\", shotnr), calc_base_emb(\"missing_cable\", shotnr), \n",
    "#         #                         calc_base_emb(\"missing_wire\", shotnr), calc_base_emb(\"poke_insulation\", shotnr)]),\n",
    "#         \"bent_wire\": calc_base_emb(\"bent_wire\", shotnr),\n",
    "#         \"cable_swap\": calc_base_emb(\"cable_swap\", shotnr), \n",
    "#         \"combined\": calc_base_emb(\"combined\", shotnr), \n",
    "#         \"cut_inner_insulation\": calc_base_emb(\"cut_inner_insulation\", shotnr), \n",
    "#         \"cut_outer_insulation\": calc_base_emb(\"cut_outer_insulation\", shotnr), \n",
    "#         \"missing_cable\": calc_base_emb(\"missing_cable\", shotnr), \n",
    "#         \"missing_wire\": calc_base_emb(\"missing_wire\", shotnr), \n",
    "#         \"poke_insulation\": calc_base_emb(\"poke_insulation\", shotnr), \n",
    "#         }\n",
    "\n",
    "# euclidean distance\n",
    "euclidean_distance_metric = lambda emb1,emb2 : math.pow(euclidean_distances([emb1.flatten(), emb2.flatten()], [emb1.flatten(), emb2.flatten()])[0][1], 2)\n",
    "# cosine metric\n",
    "cosine_similarity_metric = lambda emb1,emb2 : cosine_similarity([emb1.flatten(), emb2.flatten()])[0][1]\n",
    "\n",
    "lmnn = LMNN(n_neighbors=2, learn_rate=1e-3, verbose=True)\n",
    "#lmnn.fit(data, [0,0,0,1,1,1,2,2,2,3,3,3])\n",
    "\n",
    "lmnn_similarity_metric = lambda emb1,emb2 : lmnn.get_metric()(emb1.flatten(), emb2.flatten())\n",
    "\n",
    "Smaller_Better_Metric = False\n",
    "\n",
    "def test(type):\n",
    "    predictions = []\n",
    "\n",
    "    _, _, files = next(os.walk(f\"./data/{MAIN_TYPE}/test/{type}/\"))\n",
    "    file_count = len(files)\n",
    "    for i in range(5,file_count):\n",
    "        print(\".\", end=\"\")\n",
    "\n",
    "        emb = m(read_img(f\"./data/{MAIN_TYPE}/test/{type}/{i:03d}.png\")).detach().numpy()\n",
    "        curr_score = .0 if Smaller_Better_Metric else 999999.0\n",
    "        max_type = \"\"\n",
    "        for t in types.keys():\n",
    "#        for t in [\"good\", \"bad\"]:\n",
    "            score = compare_embeddings(emb, types[t], euclidean_distance_metric)\n",
    "            \n",
    "            if Smaller_Better_Metric:\n",
    "                if score > curr_score:\n",
    "                    curr_score = score\n",
    "                    max_type = t\n",
    "            else:\n",
    "                if score < curr_score:\n",
    "                    curr_score = score\n",
    "                    max_type = t\n",
    "            pass\n",
    "        predictions.append(max_type)\n",
    "        pass\n",
    "    print()\n",
    "    return np.mean([x == type for x in predictions])\n",
    "#    return np.mean([x == (\"good\" if type == \"good\" else \"bad\") for x in predictions])\n",
    "    pass\n",
    "\n",
    "accs = []\n",
    "for t in types.keys():\n",
    "    if t == \"bad\":\n",
    "        continue\n",
    "    accuracy = test(t)\n",
    "    print(f\"accuracy for {t} = {accuracy}\")\n",
    "    accs.append(accuracy)\n",
    "print(f\"overall accuracy: {np.mean(accs)}\")\n",
    "#print(m)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "RESNET 50:\n",
    "Resulsts:\n",
    "\n",
    "bottle:\n",
    "jeweils 1,3,5 shots normal\n",
    "[0.5892857142857143 0.7321428571428571 0.75]\n",
    "\n",
    "inbalanced - mehr good shots 5,10,15,30 -> alle anderen nur 5\n",
    "[0.75 0.732 0.696 0.696]\n",
    "\n",
    "2 ways nur detektieren ob fehlerhaft oder nicht 1,3,5 shots\n",
    "[0.8395 0.8315 0.8031]\n",
    "\n",
    "inbalance 2 way 5,10,15,30 -> rest 5\n",
    "[0.8031 0.81893 0.8336 0.8031]\n",
    "\n",
    "nur fehlerklasse erkennen 1,3,5\n",
    "[0.7638 0.7428 0.787]\n",
    "\n",
    "\n",
    "cable:\n",
    "jeweils 1,3,5 shots normal\n",
    "[0.21808 0.43815 0.4321478]\n",
    "\n",
    "inbalanced - mehr good shots 5,10,15,30 -> alle anderen nur 5\n",
    "[0.4321478 0.432986 0.42340 0.4464635]\n",
    "\n",
    "2 ways nur detektieren ob fehlerhaft oder nicht 1,3,5 shots\n",
    "[0.8592 0.8772 0.8495]\n",
    "\n",
    "inbalance 2 way 5,10,15,30 -> rest 5\n",
    "[0.8495 0.8180 0.7460 0.6846]\n",
    "\n",
    "nur fehlerklasse erkennen 1,3,5\n",
    "[0.240 0.4740 0.4805]\n"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.14"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
