cycool29 commited on
Commit
92bf372
·
1 Parent(s): eb01e5b
Files changed (7) hide show
  1. augment.py +0 -1
  2. combine_dats.py +42 -0
  3. configs.py +6 -5
  4. eda.py +103 -0
  5. eval.py +25 -5
  6. test.py +39 -0
  7. tuning.py +1 -1
augment.py CHANGED
@@ -39,7 +39,6 @@ for task in ["1"]:
39
  output_directory=f"{class_label}/",
40
  save_format="png",
41
  )
42
- p.rotate(probability=0.8, max_left_rotation=5, max_right_rotation=5)
43
  p.flip_left_right(probability=0.8)
44
  p.zoom_random(probability=0.8, percentage_area=0.8)
45
  p.flip_top_bottom(probability=0.8)
 
39
  output_directory=f"{class_label}/",
40
  save_format="png",
41
  )
 
42
  p.flip_left_right(probability=0.8)
43
  p.zoom_random(probability=0.8, percentage_area=0.8)
44
  p.flip_top_bottom(probability=0.8)
combine_dats.py ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copy the all the data from external, augmented and raw folders to combined folder
2
+ import os
3
+ import shutil
4
+ import uuid
5
+
6
+ from configs import *
7
+
8
+ for disease in CLASSES:
9
+ # check if the original folder exists
10
+ if os.path.exists(RAW_DATA_DIR + '1/' + disease):
11
+ print("Copying raw data for disease: ", disease)
12
+ if not os.path.exists(COMBINED_DATA_DIR + '1/' + disease):
13
+ os.makedirs(COMBINED_DATA_DIR + '1/' + disease)
14
+ for file in os.listdir(RAW_DATA_DIR + '1/' + disease):
15
+ random_name = str(uuid.uuid4()) + ".png"
16
+ shutil.copy(
17
+ RAW_DATA_DIR + '1/' + disease + '/' + file,
18
+ COMBINED_DATA_DIR + '1/' + disease + '/' + random_name,
19
+ )
20
+
21
+ if os.path.exists(EXTERNAL_DATA_DIR + '1/' + disease):
22
+ print("Copying external data for disease: ", disease)
23
+ if not os.path.exists(COMBINED_DATA_DIR + '1/' + disease):
24
+ os.makedirs(COMBINED_DATA_DIR + '1/' + disease)
25
+ for file in os.listdir(EXTERNAL_DATA_DIR + '1/' + disease):
26
+ random_name = str(uuid.uuid4()) + ".png"
27
+ shutil.copy(
28
+ EXTERNAL_DATA_DIR + '1/' + disease + '/' + file,
29
+ COMBINED_DATA_DIR + '1/' + disease + '/' + random_name,
30
+ )
31
+
32
+ if os.path.exists(AUG_DATA_DIR + '1/' + disease):
33
+ print("Copying augmented data for disease: ", disease)
34
+ if not os.path.exists(COMBINED_DATA_DIR + '1/' + disease):
35
+ os.makedirs(COMBINED_DATA_DIR + '1/' + disease)
36
+ for file in os.listdir(AUG_DATA_DIR + '1/' + disease):
37
+ random_name = str(uuid.uuid4()) + ".png"
38
+ shutil.copy(
39
+ AUG_DATA_DIR + '1/' + disease + '/' + file,
40
+ COMBINED_DATA_DIR + '1/' + disease + '/' + random_name,
41
+ )
42
+
configs.py CHANGED
@@ -14,17 +14,18 @@ from torchvision.models import squeezenet1_0
14
 
15
  # Constants
16
  RANDOM_SEED = 123
17
- BATCH_SIZE = 16
18
  NUM_EPOCHS = 100
19
- LEARNING_RATE = 2.0950584442749585e-05
20
  STEP_SIZE = 10
21
- GAMMA = 0.5
22
  DEVICE = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
23
  NUM_PRINT = 100
24
  TASK = 1
25
  RAW_DATA_DIR = r"data/train/raw/Task "
26
  AUG_DATA_DIR = r"data/train/augmented/Task "
27
  EXTERNAL_DATA_DIR = r"data/train/external/Task "
 
28
  TEMP_DATA_DIR = "data/temp/"
29
  NUM_CLASSES = 7
30
  EARLY_STOPPING_PATIENCE = 20
@@ -108,7 +109,7 @@ class ResNet18WithNorm(nn.Module):
108
  nn.AdaptiveAvgPool2d((1, 1)),
