Felix Kleinsteuber 2 năm trước cách đây
mục cha
commit
75b01eda47
66 tập tin đã thay đổi với 618 bổ sung25 xóa
  1. BIN
      annotations.npy
  2. 11 5
      approach1a_basic_frame_differencing.ipynb
  3. BIN
      approach1b_results.npy
  4. 196 0
      approach3_boxplot.ipynb
  5. 0 0
      approach3_local_features.ipynb
  6. BIN
      approach4_ae1.png
  7. BIN
      approach4_ae2.png
  8. BIN
      approach4_ae2_noise.png
  9. 329 0
      approach4_boxplot.ipynb
  10. BIN
      exp1a_annotations.npy
  11. 0 0
      imgs/approach1a_difference_image.png
  12. 0 0
      imgs/approach1a_difference_image2.png
  13. 0 0
      imgs/approach1a_gaussianworksbetter_sigma0.png
  14. 0 0
      imgs/approach1a_gaussianworksbetter_sigma4.png
  15. BIN
      imgs/approach1a_lapse.pdf
  16. BIN
      imgs/approach1a_motion.pdf
  17. BIN
      imgs/approach1a_sqdiff.pdf
  18. 0 0
      imgs/approach2_bad_example_imgs.png
  19. 0 0
      imgs/approach2_bad_example_median.png
  20. 0 0
      imgs/approach2_good_example_imgs.png
  21. 0 0
      imgs/approach2_good_example_median.png
  22. 0 0
      imgs/approach3_dsift.png
  23. 0 0
      imgs/approach3_keypoints.pdf
  24. 0 0
      imgs/approach3_keypoints_lapse.pdf
  25. 0 0
      imgs/approach4_difficult_anomalous_beaver_01.png
  26. 0 0
      imgs/approach4_difficult_anomalous_marten_01.png
  27. 0 0
      imgs/approach4_difficult_normal_beaver_01.png
  28. 0 0
      imgs/approach4_difficult_normal_marten_01.png
  29. 0 0
      imgs/approach4_easy_anomalous_beaver_01.png
  30. 0 0
      imgs/approach4_easy_anomalous_marten_01.png
  31. 0 0
      imgs/approach4_easy_normal_beaver_01.png
  32. 0 0
      imgs/approach4_easy_normal_marten_01.png
  33. 0 0
      imgs/approach4_reconstructions.png
  34. 0 0
      imgs/approach4_reconstructions_beaver01.png
  35. 58 0
      index.ipynb
  36. BIN
      plots/approach1a/roc_curves/Marten_01_absmean.pdf
  37. BIN
      plots/approach1a/roc_curves/Marten_01_absmean.png
  38. BIN
      plots/approach1a/roc_curves/Marten_01_absmean_sigma6.pdf
  39. BIN
      plots/approach1a/roc_curves/Marten_01_absmean_sigma6.png
  40. BIN
      plots/approach1a/roc_curves/Marten_01_absvar.pdf
  41. BIN
      plots/approach1a/roc_curves/Marten_01_absvar.png
  42. BIN
      plots/approach1a/roc_curves/Marten_01_absvar_sigma6.pdf
  43. BIN
      plots/approach1a/roc_curves/Marten_01_absvar_sigma6.png
  44. BIN
      plots/approach1a/roc_curves/Marten_01_sqmean.pdf
  45. BIN
      plots/approach1a/roc_curves/Marten_01_sqmean.png
  46. BIN
      plots/approach1a/roc_curves/Marten_01_sqmean_sigma6.pdf
  47. BIN
      plots/approach1a/roc_curves/Marten_01_sqmean_sigma6.png
  48. BIN
      plots/approach1a/roc_curves/Marten_01_sqvar.pdf
  49. BIN
      plots/approach1a/roc_curves/Marten_01_sqvar.png
  50. BIN
      plots/approach1a/roc_curves/Marten_01_sqvar_sigma6.pdf
  51. BIN
      plots/approach1a/roc_curves/Marten_01_sqvar_sigma6.png
  52. BIN
      plots/approach3/boxplot_random.pdf
  53. BIN
      plots/approach3/boxplot_random_tnr95.pdf
  54. BIN
      plots/approach4/boxplot_kde_denoising.pdf
  55. BIN
      plots/approach4/boxplot_kde_denoising_and_sparse.pdf
  56. BIN
      plots/approach4/boxplot_kde_denoising_and_sparse_tnr95.pdf
  57. BIN
      plots/approach4/boxplot_kde_denoising_tnr95.pdf
  58. BIN
      plots/approach4/boxplot_kde_latentfeatures.pdf
  59. BIN
      plots/approach4/boxplot_kde_latentfeatures_tnr95.pdf
  60. BIN
      plots/approach4/boxplot_kde_sparse.pdf
  61. BIN
      plots/approach4/boxplot_kde_sparse_tnr95.pdf
  62. 1 0
      py/ImageUtils.py
  63. 6 2
      py/PlotUtils.py
  64. 1 1
      py/Session.py
  65. 1 8
      resize_session.ipynb
  66. 15 9
      train_autoencoder.py

