Spaces:
Sleeping
Sleeping
File size: 3,505 Bytes
ae51a24 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
import numpy as np
from PIL import Image
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, BatchNormalization, Conv2D, MaxPooling2D, Flatten, Activation, Dropout
from sklearn.preprocessing import LabelEncoder
from tensorflow.keras.utils import to_categorical
from typing import List
def getTargets(filepaths: List[str]) -> List[str]:
"""
Extract class labels from file paths.
Assumes the file path structure includes the class name as the parent folder.
Example: /path/to/data/VeryMildDemented/image1.jpg -> VeryMildDemented
"""
labels = [fp.split('/')[-2] for fp in filepaths] # Get the parent folder name as the label
return labels
def encodeLabels(y_train: List, y_test: List):
"""
Encode class labels into one-hot vectors.
"""
label_encoder = LabelEncoder()
y_train_labels = label_encoder.fit_transform(y_train)
y_test_labels = label_encoder.transform(y_test)
y_train_1h = to_categorical(y_train_labels)
y_test_1h = to_categorical(y_test_labels)
LABELS = label_encoder.classes_
print(f"Classes: {LABELS} -- Encoded: {label_encoder.transform(LABELS)}")
return LABELS, y_train_1h, y_test_1h
def getFeatures(filepaths: List[str]) -> np.array:
"""
Load images from file paths and convert them to numpy arrays.
Assumes images are already resized to 64x64 during preprocessing.
"""
images = []
for imagePath in filepaths:
image = Image.open(imagePath).convert("RGB") # Ensure 3-channel RGB
image = np.array(image)
images.append(image)
return np.array(images)
def buildModel(inputShape: tuple, classes: int) -> Sequential:
"""
Build a CNN model for Alzheimer's image classification.
"""
model = Sequential()
height, width, depth = inputShape
inputShape = (height, width, depth)
chanDim = -1
# CONV => RELU => POOL layer set
model.add(Conv2D(32, (3, 3), padding="same", name='conv_32_1', input_shape=inputShape))
model.add(Activation("relu"))
model.add(BatchNormalization(axis=chanDim))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
# (CONV => RELU) * 2 => POOL layer set
model.add(Conv2D(64, (3, 3), padding="same", name='conv_64_1'))
model.add(Activation("relu"))
model.add(BatchNormalization(axis=chanDim))
model.add(Conv2D(64, (3, 3), padding="same", name='conv_64_2'))
model.add(Activation("relu"))
model.add(BatchNormalization(axis=chanDim))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
# (CONV => RELU) * 3 => POOL layer set
model.add(Conv2D(128, (3, 3), padding="same", name='conv_128_1'))
model.add(Activation("relu"))
model.add(BatchNormalization(axis=chanDim))
model.add(Conv2D(128, (3, 3), padding="same", name='conv_128_2'))
model.add(Activation("relu"))
model.add(BatchNormalization(axis=chanDim))
model.add(Conv2D(128, (3, 3), padding="same", name='conv_128_3'))
model.add(Activation("relu"))
model.add(BatchNormalization(axis=chanDim))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
# Fully connected layer
model.add(Flatten())
model.add(Dense(512, name='fc_1'))
model.add(Activation("relu"))
model.add(BatchNormalization())
model.add(Dropout(0.5))
# Output layer with softmax activation
model.add(Dense(classes, name='output'))
model.add(Activation("softmax"))
return model |