Kaggle Ultrasound Nerve Segmentation competition [Keras]

Overview

Ultrasound nerve segmentation using Keras (1.0.7)

Kaggle Ultrasound Nerve Segmentation competition [Keras]

#Install (Ubuntu {14,16}, GPU)

cuDNN required.

###Theano

In ~/.theanorc

[global]
device = gpu0
[dnn]
enabled = True

###Keras

  • sudo apt-get install libhdf5-dev
  • sudo pip install h5py
  • sudo pip install pydot
  • sudo pip install nose_parameterized
  • sudo pip install keras

In ~/.keras/keras.json (it's very important, the project was running on theano backend, and some issues are possible in case of TensorFlow)

{
    "image_dim_ordering": "th",
    "epsilon": 1e-07,
    "floatx": "float32",
    "backend": "theano"
}

###Python deps

  • sudo apt-get install python-opencv
  • sudo apt-get install python-sklearn

#Prepare

Place train and test data into '../train' and '../test' folders accordingly.

mkdir np_data
python data.py

#Training

Single model training.

python train.py

Results will be generatated in "res/" folder. res/unet.hdf5 - best model

Generate submission:

python submission.py

Generate predection with a model in res/unet.hdf5

python current.py

#Model

Motivation's explained in my internal pres (slides: http://www.slideshare.net/Eduardyantov/ultrasound-segmentation-kaggle-review)

I used U-net like architecture (http://arxiv.org/abs/1505.04597). Main differences:

  • inception blocks instead of VGG like
  • Conv with stride instead of MaxPooling
  • Dropout, p=0.5
  • skip connections from encoder to decoder layers with residual blocks
  • BatchNorm everywhere
  • 2 heads training: auxiliary branch for scoring nerve presence (in the middle of the network), one branch for segmentation
  • ELU activation
  • sigmoid activation in output
  • Adam optimizer, without weight regularization in layers
  • Dice coeff loss, average per batch, without smoothing
  • output layers - sigmoid activation
  • batch_size=64,128 (for GeForce 1080 and Titan X respectively)

Augmentation:

  • flip x,y
  • random zoom
  • random channel shift
  • elastic transormation didn't help in this configuration

Augmentation generator (generate augmented data on the fly for each epoch) didn't improve the score. For prediction augmented images were used.

Validation:

For some reason validation split by patient (which is proper in this competition) didn't work for me, probably due to bug in the code. So I used random split.

Final prediction uses probability of a nerve presence: p_nerve = (p_score + p_segment)/2, where p_segment based on number of output pixels in the mask.

#Results and technical aspects

  • On GPU Titan X an epoch took about 6 minutes. Training early stops at 15-30 epochs.
  • For batch_size=64 6Gb GPU memory is required.
  • Best single model achieved 0.694 LB score.
  • An ensemble of 6 different k-fold ensembles (k=5,6,8) scored 0.70399

#Credits This code was originally based on https://github.com/jocicmarko/ultrasound-nerve-segmentation/

Comments
  • Regarding img_rows and img_cols in preprocess(imgs) function

    Regarding img_rows and img_cols in preprocess(imgs) function

    Hi Edward,

    While running your code, I have a question regarding preprocess(imgs).

    def preprocess(imgs, to_rows=None, to_cols=None):
        if to_rows is None or to_cols is None:
            to_rows = img_rows
            to_cols = img_cols
        imgs_p = np.ndarray((imgs.shape[0], imgs.shape[1], to_rows, to_cols), dtype=np.uint8)
        for i in xrange(imgs.shape[0]):
            imgs_p[i, 0] = cv2.resize(imgs[i, 0], (to_cols, to_rows), interpolation=cv2.INTER_CUBIC)
        return imgs_p
    
    
    

    At first, you define imgs_p with the shape of (batchsize, channel, to_rows,to_cols). However, in the resize function, you resize the original image to (to_cols, to_rows). It seems to me that it should resize to (to_rows,to_cols).

    In fact, if I use the original shape, imgs_p[i, 0] = resize(imgs[i, 0], (to_cols, to_rows)) I got the following error message

    Traceback (most recent call last): File "train.py", line 153, in <module> train_and_predict() File "train.py", line 92, in train_and_predict imgs_train = preprocess(imgs_train) File "train.py", line 81, in preprocess imgs_p[i, 0] = resize(imgs[i, 0], (to_cols, to_rows)) ValueError: could not broadcast input array from shape (80,64) into shape (64,80)

    Would you like to take a look at this issue? Thank you very much.

    opened by huaiyanggongzi 7
  • questions on the loss value and dice_coeff during the training process

    questions on the loss value and dice_coeff during the training process

    Hi Edward,

    During the training process for some data set, I can find the loss value computed for each epoch is negative, and it keeps decreasing along with different epochs; while dice_coef keeps increasing. Is this the right trend. For instance

    Epoch 5/50 5250/5250 [==============================] - 284s - loss: -0.7539 - dice_coef: 0.7539 Epoch 6/50 5250/5250 [==============================] - 283s - loss: -0.7808 - dice_coef: 0.7808 Epoch 7/50 5250/5250 [==============================] - 283s - loss: -0.7891 - dice_coef: 0.7891 Epoch 8/50 5250/5250 [==============================] - 283s - loss: -0.8074 - dice_coef: 0.8074 Epoch 9/50

    At the same time, for some other data sets, I can see the loss value is of positive. I am kind of curious why the loss value gets negative for some data set, while loss value gets positive for some other data sets. What's the best way to evaluate whether the training process goes well based on the envolving process of loss and dice_coef for each epoch.

    Thank you very much.

    ouyang

    opened by wenouyang 4
  • the range of image array after standarization and pre-processing

    the range of image array after standarization and pre-processing

    Hi Edward,

    I have a question regarding the image pre-processing part.

    Were you trying to scale the image array to [0, 1] range, or keep the image array in [0, 255] range? Which one will be better for training the neural network?

    I checked your code, it seems that the image array is still in the range of [0,255] after the function of standartize(self, array, to_float=False)? Is that right? Thanks.

    opened by wenouyang 2
  • regarding the dice_loss and the image shape

    regarding the dice_loss and the image shape

    Hi Edward,

    When reading the code, I can see you use dice_coef for the performance metric. But I am not very clear why you need to setup dice_loss as -dice_coef. Is that because the higher dice_coef is, the better is performance. As a result, you try to minimize its opposite, dice_loss. Is my understanding correct?

    Secondly, why you setup IMG_ROWS, IMG_COLS = 80, 112. It seems to me the training set has rows=480,and cols=520.

    Thanks,

    opened by huaiyanggongzi 2
  • Regarding the number of iterations within each epoch

    Regarding the number of iterations within each epoch

    Hi Edward,

    Regarding the the main optimization step

    model.fit( x_train, [y_train, y_train_2], validation_data=(x_valid, [y_valid, y_valid_2]), batch_size=128, nb_epoch=50, verbose=1, shuffle=True, callbacks=[model_save_best, model_checkpoint, early_s] )

    How many iterations within each epoch will it be included? Here, we have about 5635 pairs of training images and training mask images. If batch_size=64, should it be 5635/32 iterations? I did not find a place where this parameter of training_iters are setup. Will it be handled automatically by model.fit?

    Thank you very much.

    opened by wenouyang 2
  • regarding 2 heads training

    regarding 2 heads training

    Hi Edward,

    Thanks for sharing your code.

    Would you like to help clarify some questions?

    1. What are the differences between train.py, train_generator.py and train_kfold.py?
    2. In the description, you mentioned “2 heads training: auxiliary branch for scoring nerve presence (in the middle of the network), one branch for segmentation”? How do you instantiate? Or in which part of the code, you implement this mechanism?

    Thanks a lot.

    opened by wenouyang 2
  • upsampling2D and deconvolution2D

    upsampling2D and deconvolution2D

    Hi Edward,

    In this u-net implementation, there are multiple usages of "merge" along with "upsampling". For instance. up6 = merge([UpSampling2D(size=(2, 2))(conv5), after_conv4], mode='concat', concat_axis=1)

    I can see that upsampling is to enlarge the size of layer, like conv5. In some paper, like Fully Convolutional Network, they usetransposed convolution, (the corresponding Keras implementation is Deconvolution2D). Does it make sense to use Deconvolution2D to replace upsampling2D?

    Thanks.

    opened by wenouyang 1
  • Network sturcture

    Network sturcture

    Hi Edward, tks for your code, I look at your network structure, find its a mixture of res-like blocks and inception blocks, so I have two questions

    1. how do you figure out this structure ? how much better than u-net after the changes ?
    2. u-net didnot use padding, but here you use same-padding ? does this matter ?
    opened by argman 1
  • data.py gives me empty numpy arrays

    data.py gives me empty numpy arrays

    Hi Edward,

    Thanks for your code! It's simply amazing! I am trying to run it and adapt it for my own project.

    When I call the function data.py, it creates the .npy files correctly and when I try to open and see those files, I got the following result:

    array([[[[0, 0, 0, ..., 0, 0, 0], [0, 0, 0, ..., 0, 0, 0], [0, 0, 0, ..., 0, 0, 0], ..., [0, 0, 0, ..., 0, 0, 0], [0, 0, 0, ..., 0, 0, 0], [0, 0, 0, ..., 0, 0, 0]]],

    All the .npy are empty and I'd say this is not good :(

    Maybe you have a function to convert these numpy array files to image format?

    Thanks for your help.

    opened by adriaromero 1
  • about merge

    about merge

    I notice that you use merge to concat 4 layer,like this: res = merge([c1_1, c2_3, c3_3, c4_2], mode='concat', concat_axis=1) but as I know ,merge can only concat 2 layers,and the first 2 layers have different shape,error shows like: ValueError: "concat" mode can only merge layers with matching output shapes except for the concat axis. Layer shapes: [(None, 1, 80, 8), (None, 1, 80, 16), (None, 1, 80, 4), (None, 1, 80, 4)] I do not know why you concat different shape like that.

    opened by lz666win 4
  • An error cast when I run train.py

    An error cast when I run train.py

    Dear Edward: Thanks for your sharing. But when I run train.py, it cast our an error:ValueError: Filter must not be larger than the input: Filter: (3, 1) Input: (1, 80). Do you know why?

    opened by JFChi 5
Owner
null
My published benchmark for a Kaggle Simulations Competition

Lux AI Working Title Bot Please refer to the Kaggle notebook for the comment section. The comment section contains my explanation on my code structure

Tong Hui Kang 29 Aug 22, 2022
Data visualization app for H&M competition in kaggle

handm_data_visualize_app Data visualization app by streamlit for H&M competition in kaggle. competition page: https://www.kaggle.com/competitions/h-an

Kyohei Uto 12 Apr 30, 2022
This is the solution for 2nd rank in Kaggle competition: Feedback Prize - Evaluating Student Writing.

Feedback Prize - Evaluating Student Writing This is the solution for 2nd rank in Kaggle competition: Feedback Prize - Evaluating Student Writing. The

Udbhav Bamba 41 Dec 14, 2022
Automatic detection and classification of Covid severity degree in LUS (lung ultrasound) scans

Final-Project Final project in the Technion, Biomedical faculty, by Mor Ventura, Dekel Brav & Omri Magen. Subproject 1: Automatic Detection of LUS Cha

Mor Ventura 1 Dec 18, 2021
Western-3DSlicer-Modules - Point-Set Registrations for Ultrasound Probe Calibrations

Point-Set Registrations for Ultrasound Probe Calibrations -Undergraduate Thesis-

Matteo Tanzi 0 May 4, 2022
SweiNet is an uncertainty-quantifying shear wave speed (SWS) estimator for ultrasound shear wave elasticity (SWE) imaging.

SweiNet SweiNet is an uncertainty-quantifying shear wave speed (SWS) estimator for ultrasound shear wave elasticity (SWE) imaging. SweiNet takes as in

Felix Jin 3 Mar 31, 2022
Kaggle: Cell Instance Segmentation

Kaggle: Cell Instance Segmentation The goal of this challenge is to detect cells in microscope images. with simple view on how many cels have been ann

Jirka Borovec 9 Aug 12, 2022
This is an implementation of Googles Yogi-Optimizer in Keras (tf.keras)

Yogi-Optimizer_Keras This is an implementation of Googles Yogi-Optimizer in Keras (tf.keras) The NeurIPS-Paper can be found here: http://papers.nips.c

null 14 Sep 13, 2022
Keras udrl - Keras implementation of Upside Down Reinforcement Learning

keras_udrl Keras implementation of Upside Down Reinforcement Learning This is me

Eder Santana 7 Jan 24, 2022
Example-custom-ml-block-keras - Custom Keras ML block example for Edge Impulse

Custom Keras ML block example for Edge Impulse This repository is an example on

Edge Impulse 8 Nov 2, 2022
Classification models 1D Zoo - Keras and TF.Keras

Classification models 1D Zoo - Keras and TF.Keras This repository contains 1D variants of popular CNN models for classification like ResNets, DenseNet

Roman Solovyev 12 Jan 6, 2023
A keras-based real-time model for medical image segmentation (CFPNet-M)

CFPNet-M: A Light-Weight Encoder-Decoder Based Network for Multimodal Biomedical Image Real-Time Segmentation This repository contains the implementat

null 268 Nov 27, 2022
Mask R-CNN for object detection and instance segmentation on Keras and TensorFlow

Mask R-CNN for Object Detection and Segmentation This is an implementation of Mask R-CNN on Python 3, Keras, and TensorFlow. The model generates bound

Matterport, Inc 22.5k Jan 4, 2023
Keras implementation of PersonLab for Multi-Person Pose Estimation and Instance Segmentation.

PersonLab This is a Keras implementation of PersonLab for Multi-Person Pose Estimation and Instance Segmentation. The model predicts heatmaps and vari

OCTI 160 Dec 21, 2022
Tensorflow2 Keras-based Semantic Segmentation Models Implementation

Tensorflow2 Keras-based Semantic Segmentation Models Implementation

Hah Min Lew 1 Feb 8, 2022
Kaggle Lyft Motion Prediction for Autonomous Vehicles 4th place solution

Lyft Motion Prediction for Autonomous Vehicles Code for the 4th place solution of Lyft Motion Prediction for Autonomous Vehicles on Kaggle. Discussion

null 44 Jun 27, 2022
🏅 The Most Comprehensive List of Kaggle Solutions and Ideas 🏅

?? Collection of Kaggle Solutions and Ideas ??

Farid Rashidi 2.3k Jan 8, 2023
7th place solution of Human Protein Atlas - Single Cell Classification on Kaggle

kaggle-hpa-2021-7th-place-solution Code for 7th place solution of Human Protein Atlas - Single Cell Classification on Kaggle. A description of the met

null 8 Jul 9, 2021
Kaggle | 9th place (part of) solution for the Bristol-Myers Squibb – Molecular Translation challenge

Part of the 9th place solution for the Bristol-Myers Squibb – Molecular Translation challenge translating images containing chemical structures into I

Erdene-Ochir Tuguldur 22 Nov 30, 2022