BIN
annotations.npy


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 11 - 5
approach1a_basic_frame_differencing.ipynb


BIN
approach1b_results.npy


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 196 - 0
approach3_boxplot.ipynb


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 0
approach3_local_features.ipynb


BIN
approach4_ae1.png


BIN
approach4_ae2.png


BIN
approach4_ae2_noise.png


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 329 - 0
approach4_boxplot.ipynb


BIN
exp1a_annotations.npy


+ 0 - 0
approach1a_difference_image.png → imgs/approach1a_difference_image.png


+ 0 - 0
approach1a_difference_image2.png → imgs/approach1a_difference_image2.png


+ 0 - 0
approach1a_gaussianworksbetter_sigma0.png → imgs/approach1a_gaussianworksbetter_sigma0.png


+ 0 - 0
approach1a_gaussianworksbetter_sigma4.png → imgs/approach1a_gaussianworksbetter_sigma4.png


BIN
imgs/approach1a_lapse.pdf


BIN
imgs/approach1a_motion.pdf


BIN
imgs/approach1a_sqdiff.pdf


+ 0 - 0
approach2_bad_example_imgs.png → imgs/approach2_bad_example_imgs.png


+ 0 - 0
approach2_bad_example_median.png → imgs/approach2_bad_example_median.png


+ 0 - 0
approach2_good_example_imgs.png → imgs/approach2_good_example_imgs.png


+ 0 - 0
approach2_good_example_median.png → imgs/approach2_good_example_median.png


+ 0 - 0
approach3_dsift.png → imgs/approach3_dsift.png


+ 0 - 0
approach3_keypoints.pdf → imgs/approach3_keypoints.pdf


+ 0 - 0
approach3_keypoints_lapse.pdf → imgs/approach3_keypoints_lapse.pdf


+ 0 - 0
approach4_difficult_anomalous_beaver_01.png → imgs/approach4_difficult_anomalous_beaver_01.png


+ 0 - 0
approach4_difficult_anomalous_marten_01.png → imgs/approach4_difficult_anomalous_marten_01.png


+ 0 - 0
approach4_difficult_normal_beaver_01.png → imgs/approach4_difficult_normal_beaver_01.png


+ 0 - 0
approach4_difficult_normal_marten_01.png → imgs/approach4_difficult_normal_marten_01.png


+ 0 - 0
approach4_easy_anomalous_beaver_01.png → imgs/approach4_easy_anomalous_beaver_01.png


+ 0 - 0
approach4_easy_anomalous_marten_01.png → imgs/approach4_easy_anomalous_marten_01.png


+ 0 - 0
approach4_easy_normal_beaver_01.png → imgs/approach4_easy_normal_beaver_01.png


+ 0 - 0
approach4_easy_normal_marten_01.png → imgs/approach4_easy_normal_marten_01.png


+ 0 - 0
approach4_reconstructions.png → imgs/approach4_reconstructions.png


