How to train 3D CNN for regression

Viewed 115

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

0 Answers
Related