109
  nn.Flatten(),
110
  nn.Linear(512, num_classes),
111
- nn.BatchNorm2d(num_classes), # Add batch normalization
112
  )
113
 
114
  def forward(self, x):
@@ -123,7 +124,7 @@ print(CLASSES)
123
 
124
  preprocess = transforms.Compose(
125
  [
126
- transforms.Resize((64, 64)), # Resize images to 64x64
127
  transforms.ToTensor(), # Convert to tensor
128
  transforms.Grayscale(num_output_channels=3), # Convert to 3 channels
129
  # Normalize 3 channels
 
14
 
15
  # Constants
16
  RANDOM_SEED = 123
17
+ BATCH_SIZE = 64
18
  NUM_EPOCHS = 100
19
+ LEARNING_RATE = 0.00016633192288673592
20
  STEP_SIZE = 10
21
+ GAMMA = 0.9
22
  DEVICE = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
23
  NUM_PRINT = 100
24
  TASK = 1
25
  RAW_DATA_DIR = r"data/train/raw/Task "
26
  AUG_DATA_DIR = r"data/train/augmented/Task "
27
  EXTERNAL_DATA_DIR = r"data/train/external/Task "
28
+ COMBINED_DATA_DIR = r"data/train/combined/Task "
29
  TEMP_DATA_DIR = "data/temp/"
30
  NUM_CLASSES = 7
31
  EARLY_STOPPING_PATIENCE = 20
 
109
  nn.AdaptiveAvgPool2d((1, 1)),
110
  nn.Flatten(),
111
  nn.Linear(512, num_classes),
112
+ nn.BatchNorm1d(num_classes), # Add batch normalization
113
  )
114
 
115
  def forward(self, x):
 
124
 
125
  preprocess = transforms.Compose(
126
  [
127
+ transforms.Resize((112, 112)), # Resize to 112x112
128
  transforms.ToTensor(), # Convert to tensor
129
  transforms.Grayscale(num_output_channels=3), # Convert to 3 channels
130
  # Normalize 3 channels
eda.py ADDED
@@ -0,0 +1,103 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import pandas as pd
3
+ import numpy as np
4
+ import matplotlib.pyplot as plt
5
+ import seaborn as sns
6
+ from matplotlib import rcParams
7
+
8
+ rcParams['font.family'] = 'Times New Roman'
9
+
10
+ # Define the directory where your dataset is located
11
+ dataset_directory = 'data/train/combined/Task 1/'
12
+
13
+ # Create a list of class labels based on subdirectories in the dataset directory
14
+ class_labels = os.listdir(dataset_directory)
15
+
16
+ # Initialize lists to store data for EDA
17
+ num_samples_per_class = []
18
+ class_labels_processed = []
19
+
20
+ # Initialize an empty DataFrame to store image dimensions
21
+ image_dimensions_df = pd.DataFrame(columns=['Height', 'Width'])
22
+
23
+ # Initialize a dictionary to store a random sample of images from each class
24
+ sampled_images = {label: [] for label in class_labels}
25
+
26
+ # Iterate through class labels and count the number of samples per class
27
+ for label in class_labels:
28
+ if label != ".DS_Store":
29
+ class_directory = os.path.join(dataset_directory, label)
30
+ num_samples = len(os.listdir(class_directory))
31
+ num_samples_per_class.append(num_samples)
32
+ class_labels_processed.append(label)
33
+
34
+ # Extract image dimensions and add them to the DataFrame
35
+ for image_file in os.listdir(class_directory):
36
+ image_path = os.path.join(class_directory, image_file)
37
+ image = plt.imread(image_path)
38
+ height, width, _ = image.shape
39
+ image_dimensions_df = image_dimensions_df._append({'Height': height, 'Width': width}, ignore_index=True)
40
+
41
+ # Randomly sample 5 images from each class for visualization
42
+ if len(sampled_images[label]) < 5:
43
+ sampled_images[label].append(image)
44
+
45
+ # Create a Pandas DataFrame for EDA
46
+ eda_data = pd.DataFrame({'Class Label': class_labels_processed, 'Number of Samples': num_samples_per_class})
47
+
48
+ # Plot the number of samples per class
49
+ plt.figure(figsize=(10, 6))
50
+ sns.barplot(x='Class Label', y='Number of Samples', data=eda_data)
51
+ plt.title('Number of Samples per Class')
52
+ plt.xticks(rotation=45)
53
+ plt.xlabel('Class Label')
54
+ plt.ylabel('Number of Samples')
55
+ plt.savefig('docs/eda/Number of Samples per Class.png')
56
+ plt.show()
57
+
58
+ # Calculate and plot the distribution of sample sizes (image dimensions)
59
+ plt.figure(figsize=(10, 6))
60
+ plt.scatter(image_dimensions_df['Width'], image_dimensions_df['Height'], alpha=0.5)
61
+ plt.title('Distribution of Sample Sizes (Image Dimensions)')
62
+ plt.xlabel('Width (Pixels)')
63
+ plt.ylabel('Height (Pixels)')
64
+ plt.savefig('docs/eda/Distribution of Sample Sizes (Image Dimensions).png')
65
+ plt.show()
66
+
67
+ # Plot a random sample of images from each class
68
+ for label, images in sampled_images.items():
69
+ plt.figure(figsize=(15, 5))
70
+ plt.suptitle(f'Random Sample of Images from Class: {label}')
71
+ for i, image in enumerate(images, start=1):
72
+ plt.subplot(1, 5, i)
73
+ plt.imshow(image)
74
+ plt.axis('off')
75
+ plt.title(f'Sample {i}')
76
+ plt.savefig(f'docs/eda/Random Sample of Images from Class {label}.png')
77
+ plt.show()
78
+
79
+ # Calculate and plot the correlation matrix for image dimensions
80
+ correlation_matrix = image_dimensions_df.corr()
81
+ plt.figure(figsize=(8, 6))
82
+ sns.heatmap(correlation_matrix, annot=True, cmap='coolwarm', linewidths=0.5)
83
+ plt.title('Correlation Matrix of Image Dimensions')
84
+ plt.savefig('docs/eda/Correlation Matrix of Image Dimensions.png')
85
+ plt.show()
86
+
87
+ # Plot the distribution of image widths
88
+ plt.figure(figsize=(10, 6))
89
+ sns.histplot(image_dimensions_df['Width'], bins=20, kde=True)
90
+ plt.title('Distribution of Image Widths')
91
+ plt.xlabel('Width (Pixels)')
92
+ plt.ylabel('Frequency')
93
+ plt.savefig('docs/eda/Distribution of Image Widths.png')
94
+ plt.show()
95
+
96
+ # Plot the distribution of image heights
97
+ plt.figure(figsize=(10, 6))
98
+ sns.histplot(image_dimensions_df['Height'], bins=20, kde=True)
99
+ plt.title('Distribution of Image Heights')
100
+ plt.xlabel('Height (Pixels)')
101
+ plt.ylabel('Frequency')
102
+ plt.savefig('docs/eda/Distribution of Image Heights.png')
103
+ plt.show()
eval.py CHANGED
@@ -5,17 +5,23 @@ import pathlib
5
  from PIL import Image
6
  from torchmetrics import ConfusionMatrix, Accuracy, F1Score
7
  import matplotlib.pyplot as plt
 
 
 
 
 
 
 
8
  from configs import *
9
  from data_loader import load_data # Import the load_data function
10
-
11
- image_path = "data/test/Task 1/"
12
 
13
  # Constants
14
  DEVICE = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
15
 
16
  # Load the model
17
  MODEL = MODEL.to(DEVICE)
18
- MODEL.load_state_dict(torch.load(MODEL_SAVE_PATH, map_location=DEVICE))
19
  MODEL.eval()
20
 
21
 
@@ -30,6 +36,7 @@ def predict_image(image_path, model, transform):
30
 
31
  true_classes = []
32
  predicted_labels = []
 
33
 
34
  accuracy_metric = Accuracy(num_classes=NUM_CLASSES, task="multiclass")
35
  f1_metric = F1Score(num_classes=NUM_CLASSES, task="multiclass")
@@ -51,6 +58,9 @@ def predict_image(image_path, model, transform):
51
  # Append true and predicted labels to their respective lists
52
  true_classes.append(true_class)
53
  predicted_labels.append(predicted_class)
 
 
 
54
 
55
  # Check if the prediction is correct
56
  if predicted_class == true_class:
@@ -73,8 +83,18 @@ def predict_image(image_path, model, transform):
73
  # Plot the confusion matrix
74
  conf_matrix.compute()
75
  conf_matrix.plot()
 
76
  plt.show()
77
 
 
 
 
 
 
 
 
 
 
78
 
79
- # Call predict_image function
80
- predict_image(image_path, MODEL, preprocess)
 
5
  from PIL import Image
6
  from torchmetrics import ConfusionMatrix, Accuracy, F1Score
7
  import matplotlib.pyplot as plt
8
+ from sklearn.metrics import (
9
+ classification_report,
10
+ precision_recall_curve,
11
+ roc_curve,
12
+ auc,
13
+ confusion_matrix,
14
+ )
15
  from configs import *
16
  from data_loader import load_data # Import the load_data function
17
+ import numpy as np
 
18
 
19
  # Constants
20
  DEVICE = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
21
 
22
  # Load the model
23
  MODEL = MODEL.to(DEVICE)
24
+ MODEL.load_state_dict(torch.load(r"C:\Users\User\Documents\Flutter-test\handetect\assets\model.pt", map_location=DEVICE))
25
  MODEL.eval()
26
 
27
 
 
36
 
37
  true_classes = []
38
  predicted_labels = []
39
+ predicted_scores = [] # To store predicted class probabilities
40
 
41
  accuracy_metric = Accuracy(num_classes=NUM_CLASSES, task="multiclass")
42
  f1_metric = F1Score(num_classes=NUM_CLASSES, task="multiclass")
 
58
  # Append true and predicted labels to their respective lists
59
  true_classes.append(true_class)
60
  predicted_labels.append(predicted_class)
61
+ predicted_scores.append(
62
+ output.softmax(dim=1).cpu().numpy()
63
+ ) # Store predicted class probabilities
64
 
65
  # Check if the prediction is correct
66
  if predicted_class == true_class:
 
83
  # Plot the confusion matrix
84
  conf_matrix.compute()
85
  conf_matrix.plot()
86
+ plt.title("Confusion Matrix")
87
  plt.show()
88
 
89
+ # Classification report
90
+ class_names = [str(cls) for cls in range(NUM_CLASSES)]
91
+ report = classification_report(
92
+ true_classes, predicted_labels, target_names=class_names
93
+ )
94
+ print("Classification Report:\n", report)
95
+
96
+
97
+
98
 
99
+ # Call predict_image function with your image path
100
+ predict_image("data/test/Task 1/", MODEL, preprocess)
test.py ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ import torch.optim as optim
3
+ import torchvision.models as models
4
+ import torchvision.transforms as transforms
5
+ from configs import *
6
+
7
+ # Load a pre-trained model (e.g., VGG16)
8
+ MODEL = MODEL.to(DEVICE)
9
+ MODEL.load_state_dict(torch.load(MODEL_SAVE_PATH, map_location=DEVICE))
10
+ MODEL.eval()
11
+
12
+ # Prepare an initial image (e.g., a random noise image)
13
+ image = torch.randn(1, 3, 224, 224, requires_grad=True).cuda()
14
+
15
+ # Define a loss function to maximize a specific layer or neuron's activation
16
+ loss_function = torch.nn.CrossEntropyLoss()
17
+
18
+ # Create an optimizer (e.g., Adam) for updating the image
19
+ optimizer = optim.Adam([image], lr=0.01)
20
+
21
+ # Optimization loop
22
+ for _ in range(1000):
23
+ optimizer.zero_grad()
24
+ output = MODEL(image)
25
+ loss = -output[0, 'Healthy'] # Maximize the activation of a specific class
26
+ loss.backward()
27
+ optimizer.step()
28
+
29
+ # Visualize the optimized image
30
+ import matplotlib.pyplot as plt
31
+ import torchvision.transforms as transforms
32
+
33
+ # Convert the tensor to an image
34
+ image = transforms.ToPILImage()(image.squeeze())
35
+
36
+ # Display the generated image
37
+ plt.imshow(image)
38
+ plt.axis('off')
39
+ plt.show()
tuning.py CHANGED
@@ -12,7 +12,7 @@ from torch.utils.tensorboard import SummaryWriter
12
  DEVICE = torch.device("cuda" if torch.cuda.is_available() else "cpu")
13
  EPOCHS = 10
14
  N_TRIALS = 1000
15
- TIMEOUT = 7200
16
 
17
  # Create a TensorBoard writer
18
  writer = SummaryWriter(log_dir="output/tensorboard/tuning")
 
12
  DEVICE = torch.device("cuda" if torch.cuda.is_available() else "cpu")
13
  EPOCHS = 10
14
  N_TRIALS = 1000
15
+ TIMEOUT = 1800
16
 
17
  # Create a TensorBoard writer
18
  writer = SummaryWriter(log_dir="output/tensorboard/tuning")