+ 0 - 0
approach4_reconstructions_beaver01.png → imgs/approach4_reconstructions_beaver01.png


+ 58 - 0
index.ipynb

@@ -0,0 +1,58 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Anomaly Detection in Camera Trap Images - Implementation\n",
+    "This is an index file for the implementation part of my bachelor thesis 'Anomaly Detection in Camera Trap Images'."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Approach 1: Lapse Frame Differencing\n",
+    " - *approach1a_basic_frame_differencing.ipynb*: Implementation.\n",
+    " - *approach1b_histograms.ipynb*: Discarded similar approach using histogram distribution to compare Lapse and Motion images.\n",
+    "\n",
+    "## Approach 2: Median Frame Differencing\n",
+    " - *approach2_background_estimation.ipynb*: Implementation.\n",
+    "\n",
+    "## Approach 3: Bag of Visual Words\n",
+    " - *approach3_local_features.ipynb*: Visualizations and evaluation of single trainings.\n",
+    " - *approach3_boxplot.ipynb*: Boxplot to compare multiple vocabularies generated using random prototypes.\n",
+    "\n",
+    "## Approach 4: Autoencoder\n",
+    " - *approach4_autoencoder.ipynb*: Visualizations and evaluation of single trainings.\n",
+    " - *approach4_boxplot.ipynb*: Boxplot to compare multiple trainings."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "Python 3.10.4 ('pytorch-gpu')",
+   "language": "python",
+   "name": "python3"
+  },
+  "language_info": {
+   "name": "python",
+   "version": "3.10.4"
+  },
+  "orig_nbformat": 4,
+  "vscode": {
+   "interpreter": {
+    "hash": "17cd5c528a3345b75540c61f907eece919c031d57a2ca1e5653325af249173c9"
+   }
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}

BIN
plots/approach1a/roc_curves/Marten_01_absmean.pdf


BIN
plots/approach1a/roc_curves/Marten_01_absmean.png


BIN
plots/approach1a/roc_curves/Marten_01_absmean_sigma6.pdf


BIN
plots/approach1a/roc_curves/Marten_01_absmean_sigma6.png


BIN
plots/approach1a/roc_curves/Marten_01_absvar.pdf


BIN
plots/approach1a/roc_curves/Marten_01_absvar.png


BIN
plots/approach1a/roc_curves/Marten_01_absvar_sigma6.pdf


BIN
plots/approach1a/roc_curves/Marten_01_absvar_sigma6.png


BIN
plots/approach1a/roc_curves/Marten_01_sqmean.pdf


BIN
plots/approach1a/roc_curves/Marten_01_sqmean.png


BIN
plots/approach1a/roc_curves/Marten_01_sqmean_sigma6.pdf


BIN
plots/approach1a/roc_curves/Marten_01_sqmean_sigma6.png


BIN
plots/approach1a/roc_curves/Marten_01_sqvar.pdf


BIN
plots/approach1a/roc_curves/Marten_01_sqvar.png


BIN
plots/approach1a/roc_curves/Marten_01_sqvar_sigma6.pdf


BIN
plots/approach1a/roc_curves/Marten_01_sqvar_sigma6.png


BIN
plots/approach3/boxplot_random.pdf


BIN
plots/approach3/boxplot_random_tnr95.pdf


BIN
plots/approach4/boxplot_kde_denoising.pdf


BIN
plots/approach4/boxplot_kde_denoising_and_sparse.pdf


BIN
plots/approach4/boxplot_kde_denoising_and_sparse_tnr95.pdf


BIN
plots/approach4/boxplot_kde_denoising_tnr95.pdf


BIN
plots/approach4/boxplot_kde_latentfeatures.pdf


BIN
plots/approach4/boxplot_kde_latentfeatures_tnr95.pdf


BIN
plots/approach4/boxplot_kde_sparse.pdf


BIN
plots/approach4/boxplot_kde_sparse_tnr95.pdf


+ 1 - 0
py/ImageUtils.py

