test commited on
Commit
a3d82f6
·
verified ·
1 Parent(s): fef9706

Adding model code

Browse files
.gitattributes CHANGED
@@ -33,3 +33,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ xray_image_classifier_model.keras filter=lfs diff=lfs merge=lfs -text
README ADDED
@@ -0,0 +1 @@
 
 
1
+ poetry run python train_model.py
augment_images.py ADDED
@@ -0,0 +1,64 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ from PIL import Image
3
+ from tensorflow.keras.preprocessing.image import ImageDataGenerator
4
+
5
+ # Set paths
6
+ base_dir = 'data/chest_xray'
7
+ val_dir = os.path.join(base_dir, 'val')
8
+ normal_class_dir = os.path.join(val_dir, 'NORMAL')
9
+ pneumonia_class_dir = os.path.join(val_dir, 'PNEUMONIA')
10
+
11
+
12
+ def augment_images(class_directory, num_augmented_images):
13
+ datagen = ImageDataGenerator(
14
+ rescale=1. / 255,
15
+ rotation_range=20,
16
+ width_shift_range=0.2,
17
+ height_shift_range=0.2,
18
+ shear_range=0.2,
19
+ zoom_range=0.2,
20
+ horizontal_flip=True,
21
+ fill_mode='nearest'
22
+ )
23
+
24
+ generator = datagen.flow_from_directory(
25
+ directory=os.path.dirname(class_directory), # Parent directory
26
+ target_size=(150, 150),
27
+ batch_size=1,
28
+ class_mode=None,
29
+ shuffle=False,
30
+ classes=[os.path.basename(class_directory)] # Specify class if using subdirectory
31
+ )
32
+
33
+ print(f"Found {generator.samples} images in {class_directory}")
34
+
35
+ if generator.samples == 0:
36
+ print("No images found in the directory.")
37
+ return
38
+
39
+ count = 0
40
+
41
+ while count < num_augmented_images:
42
+ try:
43
+ img_batch = generator.__next__() # Use __next__() to get image batch
44
+ img = (img_batch[0] * 255).astype('uint8') # Extract the first image in the batch
45
+ img_pil = Image.fromarray(img)
46
+ img_path = os.path.join(class_directory, f"augmented_{count}.png")
47
+ img_pil.save(img_path)
48
+ count += 1
49
+ except StopIteration:
50
+ print("No more images to generate.")
51
+ break
52
+
53
+ print(f"Total augmented images created: {count}")
54
+
55
+
56
+ # Number of augmented images to generate
57
+ num_augmented_images_normal = 2944 - 3875 # This should be a negative number since NORMAL is already balanced
58
+ num_augmented_images_pneumonia = 2944 - 1171 # To match the number of NORMAL images
59
+
60
+ # Generate augmented images for the NORMAL class
61
+ augment_images(normal_class_dir, max(num_augmented_images_normal, 0))
62
+
63
+ # Generate augmented images for the PNEUMONIA class
64
+ augment_images(pneumonia_class_dir, num_augmented_images_pneumonia)
data_check.py ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ from PIL import Image
3
+
4
+ # Define the data directories
5
+ base_dir = 'data/chest_xray'
6
+ train_dir = os.path.join(base_dir, 'train')
7
+ val_dir = os.path.join(base_dir, 'val')
8
+
9
+
10
+ # Function to count images in a specific category (e.g., NORMAL, PNEUMONIA)
11
+ def count_images(directory, category):
12
+ category_dir = os.path.join(directory, category)
13
+ count = 0
14
+ for root, dirs, files in os.walk(category_dir):
15
+ count += len([f for f in files if f.endswith(('.jpg', '.jpeg', '.png'))])
16
+ return count
17
+
18
+
19
+ # Function to check for corrupted images in a specific category
20
+ def check_corrupted_images(directory, category):
21
+ category_dir = os.path.join(directory, category)
22
+ corrupted_files = []
23
+ for root, dirs, files in os.walk(category_dir):
24
+ for file in files:
25
+ if file.endswith(('.jpg', '.jpeg', '.png')):
26
+ try:
27
+ img = Image.open(os.path.join(root, file))
28
+ img.verify() # Check if the image can be opened and is not corrupted
29
+ except (IOError, SyntaxError) as e:
30
+ corrupted_files.append(os.path.join(root, file))
31
+ return corrupted_files
32
+
33
+
34
+ # Count images in the train and validation sets
35
+ train_normal_count = count_images(train_dir, 'NORMAL')
36
+ train_pneumonia_count = count_images(train_dir, 'PNEUMONIA')
37
+ val_normal_count = count_images(val_dir, 'NORMAL')
38
+ val_pneumonia_count = count_images(val_dir, 'PNEUMONIA')
39
+
40
+ # Check for corrupted images in the train and validation sets
41
+ train_normal_corrupted = check_corrupted_images(train_dir, 'NORMAL')
42
+ train_pneumonia_corrupted = check_corrupted_images(train_dir, 'PNEUMONIA')
43
+ val_normal_corrupted = check_corrupted_images(val_dir, 'NORMAL')
44
+ val_pneumonia_corrupted = check_corrupted_images(val_dir, 'PNEUMONIA')
45
+
46
+ # Print the results
47
+ print(f"Training NORMAL images: {train_normal_count}")
48
+ print(f"Training PNEUMONIA images: {train_pneumonia_count}")
49
+ print(f"Validation NORMAL images: {val_normal_count}")
50
+ print(f"Validation PNEUMONIA images: {val_pneumonia_count}")
51
+
52
+ print(f"Corrupted images in training NORMAL: {train_normal_corrupted}")
53
+ print(f"Corrupted images in training PNEUMONIA: {train_pneumonia_corrupted}")
54
+ print(f"Corrupted images in validation NORMAL: {val_normal_corrupted}")
55
+ print(f"Corrupted images in validation PNEUMONIA: {val_pneumonia_corrupted}")
evaluate_model.py ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import tensorflow as tf
3
+ from tensorflow.keras.preprocessing.image import ImageDataGenerator
4
+ from tensorflow.keras.models import load_model
5
+
6
+ base_dir = 'data/chest_xray'
7
+ val_dir = os.path.join(base_dir, 'val')
8
+
9
+ val_datagen = ImageDataGenerator(rescale=1./255)
10
+ val_generator = val_datagen.flow_from_directory(
11
+ val_dir,
12
+ target_size=(150, 150),
13
+ batch_size=32,
14
+ class_mode='binary'
15
+ )
16
+
17
+ model = load_model('xray_image_classifier_model.keras')
18
+
19
+ loss, accuracy = model.evaluate(val_generator)
20
+ print(f'Validation Loss: {loss:.4f}')
21
+ print(f'Validation Accuracy: {accuracy:.4f}')
model.py ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import tensorflow as tf
2
+ from tensorflow.keras import layers, models
3
+ from tensorflow.keras.applications import InceptionV3
4
+
5
+ def create_model():
6
+ base_model = InceptionV3(weights='imagenet', include_top=False, input_shape=(150, 150, 3))
7
+ base_model.trainable = False # Freezing the base model layers
8
+
9
+ model = models.Sequential([
10
+ base_model,
11
+ layers.GlobalAveragePooling2D(),
12
+ layers.Dense(512, activation='relu'),
13
+ layers.Dropout(0.5),
14
+ layers.Dense(1, activation='sigmoid')
15
+ ])
16
+
17
+ model.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=0.0001),
18
+ loss='binary_crossentropy',
19
+ metrics=['accuracy'])
20
+ return model
poetry.lock ADDED
The diff for this file is too large to render. See raw diff
 
