first commit
This commit is contained in:
@@ -0,0 +1,4 @@
|
|||||||
|
models/
|
||||||
|
Datasets/
|
||||||
|
test_images/
|
||||||
|
train_logs/
|
||||||
@@ -0,0 +1,91 @@
|
|||||||
|
# %% Импорт библиотек
|
||||||
|
|
||||||
|
import kagglehub
|
||||||
|
import splitfolders
|
||||||
|
import pytorch_lightning as pl
|
||||||
|
|
||||||
|
from torch.utils.data import DataLoader
|
||||||
|
from torchvision.datasets import ImageFolder
|
||||||
|
from torchvision.transforms import v2 as transforms
|
||||||
|
|
||||||
|
from pathlib import Path
|
||||||
|
from typing import Optional, Callable, Any
|
||||||
|
|
||||||
|
# %% Скачивание набора данных
|
||||||
|
|
||||||
|
path = kagglehub.dataset_download("jehanbhathena/weather-dataset",
|
||||||
|
output_dir="./Datasets",
|
||||||
|
force_download=False)
|
||||||
|
|
||||||
|
# %% Разделение набора данных
|
||||||
|
|
||||||
|
splitfolders.ratio("./Datasets/weather-dataset",
|
||||||
|
output="./Datasets/weather-dataset-split",
|
||||||
|
ratio=(.8, .1, .1),
|
||||||
|
group_prefix=None,
|
||||||
|
move=False)
|
||||||
|
|
||||||
|
# %% Пример модуля для загрузки данных
|
||||||
|
|
||||||
|
TransformType = Optional[Callable[..., Any]]
|
||||||
|
|
||||||
|
class MyImageDataset(pl.LightningDataModule):
|
||||||
|
def __init__(self,
|
||||||
|
batch_size: int = 1,
|
||||||
|
train_transform: TransformType = None,
|
||||||
|
val_transform: TransformType = None,
|
||||||
|
img_root: str = ""
|
||||||
|
):
|
||||||
|
|
||||||
|
super().__init__()
|
||||||
|
|
||||||
|
self.batch_size = batch_size
|
||||||
|
self.train_transform = train_transform
|
||||||
|
self.val_transform = val_transform
|
||||||
|
self.img_root = img_root
|
||||||
|
|
||||||
|
def setup(self, stage=None):
|
||||||
|
self.train_set = ImageFolder(self.img_root / Path("train"),
|
||||||
|
transform=self.train_transform)
|
||||||
|
self.val_set = ImageFolder(self.img_root / Path("val"),
|
||||||
|
transform=self.val_transform)
|
||||||
|
self.test_set = ImageFolder(self.img_root / Path("test"),
|
||||||
|
transform=self.val_transform)
|
||||||
|
|
||||||
|
def train_dataloader(self):
|
||||||
|
return DataLoader(self.train_set, batch_size=self.batch_size,
|
||||||
|
shuffle=True, num_workers=2)
|
||||||
|
|
||||||
|
def val_dataloader(self):
|
||||||
|
return DataLoader(self.val_set, batch_size=self.batch_size,
|
||||||
|
shuffle=False, num_workers=2)
|
||||||
|
|
||||||
|
def test_dataloader(self):
|
||||||
|
return DataLoader(self.test_set, batch_size=self.batch_size,
|
||||||
|
shuffle=False, num_workers=2)
|
||||||
|
|
||||||
|
# %% Создание трансформаций
|
||||||
|
|
||||||
|
transform_train = transforms.Compose([
|
||||||
|
transforms.Resize((224, 224)),
|
||||||
|
transforms.RandomHorizontalFlip(p=.5),
|
||||||
|
transforms.ToTensor(),
|
||||||
|
transforms.Normalize(mean=[0.485, 0.456, 0.406],
|
||||||
|
std=[0.229, 0.224, 0.225])
|
||||||
|
])
|
||||||
|
|
||||||
|
transform_test = transforms.Compose([
|
||||||
|
transforms.Resize((224, 224)),
|
||||||
|
transforms.ToTensor(),
|
||||||
|
transforms.Normalize(mean=[0.485, 0.456, 0.406],
|
||||||
|
std=[0.229, 0.224, 0.225])
|
||||||
|
])
|
||||||
|
|
||||||
|
# %% Создание экземляра класса и вывод объектов класса
|
||||||
|
|
||||||
|
dm = MyImageDataset(train_transform=transform_train,
|
||||||
|
val_transform=transform_test,
|
||||||
|
img_root="./Datasets/weather-dataset-split")
|
||||||
|
dm.setup()
|
||||||
|
|
||||||
|
print({k:v for k, v in enumerate(dm.test_set.classes)})
|
||||||
@@ -0,0 +1,229 @@
|
|||||||
|
# %% Импорт библиотек
|
||||||
|
|
||||||
|
import torch
|
||||||
|
import torch.nn as nn
|
||||||
|
import pytorch_lightning as pl
|
||||||
|
|
||||||
|
from torch.utils.data import DataLoader
|
||||||
|
from torchmetrics import MetricCollection
|
||||||
|
from torchvision import datasets, transforms
|
||||||
|
from torchmetrics.classification import Accuracy, Precision, Recall, F1Score
|
||||||
|
|
||||||
|
# Автоматическое логирование результатов
|
||||||
|
from pytorch_lightning.loggers import WandbLogger, TensorBoardLogger, CSVLogger
|
||||||
|
# сохранение весов
|
||||||
|
from pytorch_lightning.callbacks.model_checkpoint import ModelCheckpoint
|
||||||
|
# автоматическое отслеживание lr
|
||||||
|
from pytorch_lightning.callbacks import LearningRateMonitor
|
||||||
|
# ранние остановки
|
||||||
|
from pytorch_lightning.callbacks.early_stopping import EarlyStopping
|
||||||
|
|
||||||
|
# %% Гиперпараметры
|
||||||
|
|
||||||
|
num_epoch = 8
|
||||||
|
batch_size = 64
|
||||||
|
|
||||||
|
# %% Создание модели PyTorch
|
||||||
|
|
||||||
|
class MyTorchCNNModel(nn.Module):
|
||||||
|
def __init__(self,
|
||||||
|
output_size: int = 10):
|
||||||
|
super().__init__()
|
||||||
|
|
||||||
|
self.output_size = output_size
|
||||||
|
|
||||||
|
self.feature = nn.Sequential(
|
||||||
|
nn.LazyConv2d(64, kernel_size=3, stride=1, padding=1),
|
||||||
|
nn.BatchNorm2d(64),
|
||||||
|
nn.ReLU(),
|
||||||
|
nn.Conv2d(64, 128, kernel_size=3, stride=1, padding=1),
|
||||||
|
nn.BatchNorm2d(128),
|
||||||
|
nn.ReLU(),
|
||||||
|
nn.Conv2d(128, 256, kernel_size=3, stride=1, padding=1),
|
||||||
|
nn.BatchNorm2d(256),
|
||||||
|
nn.ReLU(),
|
||||||
|
nn.MaxPool2d(kernel_size=2)
|
||||||
|
)
|
||||||
|
|
||||||
|
self.head = nn.Conv2d(256, self.output_size, kernel_size=1)
|
||||||
|
self.pool = nn.AdaptiveAvgPool2d((1, 1))
|
||||||
|
|
||||||
|
|
||||||
|
def forward(self, image):
|
||||||
|
x = self.feature(image)
|
||||||
|
x = self.head(x)
|
||||||
|
x = self.pool(x)
|
||||||
|
|
||||||
|
return x.flatten(1)
|
||||||
|
|
||||||
|
# %% Создание модели PyTorch Lightning
|
||||||
|
|
||||||
|
class MyNNExample(pl.LightningModule):
|
||||||
|
def __init__(self,
|
||||||
|
model: nn.Module,
|
||||||
|
eta=3e-4):
|
||||||
|
super().__init__()
|
||||||
|
|
||||||
|
self.save_hyperparameters(ignore=["model"])
|
||||||
|
# device = "cuda" if torch.cuda.is_available() else "cpu"
|
||||||
|
self.model = model
|
||||||
|
|
||||||
|
self.criterion = nn.CrossEntropyLoss()
|
||||||
|
self.train_metrics = MetricCollection({
|
||||||
|
"accuracy": Accuracy(task="multiclass",
|
||||||
|
num_classes=model.output_size),
|
||||||
|
"precision": Precision(task="multiclass",
|
||||||
|
num_classes=model.output_size,
|
||||||
|
average="macro"),
|
||||||
|
"recall": Recall(task="multiclass",
|
||||||
|
num_classes=model.output_size,
|
||||||
|
average="macro"),
|
||||||
|
"f1": F1Score(task="multiclass",
|
||||||
|
num_classes=model.output_size,
|
||||||
|
average="macro")
|
||||||
|
})
|
||||||
|
|
||||||
|
self.val_metrics = self.train_metrics.clone()
|
||||||
|
self.test_metrics = self.train_metrics.clone()
|
||||||
|
|
||||||
|
|
||||||
|
def forward(self, image):
|
||||||
|
return self.model(image)
|
||||||
|
|
||||||
|
|
||||||
|
def _shared_step(self,
|
||||||
|
sample,
|
||||||
|
stage,
|
||||||
|
metrics):
|
||||||
|
x, y = sample
|
||||||
|
logits = self.forward(x.to(torch.float32))
|
||||||
|
preds = torch.argmax(logits, 1)
|
||||||
|
loss = self.criterion(logits, y.to(torch.int64))
|
||||||
|
|
||||||
|
metrics.update(preds, y)
|
||||||
|
self.log(f"{stage}_loss", loss,
|
||||||
|
prog_bar=True, on_epoch=True, on_step=False)
|
||||||
|
|
||||||
|
return loss
|
||||||
|
|
||||||
|
def _log_metrics(self, stage, metrics):
|
||||||
|
computed = metrics.compute()
|
||||||
|
|
||||||
|
for name, value in computed.items():
|
||||||
|
self.log(f"{stage}_{name}", value, prog_bar=True)
|
||||||
|
|
||||||
|
metrics.reset()
|
||||||
|
|
||||||
|
def training_step(self, batch, batch_idx):
|
||||||
|
return self._shared_step(batch, "train", self.train_metrics)
|
||||||
|
|
||||||
|
def on_train_epoch_end(self):
|
||||||
|
self._log_metrics("train", self.train_metrics)
|
||||||
|
|
||||||
|
def validation_step(self, batch, batch_idx):
|
||||||
|
return self._shared_step(batch, "val", self.val_metrics)
|
||||||
|
|
||||||
|
def on_validation_epoch_end(self):
|
||||||
|
self._log_metrics("val", self.val_metrics)
|
||||||
|
|
||||||
|
def test_step(self, batch, batch_idx):
|
||||||
|
return self._shared_step(batch, "test", self.test_metrics)
|
||||||
|
|
||||||
|
def on_test_epoch_end(self):
|
||||||
|
self._log_metrics("test", self.test_metrics)
|
||||||
|
|
||||||
|
def configure_optimizers(self):
|
||||||
|
optimizer = torch.optim.Adam(self.parameters(), lr=self.hparams.eta)
|
||||||
|
scheduler = torch.optim.lr_scheduler.ReduceLROnPlateau(
|
||||||
|
optimizer, patience=5, mode="min"
|
||||||
|
)
|
||||||
|
|
||||||
|
return {
|
||||||
|
"optimizer": optimizer,
|
||||||
|
"lr_scheduler": {
|
||||||
|
"scheduler": scheduler,
|
||||||
|
"monitor": "val_loss",
|
||||||
|
"interval": "epoch",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# %% Загрузка набора данных
|
||||||
|
|
||||||
|
image_transforms = transforms.Compose([
|
||||||
|
transforms.ToTensor()
|
||||||
|
])
|
||||||
|
|
||||||
|
train_dataset = datasets.MNIST(
|
||||||
|
root="./Datasets",
|
||||||
|
train=True,
|
||||||
|
download=False, # Если скачен, то убрать
|
||||||
|
transform=image_transforms
|
||||||
|
)
|
||||||
|
|
||||||
|
test_dataset = datasets.MNIST(
|
||||||
|
root="./Datasets",
|
||||||
|
train=False,
|
||||||
|
download=False, # Если скачен, то убрать
|
||||||
|
transform=image_transforms
|
||||||
|
)
|
||||||
|
|
||||||
|
train_loader = DataLoader(dataset=train_dataset,
|
||||||
|
batch_size=batch_size,
|
||||||
|
shuffle=True)
|
||||||
|
|
||||||
|
test_loader = DataLoader(dataset=test_dataset,
|
||||||
|
batch_size=batch_size,
|
||||||
|
shuffle=False)
|
||||||
|
|
||||||
|
# %% Запуск обучения
|
||||||
|
|
||||||
|
model = MyNNExample(model=MyTorchCNNModel())
|
||||||
|
callbacks = [
|
||||||
|
ModelCheckpoint(dirpath="models",
|
||||||
|
filename="{epoch}_{val_accuracy:.4f}_{val_loss:.4f}",
|
||||||
|
auto_insert_metric_name=False,
|
||||||
|
save_last=True,
|
||||||
|
save_top_k=1,
|
||||||
|
monitor="val_loss",
|
||||||
|
mode="min"),
|
||||||
|
LearningRateMonitor(logging_interval="step"),
|
||||||
|
EarlyStopping(monitor="val_loss",
|
||||||
|
min_delta=2e-4,
|
||||||
|
patience=10,
|
||||||
|
verbose=False,
|
||||||
|
mode="min")
|
||||||
|
]
|
||||||
|
|
||||||
|
trainer = pl.Trainer(
|
||||||
|
max_epochs=num_epoch,
|
||||||
|
accelerator="gpu",
|
||||||
|
devices=1,
|
||||||
|
logger=CSVLogger("./train_logs", name="mnist_csv",
|
||||||
|
version=None, flush_logs_every_n_steps=100),
|
||||||
|
callbacks=callbacks
|
||||||
|
)
|
||||||
|
|
||||||
|
trainer.fit(model=model,
|
||||||
|
train_dataloaders=train_loader,
|
||||||
|
val_dataloaders=test_loader)
|
||||||
|
|
||||||
|
# %% Инференс модели
|
||||||
|
|
||||||
|
checkpoint_path = "./models/6_0.9460_0.1643.ckpt"
|
||||||
|
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
|
||||||
|
model = MyNNExample.load_from_checkpoint(checkpoint_path,
|
||||||
|
model=MyTorchCNNModel(output_size=10))
|
||||||
|
model = model.to(device)
|
||||||
|
model.eval()
|
||||||
|
|
||||||
|
image, true_label = test_dataset[42]
|
||||||
|
image_batch = image.unsqueeze(0).to(device)
|
||||||
|
|
||||||
|
with torch.no_grad():
|
||||||
|
logits = model(image_batch)
|
||||||
|
probs = torch.softmax(logits, dim=1)
|
||||||
|
pred_label = logits.argmax(dim=1).item()
|
||||||
|
|
||||||
|
print(f"Предсказание: {pred_label}")
|
||||||
|
print(f"Истинная метка: {true_label}")
|
||||||
|
print(f"Уверенность: {probs[0, pred_label].item():.2%}")
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
Установка с созданием новой среды:
|
||||||
|
```bash
|
||||||
|
conda env create -f environment.yml
|
||||||
|
```
|
||||||
|
|
||||||
|
Установка в уже созданную среду:
|
||||||
|
```bash
|
||||||
|
conda env update --file environment.yml --prune
|
||||||
|
```
|
||||||
|
|
||||||
|
Для переноса в другую ОС:
|
||||||
|
```bash
|
||||||
|
conda env export --from-history > environment.yml
|
||||||
|
```
|
||||||
|
|
||||||
|
Просто сохранить зависимости:
|
||||||
|
```bash
|
||||||
|
conda env export > environment.yml
|
||||||
|
```
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
# %% Импорт библиотек
|
||||||
|
import torch
|
||||||
|
import torch.nn as nn
|
||||||
|
|
||||||
|
# %% Входные переменные
|
||||||
|
input_ = 32*32
|
||||||
|
hidden_1 = 5
|
||||||
|
hidden_2 = 12
|
||||||
|
output = 2
|
||||||
|
learning_rate = 1e-3
|
||||||
|
|
||||||
|
weights_1 = torch.rand(size=(input_, hidden_1), requires_grad=True)
|
||||||
|
weights_2 = torch.rand(size=(hidden_1, hidden_2), requires_grad=True)
|
||||||
|
weights_3 = torch.rand(size=(hidden_2, output), requires_grad=True)
|
||||||
|
|
||||||
|
random_input = torch.rand(1, input_)
|
||||||
|
|
||||||
|
true_label = torch.zeros(1, output)
|
||||||
|
true_label[0][0] = 1
|
||||||
|
# %% Цикл обучения
|
||||||
|
criterion = nn.CrossEntropyLoss()
|
||||||
|
optimizer = torch.optim.SGD([weights_1, weights_2, weights_3], lr=learning_rate)
|
||||||
|
|
||||||
|
hidden_layer_1 = random_input @ weights_1
|
||||||
|
hidden_layer_2 = hidden_layer_1 @ weights_2
|
||||||
|
output_layer = hidden_layer_2 @ weights_3
|
||||||
|
|
||||||
|
loss = criterion(output_layer, true_label)
|
||||||
|
print(loss)
|
||||||
|
|
||||||
|
optimizer.zero_grad()
|
||||||
|
loss.backward()
|
||||||
|
optimizer.step()
|
||||||
|
|
||||||
|
print(weights_1._grad)
|
||||||
|
print(weights_2._grad)
|
||||||
|
print(weights_3._grad)
|
||||||
+427
@@ -0,0 +1,427 @@
|
|||||||
|
name: CV
|
||||||
|
channels:
|
||||||
|
- defaults
|
||||||
|
- conda-forge
|
||||||
|
dependencies:
|
||||||
|
- _libgcc_mutex=0.1=main
|
||||||
|
- _openmp_mutex=5.1=52_gnu
|
||||||
|
- aiodns=3.6.1=py312h06a4308_0
|
||||||
|
- aiohappyeyeballs=2.6.2=py312h06a4308_0
|
||||||
|
- aiohttp=3.14.3=py312h47b2149_0
|
||||||
|
- aiosignal=1.4.0=py312h06a4308_0
|
||||||
|
- alabaster=1.0.0=py312h06a4308_0
|
||||||
|
- alsa-lib=1.2.15.3=h47b2149_0
|
||||||
|
- anyio=4.12.1=py312h06a4308_0
|
||||||
|
- aom=3.13.2=h664349e_0
|
||||||
|
- argon2-cffi=25.1.0=py312h06a4308_0
|
||||||
|
- argon2-cffi-bindings=25.1.0=py312hee96239_0
|
||||||
|
- arrow=1.4.0=py312h06a4308_0
|
||||||
|
- astroid=4.0.3=py312h06a4308_0
|
||||||
|
- asttokens=3.0.1=py312h06a4308_0
|
||||||
|
- async-lru=2.3.0=py312h06a4308_0
|
||||||
|
- asyncssh=2.24.0=py312h06a4308_0
|
||||||
|
- attrs=26.1.0=py312h0c820a0_0
|
||||||
|
- autopep8=2.0.4=pyhd3eb1b0_0
|
||||||
|
- babel=2.18.0=py312h06a4308_0
|
||||||
|
- bcrypt=5.0.0=py312h498d7c9_0
|
||||||
|
- beartype=0.22.9=py312h06a4308_0
|
||||||
|
- beautifulsoup4=4.15.0=py312h06a4308_0
|
||||||
|
- binaryornot=0.6.0=py312h06a4308_0
|
||||||
|
- black=26.5.1=py312h06a4308_0
|
||||||
|
- blas=1.0=openblas
|
||||||
|
- bleach=6.4.0=py312h06a4308_0
|
||||||
|
- brotlicffi=1.2.0.1=py312h7354ed3_0
|
||||||
|
- bzip2=1.0.8=h5eee18b_6
|
||||||
|
- c-ares=1.34.7=hd44998d_0
|
||||||
|
- ca-certificates=2026.8.13=h06a4308_0
|
||||||
|
- cairo=1.18.4=h44eff21_0
|
||||||
|
- cattrs=26.1.0=py312h06a4308_0
|
||||||
|
- certifi=2026.7.22=py312h06a4308_0
|
||||||
|
- cffi=2.1.1=py312h3b52fac_0
|
||||||
|
- chardet=5.2.0=py312h06a4308_1
|
||||||
|
- charset-normalizer=3.4.7=py312h06a4308_0
|
||||||
|
- click=8.5.0=py312h06a4308_0
|
||||||
|
- cloudpickle=3.1.2=py312h06a4308_0
|
||||||
|
- comm=0.2.3=py312h06a4308_0
|
||||||
|
- cookiecutter=2.7.1=py312h06a4308_0
|
||||||
|
- cpython=3.12.14=py312hd8ed1ab_3
|
||||||
|
- cryptography=50.0.0=py312hef7b95b_0
|
||||||
|
- cuda-crt-tools=12.9.86=ha770c72_2
|
||||||
|
- cuda-cudart=12.9.79=h5888daf_0
|
||||||
|
- cuda-cudart_linux-64=12.9.79=h3f2d84a_0
|
||||||
|
- cuda-cuobjdump=12.9.82=hffce074_1
|
||||||
|
- cuda-cupti=12.9.79=h676940d_2
|
||||||
|
- cuda-nvcc-tools=12.9.86=he02047a_2
|
||||||
|
- cuda-nvdisasm=12.9.88=hffce074_1
|
||||||
|
- cuda-nvrtc=12.9.86=hecca717_1
|
||||||
|
- cuda-nvtx=12.9.79=hecca717_1
|
||||||
|
- cuda-nvvm-tools=12.9.86=h4bc722e_2
|
||||||
|
- cuda-version=12.9=h4f385c5_3
|
||||||
|
- cudnn=9.25.1.1=ha9dd1bd_0
|
||||||
|
- cusparselt=0.7.0.0=hcd2ec93_0
|
||||||
|
- cyrus-sasl=2.1.28=h2f687bf_5
|
||||||
|
- dav1d=1.5.3=h12c9f22_1
|
||||||
|
- dbus=1.16.2=h5bd4931_0
|
||||||
|
- debugpy=1.8.21=py312h7354ed3_0
|
||||||
|
- decorator=5.3.1=py312h06a4308_0
|
||||||
|
- defusedxml=0.7.1=pyhd3eb1b0_0
|
||||||
|
- diff-match-patch=20200713=pyhd3eb1b0_0
|
||||||
|
- dill=0.4.1=py312h06a4308_0
|
||||||
|
- docstring-to-markdown=0.17=py312h06a4308_0
|
||||||
|
- docutils=0.21.2=py312h06a4308_1
|
||||||
|
- executing=2.2.1=py312h06a4308_1
|
||||||
|
- expat=2.8.4=h7354ed3_0
|
||||||
|
- filelock=3.32.5=pyhd8ed1ab_0
|
||||||
|
- flake8=7.1.1=py312h06a4308_0
|
||||||
|
- fmt=12.1.0=h44f220b_0
|
||||||
|
- fontconfig=2.15.0=h2c49b7f_0
|
||||||
|
- freetype=2.14.1=hf5b9546_0
|
||||||
|
- fribidi=1.0.16=h10f3c28_1
|
||||||
|
- frozenlist=1.8.0=py312hbdd6827_0
|
||||||
|
- fsspec=2026.7.0=pyhd8ed1ab_0
|
||||||
|
- gettext=0.25.1=h92eb808_0
|
||||||
|
- gettext-tools=0.25.1=h6a67909_0
|
||||||
|
- giflib=6.1.3=h621bd71_1
|
||||||
|
- gmp=6.3.0=hfd2156b_3
|
||||||
|
- gmpy2=2.3.1=py312h04c1168_0
|
||||||
|
- graphite2=1.3.15=h9ba177b_0
|
||||||
|
- h11=0.16.0=py312h06a4308_1
|
||||||
|
- harfbuzz=12.3.0=h79d275a_1
|
||||||
|
- httpcore=1.0.9=py312h06a4308_0
|
||||||
|
- httpx=0.28.1=py312h06a4308_1
|
||||||
|
- icu=73.1=h6a678d5_0
|
||||||
|
- idna=3.18=py312h06a4308_0
|
||||||
|
- imagesize=1.4.1=py312h06a4308_0
|
||||||
|
- importlib-metadata=9.0.0=py312h06a4308_0
|
||||||
|
- inflection=0.5.1=py312h06a4308_1
|
||||||
|
- intervaltree=3.2.1=pyhd3eb1b0_0
|
||||||
|
- ipykernel=6.31.0=py312h7040dfc_0
|
||||||
|
- ipython=9.15.0=py312h06a4308_0
|
||||||
|
- ipython_pygments_lexers=1.1.1=py312h06a4308_0
|
||||||
|
- isort=8.0.1=py312h06a4308_1
|
||||||
|
- jansson=2.15.0=hbcba0ee_0
|
||||||
|
- jaraco.classes=3.4.0=py312h06a4308_0
|
||||||
|
- jaraco.context=6.1.0=py312h06a4308_0
|
||||||
|
- jaraco.functools=4.4.0=py312h06a4308_0
|
||||||
|
- jedi=0.19.2=py312h06a4308_0
|
||||||
|
- jeepney=0.7.1=pyhd3eb1b0_0
|
||||||
|
- jellyfish=1.2.1=py312h498d7c9_0
|
||||||
|
- jinja2=3.1.6=pyhcf101f3_1
|
||||||
|
- jpeg=9f=he7e78df_1
|
||||||
|
- json5=0.15.0=py312h06a4308_0
|
||||||
|
- jsonschema=4.26.0=py312h06a4308_0
|
||||||
|
- jsonschema-specifications=2025.9.1=py312h06a4308_0
|
||||||
|
- jupyter-builder=1.2.0=py312h06a4308_0
|
||||||
|
- jupyter-lsp=2.3.0=py312h06a4308_0
|
||||||
|
- jupyter_client=8.10.0=py312h06a4308_0
|
||||||
|
- jupyter_core=5.9.1=py312h06a4308_0
|
||||||
|
- jupyter_events=0.12.1=py312h06a4308_0
|
||||||
|
- jupyter_server=2.20.0=py312h06a4308_0
|
||||||
|
- jupyter_server_terminals=0.5.4=py312h06a4308_0
|
||||||
|
- jupyterlab=4.6.2=py312h06a4308_1
|
||||||
|
- jupyterlab_pygments=0.3.0=py312h06a4308_0
|
||||||
|
- jupyterlab_server=2.28.0=py312h06a4308_1
|
||||||
|
- kagglehub=1.0.2=py312h06a4308_0
|
||||||
|
- kagglesdk=0.1.35=py312h06a4308_0
|
||||||
|
- keyring=25.7.0=py312h06a4308_0
|
||||||
|
- krb5=1.20.1=h143b758_1
|
||||||
|
- lcms2=2.19=he283960_0
|
||||||
|
- ld_impl_linux-64=2.44=h9e0c5a2_3
|
||||||
|
- lerc=4.1.0=h7354ed3_2
|
||||||
|
- libabseil=20260107.0=cxx17_h6199ee8_0
|
||||||
|
- libasprintf=0.25.1=hf2ab22a_0
|
||||||
|
- libasprintf-devel=0.25.1=hf2ab22a_0
|
||||||
|
- libavif=1.3.0=h2b90b00_1
|
||||||
|
- libbrotlicommon=1.2.0=h32cd6e7_0
|
||||||
|
- libbrotlidec=1.2.0=ha2c5f68_0
|
||||||
|
- libbrotlienc=1.2.0=h2e96acb_0
|
||||||
|
- libcap=2.78=h084b8d7_1
|
||||||
|
- libcublas=12.9.2.10=h676940d_0
|
||||||
|
- libcudnn=9.25.1.1=hfd19c1e_0
|
||||||
|
- libcudnn-dev=9.25.1.1=ha9dd1bd_0
|
||||||
|
- libcudss0=0.4.0.2=he55f5cd_2
|
||||||
|
- libcufft=11.4.1.4=hecca717_1
|
||||||
|
- libcufile=1.14.1.1=hbc026e6_1
|
||||||
|
- libcups=2.4.19=h23114ae_0
|
||||||
|
- libcurand=10.3.10.19=h676940d_1
|
||||||
|
- libcurl=8.19.0=ha05a353_0
|
||||||
|
- libcusolver=11.7.5.82=h676940d_2
|
||||||
|
- libcusparse=12.5.10.65=hecca717_2
|
||||||
|
- libdeflate=1.22=h5eee18b_0
|
||||||
|
- libdrm=2.4.134=h9c74679_0
|
||||||
|
- libedit=3.1.20230828=h5eee18b_0
|
||||||
|
- libegl=1.7.0=h5eee18b_2
|
||||||
|
- libev=4.33=h7f8727e_1
|
||||||
|
- libevent=2.1.12=hdbd6064_1
|
||||||
|
- libexpat=2.8.4=h7354ed3_0
|
||||||
|
- libffi=3.4.8=h06d3fd0_3
|
||||||
|
- libgcc=15.2.0=h69a1729_8
|
||||||
|
- libgcc-ng=15.2.0=h166f726_8
|
||||||
|
- libgettextpo=0.25.1=hf2ab22a_0
|
||||||
|
- libgettextpo-devel=0.25.1=hf2ab22a_0
|
||||||
|
- libgfortran=15.2.0=h69a702a_20
|
||||||
|
- libgfortran5=15.2.0=h68bc16d_20
|
||||||
|
- libgl=1.7.0=h5eee18b_2
|
||||||
|
- libglib=2.88.3=ha16e27a_0
|
||||||
|
- libglvnd=1.7.0=h5eee18b_2
|
||||||
|
- libglx=1.7.0=h5eee18b_2
|
||||||
|
- libgomp=15.2.0=h4751f2c_8
|
||||||
|
- libiconv=1.18=h75a1612_0
|
||||||
|
- libidn2=2.3.8=hf80d704_0
|
||||||
|
- libkrb5=1.22.1=h6d2bf13_0
|
||||||
|
- libllvm20=20.1.8=h465586c_0
|
||||||
|
- libllvm22=22.1.2=hfb1d434_0
|
||||||
|
- liblzma=5.8.2=hb03c661_0
|
||||||
|
- libnghttp2=1.67.1=h697f920_0
|
||||||
|
- libnl=3.11.0=hb03c661_1
|
||||||
|
- libnvjitlink=12.9.86=hecca717_2
|
||||||
|
- libnvjpeg=12.4.0.76=h7354ed3_0
|
||||||
|
- libopenblas=0.3.34=pthreads_h94d23a6_0
|
||||||
|
- libopengl=1.7.0=h5eee18b_2
|
||||||
|
- libopenjpeg=2.5.4=hee96239_1
|
||||||
|
- libopus=1.6.1=h9f10d21_1
|
||||||
|
- libpciaccess=0.18=h5eee18b_0
|
||||||
|
- libpng=1.6.56=h22898a0_0
|
||||||
|
- libpq=17.9=h0cb448f_1
|
||||||
|
- libprotobuf=6.33.5=h4435b4a_0
|
||||||
|
- libre2-11=2025.11.05=h3356fce_1
|
||||||
|
- libsodium=1.0.21=h83fc4cd_1
|
||||||
|
- libspatialindex=2.1.0=hf7d4471_0
|
||||||
|
- libssh2=1.11.1=hfbabe93_1
|
||||||
|
- libstdcxx=15.2.0=h39759b7_8
|
||||||
|
- libstdcxx-ng=15.2.0=hc03a8fd_8
|
||||||
|
- libsystemd0=261.2=h6f4a2f1_0
|
||||||
|
- libtiff=4.7.1=h029b1ac_0
|
||||||
|
- libtirpc=1.3.7=h47b2149_0
|
||||||
|
- libtorch=2.12.0=gpu_cuda129_h0198de7_200
|
||||||
|
- libudev1=261.2=h6f4a2f1_0
|
||||||
|
- libunistring=1.4.2=h34b0ebb_0
|
||||||
|
- libuuid=1.41.5=h5eee18b_0
|
||||||
|
- libuv=1.52.1=h280c20c_1
|
||||||
|
- libvpx=1.16.0=h4b463fa_0
|
||||||
|
- libwebp-base=1.6.0=hb7bb969_0
|
||||||
|
- libxcb=1.17.0=h9b100fa_0
|
||||||
|
- libxkbcommon=1.9.1=h69220b7_0
|
||||||
|
- libxkbfile=1.1.0=hf54ef8a_2
|
||||||
|
- libxml2=2.13.9=h2c43086_0
|
||||||
|
- libxslt=1.1.43=h28b3bda_0
|
||||||
|
- libzlib=1.3.2=h47b2149_0
|
||||||
|
- lightning-utilities=0.15.3=pyhd8ed1ab_0
|
||||||
|
- lmdb=1.0.0=hfe55579_0
|
||||||
|
- lsprotocol=2025.0.0=py312h06a4308_1
|
||||||
|
- lz4-c=1.9.4=h7354ed3_5
|
||||||
|
- magma=2.10.0=hfa452ef_1
|
||||||
|
- markdown-it-py=4.2.0=py312h06a4308_0
|
||||||
|
- markupsafe=3.0.3=py312h47b2149_0
|
||||||
|
- matplotlib-inline=0.2.2=py312h06a4308_0
|
||||||
|
- mccabe=0.7.0=pyhd3eb1b0_0
|
||||||
|
- mdurl=0.1.2=py312h06a4308_0
|
||||||
|
- mesalib=25.1.5=h3583ad3_5
|
||||||
|
- minizip=4.2.1=h7e49174_0
|
||||||
|
- mistune=3.3.3=py312h06a4308_0
|
||||||
|
- more-itertools=11.0.2=py312h06a4308_0
|
||||||
|
- mpc=1.4.0=ha2cb11d_1
|
||||||
|
- mpfr=4.2.2=ha2cb11d_1
|
||||||
|
- mpmath=1.4.1=pyhd8ed1ab_0
|
||||||
|
- multidict=6.7.1=py312h47b2149_0
|
||||||
|
- mypy_extensions=1.1.0=py312h06a4308_0
|
||||||
|
- mysql=9.3.0=hef88997_5
|
||||||
|
- mysql-client=9.3.0=hf2c64df_5
|
||||||
|
- mysql-common=9.3.0=h9e076cb_5
|
||||||
|
- mysql-devel=9.3.0=h9e076cb_5
|
||||||
|
- mysql-libs=9.3.0=h6ecde68_5
|
||||||
|
- mysql-server=9.3.0=h284711e_5
|
||||||
|
- nbclient=0.11.0=py312h06a4308_0
|
||||||
|
- nbconvert=7.17.1=py312h06a4308_0
|
||||||
|
- nbconvert-core=7.17.1=py312h06a4308_0
|
||||||
|
- nbconvert-pandoc=7.17.1=py312h06a4308_0
|
||||||
|
- nbformat=5.11.0=py312h06a4308_0
|
||||||
|
- nccl=2.30.7.1=h4d09622_0
|
||||||
|
- ncurses=6.6=hfaaeb4e_0
|
||||||
|
- nest-asyncio=1.6.0=py312h06a4308_1
|
||||||
|
- nest-asyncio2=1.7.2=py312h06a4308_0
|
||||||
|
- networkx=3.6.1=pyhcf101f3_0
|
||||||
|
- nomkl=1.0=h5ca1d4c_0
|
||||||
|
- notebook-shim=0.2.4=py312h06a4308_1
|
||||||
|
- nspr=4.39=h6e5897e_0
|
||||||
|
- nss=3.125=hcf7f90d_0
|
||||||
|
- numpy=2.5.2=py312h35deafb_0
|
||||||
|
- numpy-base=2.5.2=py312h4bc27c9_0
|
||||||
|
- numpydoc=1.10.0=py312h06a4308_0
|
||||||
|
- openjpeg=2.5.4=h4e0627c_1
|
||||||
|
- openldap=2.6.12=h007892f_1
|
||||||
|
- openssl=3.6.4=h781a0a9_0
|
||||||
|
- optree=0.20.0=py312ha5105d2_1
|
||||||
|
- packaging=26.3=py312h06a4308_0
|
||||||
|
- pandoc=3.8=h06a4308_0
|
||||||
|
- pandocfilters=1.5.1=py312h06a4308_0
|
||||||
|
- parso=0.8.7=py312h06a4308_0
|
||||||
|
- pathspec=1.1.1=py312h06a4308_0
|
||||||
|
- pcre2=10.46=hf426167_0
|
||||||
|
- pexpect=4.9.0=py312h06a4308_1
|
||||||
|
- pickleshare=0.7.5=pyhd3eb1b0_1003
|
||||||
|
- pillow=12.2.0=py312haa37d31_0
|
||||||
|
- pip=26.2.1=pyhc872135_0
|
||||||
|
- pixman=0.46.4=h86ba9f7_1
|
||||||
|
- platformdirs=4.11.0=py312h06a4308_0
|
||||||
|
- pluggy=1.6.0=py312h06a4308_0
|
||||||
|
- prometheus_client=0.24.1=py312h06a4308_0
|
||||||
|
- prompt-toolkit=3.0.53=py312h06a4308_0
|
||||||
|
- prompt_toolkit=3.0.53=hd3eb1b0_0
|
||||||
|
- propcache=0.5.2=py312h47b2149_0
|
||||||
|
- protobuf=6.33.5=py312h7354ed3_0
|
||||||
|
- psutil=7.2.2=py312h47b2149_0
|
||||||
|
- pthread-stubs=0.3=h47b2149_2
|
||||||
|
- ptyprocess=0.7.0=pyhd3eb1b0_3
|
||||||
|
- pure_eval=0.2.3=py312h06a4308_0
|
||||||
|
- pybind11=3.0.4=py312h24d9097_0
|
||||||
|
- pybind11-abi=11=hd3eb1b0_0
|
||||||
|
- pybind11-global=3.0.4=py312h24d9097_0
|
||||||
|
- pycares=4.10.0=py312ha137689_0
|
||||||
|
- pycodestyle=2.12.1=py312h06a4308_0
|
||||||
|
- pycparser=3.0=py312h06a4308_0
|
||||||
|
- pydocstyle=6.3.0=py312h06a4308_1
|
||||||
|
- pyflakes=3.2.0=py312h06a4308_0
|
||||||
|
- pygithub=2.9.1=py312h06a4308_0
|
||||||
|
- pygments=2.20.0=py312h06a4308_0
|
||||||
|
- pyjwt=2.13.0=py312h06a4308_0
|
||||||
|
- pylint=4.0.6=py312h06a4308_0
|
||||||
|
- pylint-venv=3.0.3=py312h06a4308_0
|
||||||
|
- pyls-spyder=0.4.0=pyhd3eb1b0_0
|
||||||
|
- pynacl=1.6.2=py312h83fc4cd_1
|
||||||
|
- pyqt=6.11.0=py312h0eb9b55_0
|
||||||
|
- pyqt6-sip=13.11.1=py312h47b2149_0
|
||||||
|
- pyqtwebengine=6.11.0=py312hdc71590_0
|
||||||
|
- pysocks=1.7.1=py312h06a4308_1
|
||||||
|
- python=3.12.14=hc5f7cf0_0
|
||||||
|
- python-dateutil=2.9.0post0=py312h06a4308_2
|
||||||
|
- python-fastjsonschema=2.22.1=py312h06a4308_0
|
||||||
|
- python-json-logger=4.1.0=py312h06a4308_0
|
||||||
|
- python-lsp-black=2.0.0=py312h06a4308_1
|
||||||
|
- python-lsp-jsonrpc=1.1.2=pyhd3eb1b0_0
|
||||||
|
- python-lsp-ruff=2.3.0=py312h06a4308_0
|
||||||
|
- python-lsp-server=1.14.0=py312h7040dfc_1
|
||||||
|
- python-slugify=8.0.4=py312h06a4308_0
|
||||||
|
- python-tzdata=2026.3=pyhd3eb1b0_0
|
||||||
|
- python_abi=3.12=4_cp312
|
||||||
|
- pytokens=0.4.1=py312h47b2149_0
|
||||||
|
- pytoolconfig=1.3.1=py312h06a4308_0
|
||||||
|
- pytorch=2.12.0=gpu_cuda129_py312h95261ae_200
|
||||||
|
- pytorch-lightning=2.6.5=pyhcf101f3_0
|
||||||
|
- pyuca=1.2=py312h06a4308_1
|
||||||
|
- pyxdg=0.28=py312h06a4308_0
|
||||||
|
- pyyaml=6.0.3=py312h8a5da7c_1
|
||||||
|
- pyzmq=27.1.0=py312hcf8288c_1
|
||||||
|
- qdarkstyle=3.2.3=pyhd3eb1b0_0
|
||||||
|
- qstylizer=0.2.4=py312h06a4308_0
|
||||||
|
- qtawesome=1.4.2=py312h4333747_0
|
||||||
|
- qtbase=6.11.0=h9201cad_0
|
||||||
|
- qtconsole=5.7.2=py312h06a4308_0
|
||||||
|
- qtdeclarative=6.11.0=h89ee561_1
|
||||||
|
- qtpy=2.4.3=py312h06a4308_0
|
||||||
|
- qtsvg=6.11.0=hbecefc2_1
|
||||||
|
- qttools=6.11.0=h0af0a4d_1
|
||||||
|
- qtwayland=6.11.0=h9a62c7d_0
|
||||||
|
- qtwebchannel=6.11.0=h7ebffc9_1
|
||||||
|
- qtwebengine=6.11.0=hb54882b_0
|
||||||
|
- qtwebsockets=6.11.0=h03d4248_1
|
||||||
|
- rdma-core=65.0=h7b4f2e6_0
|
||||||
|
- re2=2025.11.05=h71b5c5c_1
|
||||||
|
- readline=8.3=hc2a1206_0
|
||||||
|
- referencing=0.37.0=py312h06a4308_0
|
||||||
|
- requests=2.34.2=py312h06a4308_0
|
||||||
|
- rfc3339-validator=0.1.4=py312h06a4308_0
|
||||||
|
- rfc3986-validator=0.1.1=py312h06a4308_0
|
||||||
|
- rich=15.0.0=py312h06a4308_0
|
||||||
|
- roman-numerals=3.1.0=py312h06a4308_0
|
||||||
|
- rope=1.14.0=py312h06a4308_0
|
||||||
|
- rpds-py=0.28.0=py312h498d7c9_0
|
||||||
|
- rtree=1.4.1=py312hd966e25_1
|
||||||
|
- ruff=0.15.1=py312h6e1b9ff_0
|
||||||
|
- secretstorage=3.5.0=py312h3e8c6aa_0
|
||||||
|
- send2trash=1.8.3=py312h06a4308_0
|
||||||
|
- setuptools=80.10.2=py312h06a4308_0
|
||||||
|
- sip=6.15.1=py312he6c97cb_0
|
||||||
|
- six=1.17.0=py312h06a4308_0
|
||||||
|
- sleef=3.9.0=ha0421bc_0
|
||||||
|
- snappy=1.2.2=h4bcf44c_1
|
||||||
|
- snowballstemmer=3.1.1=py312h06a4308_0
|
||||||
|
- sortedcontainers=2.4.0=pyhd3eb1b0_0
|
||||||
|
- soupsieve=2.8.4=py312h06a4308_0
|
||||||
|
- sphinx=9.1.0=py312h893fd2c_0
|
||||||
|
- sphinxcontrib-applehelp=2.0.0=pyhd3eb1b0_1
|
||||||
|
- sphinxcontrib-devhelp=2.0.0=pyhd3eb1b0_0
|
||||||
|
- sphinxcontrib-htmlhelp=2.1.0=pyhd3eb1b0_0
|
||||||
|
- sphinxcontrib-jsmath=1.0.1=pyhd3eb1b0_0
|
||||||
|
- sphinxcontrib-qthelp=2.0.0=pyhd3eb1b0_1
|
||||||
|
- sphinxcontrib-serializinghtml=2.0.0=pyhd3eb1b0_0
|
||||||
|
- spirv-tools=2026.1=h24d9097_0
|
||||||
|
- spyder=6.1.5=py312h06a4308_0
|
||||||
|
- spyder-kernels=3.1.6=py312h7040dfc_0
|
||||||
|
- sqlite=3.53.2=h795bf6d_0
|
||||||
|
- stack_data=0.6.3=py312h06a4308_0
|
||||||
|
- superqt=0.8.1=py312ha9b9ae4_0
|
||||||
|
- sympy=1.14.0=pyh2585a3b_106
|
||||||
|
- terminado=0.18.1=py312h06a4308_1
|
||||||
|
- text-unidecode=1.3=pyhd3eb1b0_0
|
||||||
|
- textdistance=4.6.3=py312he3bba80_1
|
||||||
|
- three-merge=0.1.1=pyhd3eb1b0_0
|
||||||
|
- tinycss2=1.5.1=py312h06a4308_0
|
||||||
|
- tk=8.6.15=h54e0aa7_0
|
||||||
|
- tomlkit=0.15.1=py312h06a4308_0
|
||||||
|
- torchao=0.17.0=cuda129_py312hd0f1f67_2
|
||||||
|
- torchmetrics=1.9.0=pyhd8ed1ab_0
|
||||||
|
- torchvision=0.27.0=cuda129py312h054a6d6_100
|
||||||
|
- tornado=6.5.8=py312h47b2149_0
|
||||||
|
- tqdm=4.70.0=pyh8f84b5b_0
|
||||||
|
- traitlets=5.15.0=py312h06a4308_0
|
||||||
|
- triton=3.7.0=cuda129py312h338dc61_1
|
||||||
|
- typing-extensions=4.16.0=py312h06a4308_0
|
||||||
|
- typing_extensions=4.16.0=py312h06a4308_0
|
||||||
|
- tzdata=2026c=he532380_0
|
||||||
|
- ujson=5.13.0=py312h7354ed3_0
|
||||||
|
- urllib3=2.7.0=py312h06a4308_0
|
||||||
|
- uvloop=0.22.1=py312h939ff40_1
|
||||||
|
- watchdog=6.0.0=py312h06a4308_0
|
||||||
|
- wayland=1.24.0=hdac8c69_0
|
||||||
|
- wcwidth=0.8.2=py312h06a4308_0
|
||||||
|
- webencodings=0.6.1=py312h06a4308_0
|
||||||
|
- websocket-client=1.8.0=py312h06a4308_0
|
||||||
|
- whatthepatch=1.0.7=py312h06a4308_0
|
||||||
|
- wheel=0.47.0=py312h06a4308_0
|
||||||
|
- wurlitzer=3.1.1=py312h06a4308_0
|
||||||
|
- xcb-util=0.4.1=h5eee18b_2
|
||||||
|
- xcb-util-cursor=0.1.5=h5eee18b_0
|
||||||
|
- xcb-util-image=0.4.0=h5eee18b_2
|
||||||
|
- xcb-util-keysyms=0.4.1=h5eee18b_0
|
||||||
|
- xcb-util-renderutil=0.3.10=h5eee18b_0
|
||||||
|
- xcb-util-wm=0.4.2=h5eee18b_0
|
||||||
|
- xkeyboard-config=2.48=h382ed1a_0
|
||||||
|
- xorg-libice=1.1.2=h9b100fa_0
|
||||||
|
- xorg-libsm=1.2.6=h9b100fa_0
|
||||||
|
- xorg-libx11=1.8.12=h9b100fa_1
|
||||||
|
- xorg-libxau=1.0.12=h9b100fa_0
|
||||||
|
- xorg-libxcomposite=0.4.6=h9b100fa_2
|
||||||
|
- xorg-libxdamage=1.1.6=h9b100fa_0
|
||||||
|
- xorg-libxdmcp=1.1.5=h9b100fa_0
|
||||||
|
- xorg-libxext=1.3.7=h1ce37a7_0
|
||||||
|
- xorg-libxfixes=6.0.1=h9b100fa_0
|
||||||
|
- xorg-libxi=1.8.2=h9b100fa_0
|
||||||
|
- xorg-libxrandr=1.5.4=h9b100fa_0
|
||||||
|
- xorg-libxrender=0.9.12=h9b100fa_0
|
||||||
|
- xorg-libxshmfence=1.3.3=h9b100fa_0
|
||||||
|
- xorg-libxtst=1.2.5=h9b100fa_3
|
||||||
|
- xorg-libxxf86vm=1.1.6=h9b100fa_0
|
||||||
|
- xorg-xorgproto=2024.1=h47b2149_2
|
||||||
|
- xz=5.8.2=h448239c_0
|
||||||
|
- yaml=0.2.5=h591646f_1
|
||||||
|
- yapf=0.43.0=py312h06a4308_0
|
||||||
|
- yarl=1.24.2=py312h47b2149_0
|
||||||
|
- zeromq=4.3.5=hf801bfb_2
|
||||||
|
- zipp=4.1.0=py312h06a4308_0
|
||||||
|
- zlib=1.3.2=h47b2149_0
|
||||||
|
- zstd=1.5.7=h11fc155_0
|
||||||
|
- pip:
|
||||||
|
- pyqt6-qt6==6.11.2
|
||||||
|
- split-folders==0.6.1
|
||||||
|
prefix: /home/daniel/anaconda3/envs/CV
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
name: CV
|
||||||
|
channels:
|
||||||
|
- defaults
|
||||||
|
dependencies:
|
||||||
|
- python=3.12
|
||||||
|
- jupyterlab
|
||||||
|
- spyder
|
||||||
|
- pytorch-lightning
|
||||||
|
- torchao
|
||||||
|
- beartype
|
||||||
|
- torchvision
|
||||||
|
- kagglehub
|
||||||
|
prefix: /home/daniel/anaconda3/envs/CV
|
||||||
@@ -0,0 +1,189 @@
|
|||||||
|
# %% Импорт библиотек
|
||||||
|
|
||||||
|
import tqdm
|
||||||
|
import torch
|
||||||
|
import torch.nn as nn
|
||||||
|
|
||||||
|
from torch.utils.data import DataLoader
|
||||||
|
from torchmetrics import MetricCollection
|
||||||
|
from torchvision import datasets, transforms
|
||||||
|
from torchmetrics.classification import Accuracy, Precision, Recall, F1Score
|
||||||
|
|
||||||
|
from PIL import Image
|
||||||
|
from beartype import beartype
|
||||||
|
|
||||||
|
# %% Гиперпараметры
|
||||||
|
num_epoch = 8
|
||||||
|
batch_size = 64
|
||||||
|
learning_rate = 1e-3
|
||||||
|
device = "cuda" if torch.cuda.is_available() else "cpu"
|
||||||
|
|
||||||
|
# %% Трансформация данных
|
||||||
|
|
||||||
|
# Resize(size) — изменяет размер изображения.
|
||||||
|
# Grayscale() — преобразование изображения в оттенки серого.
|
||||||
|
# ToTensor() — преобразует изображение PIL или NumPy-массив в PyTorch-тензор.
|
||||||
|
# Normalize(mean, std) — нормализация тензора изображения.
|
||||||
|
# GaussianBlur(kernel_size) — размытие по Гауссу.
|
||||||
|
|
||||||
|
|
||||||
|
image_transforms = transforms.Compose([
|
||||||
|
transforms.ToTensor()
|
||||||
|
])
|
||||||
|
|
||||||
|
# %% Загрузка набора данных
|
||||||
|
|
||||||
|
train_dataset = datasets.MNIST(
|
||||||
|
root="./MNIST",
|
||||||
|
train=True,
|
||||||
|
download=False, # Если скачен, то убрать
|
||||||
|
transform=image_transforms
|
||||||
|
)
|
||||||
|
|
||||||
|
test_dataset = datasets.MNIST(
|
||||||
|
root="./MNIST",
|
||||||
|
train=False,
|
||||||
|
download=False, # Если скачен, то убрать
|
||||||
|
transform=image_transforms
|
||||||
|
)
|
||||||
|
|
||||||
|
train_loader = DataLoader(dataset=train_dataset,
|
||||||
|
batch_size=batch_size,
|
||||||
|
shuffle=True)
|
||||||
|
|
||||||
|
test_loader = DataLoader(dataset=test_dataset,
|
||||||
|
batch_size=batch_size,
|
||||||
|
shuffle=False)
|
||||||
|
# %% Структура модели
|
||||||
|
|
||||||
|
class FFN(nn.Module):
|
||||||
|
|
||||||
|
@beartype
|
||||||
|
def __init__(self,
|
||||||
|
input_size: int,
|
||||||
|
output_size: int):
|
||||||
|
super().__init__()
|
||||||
|
|
||||||
|
self.input_layer = nn.Linear(input_size, 32*32)
|
||||||
|
self.hidden_layer_1 = nn.Linear(32*32, 32*32)
|
||||||
|
self.hidden_layer_2 = nn.Linear(32*32, 32*32)
|
||||||
|
self.output_layer = nn.Linear(32*32, output_size)
|
||||||
|
|
||||||
|
@beartype
|
||||||
|
def forward(self, image: torch.Tensor) -> torch.Tensor:
|
||||||
|
x = image.flatten(start_dim=1) # batch_size x 28*28
|
||||||
|
x = torch.relu(self.input_layer(x))
|
||||||
|
x = torch.relu(self.hidden_layer_1(x))
|
||||||
|
x = torch.relu(self.hidden_layer_2(x))
|
||||||
|
x = self.output_layer(x)
|
||||||
|
|
||||||
|
return x # batch_size x 10
|
||||||
|
|
||||||
|
model = FFN(input_size=28*28,
|
||||||
|
output_size=10)
|
||||||
|
model.to(device)
|
||||||
|
|
||||||
|
# %% Метрики
|
||||||
|
|
||||||
|
train_metrics = MetricCollection({
|
||||||
|
"accuracy": Accuracy(task="multiclass", num_classes=10),
|
||||||
|
"precision": Precision(task="multiclass", num_classes=10, average="macro"),
|
||||||
|
"recall": Recall(task="multiclass", num_classes=10, average="macro"),
|
||||||
|
"f1": F1Score(task="multiclass", num_classes=10, average="macro")
|
||||||
|
}).to(device)
|
||||||
|
|
||||||
|
test_metrics = MetricCollection({
|
||||||
|
"accuracy": Accuracy(task="multiclass", num_classes=10),
|
||||||
|
"precision": Precision(task="multiclass", num_classes=10, average="macro"),
|
||||||
|
"recall": Recall(task="multiclass", num_classes=10, average="macro"),
|
||||||
|
"f1": F1Score(task="multiclass", num_classes=10, average="macro")
|
||||||
|
}).to(device)
|
||||||
|
|
||||||
|
# %% Оптимизаторы
|
||||||
|
|
||||||
|
criterion = nn.CrossEntropyLoss()
|
||||||
|
optim = torch.optim.Adam(model.parameters(), lr=learning_rate)
|
||||||
|
# %% Тренировочный цикл
|
||||||
|
|
||||||
|
for epoch in tqdm.tqdm(range(num_epoch)):
|
||||||
|
model.train()
|
||||||
|
running_loss = 0
|
||||||
|
|
||||||
|
for data, target in train_loader:
|
||||||
|
data, target = data.to(device), target.to(device)
|
||||||
|
|
||||||
|
optim.zero_grad()
|
||||||
|
outputs = model(data)
|
||||||
|
loss = criterion(outputs, target)
|
||||||
|
loss.backward()
|
||||||
|
running_loss += loss.item()
|
||||||
|
optim.step()
|
||||||
|
|
||||||
|
preds = outputs.argmax(dim=1)
|
||||||
|
train_metrics.update(preds, target)
|
||||||
|
|
||||||
|
results = train_metrics.compute()
|
||||||
|
print(f"Epoch: {epoch+1}")
|
||||||
|
print("=== TRAIN ===")
|
||||||
|
print(f" Loss: {(running_loss/len(train_loader)):.4f}")
|
||||||
|
print(f" Accuracy: {results['accuracy']:.4f}")
|
||||||
|
print(f" Precision: {results['precision']:.4f}")
|
||||||
|
print(f" Recall: {results['recall']:.4f}")
|
||||||
|
print(f" F1: {results['f1']:.4f}")
|
||||||
|
print()
|
||||||
|
|
||||||
|
train_metrics.reset()
|
||||||
|
|
||||||
|
model.eval()
|
||||||
|
with torch.no_grad():
|
||||||
|
test_loss = 0
|
||||||
|
for data, target in test_loader:
|
||||||
|
data, target = data.to(device), target.to(device)
|
||||||
|
|
||||||
|
outputs = model(data)
|
||||||
|
loss = criterion(outputs, target)
|
||||||
|
test_loss += loss.item()
|
||||||
|
preds = outputs.argmax(dim=1)
|
||||||
|
test_metrics.update(preds, target)
|
||||||
|
|
||||||
|
results = test_metrics.compute()
|
||||||
|
|
||||||
|
print("=== TEST ===")
|
||||||
|
print(f" Loss: {(test_loss/len(train_loader)):.4f}")
|
||||||
|
print(f" Accuracy: {results['accuracy']:.4f}")
|
||||||
|
print(f" Precision: {results['precision']:.4f}")
|
||||||
|
print(f" Recall: {results['recall']:.4f}")
|
||||||
|
print(f" F1: {results['f1']:.4f}")
|
||||||
|
print()
|
||||||
|
|
||||||
|
test_metrics.reset()
|
||||||
|
|
||||||
|
|
||||||
|
torch.save(model.state_dict(), "./models/mnist_model.pth")
|
||||||
|
# %% Инференс модели
|
||||||
|
|
||||||
|
image_transforms = transforms.Compose([
|
||||||
|
transforms.Grayscale(),
|
||||||
|
transforms.Resize((28,28)),
|
||||||
|
transforms.ToTensor()
|
||||||
|
])
|
||||||
|
|
||||||
|
model.eval()
|
||||||
|
model.load_state_dict(torch.load("./models/mnist_model.pth"))
|
||||||
|
|
||||||
|
def predict(image_path):
|
||||||
|
image = Image.open(image_path)
|
||||||
|
image = image_transforms(image)
|
||||||
|
image = image.unsqueeze(0)
|
||||||
|
image = image.to(device)
|
||||||
|
|
||||||
|
with torch.no_grad():
|
||||||
|
output = model(image)
|
||||||
|
|
||||||
|
pred = output.argmax(dim=1).item()
|
||||||
|
|
||||||
|
return pred
|
||||||
|
|
||||||
|
print(f"Predicted label: {predict('./test_images/mnist/3.png')}")
|
||||||
|
print(f"Predicted label: {predict('./test_images/mnist/5.png')}")
|
||||||
|
print(f"Predicted label: {predict('./test_images/mnist/6.png')}")
|
||||||
Reference in New Issue
Block a user