You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
DroneDetector/train_scripts/Training_models 3pic.ipynb

668 lines
72 KiB
Plaintext

{
"cells": [
{
"cell_type": "markdown",
"id": "5a13ad6b-56c9-4381-b376-1765f6dd7553",
"metadata": {
"slideshow": {
"slide_type": ""
},
"tags": []
},
"source": [
"# Импортирование библиотек"
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "7311cb4a-5bf3-4268-b431-43eea10e9ed6",
"metadata": {
"slideshow": {
"slide_type": ""
},
"tags": []
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"cuda\n"
]
},
{
"data": {
"text/plain": [
"112"
]
},
"execution_count": 1,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from sklearn.model_selection import train_test_split\n",
"from torch.utils.data import Dataset, DataLoader\n",
"from torch import default_generator, randperm\n",
"from torch.utils.data.dataset import Subset\n",
"import torchvision.transforms as transforms\n",
"from torchvision.io import read_image\n",
"from importlib import import_module\n",
"import matplotlib.pyplot as plt\n",
"from torchvision import models\n",
"import torch, torchvision\n",
"from pathlib import Path\n",
"from PIL import Image\n",
"import torch.nn as nn\n",
"from tqdm import tqdm\n",
"import pandas as pd\n",
"import numpy as np\n",
"import matplotlib\n",
"import os, shutil\n",
"import mlconfig\n",
"import random\n",
"import shutil\n",
"import timeit\n",
"import copy\n",
"import time\n",
"import cv2\n",
"import csv\n",
"import sys\n",
"import io\n",
"import gc\n",
"\n",
"plt.rcParams[\"savefig.bbox\"] = 'tight'\n",
"torch.manual_seed(1)\n",
"#matplotlib.use('Agg')\n",
"device = 'cuda' if torch.cuda.is_available() else 'cpu'\n",
"print(device)\n",
"torch.cuda.empty_cache()\n",
"cv2.destroyAllWindows()\n",
"gc.collect()"
]
},
{
"cell_type": "markdown",
"id": "384de097-82c6-41f5-bda9-b2f54bc99593",
"metadata": {
"slideshow": {
"slide_type": ""
},
"tags": []
},
"source": [
"# Подготовка и обучение детектирование"
]
},
{
"cell_type": "code",
"execution_count": 28,
"id": "46e4dc99-6994-4fee-a32e-f3983bd991bd",
"metadata": {},
"outputs": [],
"source": [
"def prepare_and_learning_detection(num_classes, num_samples, path_dataset, model_name, config_name, model,selected_freq):\n",
" num_samples_per_class = num_samples // num_classes\n",
"\n",
" #----------Создаём папку для сохранения результатов обучения--------------\n",
" os.makedirs(\"models\", exist_ok=True)\n",
" ind = 1\n",
" while True:\n",
" if os.path.exists(\"models/\" + model_name + str(ind)):\n",
" ind += 1\n",
" else:\n",
" os.mkdir(\"models/\" + model_name + str(ind))\n",
" path_res = \"models/\" + model_name + str(ind) + '/'\n",
" break\n",
" \n",
" #----------Создаём файл dataset.csv для обучения--------------\n",
" \n",
" pd_columns = ['file_name']\n",
" df = pd.DataFrame(columns=pd_columns)\n",
" \n",
" subdirs = os.listdir(path_dataset)\n",
" print(subdirs)\n",
" \n",
" for subdir in subdirs:\n",
" freq_dir = os.path.join(path_dataset, subdir, str(selected_freq))\n",
" if not os.path.isdir(freq_dir):\n",
" continue\n",
"\n",
" files = [\n",
" f for f in os.listdir(freq_dir)\n",
" if os.path.isfile(os.path.join(freq_dir, f)) and f.endswith('.npy')\n",
" ]\n",
" num_samples_per_class = min(num_samples_per_class, len(files))\n",
"\n",
" for subdir in subdirs:\n",
" freq_dir = os.path.join(path_dataset, subdir, str(selected_freq))\n",
" if not os.path.isdir(freq_dir):\n",
" continue\n",
"\n",
" files = [\n",
" f for f in os.listdir(freq_dir)\n",
" if os.path.isfile(os.path.join(freq_dir, f)) and f.endswith('.npy')\n",
" ]\n",
" random.shuffle(files)\n",
" files_to_process = files[:num_samples_per_class]\n",
"\n",
" for file in files_to_process:\n",
" row = pd.DataFrame({\n",
" pd_columns[0]: [str(os.path.join(freq_dir, file))]\n",
" })\n",
" df = pd.concat([df, row], ignore_index=True)\n",
"\n",
" dataset_csv_path = os.path.join(path_res, 'dataset.csv')\n",
" df.to_csv(dataset_csv_path, index=False)\n",
"\n",
" if not os.path.exists(dataset_csv_path):\n",
" raise RuntimeError(f'dataset.csv was not created: {dataset_csv_path}')\n",
" #----------Импортируем параметры для обучения--------------\n",
" \n",
" def load_function(attr):\n",
" module_, func = attr.rsplit('.', maxsplit=1)\n",
" return getattr(import_module(module_), func)\n",
" \n",
" config = mlconfig.load('config_' + config_name + '.yaml')\n",
" \n",
" #----------Создаём класс датасета--------------\n",
" \n",
" class MyDataset(Dataset):\n",
" def __init__(self, path_dataset, csv_file):\n",
" data=[]\n",
" with open(os.path.join(path_dataset, csv_file), newline='') as csvfile:\n",
" reader = csv.reader(csvfile, delimiter=' ', quotechar='|')\n",
" for row in list(reader)[1:]:\n",
" row = str(row)\n",
" data.append(row[2: len(row)-2])\n",
" self.sig_filenames = data\n",
" self.path_dataset = path_dataset\n",
" \n",
" def __len__(self):\n",
" return len(self.sig_filenames)\n",
" \n",
" def __getitem__(self, idx):\n",
" base = os.path.splitext(self.sig_filenames[idx])[0]\n",
"\n",
" image_real = np.asarray(cv2.split(cv2.imread(base + '_real.png')), dtype=np.float32)\n",
" image_imag = np.asarray(cv2.split(cv2.imread(base + '_imag.png')), dtype=np.float32)\n",
" image_spec = np.asarray(cv2.split(cv2.imread(base + '_spec.png')), dtype=np.float32)\n",
"\n",
" if 'drone' in list(self.sig_filenames[idx].split('/')):\n",
" label = torch.tensor(0)\n",
" if 'noise' in list(self.sig_filenames[idx].split('/')):\n",
" label = torch.tensor(1)\n",
" return image_real, image_imag, image_spec, label\n",
" \n",
" #----------Создаём датасет--------------\n",
" \n",
" dataset = MyDataset(path_dataset=path_res, csv_file='dataset.csv')\n",
" train_set, valid_set = torch.utils.data.random_split(dataset, [0.7, 0.3], generator=torch.Generator().manual_seed(42))\n",
" batch_size = config.batch_size\n",
" train_dataloader = torch.utils.data.DataLoader(train_set, batch_size=batch_size, shuffle=True, drop_last=True)\n",
" valid_dataloader = torch.utils.data.DataLoader(valid_set, batch_size=batch_size, shuffle=True, drop_last=True)\n",
" \n",
" dataloaders = {}\n",
" dataloaders['train'] = train_dataloader\n",
" dataloaders['val'] = valid_dataloader\n",
" dataset_sizes = {}\n",
" dataset_sizes['train'] = len(train_set)\n",
" dataset_sizes['val'] = len(valid_set)\n",
"\n",
" #----------Обучаем модель--------------\n",
"\n",
" val_loss = []\n",
" val_acc = []\n",
" train_loss = []\n",
" train_acc = []\n",
" epochs = config.epoch\n",
" \n",
" best_acc = 0.0\n",
" best_model = copy.deepcopy(model.state_dict())\n",
" limit = config.limit\n",
" epoch_limit = epochs\n",
" \n",
" start = timeit.default_timer()\n",
" for epoch in range(1, epochs+1):\n",
" print(f\"Epoch : {epoch}\\n\")\n",
" dataloader = None\n",
" \n",
" for phase in ['train', 'val']:\n",
" running_loss = 0.0\n",
" running_corrects = 0\n",
" \n",
" for (img1, img2, img3, label) in tqdm(dataloaders[phase]):\n",
" img1, img2, img3, label = img1.to(device), img2.to(device), img3.to(device), label.to(device)\n",
" optimizer.zero_grad()\n",
" \n",
" with torch.set_grad_enabled(phase == 'train'):\n",
" output = model([img1, img2, img3])\n",
" _, pred = torch.max(output.data, 1)\n",
" loss = criterion(output, label)\n",
" if phase=='train' :\n",
" loss.backward()\n",
" optimizer.step()\n",
" \n",
" running_loss += loss.item() * 3 * img1.size(0)\n",
" running_corrects += torch.sum(pred == label.data)\n",
" \n",
" epoch_loss = running_loss / dataset_sizes[phase]\n",
" epoch_acc = running_corrects.double() / dataset_sizes[phase]\n",
" \n",
" print('{} Loss: {:.4f} Acc: {:.4f}'.format(phase, epoch_loss, epoch_acc))\n",
" \n",
" if phase=='train' :\n",
" train_loss.append(epoch_loss)\n",
" train_acc.append(epoch_acc)\n",
" else :\n",
" val_loss.append(epoch_loss)\n",
" val_acc.append(epoch_acc)\n",
" if val_acc[-1] > best_acc :\n",
" ind_limit = 0\n",
" best_acc = val_acc[-1]\n",
" best_model = copy.deepcopy(model.state_dict())\n",
" torch.save(best_model, path_res + model_name + '.pth')\n",
" else:\n",
" ind_limit += 1\n",
" \n",
" if ind_limit >= limit:\n",
" break\n",
" \n",
" if ind_limit >= limit:\n",
" epoch_limit = epoch\n",
" break\n",
" \n",
" print()\n",
" \n",
" end = timeit.default_timer()\n",
" print(f\"Total time elapsed = {end - start} seconds\")\n",
" epoch_limit += 1\n",
" \n",
" #----------Вывод графиков и сохранение результатов обучения--------------\n",
" \n",
" train_acc = np.asarray(list(map(lambda x: x.item(), train_acc)))\n",
" val_acc = np.asarray(list(map(lambda x: x.item(), val_acc)))\n",
" \n",
" np.save(path_res+'train_acc.npy', train_acc)\n",
" np.save(path_res+'val_acc.npy', val_acc)\n",
" np.save(path_res+'train_loss.npy', train_loss)\n",
" np.save(path_res+'val_loss.npy', val_loss)\n",
" \n",
" plt.figure()\n",
" plt.plot(range(1,epoch_limit), train_loss, color='blue')\n",
" plt.plot(range(1,epoch_limit), val_loss, color='red')\n",
" plt.xlabel('Epoch')\n",
" plt.ylabel('Loss')\n",
" plt.title('Loss Curve')\n",
" plt.legend(['Train Loss', 'Validation Loss'])\n",
" plt.show()\n",
" plt.clf()\n",
" plt.cla()\n",
" plt.close()\n",
" \n",
" plt.figure()\n",
" plt.plot(range(1,epoch_limit), train_acc, color='blue')\n",
" plt.plot(range(1,epoch_limit), val_acc, color='red')\n",
" plt.xlabel('Epoch')\n",
" plt.ylabel('Accuracy')\n",
" plt.title('Accuracy Curve')\n",
" plt.legend(['Train Accuracy', 'Validation Accuracy'])\n",
" plt.show()\n",
" \n",
" plt.clf()\n",
" plt.cla()\n",
" plt.close()\n",
" torch.cuda.empty_cache()\n",
" cv2.destroyAllWindows()\n",
" del model\n",
" gc.collect()\n",
"\n",
" return path_res, model_name"
]
},
{
"cell_type": "markdown",
"id": "93c136ee",
"metadata": {},
"source": [
"### Ensemble"
]
},
{
"cell_type": "code",
"execution_count": 29,
"id": "52e8d4c5",
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/sibscience-4/from_ssh/DroneDetector/.venv-train/lib/python3.12/site-packages/torchvision/models/_utils.py:208: UserWarning: The parameter 'pretrained' is deprecated since 0.13 and may be removed in the future, please use 'weights' instead.\n",
" warnings.warn(\n",
"/home/sibscience-4/from_ssh/DroneDetector/.venv-train/lib/python3.12/site-packages/torchvision/models/_utils.py:223: UserWarning: Arguments other than a weight enum or `None` for 'weights' are deprecated since 0.13 and may be removed in the future. The current behavior is equivalent to passing `weights=None`.\n",
" warnings.warn(msg)\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"['noise', 'drone']\n",
"Epoch : 1\n",
"\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"100%|██████████| 168/168 [01:10<00:00, 2.39it/s]\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"train Loss: 0.0628 Acc: 0.9956\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"100%|██████████| 72/72 [00:11<00:00, 6.27it/s]\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"val Loss: 0.0029 Acc: 1.0000\n",
"\n",
"Epoch : 2\n",
"\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"100%|██████████| 168/168 [01:10<00:00, 2.38it/s]\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"train Loss: 0.0018 Acc: 0.9956\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"100%|██████████| 72/72 [00:11<00:00, 6.13it/s]\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"val Loss: 0.0011 Acc: 1.0000\n",
"\n",
"Epoch : 3\n",
"\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"100%|██████████| 168/168 [01:10<00:00, 2.38it/s]\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"train Loss: 0.0008 Acc: 0.9956\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"100%|██████████| 72/72 [00:11<00:00, 6.20it/s]\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"val Loss: 0.0006 Acc: 1.0000\n",
"\n",
"Epoch : 4\n",
"\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"100%|██████████| 168/168 [01:10<00:00, 2.38it/s]\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"train Loss: 0.0005 Acc: 0.9956\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"100%|██████████| 72/72 [00:11<00:00, 6.13it/s]\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"val Loss: 0.0004 Acc: 1.0000\n",
"\n",
"Epoch : 5\n",
"\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"100%|██████████| 168/168 [01:10<00:00, 2.38it/s]\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"train Loss: 0.0003 Acc: 0.9956\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"100%|██████████| 72/72 [00:11<00:00, 6.12it/s]\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"val Loss: 0.0003 Acc: 1.0000\n",
"\n",
"Epoch : 6\n",
"\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"100%|██████████| 168/168 [01:10<00:00, 2.38it/s]\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"train Loss: 0.0002 Acc: 0.9956\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"100%|██████████| 72/72 [00:11<00:00, 6.11it/s]\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"val Loss: 0.0002 Acc: 1.0000\n",
"Total time elapsed = 493.41988416798995 seconds\n"
]
},
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAkAAAAHHCAYAAABXx+fLAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjAsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvlHJYcgAAAAlwSFlzAAAPYQAAD2EBqD+naQAAUC5JREFUeJzt3Xl0VPX9//HnTEISEpKwJywRVMIeEtYQQNZAUGqNG5FSNmn9agGxqFVENjfcaFFBKFqB9ieCWKEUEQgREAVkCasiKmWJQlgUEhIggcz9/THMwJgASZjkzkxej3PumTt3PvfO+061eXnv+95rMQzDQERERKQCsZpdgIiIiEh5UwASERGRCkcBSERERCocBSARERGpcBSAREREpMJRABIREZEKRwFIREREKhwFIBEREalwFIBERESkwlEAEhERkQpHAUhEbtjcuXOxWCxs3brV7FKKZceOHfz+978nKiqKwMBAqlevTmJiInPmzKGgoMDs8kSkHPibXYCISHl69913efjhh4mIiGDQoEFER0dz5swZ0tLSGD58OEePHuWZZ54xu0wRKWMKQCJSYWzatImHH36YhIQEli9fTmhoqPOzxx57jK1bt7Jnzx63fFdubi4hISFu2ZaIuJ9OgYlIudm+fTu33347YWFhVKlShV69erFp0yaXMRcuXGDy5MlER0cTFBREjRo16NKlC6mpqc4xmZmZDBs2jPr16xMYGEidOnW46667OHjw4DW/f/LkyVgsFt5//32X8OPQrl07hg4dCsDatWuxWCysXbvWZczBgwexWCzMnTvXuWzo0KFUqVKF/fv3c8cddxAaGsrAgQMZOXIkVapU4ezZs4W+a8CAAURGRrqccvv000+57bbbCAkJITQ0lH79+vH1119fc59EpHQUgESkXHz99dfcdttt7Ny5k7/85S+MHz+eAwcO0L17d7766ivnuEmTJjF58mR69OjB9OnTGTduHDfddBPp6enOMffeey+LFy9m2LBhvP322zz66KOcOXOGw4cPX/X7z549S1paGl27duWmm25y+/5dvHiRpKQkateuzeuvv869995LSkoKubm5fPLJJ4Vq+e9//8t9992Hn58fAP/617/o168fVapU4ZVXXmH8+PF88803dOnS5brBTkRKwRARuUFz5swxAGPLli1XHZOcnGwEBAQY+/fvdy47cuSIERoaanTt2tW5LDY21ujXr99Vt3Pq1CkDMF577bUS1bhz504DMEaPHl2s8WvWrDEAY82aNS7LDxw4YADGnDlznMuGDBliAMbTTz/tMtZmsxn16tUz7r33XpflH374oQEYn3/+uWEYhnHmzBmjatWqxh//+EeXcZmZmUZ4eHih5SJy43QESETKXEFBAatWrSI5OZlbbrnFubxOnTr87ne/44svviA7OxuAqlWr8vXXX/P9998Xua3KlSsTEBDA2rVrOXXqVLFrcGy/qFNf7vLII4+4vLdYLNx///0sX76cnJwc5/KFCxdSr149unTpAkBqaiqnT59mwIABnDx50jn5+fkRHx/PmjVryqxmkYpKAUhEytyJEyc4e/YsTZo0KfRZs2bNsNlsZGRkAPDcc89x+vRpGjduTExMDE8++SS7du1yjg8MDOSVV17h008/JSIigq5du/Lqq6+SmZl5zRrCwsIAOHPmjBv37DJ/f3/q169faHlKSgrnzp1j6dKlAOTk5LB8+XLuv/9+LBYLgDPs9ezZk1q1arlMq1at4vjx42VSs0hFpgAkIh6la9eu7N+/n/fee4+WLVvy7rvv0qZNG959913nmMcee4zvvvuOKVOmEBQUxPjx42nWrBnbt2+/6nYbNWqEv78/u3fvLlYdjnDya1e7T1BgYCBWa+H/S+3YsSMNGzbkww8/BOC///0v586dIyUlxTnGZrMB9j6g1NTUQtN//vOfYtUsIsWnACQiZa5WrVoEBwezb9++Qp99++23WK1WoqKinMuqV6/OsGHD+OCDD8jIyKBVq1ZMmjTJZb1bb72Vxx9/nFWrVrFnzx7y8/OZOnXqVWsIDg6mZ8+efP75586jTddSrVo1AE6fPu2y/NChQ9dd99f69+/PihUryM7OZuHChTRs2JCOHTu67AtA7dq1SUxMLDR17969xN8pItemACQiZc7Pz48+ffrwn//8x+WKpmPHjjF//ny6dOniPEX1888/u6xbpUoVGjVqRF5eHmC/gur8+fMuY2699VZCQ0OdY65m4sSJGIbBoEGDXHpyHLZt28a8efMAaNCgAX5+fnz++ecuY95+++3i7fQVUlJSyMvLY968eaxYsYL+/fu7fJ6UlERYWBgvvfQSFy5cKLT+iRMnSvydInJtuhGiiLjNe++9x4oVKwotHz16NC+88AKpqal06dKFP/3p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sHr1agDCw8MLbSM3N5ekpCQSEhLYsmULx48f5w9/+AMjR450CXlr1qyhTp06rFmzhh9++IGUlBTi4uL4YyluTGez2ZzhZ926dVy8eJERI0aQkpLi/Fs+cOBAWrduzcyZM/Hz82PHjh1UqlQJgBEjRpCfn8/nn39OSEgI33zzDVWqVClxHSViSCFZWVkGYGRlZZXL933yiWGAYTRoYBg2W7l8pYhImTh37pzxzTffGOfOnbMvyMmx/x+cGVNOTrHr3rt3rwEYa9ascS677bbbjN///vdXXadfv37G448/7nzfrVs3Y/To0c73DRo0MP72t78ZhmEYK1euNPz9/Y2ffvrJ+fmnn35qAMbixYuv+h2vvfaa0bZtW+f7iRMnGrGxsYXGXbmd2bNnG9WqVTNyrtj/Tz75xLBarUZmZqZhGIYxZMgQo0GDBsbFixedY+6//34jJSXlqrXMmTPHCA8PL/KzVatWGX5+fsbhw4edy77++msDMDZv3mwYhmGEhoYac+fOLXL9mJgYY9KkSVf97isV+mfsCiX5++1Tl8F7q27dICDA/kiM7783uxoRkYqnadOmdOrUiffeew+AH374gfXr1zN8+HAACgoKeP7554mJiaF69epUqVKFlStXFvs5k3v37iUqKoq6des6lxV1wc/ChQvp3LkzkZGRVKlShWeffbbEz7Lcu3cvsbGxhISEOJd17twZm83mcpFQixYt8PPzc76vU6fOVR9FVZzvjIqKcrmPXvPmzalatSp79+4F7H2/f/jDH0hMTOTll19m//79zrGPPvooL7zwAp07d2bixImlajovKQUgDxASAo4WJV0NJiI+JTgYcnLMmYKDS1Tq8OHD+fe//82ZM2eYM2cOt956K926dQPgtdde44033uCpp55izZo17Nixg6SkJPLz8932U23cuJGBAwdyxx13sGzZMrZv3864cePc+h1Xcpx+crBYLM776ZWFSZMm8fXXX9OvXz8+++wzmjdvzuLFiwH4wx/+wP/+9z8GDRrE7t27adeuHW+99VaZ1QIKQB7DcTWY7gckIj7FYrH/V54ZUzH6f67Uv39/rFYr8+fP55///CcPPvigsx/oyy+/5K677uL3v/89sbGx3HLLLXz33XfF3nazZs3IyMhwubBn06ZNLmM2bNhAgwYNGDduHO3atSM6OppDv3padkBAAAUFBdf9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",
"text/plain": [
"<Figure size 640x480 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAkkAAAHHCAYAAACr0swBAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjAsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvlHJYcgAAAAlwSFlzAAAPYQAAD2EBqD+naQAASbFJREFUeJzt3Xl4Dvf+//HXnci+CSILEUs1QYnTWBot6jQVSx1LVDg0obTVojRHW0pLq6qLqrW6HEuLllqr9cVJY2k5WooopZbQIhKhJRsics/vD7/ex92MJRpu0ufjuua63J/7fc+8Z5pz3a8z87lnLIZhGAIAAIAdJ0c3AAAAcCsiJAEAAJggJAEAAJggJAEAAJggJAEAAJggJAEAAJggJAEAAJggJAEAAJggJAEAAJggJAEAAJggJAG4qnfffVcWi0VNmzZ1dCu3pePHj2vo0KGKiIiQp6envLy8FBUVpVdffVWnT592dHsALsPCs9sAXM29996rY8eO6eeff9b+/ft1xx13OLql28aWLVvUrl075eXlqVevXoqKipIkff/995o/f76aNWum//znPw7uEoAZQhKAKzp06JBq1qypJUuW6IknntCAAQM0atQoR7dlKj8/X15eXo5uw+b06dO66667dOHCBa1bt04RERF27x8/flwffvihRo4c+ae3davtO1AWcLkNwBXNmzdP/v7+at++vbp27ap58+aZ1p0+fVrPPPOMqlevLjc3N1WtWlUJCQk6efKkrebcuXMaPXq07rzzTrm7uys4OFhdunRRWlqaJGndunWyWCxat26d3bp//vlnWSwWzZ492zbWu3dveXt7Ky0tTe3atZOPj4969uwpSfrmm2/08MMPq1q1anJzc1NoaKieeeYZnT17tljfP/30k7p166aAgAB5eHgoPDxcI0aMkCStXbtWFotFS5cuLfa5Tz75RBaLRZs2bbrssXv//feVnp6uCRMmFAtIkhQYGGgXkCwWi0aPHl2srnr16urdu7ft9ezZs2WxWLR+/Xo99dRTqly5sqpWrapFixbZxs16sVgs2rVrl92+d+3aVRUqVJC7u7saNWqk5cuXX3Z/gL+aco5uAMCtbd68eerSpYtcXV3Vo0cPTZ8+XVu2bFHjxo1tNXl5eWrevLn27NmjRx99VHfffbdOnjyp5cuX6+jRo6pUqZKKior00EMPKSUl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t29fLV68WLm5uZo1a5Zq1apl+1J96623NGnSJD3//PNau3atUlNTFRsbq/Pnz5faodq0aZN69uypdu3a6csvv9T27ds1YsSIUt3Gpf4YZCwWiy3smFm9erXS09MVHx+vcuXKqVy5curevbt++eUX26/PPTw8Lvv5K70nXZxeI12cjP27y82RujQAStLQoUO1dOlSvfbaa/rmm2+Umpqq+vXr247d1bYtSf369dP8+fN19uxZzZo1S/Hx8Td84n2JQ9Lhw4dVo0aNYuNhYWElTtMAAAezWCQvL8cs1zAf6VLdunWTk5OTPvnkE3388cd69NFHbfOTNm7cqI4dO6pXr16KjIxUzZo1tW/fvmted506dXTkyBFlZGTYxr799lu7mv/+978KCwvTiBEj1KhRI9WuXVu//PKLXY2rq+tVnzxRp04d7dixQ/n5+baxjRs3ysnJSeHh4dfc8x/NmDFD3bt3V2pqqt3SvXt32wTuBg0a6JtvvjENNz4+Pqpevfplb+cTEBAgSXbH6NJJ3FeyceNG9e7dW507d1b9+vUVFBSkn3/+2fZ+/fr1ZbVatX79+suuo127dvLy8tL06dO1atUqPfroo9e07T+jxCGpcuXKpvej2LFjhypWrFgqTQEA8Efe3t6Kj4/X8OHDlZGRod69e9veq127tpKTk/Xf//5Xe/bs0RNPPKHjx49f87pjYmJ05513KjExUTt27NA333yjESNG2NXUrl1bhw8f1vz585WWlqbJkycXewpF9erVdejQIaWmpurkyZOm9ynq2bOn3N3dlZiYqF27dmnt2rUaNGiQHnnkEQUGBpbsoPx/J06c0BdffKHExETddddddktCQoKWLVum3377TQMHDlROTo66d++u77//Xvv379ecOXNsl/lGjx6tt99+W5MnT9b+/fu1bds2TZkyRdLFsz333HOPXn/9de3Zs0fr16/XyJEjr6m/2rVra8mSJUpNTdWOHTv0z3/+0+6sWPXq1ZWYmKhHH31Uy5Yt06FDh7Ru3Tp99tlnthpnZ2f17t1bw4cPV+3atU0vh5a2EoekHj166Omnn9batWtVVFSkoqIirVmzRoMHD1b37t1vRI8AAEi6eMnt1KlTio2NtZs/NHLkSN19992KjY3V/fffr6CgoBLd3drJyUlLly7V2bNn1aRJE/Xr109jx461q/nHP/6hZ555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+d0333yjvXv3ql+/flfsdfjw4crOzrYtR44cuY49BgAAtwuHhiRXV1dFRUXZTZa2Wq1KSUlRdHT0FT/r7u6uKlWq6MKFC1q8eLE6duxYrMbLy0vBwcE6deqUVq9ebVozY8YMRUVFKTIy8orbc3Nzk6+vr90CAADKrnKObiApKUmJiYlq1KiRmjRpookTJyo/P199+vSRJCUkJKhKlSoaN26cJOm7775Tenq6GjZsqPT0dI0ePVpWq1XPPfecbZ2rV6+WYRgKDw/XgQMH9OyzzyoiIsK2zt/l5ORo4cKFevvtt2/eDgMAgNuCw0NSfHy8Tpw4oZdeekmZmZlq2LChVq1aZZvMffjwYbu5ROfOndPIkSN18OBBeXt7q127dpozZ47Kly9vq8nOztbw4cN19OhRVahQQXFxcRo7dqxcXFzstj1//nwZhqEePXrclH0FAAC3D4ffJ+l2xX2SAAC4/dw290kCAAC4VRGSAAAATBCSAAAATBCSAAAATBCSAAAATBCSAAAATBCSAAAATBCSAAAATBCSAAAATBCSAAAATBCSAAAATBCSAAAATBCSAAAATBCSAAAATBCSAAAATBCSAAAATBCSAAAATBCSAAAATBCSAAAATBCSAAAATBCSAAAATBCSAAAATBCSAAAATBCSAAAATBCSAAAATBCSAAAATBCSAAAATBCSAAAATBCSAAAATBCSAAAATBCSAAAATBCSAAAATBCSAAAATBCSAAAATBCSAAAATBCSAAAATBCSAAAATBCSAAAATBCSAAAATBCSAAAATBCSAAAATBCSAAAATBCSAAAATBCSAAAATBCSAAAATBCSAAAATBCSAAAATBCSAAAATBCSAAAATBCSAAAATBCSAAAATBCSAAAATBCSAAAATBCSAAAATBCSAAAATBCSAAAATBCSAAAATBCSAAAATBCSAAAATBCSAAAATBCSAAAATBCSAAAATBCSAAAATBCSAAAATBCSAAAATDg8JE2bNk3Vq1eXu7u7mjZtqs2bN1+2trCwUK+88opq1aold3d3RUZGatWqVXY1ubm5GjJkiMLCwuTh4aFmzZppy5Ytxda1Z88e/eMf/5Cfn5+8vLzUuHFjHT58uNT3DwAA3J4cGpIWLFigpKQkjRo1Stu2bVNkZKRiY2OVlZVlWj9y5Ei9//77mjJlinbv3q3+/furc+fO2r59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",
"text/plain": [
"<Figure size 640x480 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
"67"
]
},
"execution_count": 29,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"#----------Инициализируем модель и параметры обучения--------------\n",
"\n",
"torch.cuda.empty_cache()\n",
"cv2.destroyAllWindows()\n",
"gc.collect()\n",
"\n",
"num_classes = 3\n",
"config_name = \"ensemble\"\n",
" \n",
"def load_function(attr):\n",
" module_, func = attr.rsplit('.', maxsplit=1)\n",
" return getattr(import_module(module_), func)\n",
" \n",
"config = mlconfig.load('config_' + config_name + '.yaml')\n",
"\n",
"model1 = models.resnet18(pretrained=False)\n",
"model2 = models.resnet50(pretrained=False)\n",
"model3 = models.resnet101(pretrained=False)\n",
"\n",
"num_classes = 2\n",
"\n",
"model1.fc = nn.Linear(model1.fc.in_features, num_classes)\n",
"model2.fc = nn.Linear(model2.fc.in_features, num_classes)\n",
"model3.fc = nn.Linear(model3.fc.in_features, num_classes)\n",
"\n",
"class Ensemble(nn.Module):\n",
" def __init__(self, model1, model2, model3):\n",
" super(Ensemble, self).__init__()\n",
" self.model1 = model1\n",
" self.model2 = model2\n",
" self.model3 = model3\n",
" self.fc = nn.Linear(3 * num_classes, num_classes)\n",
"\n",
" def forward(self, x):\n",
" x1 = self.model1(x[0])\n",
" x2 = self.model2(x[1])\n",
" x3 = self.model3(x[2])\n",
" x = torch.cat((x1, x2, x3), dim=1)\n",
" x = self.fc(x)\n",
" return x\n",
"\n",
"model = Ensemble(model1, model2, model3)\n",
"\n",
"optimizer = load_function(config.optimizer.name)(model.parameters(), lr=config.optimizer.lr)\n",
"criterion = load_function(config.loss_function.name)()\n",
"scheduler = load_function(config.scheduler.name)(optimizer, step_size=config.scheduler.step_size, gamma=config.scheduler.gamma)\n",
"\n",
"if device != 'cpu':\n",
" model = model.to(device)\n",
"\n",
"#----------Создания датасета и обучение модели--------------\n",
"\n",
"path_res, model_name = prepare_and_learning_detection(num_classes = num_classes, num_samples = 10000, path_dataset = \"/mnt/nvme1/dataset_img\", \n",
" selected_freq=1200,model_name = config_name+\"_1.2_jpg_\", config_name = config_name, model=model)\n",
"\n",
"\n",
"torch.cuda.empty_cache()\n",
"cv2.destroyAllWindows()\n",
"del model\n",
"gc.collect()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "4234ee26",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"celltoolbar": "Отсутствует",
"kernelspec": {
"display_name": ".venv-train (3.12.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.12.3"
}
},
"nbformat": 4,
"nbformat_minor": 5
}