pyproject.toml ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [tool.poetry]
2
+ name = "xray-image-classifier"
3
+ version = "0.1.0"
4
+ description = ""
5
+ authors = ["Your Name <[email protected]>"]
6
+ readme = "README.md"
7
+
8
+ [tool.poetry.dependencies]
9
+ python = "3.11.8"
10
+ tensorflow = "2.15.1"
11
+ keras = "^2.15.0"
12
+ numpy = "^1.23.5"
13
+ pandas = "^2.2.2"
14
+ matplotlib = "^3.9.2"
15
+ jupyter = "^1.0.0"
16
+ scipy = "^1.14.1"
17
+ [tool.poetry.group.dev.dependencies]
18
+ pytest = "^8.3.2"
19
+ ipython = "^8.26.0"
20
+ autopep8 = "^2.3.1"
21
+ jupyter = "^1.0.0"
22
+
23
+ [build-system]
24
+ requires = ["poetry-core"]
25
+ build-backend = "poetry.core.masonry.api"
train_model.py ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import numpy as np
3
+ import tensorflow as tf
4
+ import matplotlib.pyplot as plt
5
+ from tensorflow.keras.preprocessing.image import ImageDataGenerator
6
+ from model import create_model
7
+
8
+ base_dir = 'data/chest_xray'
9
+ train_dir = os.path.join(base_dir, 'train')
10
+ val_dir = os.path.join(base_dir, 'val')
11
+
12
+ train_datagen = ImageDataGenerator(
13
+ rescale=1./255,
14
+ rotation_range=20,
15
+ width_shift_range=0.2,
16
+ height_shift_range=0.2,
17
+ shear_range=0.2,
18
+ zoom_range=0.2,
19
+ horizontal_flip=True,
20
+ fill_mode='nearest'
21
+ )
22
+ val_datagen = ImageDataGenerator(rescale=1./255)
23
+
24
+ train_generator = train_datagen.flow_from_directory(
25
+ train_dir,
26
+ target_size=(150, 150),
27
+ batch_size=32,
28
+ class_mode='binary'
29
+ )
30
+
31
+ val_generator = val_datagen.flow_from_directory(
32
+ val_dir,
33
+ target_size=(150, 150),
34
+ batch_size=32,
35
+ class_mode='binary'
36
+ )
37
+
38
+ sample_images, _ = next(train_generator)
39
+ for i in range(5):
40
+ plt.subplot(1, 5, i+1)
41
+ plt.imshow(sample_images[i])
42
+ plt.axis('off')
43
+ plt.show()
44
+
45
+ model = create_model()
46
+
47
+ history = model.fit(
48
+ train_generator,
49
+ steps_per_epoch=243,
50
+ epochs=10,
51
+ validation_data=val_generator,
52
+ validation_steps=280,
53
+ callbacks=[tf.keras.callbacks.EarlyStopping(monitor='val_loss', patience=3, restore_best_weights=True)]
54
+ )
55
+
56
+ model.save('xray_image_classifier_model.keras')
xray_image_classifier_model.keras ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:ad1c91968bb830cc6f96327676f487e94763aaec1c83be18e6270cb47bf273fa
3
+ size 100786904