@@ -49,6 +49,7 @@ def save_image(image, filename: str, title: str, colorbar=False, size=(8, 5), **
         colorbar (bool, optional): Display colorbars. Defaults to False.
         size (tuple, optional): plt size (width, height). Defaults to (8, 5).
     """
+    plt.ioff()
     plt.figure(figsize=size)
     plt.imshow(image, **imshowargs)
     plt.title(title)

+ 6 - 2
py/PlotUtils.py

@@ -5,6 +5,8 @@ def plot_roc_curve(test_labels: list, test_df: list, title: str, figsize=(8, 8),
     fpr, tpr, thresholds = roc_curve(test_labels, test_df)
     auc_score = auc(fpr, tpr)
 
+    if not show:
+        plt.ioff()
     plt.figure(figsize=figsize)
     plt.plot(fpr, tpr, lw=1)
     plt.fill_between(fpr, tpr, label=f"AUC = {auc_score:.4f}", alpha=0.5)
@@ -22,12 +24,14 @@ def plot_roc_curve(test_labels: list, test_df: list, title: str, figsize=(8, 8),
         plt.show()
     return fpr, tpr, thresholds, auc_score
 
-def get_percentiles(fpr, tpr, thresholds, percentiles=[0.9, 0.95, 0.98, 0.99]):
+def get_percentiles(fpr, tpr, thresholds, percentiles=[0.9, 0.95, 0.98, 0.99], verbose = True):
+    assert percentiles == sorted(percentiles)
     tnrs = []
     for percentile in percentiles:
         for i, tp in enumerate(tpr):
             if tp >= percentile:
                 tnrs.append(1 - fpr[i]) # append tnr
-                print(f"{percentile} percentile : TPR = {tp:.4f}, FPR = {fpr[i]:.4f} <-> TNR = {(1 - fpr[i]):.4f} @ thresh {thresholds[i]}")
+                if verbose:
+                    print(f"{percentile} percentile : TPR = {tp:.4f}, FPR = {fpr[i]:.4f} <-> TNR = {(1 - fpr[i]):.4f} @ thresh {thresholds[i]}")
                 break
     return tnrs

+ 1 - 1
py/Session.py

@@ -108,7 +108,7 @@ class Session:
             print("Saving...")
             self.save_scans()
     
-    def check_lapse_duplicates(self) -> bool:
+    def check_lapse_duplicates(self):
         total = 0
         total_duplicates = 0
         total_multiples = 0

+ 1 - 8
resize_session.ipynb

@@ -9,7 +9,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 11,
+   "execution_count": 1,
    "metadata": {},
    "outputs": [
     {
@@ -107,13 +107,6 @@
    "source": [
     "copy_session(session, \"ResizedSessions256_NoBackup\", size=(256, 256), truncate_y=(40, 40))"
    ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": []
   }
  ],
  "metadata": {

+ 15 - 9
train_autoencoder.py

@@ -15,9 +15,10 @@ from torchvision.utils import save_image
 from torchinfo import summary
 
 from py.PyTorchData import create_dataloader, model_output_to_image
+from py.Dataset import Dataset
 from py.Autoencoder2 import Autoencoder
 
-def train_autoencoder(model: Autoencoder, train_dataloader: DataLoader, name: str, device: str = "cpu", num_epochs=100, criterion = nn.MSELoss(), lr: float = 1e-3, weight_decay: float = 1e-5, noise: bool = False, sparse: bool = False, reg_rate: float = 1e-4):
+def train_autoencoder(model: Autoencoder, train_dataloader: DataLoader, name: str, device: str = "cpu", num_epochs=100, criterion = nn.MSELoss(), lr: float = 1e-3, weight_decay: float = 1e-5, noise: bool = False, sparse: bool = False, reg_rate: float = 1e-4, noise_var: float = 0.015):
     model = model.to(device)
     print(f"Using {device} device")
     optimizer = torch.optim.Adam(model.parameters(), lr=lr, weight_decay=weight_decay)
@@ -34,7 +35,7 @@ def train_autoencoder(model: Autoencoder, train_dataloader: DataLoader, name: st
             img = Variable(img).to(device)
             input = img
             if noise:
-                input = input + (0.015 ** 0.5) * torch.randn(img.size(), device=device)
+                input = input + (noise_var ** 0.5) * torch.randn(img.size(), device=device)
             # ===================forward=====================
             latent = model.encoder(input)
             output = model.decoder(latent)
@@ -59,7 +60,7 @@ def train_autoencoder(model: Autoencoder, train_dataloader: DataLoader, name: st
             f.write(f"{dsp_epoch},{total_loss},{total_reg_loss}\n")
         
         # output image
-        if epoch % 2 == 0:
+        if epoch % 10 == 0:
             pic = model_output_to_image(output.cpu().data)
             save_image(pic, f"./ae_train_NoBackup/{name}/image_{dsp_epoch:03d}.png")
         
@@ -73,7 +74,8 @@ def train_autoencoder(model: Autoencoder, train_dataloader: DataLoader, name: st
 if __name__ == "__main__":
     parser = argparse.ArgumentParser(description="Autoencoder train script")
     parser.add_argument("name", type=str, help="Name of the training session (name of the save folder)")
-    parser.add_argument("img_folder", type=str, help="Path to directory containing train images (may contain subfolders)")
+    parser.add_argument("dataset_folder", type=str, help="Path to dataset folder containing sessions")
+    parser.add_argument("session", type=str, help="Session name")
     parser.add_argument("--device", type=str, help="PyTorch device to train on (cpu or cuda)", default="cpu")
     parser.add_argument("--epochs", type=int, help="Number of epochs", default=100)
     parser.add_argument("--batch_size", type=int, help="Batch size (>=1)", default=32)
@@ -83,20 +85,24 @@ if __name__ == "__main__":
     parser.add_argument("--latent", type=int, help="Number of latent features", default=512)
     parser.add_argument("--image_transforms", action="store_true", help="Truncate and resize images (only enable if the input images have not been truncated resized to the target size already)")
     parser.add_argument("--noise", action="store_true", help="Add Gaussian noise to model input")
+    parser.add_argument("--noise_var", type=float, help="Noise variance", default=0.015)
     parser.add_argument("--sparse", action="store_true", help="Add L1 penalty to latent features")
 
     args = parser.parse_args()
 
+    ds = Dataset(args.dataset_folder)
+    session = ds.create_session(args.session)
+
     if args.image_transforms:
         print("Image transforms enabled: Images will be truncated and resized.")
     else:
         print("Image transforms disabled: Images are expected to be of the right size.")
 
-    torch.manual_seed(10810)
-    np.random.seed(10810)
-    random.seed(10810)
+    # torch.manual_seed(10810)
+    # np.random.seed(10810)
+    # random.seed(10810)
     
-    data_loader = create_dataloader(args.img_folder, batch_size=args.batch_size, skip_transforms=not args.image_transforms)
+    data_loader = create_dataloader(session.get_lapse_folder(), batch_size=args.batch_size, skip_transforms=not args.image_transforms)
     model = Autoencoder(dropout=args.dropout, latent_features=args.latent)
     print("Model:")
     summary(model, (args.batch_size, 3, 256, 256))
@@ -108,4 +114,4 @@ if __name__ == "__main__":
         print("Adding Gaussian noise to model input")
     if args.sparse:
         print("Adding L1 penalty to latent features (sparse)")
-    train_autoencoder(model, data_loader, args.name, device=args.device, num_epochs=args.epochs, lr=args.lr, noise=args.noise, sparse=args.sparse, reg_rate=args.reg_rate)
+    train_autoencoder(model, data_loader, args.name, device=args.device, num_epochs=args.epochs, lr=args.lr, noise=args.noise, sparse=args.sparse, reg_rate=args.reg_rate, noise_var=args.noise_var)

Một số tệp đã không được hiển thị bởi vì quá nhiều tập tin thay đổi trong này khác