I am working on 3D CNN to predict numerical values of rock permeability with regression, so i will do the features extraction with the 3D CNN and output with regression.
i Have Built the database of 2178 3D BINARY(only 0 and 1) images(.raw) with shape of (200,200,200), and i have .csv file containing all 3d images filenames and their permeability values I've written the code but it didn't work, when i launch the training it stuck at epoch 1 here is the full code :
NB: I'm new to ML and DL
import os
import numpy as np
import pandas as pd
import tensorflow as tf
import keras_preprocessing
from keras_preprocessing import image
from keras_preprocessing.image import ImageDataGenerator
from tensorflow import keras
from tensorflow.keras import layers
import matplotlib.pyplot as plt
np.set_printoptions(precision=4)
np.random.seed(10)
# import nibabel as nib
# from scipy import ndimage
def read_raw_file(filepath):
"""Read and load volume"""
patch_file = np.fromfile(filepath, dtype=np.uint8)
patch_im = (patch_file.reshape(200,200,200))
patch_im = patch_im==1;
return patch_im
# def resize_volume(img):
# """Resize across z-axis"""
# # Set the desired depth
# desired_depth = 200
# desired_width = 200
# desired_height = 200
# # Get current depth
# current_depth = img.shape[-1]
# current_width = img.shape[0]
# current_height = img.shape[1]
# # Compute depth factor
# depth = current_depth / desired_depth
# width = current_width / desired_width
# height = current_height / desired_height
# depth_factor = 1 / depth
# width_factor = 1 / width
# height_factor = 1 / height
# # Rotate
# img = ndimage.rotate(img, 90, reshape=False)
# # Resize across z-axis
# img = ndimage.zoom(img, (width_factor, height_factor, depth_factor), order=1)
# return img
def process_scan(path):
"""Read and resize volume"""
# Read scan
volume = read_raw_file(path)
# # Normalize
# volume = normalize(volume)
# # Resize width, height and depth
# volume = resize_volume(volume)
return volume
dataset_paths = [
os.path.join("./patches", x)
for x in os.listdir("patches")
]
print("CT scans: " + str(len(dataset_paths)))
# Read and process the scans.
# Each scan is passed by above preprocessing helper fucntions.
images_dataset = np.array([process_scan(path) for path in dataset_paths])
print(len(images_dataset))
#assigning labels
df = pd.read_csv(
"./training_data.csv",
sep=";")
df.sort_values(["Images"],axis=0, ascending=True,inplace=True,na_position='first')
perm_vals=df['Permeability'].values
dataset_labels= np.array(perm_vals)
# Split data in the ratio 80%-20% for training and validation.
TRAIN_PCT = 0.8
TRAIN_CUT = int(len(df) * TRAIN_PCT)
x_train = images_dataset[:TRAIN_CUT]
y_train = dataset_labels[:TRAIN_CUT]
x_val = images_dataset[TRAIN_CUT:]
y_val = dataset_labels[TRAIN_CUT:]
print(
"Number of samples in train and validation are %d and %d."
% (x_train.shape[0], x_val.shape[0])
)
import random
from scipy import ndimage
dtype=tf.float32
@tf.function
def rotate(volume):
"""Rotate the volume by a few degrees"""
def scipy_rotate(volume):
# define some rotation angles
angles = [-20, -10, -5, 5, 10, 20]
# pick angles at random
angle = random.choice(angles)
# rotate volume
volume = ndimage.rotate(volume, angle, reshape=False)
volume[volume < 0] = 0
volume[volume > 1] = 1
return volume
augmented_volume = tf.numpy_function(scipy_rotate, [volume], tf.bool)
return augmented_volume
def train_preprocessing(volume, label):
"""Process training data by rotating and adding a channel."""
# Rotate volume
# volume = rotate(volume)
volume = tf.expand_dims(volume, axis=3)
return volume, label
def validation_preprocessing(volume, label):
"""Process validation data by only adding a channel."""
volume = tf.expand_dims(volume, axis=3)
return volume, label
# Define data loaders.
train_loader = tf.data.Dataset.from_tensor_slices((x_train, y_train))
validation_loader = tf.data.Dataset.from_tensor_slices((x_val, y_val))
batch_size = 1
# Augment the on the fly during training.
train_dataset = (
# train_loader.shuffle(len(x_train))
train_loader.map(train_preprocessing)
.batch(batch_size)
.prefetch(2)
)
# Only rescale.
validation_dataset = (
# validation_loader.shuffle(len(x_val))
validation_loader.map(validation_preprocessing)
.batch(batch_size)
.prefetch(2)
)
def get_model(width=200, height=200, depth=200):
"""Build a 3D convolutional neural network model."""
inputs = keras.Input((width, height, depth, 1))
x = layers.Conv3D(filters=64, kernel_size=3, activation="relu")(inputs)
x = layers.MaxPool3D(pool_size=2)(x)
x = layers.BatchNormalization()(x)
x = layers.Conv3D(filters=64, kernel_size=3, activation="relu")(x)
x = layers.MaxPool3D(pool_size=2)(x)
x = layers.BatchNormalization()(x)
x = layers.Conv3D(filters=128, kernel_size=3, activation="relu")(x)
x = layers.MaxPool3D(pool_size=2)(x)
x = layers.BatchNormalization()(x)
x = layers.Conv3D(filters=256, kernel_size=3, activation="relu")(x)
x = layers.MaxPool3D(pool_size=2)(x)
x = layers.BatchNormalization()(x)
x = layers.GlobalAveragePooling3D()(x)
x = layers.Dense(units=512, activation="relu")(x)
x = layers.Dropout(0.3)(x)
outputs = layers.Dense(1, activation="linear")(x)
# Define the model.
model = keras.Model(inputs, outputs, name="3dcnn")
return model
# Build model.
model = get_model(width=200, height=200, depth=200)
model.summary()
# Compile model.
initial_learning_rate = 0.0001
lr_schedule = keras.optimizers.schedules.ExponentialDecay(
initial_learning_rate, decay_steps=100000, decay_rate=0.96, staircase=True
)
model.compile(
loss="binary_crossentropy",
optimizer=keras.optimizers.Adam(learning_rate=lr_schedule),
metrics=["acc"],
)
# Define callbacks.
checkpoint_cb = keras.callbacks.ModelCheckpoint(
"3d_image_classification.h5", save_best_only=True
)
early_stopping_cb = keras.callbacks.EarlyStopping(monitor="val_acc", patience=15)
# Train the model, doing validation at the end of each epoch
epochs = 100
model.fit(
train_dataset,
validation_data=validation_dataset,
epochs=epochs,
shuffle=True,
verbose=2,
callbacks=[checkpoint_cb, early_stopping_cb],
)
And the training stuck here : Training stuck image