master 84a614009cdc cached
15 files
70.1 KB
18.9k tokens
114 symbols
1 requests
Download .txt
Repository: EdwardTyantov/ultrasound-nerve-segmentation
Branch: master
Commit: 84a614009cdc
Files: 15
Total size: 70.1 KB

Directory structure:
gitextract_l79q2ook/

├── README.md
├── __init__.py
├── augmentation.py
├── average_ensembles.py
├── current.py
├── current_ensemble.py
├── data.py
├── keras_plus.py
├── metric.py
├── submission.py
├── train.py
├── train_generator.py
├── train_kfold.py
├── u_model.py
└── utils.py

================================================
FILE CONTENTS
================================================

================================================
FILE: README.md
================================================
# Ultrasound nerve segmentation using Keras (1.0.7)
Kaggle Ultrasound Nerve Segmentation competition [Keras]

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

cuDNN required.

###Theano
- http://deeplearning.net/software/theano/install_ubuntu.html#install-ubuntu
- sudo pip install pydot-ng

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/


================================================
FILE: __init__.py
================================================


================================================
FILE: augmentation.py
================================================
import sys, os
import numpy as np
from keras.preprocessing.image import (transform_matrix_offset_center, apply_transform, Iterator,
                                       random_channel_shift, flip_axis)
from scipy.ndimage.interpolation import map_coordinates
from scipy.ndimage.filters import gaussian_filter


_dir = os.path.join(os.path.realpath(os.path.dirname(__file__)), '')
data_path = os.path.join(_dir, '../')
aug_data_path = os.path.join(_dir, 'aug_data')
aug_pattern = os.path.join(aug_data_path, 'train_img_%d.npy')
aug_mask_pattern = os.path.join(aug_data_path, 'train_mask_%d.npy')


def random_zoom(x, y, zoom_range, row_index=1, col_index=2, channel_index=0,
                fill_mode='nearest', cval=0.):
    if len(zoom_range) != 2:
        raise Exception('zoom_range should be a tuple or list of two floats. '
                        'Received arg: ', zoom_range)

    if zoom_range[0] == 1 and zoom_range[1] == 1:
        zx, zy = 1, 1
    else:
        zx, zy = np.random.uniform(zoom_range[0], zoom_range[1], 2)
    zoom_matrix = np.array([[zx, 0, 0],
                            [0, zy, 0],
                            [0, 0, 1]])

    h, w = x.shape[row_index], x.shape[col_index]
    transform_matrix = transform_matrix_offset_center(zoom_matrix, h, w)
    x = apply_transform(x, transform_matrix, channel_index, fill_mode, cval)
    y = apply_transform(y, transform_matrix, channel_index, fill_mode, cval)
    return x, y


def random_rotation(x, y, rg, row_index=1, col_index=2, channel_index=0,
                    fill_mode='nearest', cval=0.):
    theta = np.pi / 180 * np.random.uniform(-rg, rg)
    rotation_matrix = np.array([[np.cos(theta), -np.sin(theta), 0],
                                [np.sin(theta), np.cos(theta), 0],
                                [0, 0, 1]])

    h, w = x.shape[row_index], x.shape[col_index]
    transform_matrix = transform_matrix_offset_center(rotation_matrix, h, w)
    x = apply_transform(x, transform_matrix, channel_index, fill_mode, cval)
    y = apply_transform(y, transform_matrix, channel_index, fill_mode, cval)
    return x, y


def random_shear(x, y, intensity, row_index=1, col_index=2, channel_index=0,
                 fill_mode='constant', cval=0.):
    shear = np.random.uniform(-intensity, intensity)
    shear_matrix = np.array([[1, -np.sin(shear), 0],
                             [0, np.cos(shear), 0],
                             [0, 0, 1]])

    h, w = x.shape[row_index], x.shape[col_index]
    transform_matrix = transform_matrix_offset_center(shear_matrix, h, w)
    x = apply_transform(x, transform_matrix, channel_index, fill_mode, cval)
    y = apply_transform(y, transform_matrix, channel_index, fill_mode, cval)
    return x, y


class CustomNumpyArrayIterator(Iterator):

    def __init__(self, X, y, image_data_generator,
                 batch_size=32, shuffle=False, seed=None,
                 dim_ordering='th'):
        self.X = X
        self.y = y
        self.image_data_generator = image_data_generator
        self.dim_ordering = dim_ordering
        super(CustomNumpyArrayIterator, self).__init__(X.shape[0], batch_size, shuffle, seed)


    def next(self):
        with self.lock:
            index_array, _, current_batch_size = next(self.index_generator)
        batch_x = np.zeros(tuple([current_batch_size] + list(self.X.shape)[1:]))
        batch_y_1, batch_y_2 = [], []
        for i, j in enumerate(index_array):
            x = self.X[j]
            y1 = self.y[0][j]
            y2 = self.y[1][j]
            _x, _y1 = self.image_data_generator.random_transform(x.astype('float32'), y1.astype('float32'))
            batch_x[i] = _x
            batch_y_1.append(_y1)
            batch_y_2.append(y2)
        return batch_x, [np.array(batch_y_1), np.array(batch_y_2)]
    

class CustomImageDataGenerator(object):
    def __init__(self, zoom_range=(1,1), channel_shift_range=0, horizontal_flip=False, vertical_flip=False,
                 rotation_range=0,
                 width_shift_range=0.,
                 height_shift_range=0.,
                 shear_range=0.,
                 elastic=None,
):
        self.zoom_range = zoom_range
        self.channel_shift_range = channel_shift_range
        self.horizontal_flip = horizontal_flip
        self.vertical_flip = vertical_flip
        self.rotation_range = rotation_range
        self.width_shift_range = width_shift_range
        self.height_shift_range = height_shift_range
        self.shear_range = shear_range
        self.elastic = elastic
    
    def random_transform(self, x, y, row_index=1, col_index=2, channel_index=0):
        
        if self.horizontal_flip:
            if True or np.random.random() < 0.5:
                x = flip_axis(x, 2)
                y = flip_axis(y, 2)
        
        # use composition of homographies to generate final transform that needs to be applied
        if self.rotation_range:
            theta = np.pi / 180 * np.random.uniform(-self.rotation_range, self.rotation_range)
        else:
            theta = 0
        rotation_matrix = np.array([[np.cos(theta), -np.sin(theta), 0],
                                    [np.sin(theta), np.cos(theta), 0],
                                    [0, 0, 1]])
        if self.height_shift_range:
            tx = np.random.uniform(-self.height_shift_range, self.height_shift_range) * x.shape[row_index]
        else:
            tx = 0

        if self.width_shift_range:
            ty = np.random.uniform(-self.width_shift_range, self.width_shift_range) * x.shape[col_index]
        else:
            ty = 0

        translation_matrix = np.array([[1, 0, tx],
                                       [0, 1, ty],
                                       [0, 0, 1]])
        if self.shear_range:
            shear = np.random.uniform(-self.shear_range, self.shear_range)
        else:
            shear = 0
        shear_matrix = np.array([[1, -np.sin(shear), 0],
                                 [0, np.cos(shear), 0],
                                 [0, 0, 1]])

        if self.zoom_range[0] == 1 and self.zoom_range[1] == 1:
            zx, zy = 1, 1
        else:
            zx, zy = np.random.uniform(self.zoom_range[0], self.zoom_range[1], 2)
        zoom_matrix = np.array([[zx, 0, 0],
                                [0, zy, 0],
                                [0, 0, 1]])

        transform_matrix = np.dot(np.dot(np.dot(rotation_matrix, translation_matrix), shear_matrix), zoom_matrix)
        
        h, w = x.shape[row_index], x.shape[col_index]
        transform_matrix = transform_matrix_offset_center(transform_matrix, h, w)
        
        x = apply_transform(x, transform_matrix, channel_index,
                            fill_mode='constant')
        y = apply_transform(y, transform_matrix, channel_index,
                            fill_mode='constant')
        
        
        #        

        if self.vertical_flip:
            if np.random.random() < 0.5:
                x = flip_axis(x, 1)
                y = flip_axis(y, 1)
        
        if self.channel_shift_range != 0:
            x = random_channel_shift(x, self.channel_shift_range)


        if self.elastic is not None:
            x, y = elastic_transform(x.reshape(h,w), y.reshape(h,w), *self.elastic)
            x, y = x.reshape(1, h, w), y.reshape(1, h, w)
        
        return x, y
    
    def flow(self, X, Y, batch_size, shuffle=True, seed=None):
        return CustomNumpyArrayIterator(
            X, Y, self,
            batch_size=batch_size, shuffle=shuffle, seed=seed)

        
def elastic_transform(image, mask, alpha, sigma, alpha_affine=None, random_state=None):
    """Elastic deformation of images as described in [Simard2003]_ (with modifications).
    .. [Simard2003] Simard, Steinkraus and Platt, "Best Practices for
         Convolutional Neural Networks applied to Visual Document Analysis", in
         Proc. of the International Conference on Document Analysis and
         Recognition, 2003.

     Based on https://gist.github.com/erniejunior/601cdf56d2b424757de5
    """
    if random_state is None:
        random_state = np.random.RandomState(None)

    shape = image.shape

    dx = gaussian_filter((random_state.rand(*shape) * 2 - 1), sigma) * alpha
    dy = gaussian_filter((random_state.rand(*shape) * 2 - 1), sigma) * alpha

    x, y = np.meshgrid(np.arange(shape[1]), np.arange(shape[0]))
    indices = np.reshape(y+dy, (-1, 1)), np.reshape(x+dx, (-1, 1))


    res_x = map_coordinates(image, indices, order=1, mode='reflect').reshape(shape)
    res_y = map_coordinates(mask, indices, order=1, mode='reflect').reshape(shape)
    return res_x, res_y


def test():
    X = np.random.randint(0,100, (1000, 1, 100, 200))
    YY = [np.random.randint(0,100, (1000, 1, 100, 200)), np.random.random((1000, 1))]
    cid = CustomImageDataGenerator(horizontal_flip=True, elastic=(100,20))
    gen = cid.flow(X, YY, batch_size=64, shuffle=False)
    n = gen.next()[0]
    
    
if __name__ == '__main__':
    sys.exit(test())


================================================
FILE: average_ensembles.py
================================================
import numpy as np
import sys
from u_model import IMG_COLS as img_cols, IMG_ROWS as img_rows
from train import Learner

ensembles = {
             'ens2': (8, 'best/ens2/res3/'), 
             'ens3': (6, 'best/ens3/res3/'), 
             'ens4': (6, 'best/ens4/res3/'), 
             'ens5': (8, 'best/ens5/res3/'), 
             'ens7': (6, 'best/ens7/res3/'), 
             'ens8': (5, 'best/ens8/res3/'),  
             }


def main():
    kfold_masks, kfold_prob = [], []
    weigths = []
    for name, (kfold, prefix) in ensembles.iteritems():
        print 'Loading name=%s, prefix=%s, kfold=%d' % (name, prefix, kfold)
        ens_x_mask = np.load(prefix + 'imgs_mask_test.npy')
        ens_x_prob = np.load(prefix + 'imgs_mask_exist_test.npy')
        kfold_masks.append(ens_x_mask)
        kfold_prob.append(ens_x_prob)
        weigths.append(kfold)
    #
    total_weight = float(sum(weigths))
    total_cnt = len(weigths)
    dlen = len(kfold_masks[0])
    res_masks = np.ndarray((dlen, 1, img_rows, img_cols), dtype=np.float32)
    res_probs = np.ndarray((dlen, ), dtype=np.float32)
    
    for i in xrange(dlen):
        masks = np.ndarray((total_cnt, 1, img_rows, img_cols), dtype=np.float32)
        probs = np.ndarray((total_cnt, ), dtype=np.float32)
        for k in xrange(total_cnt):
            masks[k] = weigths[k] * kfold_masks[k][i]
            probs[k] = weigths[k] * kfold_prob[k][i]
        res_masks[i] = np.sum(masks, 0)/total_weight
        res_probs[i] = np.sum(probs)/total_weight
    print 'Saving', Learner.test_mask_res, Learner.test_mask_exist_res
    np.save(Learner.test_mask_res, res_masks)
    np.save(Learner.test_mask_exist_res, res_probs)
    

if __name__ == '__main__':
    sys.exit(main())



================================================
FILE: current.py
================================================
import numpy as np
import sys
from data import load_test_data
from u_model import get_unet
from keras.optimizers import Adam
from train import preprocess, Learner
#aug
from u_model import IMG_COLS as img_cols, IMG_ROWS as img_rows
from keras.preprocessing.image import flip_axis, random_channel_shift

curry = lambda func, *args, **kw:\
            lambda *p, **n:\
                 func(*args + p, **dict(kw.items() + n.items()))
from keras.preprocessing.image import apply_transform, transform_matrix_offset_center


def zoom(x, zoom_range, row_index=1, col_index=2, channel_index=0,
                fill_mode='nearest', cval=0.):
    zx, zy = zoom_range
    zoom_matrix = np.array([[zx, 0, 0],
                            [0, zy, 0],
                            [0, 0, 1]])

    h, w = x.shape[row_index], x.shape[col_index]
    transform_matrix = transform_matrix_offset_center(zoom_matrix, h, w)
    x = apply_transform(x, transform_matrix, channel_index, fill_mode, cval)
    return x


transforms = (
              {'do': curry(flip_axis, axis=1), 'undo': curry(flip_axis, axis=1)},
              {'do': curry(flip_axis, axis=2), 'undo': curry(flip_axis, axis=2)},
              {'do': curry(zoom, zoom_range=(1.05, 1.05)), 'undo': curry(zoom, zoom_range=(1/1.05, 1/1.05))},
              {'do': curry(zoom, zoom_range=(0.95, 0.95)), 'undo': curry(zoom, zoom_range=(1/0.95, 1/0.95))},
              {'do': curry(random_channel_shift, intensity=5), 'undo': lambda x: x},
              )


def run_test():
    BS = 128
    print('Loading and preprocessing test data...')
    mean, std = Learner.load_meanstd()
    
    imgs_test = load_test_data()
    imgs_test = preprocess(imgs_test)

    imgs_test = imgs_test.astype('float32')
    imgs_test -= mean
    imgs_test /= std

    print('Loading saved weights...')
    model = get_unet(Adam(0.001))
    print ('Loading weights from %s' % Learner.best_weight_path)
    model.load_weights(Learner.best_weight_path)
    
    print ('Augment')
    alen, dlen = len(transforms), len(imgs_test)
    test_x = np.ndarray((alen, dlen, 1, img_rows, img_cols), dtype=np.float32)
    for i in xrange(dlen):
        for j, transform in enumerate(transforms):
            test_x[j,i] = transform['do'](imgs_test[i].copy())
    #
    print('Predicting masks on test data...')
    outputs = []
    asis_res = model.predict(imgs_test, batch_size=BS, verbose=1)
    outputs.append(asis_res)
    for j, transform in enumerate(transforms):
        t_y = model.predict(test_x[j], batch_size=BS, verbose=1)
        outputs.append(t_y)
    #
    print('Analyzing')
    test_masks = np.ndarray((dlen, 1, img_rows, img_cols), dtype=np.float32)
    test_probs = np.ndarray((dlen, ), dtype=np.float32)
    for i in xrange(dlen):
        masks = np.ndarray((alen+1, 1, img_rows, img_cols), dtype=np.float32)
        probs = np.ndarray((alen+1, ), dtype=np.float32)
        for j, t_y in enumerate(outputs):
            mask, prob = t_y[0][i], t_y[1][i]
            if j:
                mask = transforms[j-1]['undo'](mask)
            masks[j] = mask
            probs[j] = prob
        #
        test_masks[i] = np.mean(masks, 0)
        test_probs[i] = np.mean(probs)
            
    print('Saving ')
    np.save(Learner.test_mask_res, test_masks)
    np.save(Learner.test_mask_exist_res, test_probs)

def main():
    run_test()

if __name__ == '__main__':
    sys.exit(main())


================================================
FILE: current_ensemble.py
================================================
import numpy as np
import sys
from data import load_test_data
from u_model import get_unet
from keras.optimizers import Adam
from train import preprocess, Learner
#aug
from u_model import IMG_COLS as img_cols, IMG_ROWS as img_rows
from keras.preprocessing.image import flip_axis, random_channel_shift

curry = lambda func, *args, **kw:\
            lambda *p, **n:\
                 func(*args + p, **dict(kw.items() + n.items()))
from keras.preprocessing.image import apply_transform, transform_matrix_offset_center


def zoom(x, zoom_range, row_index=1, col_index=2, channel_index=0,
                fill_mode='nearest', cval=0.):
    zx, zy = zoom_range
    zoom_matrix = np.array([[zx, 0, 0],
                            [0, zy, 0],
                            [0, 0, 1]])

    h, w = x.shape[row_index], x.shape[col_index]
    transform_matrix = transform_matrix_offset_center(zoom_matrix, h, w)
    x = apply_transform(x, transform_matrix, channel_index, fill_mode, cval)
    return x


transforms = (
              {'do': curry(flip_axis, axis=1), 'undo': curry(flip_axis, axis=1)},
              {'do': curry(flip_axis, axis=2), 'undo': curry(flip_axis, axis=2)},
              {'do': curry(zoom, zoom_range=(1.05, 1.05)), 'undo': curry(zoom, zoom_range=(1/1.05, 1/1.05))},
              {'do': curry(zoom, zoom_range=(0.95, 0.95)), 'undo': curry(zoom, zoom_range=(1/0.95, 1/0.95))},
              {'do': curry(random_channel_shift, intensity=5), 'undo': lambda x: x},
              )


def run_test():
    BS = 256
    print('Loading and preprocessing test data...')
    mean, std = Learner.load_meanstd()
    
    imgs_test = load_test_data()
#    imgs_test = imgs_test[:100]
#    print ('test')
    imgs_test = preprocess(imgs_test)

    imgs_test = imgs_test.astype('float32')
    imgs_test -= mean
    imgs_test /= std

    
    print ('Augment')
    alen, dlen = len(transforms), len(imgs_test)
    test_x = np.ndarray((alen, dlen, 1, img_rows, img_cols), dtype=np.float32)
    for i in xrange(dlen):
        for j, transform in enumerate(transforms):
            test_x[j,i] = transform['do'](imgs_test[i].copy())
    #
    kfold = 6
    kfold_masks, kfold_prob = [], []
    for _iter in xrange(kfold):
        print('Iter=%d, Loading saved weights...' % _iter)
        model = get_unet(Adam(0.001))
        filepath = Learner.best_weight_path + '_%d.fold' % _iter
        print ('Loading weights from %s' % filepath)
        model.load_weights(filepath)
        #
        print('Predicting masks on test data...')
        outputs = []
        asis_res = model.predict(imgs_test, batch_size=BS, verbose=1)
        outputs.append(asis_res)
        for j, transform in enumerate(transforms):
            t_y = model.predict(test_x[j], batch_size=BS, verbose=1)
            outputs.append(t_y)
        #
        print('Analyzing')
        test_masks = np.ndarray((dlen, 1, img_rows, img_cols), dtype=np.float32)
        test_probs = np.ndarray((dlen, ), dtype=np.float32)
        for i in xrange(dlen):
            masks = np.ndarray((alen+1, 1, img_rows, img_cols), dtype=np.float32)
            probs = np.ndarray((alen+1, ), dtype=np.float32)
            for j, t_y in enumerate(outputs):
                mask, prob = t_y[0][i], t_y[1][i]
                if j:
                    mask = transforms[j-1]['undo'](mask.copy())
                masks[j] = mask
                probs[j] = prob
            #
            test_masks[i] = np.mean(masks, 0)
            test_probs[i] = np.mean(probs)
        kfold_masks.append(test_masks)
        kfold_prob.append(test_probs)
    
    print 'Summing results of ensemble'
    #
    res_masks = np.ndarray((dlen, 1, img_rows, img_cols), dtype=np.float32)
    res_probs = np.ndarray((dlen, ), dtype=np.float32)
    for i in xrange(dlen):
        masks = np.ndarray((kfold, 1, img_rows, img_cols), dtype=np.float32)
        probs = np.ndarray((kfold, ), dtype=np.float32)
        for k in xrange(kfold):
            masks[k] = kfold_masks[k][i]
            probs[k] = kfold_prob[k][i]
        res_masks[i] = np.mean(masks, 0)
        res_probs[i] = np.mean(probs)
        

    print('Saving ')
    np.save(Learner.test_mask_res, res_masks)
    np.save(Learner.test_mask_exist_res, res_probs)


def main():
    run_test()

if __name__ == '__main__':
    sys.exit(main())



================================================
FILE: data.py
================================================
from __future__ import print_function
import os, sys
import numpy as np
import cv2

image_rows = 420
image_cols = 580

_dir = os.path.join(os.path.realpath(os.path.dirname(__file__)), '')
data_path = os.path.join(_dir, '../')
preprocess_path = os.path.join(_dir, 'np_data')
img_train_path = os.path.join(preprocess_path, 'imgs_train.npy')
img_train_mask_path = os.path.join(preprocess_path, 'imgs_mask_train.npy')
img_train_patients = os.path.join(preprocess_path, 'imgs_patient.npy')
img_test_path = os.path.join(preprocess_path, 'imgs_test.npy') 
img_test_id_path = os.path.join(preprocess_path, 'imgs_id_test.npy') 



def load_test_data():
    print ('Loading test data from %s' % img_test_path)
    imgs_test = np.load(img_test_path)
    return imgs_test

def load_test_ids():
    print ('Loading test ids from %s' % img_test_id_path)
    imgs_id = np.load(img_test_id_path)
    return imgs_id

def load_train_data():
    print ('Loading train data from %s and %s' % (img_train_path, img_train_mask_path))
    imgs_train = np.load(img_train_path)
    imgs_mask_train = np.load(img_train_mask_path)
    return imgs_train, imgs_mask_train

def load_patient_num():
    print ('Loading patient numbers from %s' % img_train_patients)
    return np.load(img_train_patients)

def get_patient_nums(string):
    pat, photo = string.split('_')
    photo = photo.split('.')[0]
    return int(pat), int(photo)

def create_train_data():
    train_data_path = os.path.join(data_path, 'train')
    images = filter((lambda image: 'mask' not in image), os.listdir(train_data_path))
    total = len(images) 

    imgs = np.ndarray((total, 1, image_rows, image_cols), dtype=np.uint8)
    imgs_mask = np.ndarray((total, 1, image_rows, image_cols), dtype=np.uint8)
    i = 0
    print('Creating training images...')
    img_patients = np.ndarray((total,), dtype=np.uint8)
    for image_name in images:
        if 'mask' in image_name:
            continue
        image_mask_name = image_name.split('.')[0] + '_mask.tif'
        patient_num = image_name.split('_')[0]
        img = cv2.imread(os.path.join(train_data_path, image_name), cv2.IMREAD_GRAYSCALE)
        img_mask = cv2.imread(os.path.join(train_data_path, image_mask_name), cv2.IMREAD_GRAYSCALE)

        imgs[i, 0] = img
        imgs_mask[i, 0] = img_mask
        img_patients[i] = patient_num
        if i % 100 == 0:
            print('Done: {0}/{1} images'.format(i, total))
        i += 1
    print('Loading done.')
    np.save(img_train_patients, img_patients)
    np.save(img_train_path, imgs)
    np.save(img_train_mask_path, imgs_mask)
    print('Saving to .npy files done.')


def create_test_data():
    train_data_path = os.path.join(data_path, 'test')
    images = os.listdir(train_data_path)
    total = len(images)

    imgs = np.ndarray((total, 1, image_rows, image_cols), dtype=np.uint8)
    imgs_id = np.ndarray((total, ), dtype=np.int32)

    i = 0
    print('Creating test images...')
    for image_name in images:
        img_id = int(image_name.split('.')[0])
        img = cv2.imread(os.path.join(train_data_path, image_name), cv2.IMREAD_GRAYSCALE)

        imgs[i, 0] = img
        imgs_id[i] = img_id

        if i % 100 == 0:
            print('Done: {0}/{1} images'.format(i, total))
        i += 1
    print('Loading done.')

    np.save(img_test_path, imgs)
    np.save(img_test_id_path, imgs_id)
    print('Saving to .npy files done.')


def main():
    create_train_data()
    create_test_data()

if __name__ == '__main__':
    sys.exit(main())


================================================
FILE: keras_plus.py
================================================
from keras.callbacks import Callback
from keras.callbacks import warnings
import sys
import numpy as np
from keras import backend as K


class AdvancedLearnignRateScheduler(Callback):
    '''
    # Arguments
        monitor: quantity to be monitored.
        patience: number of epochs with no improvement
            after which training will be stopped.
        verbose: verbosity mode.
        mode: one of {auto, min, max}. In 'min' mode,
            training will stop when the quantity
            monitored has stopped decreasing; in 'max'
            mode it will stop when the quantity
            monitored has stopped increasing.
    '''
    def __init__(self, monitor='val_loss', patience=0,
                 verbose=0, mode='auto', decayRatio=0.5):
        super(Callback, self).__init__()

        self.monitor = monitor
        self.patience = patience
        self.verbose = verbose
        self.wait = 0
        self.decayRatio = decayRatio

        if mode not in ['auto', 'min', 'max']:
            warnings.warn('Mode %s is unknown, '
                          'fallback to auto mode.'
                          % (self.mode), RuntimeWarning)
            mode = 'auto'

        if mode == 'min':
            self.monitor_op = np.less
            self.best = np.Inf
        elif mode == 'max':
            self.monitor_op = np.greater
            self.best = -np.Inf
        else:
            if 'acc' in self.monitor:
                self.monitor_op = np.greater
                self.best = -np.Inf
            else:
                self.monitor_op = np.less
                self.best = np.Inf

    def on_epoch_end(self, epoch, logs={}):
        current = logs.get(self.monitor)

        current_lr = K.get_value(self.model.optimizer.lr)
        print(" \nLearning rate:", current_lr)
        if current is None:
            warnings.warn('AdvancedLearnignRateScheduler'
                          ' requires %s available!' %
                          (self.monitor), RuntimeWarning)

        if self.monitor_op(current, self.best):
            self.best = current
            self.wait = 0
        else:
            if self.wait >= self.patience:
                assert hasattr(self.model.optimizer, 'lr'), \
                    'Optimizer must have a "lr" attribute.'
                current_lr = K.get_value(self.model.optimizer.lr)
                new_lr = current_lr * self.decayRatio
                if self.verbose > 0:
                    print(' \nEpoch %05d: reducing learning rate' % (epoch))
                    sys.stderr.write(' \nnew lr: %.5f\n' % new_lr)
                K.set_value(self.model.optimizer.lr, new_lr)
                self.wait = 0

            self.wait += 1


class LearningRateDecay(Callback):
    '''Learning rate scheduler.

    # Arguments
        schedule: a function that takes an epoch index as input
            (integer, indexed from 0) and returns a new
            learning rate as output (float).
    '''
    def __init__(self, decay, every_n=1, verbose=0):
        Callback.__init__(self)
        self.decay = decay
        self.every_n = every_n
        self.verbose = verbose

    def on_epoch_end(self, epoch, logs={}):
        if not (epoch and epoch % self.every_n == 0):
            return

        assert hasattr(self.model.optimizer, 'lr'), \
            'Optimizer must have a "lr" attribute.'
        current_lr = K.get_value(self.model.optimizer.lr)
        new_lr = current_lr * self.decay
        if self.verbose > 0:
            print(' \nEpoch %05d: reducing learning rate' % (epoch))
            sys.stderr.write('new lr: %.5f\n' % new_lr)
        K.set_value(self.model.optimizer.lr, new_lr)


================================================
FILE: metric.py
================================================
import sys
import numpy as np
from keras import backend as K
smooth = 1


def mean_length_error(y_true, y_pred):
    y_true_f = K.sum(K.round(K.flatten(y_true)))
    y_pred_f = K.sum(K.round(K.flatten(y_pred)))
    delta = (y_pred_f - y_true_f)
    return K.mean(K.tanh(delta))

def dice_coef(y_true, y_pred):
    y_true_f = K.flatten(y_true)
    y_pred_f = K.flatten(y_pred)
    intersection = K.sum(y_true_f * y_pred_f)
    return (2. * intersection + smooth) / (K.sum(y_true_f) + K.sum(y_pred_f) + smooth)

def dice_coef_loss(y_true, y_pred):
    return -dice_coef(y_true, y_pred)

def np_dice_coef(y_true, y_pred):
    tr = y_true.flatten()
    pr = y_pred.flatten()
    return (2. * np.sum(tr * pr) + smooth) / (np.sum(tr) + np.sum(pr) + smooth)


def main():
    a = np.random.random((420,100))
    b = np.random.random((420,100))
#    print a.flatten().shape
    res =  np_dice_coef(a,b )
    print res


if __name__ == '__main__':
    sys.exit(main())
    

================================================
FILE: submission.py
================================================
from __future__ import print_function
import sys, os
import numpy as np
import cv2
from data import image_cols, image_rows, load_test_ids
from train import Learner


def prep(img):
    img = img.astype('float32')
    img = cv2.resize(img, (image_cols, image_rows)) 
    img = cv2.threshold(img, 0.5, 1., cv2.THRESH_BINARY)[1].astype(np.uint8)
    return img

def run_length_enc(label):
    from itertools import chain
    x = label.transpose().flatten()
    y = np.where(x > 0)[0]
    if len(y) < 10:  # consider as empty
        return ''
    z = np.where(np.diff(y) > 1)[0]
    start = np.insert(y[z+1], 0, y[0])
    end = np.append(y[z], y[-1])
    length = end - start
    res = [[s+1, l+1] for s, l in zip(list(start), list(length))]
    res = list(chain.from_iterable(res))
    return ' '.join([str(r) for r in res])


def submission():
    imgs_id_test = load_test_ids()
    
    print ('Loading test_mask_res from %s' % Learner.test_mask_res)
    imgs_test = np.load(Learner.test_mask_res)
    print ('Loading imgs_exist_test from %s' % Learner.test_mask_exist_res)
    imgs_exist_test = np.load(Learner.test_mask_exist_res)

    argsort = np.argsort(imgs_id_test)
    imgs_id_test = imgs_id_test[argsort]
    imgs_test = imgs_test[argsort]
    imgs_exist_test = imgs_exist_test[argsort]

    total = imgs_test.shape[0]
    ids = []
    rles = []
    for i in xrange(total):
        img = imgs_test[i, 0]
        img_exist = imgs_exist_test[i]
        img = prep(img)
        new_prob = (img_exist + min(1, np.sum(img)/10000.0 )* 5 / 3)/2
        if np.sum(img) > 0 and new_prob < 0.5:
            img = np.zeros((image_rows, image_cols))

        rle = run_length_enc(img)

        rles.append(rle)
        ids.append(imgs_id_test[i])

        if i % 1000 == 0:
            print('{}/{}'.format(i, total))

    file_name = os.path.join(Learner.res_dir, 'submission.csv')

    with open(file_name, 'w+') as f:
        f.write('img,pixels\n')
        for i in xrange(total):
            s = str(ids[i]) + ',' + rles[i]
            f.write(s + '\n')

def main():
    submission()


if __name__ == '__main__':
    sys.exit(main())


================================================
FILE: train.py
================================================
from __future__ import print_function
from optparse import OptionParser
import cv2, sys, os, shutil, random
import numpy as np
from keras.optimizers import Adam
from keras.callbacks import ModelCheckpoint, EarlyStopping
from keras.preprocessing.image import flip_axis, random_channel_shift
from keras.engine.training import slice_X
from keras_plus import LearningRateDecay
from u_model import get_unet, IMG_COLS as img_cols, IMG_ROWS as img_rows
from data import load_train_data, load_test_data, load_patient_num
from augmentation import random_zoom, elastic_transform, random_rotation
from utils import save_pickle, load_pickle, count_enum

_dir = os.path.join(os.path.realpath(os.path.dirname(__file__)), '')


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


class Learner(object):
    
    suffix = ''
    res_dir = os.path.join(_dir, 'res' + suffix)
    best_weight_path = os.path.join(res_dir, 'unet.hdf5')
    test_mask_res = os.path.join(res_dir, 'imgs_mask_test.npy')
    test_mask_exist_res = os.path.join(res_dir, 'imgs_mask_exist_test.npy')
    meanstd_path = os.path.join(res_dir, 'meanstd.dump')
    valid_data_path = os.path.join(res_dir, 'valid.npy')
    tensorboard_dir = os.path.join(res_dir, 'tb')
    
    def __init__(self, model_func, validation_split):
        self.model_func = model_func
        self.validation_split = validation_split
        self.__iter_res_dir = os.path.join(self.res_dir, 'res_iter')
        self.__iter_res_file = os.path.join(self.__iter_res_dir, '{epoch:02d}-{val_loss:.4f}.unet.hdf5')
        
    def _dir_init(self):
        if not os.path.exists(self.res_dir):
            os.mkdir(self.res_dir)
        #iter clean
        if os.path.exists(self.__iter_res_dir):
            shutil.rmtree(self.__iter_res_dir)
        os.mkdir(self.__iter_res_dir)
    
    def save_meanstd(self):
        data = [self.mean, self.std]
        save_pickle(self.meanstd_path, data)
        
    @classmethod
    def load_meanstd(cls):
        print ('Load meanstd from %s' % cls.meanstd_path)
        mean, std = load_pickle(cls.meanstd_path)
        return mean, std
    
    @classmethod
    def save_valid_idx(cls, idx):
        save_pickle(cls.valid_data_path, idx)
        
    @classmethod
    def load_valid_idx(cls):
        return load_pickle(cls.valid_data_path)
    
    def _init_mean_std(self, data):
        data = data.astype('float32')
        self.mean, self.std = np.mean(data), np.std(data)
        self.save_meanstd()
        return data
    
    def get_object_existance(self, mask_array):
        return np.array([int(np.sum(mask_array[i, 0]) > 0) for i in xrange(len(mask_array))])

    def standartize(self, array, to_float=False):
        if to_float:
            array = array.astype('float32')
        if self.mean is None or self.std is None:
            raise ValueError, 'No mean/std is initialised'
        
        array -= self.mean
        array /= self.std
        return array

    @classmethod
    def norm_mask(cls, mask_array):
        mask_array = mask_array.astype('float32')
        mask_array /= 255.0
        return mask_array

    @classmethod
    def shuffle_train(cls, data, mask):
        perm = np.random.permutation(len(data))
        data = data[perm]
        mask = mask[perm]
        return data, mask

    @classmethod
    def split_train_and_valid_by_patient(cls, data, mask, validation_split, shuffle=False):
        print('Shuffle & split...')
        patient_nums = load_patient_num()
        patient_dict = count_enum(patient_nums)
        pnum = len(patient_dict)
        val_num = int(pnum * validation_split)
        patients = patient_dict.keys()
        if shuffle:
            random.shuffle(patients)
        val_p, train_p = patients[:val_num], patients[val_num:]
        train_indexes = [i for i, c in enumerate(patient_nums) if c in set(train_p)]
        val_indexes = [i for i, c in enumerate(patient_nums) if c in set(val_p)]
        x_train, y_train = data[train_indexes], mask[train_indexes]
        x_valid, y_valid = data[val_indexes], mask[val_indexes]
        cls.save_valid_idx(val_indexes)
        print ('val patients:', len(x_valid), val_p)
        print ('train patients:', len(x_train), train_p)
        return (x_train, y_train), (x_valid, y_valid)

    @classmethod
    def split_train_and_valid(cls, data, mask, validation_split, shuffle=False):
        print('Shuffle & split...')
        if shuffle:
            data, mask = cls.shuffle_train(data, mask)
        split_at = int(len(data) * (1. - validation_split))
        x_train, x_valid = (slice_X(data, 0, split_at), slice_X(data, split_at))
        y_train, y_valid = (slice_X(mask, 0, split_at), slice_X(mask, split_at))
        cls.save_valid_idx(range(len(data))[split_at:])
        return (x_train, y_train), (x_valid, y_valid)
        
    def test(self, model, batch_size=256):
        print('Loading and pre-processing test data...')
        imgs_test = load_test_data()
        imgs_test = preprocess(imgs_test)
        imgs_test = self.standartize(imgs_test, to_float=True)
    
        print('Loading best saved weights...')
        model.load_weights(self.best_weight_path)
        print('Predicting masks on test data and saving...')
        imgs_mask_test = model.predict(imgs_test, batch_size=batch_size, verbose=1)
        
        np.save(self.test_mask_res, imgs_mask_test[0])
        np.save(self.test_mask_exist_res, imgs_mask_test[1])
        
    def __pretrain_model_load(self, model, pretrained_path):
        if pretrained_path is not None:
            if not os.path.exists(pretrained_path):
                raise ValueError, 'No such pre-trained path exists'
            model.load_weights(pretrained_path)
            
            
    def augmentation(self, X, Y):
        print('Augmentation model...')
        total = len(X)
        x_train, y_train = [], []
        
        for i in xrange(total):
            x, y = X[i], Y[i]
            #standart
            x_train.append(x)
            y_train.append(y)
        
#            for _ in xrange(1):
#                _x, _y = elastic_transform(x[0], y[0], 100, 20)
#                x_train.append(_x.reshape((1,) + _x.shape))
#                y_train.append(_y.reshape((1,) + _y.shape))
            
            #flip x
            x_train.append(flip_axis(x, 2))
            y_train.append(flip_axis(y, 2))
            #flip y
            x_train.append(flip_axis(x, 1))
            y_train.append(flip_axis(y, 1))
            #continue
            #zoom
            for _ in xrange(1):
                _x, _y = random_zoom(x, y, (0.9, 1.1))
                x_train.append(_x)
                y_train.append(_y)
            for _ in xrange(0):
                _x, _y = random_rotation(x, y, 5)
                x_train.append(_x)
                y_train.append(_y)
            #intentsity
            for _ in xrange(1):
                _x = random_channel_shift(x, 5.0)
                x_train.append(_x)
                y_train.append(y)
    
        x_train = np.array(x_train)
        y_train = np.array(y_train)
        return x_train, y_train
        
    def fit(self, x_train, y_train, x_valid, y_valid, pretrained_path):
        print('Creating and compiling and fitting model...')
        print('Shape:', x_train.shape)
        #second output
        y_train_2 = self.get_object_existance(y_train)
        y_valid_2 = self.get_object_existance(y_valid)

        #load model
        optimizer = Adam(lr=0.0045)
        model = self.model_func(optimizer)

        #checkpoints
        model_checkpoint = ModelCheckpoint(self.__iter_res_file, monitor='val_loss')
        model_save_best = ModelCheckpoint(self.best_weight_path, monitor='val_loss', save_best_only=True)
        early_s = EarlyStopping(monitor='val_loss', patience=5, verbose=1)
        learning_rate_adapt = LearningRateDecay(0.9, every_n=2, verbose=1)
        self.__pretrain_model_load(model, pretrained_path)
        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]
                   ) 
        
        #augment
        return model

    def train_and_predict(self, pretrained_path=None, split_random=True):
        self._dir_init()
        print('Loading and preprocessing and standarize train data...')
        imgs_train, imgs_mask_train = load_train_data()
        
        imgs_train = preprocess(imgs_train)

        imgs_mask_train = preprocess(imgs_mask_train)
        
        imgs_mask_train = self.norm_mask(imgs_mask_train)

        split_func = split_random and self.split_train_and_valid or self.split_train_and_valid_by_patient
        (x_train, y_train), (x_valid, y_valid) = split_func(imgs_train, imgs_mask_train,
                                                        validation_split=self.validation_split)
        self._init_mean_std(x_train)
        x_train = self.standartize(x_train, True)
        x_valid = self.standartize(x_valid, True)
        #augmentation
        x_train, y_train = self.augmentation(x_train, y_train)
        #fit
        model = self.fit(x_train, y_train, x_valid, y_valid, pretrained_path)
        #test
        self.test(model)


def main():
    parser = OptionParser()
    parser.add_option("-s", "--split_random", action='store', type='int', dest='split_random', default = 1)
    parser.add_option("-m", "--model_name", action='store', type='str', dest='model_name', default = 'u_model')
    #
    options, _ = parser.parse_args()
    split_random = options.split_random
    model_name = options.model_name
    if model_name is None:
        raise ValueError, 'model_name is not defined'
    #
    import imp
    model_ = imp.load_source('model_', model_name + '.py')
    model_func = model_.get_unet
    #
    lr = Learner(model_func, validation_split=0.2)
    lr.train_and_predict(pretrained_path=None, split_random=split_random)
    print ('Results in ', lr.res_dir)

if __name__ == '__main__':
    sys.exit(main())


================================================
FILE: train_generator.py
================================================
from __future__ import print_function
from optparse import OptionParser
import cv2, sys, os, shutil, random
import numpy as np
from keras.optimizers import Adam, SGD, RMSprop
from keras.callbacks import ModelCheckpoint, EarlyStopping
from keras.preprocessing.image import flip_axis, random_channel_shift
from keras.engine.training import slice_X
from keras_plus import LearningRateDecay
from u_model import get_unet, IMG_COLS as img_cols, IMG_ROWS as img_rows
from data import load_train_data, load_test_data, load_patient_num
from augmentation import CustomImageDataGenerator
from augmentation import random_zoom, elastic_transform, load_aug
from utils import save_pickle, load_pickle, count_enum

_dir = os.path.join(os.path.realpath(os.path.dirname(__file__)), '')



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

class Learner(object):
    
    suffix = ''
    res_dir = os.path.join(_dir, 'res' + suffix)
    best_weight_path = os.path.join(res_dir, 'unet.hdf5')
    test_mask_res = os.path.join(res_dir, 'imgs_mask_test.npy')
    test_mask_exist_res = os.path.join(res_dir, 'imgs_mask_exist_test.npy')
    meanstd_path = os.path.join(res_dir, 'meanstd.dump')
    valid_data_path = os.path.join(res_dir, 'valid.npy')
    tensorboard_dir = os.path.join(res_dir, 'tb')
    
    def __init__(self, model_func, validation_split):
        self.model_func = model_func
        self.validation_split = validation_split
        self.__iter_res_dir = os.path.join(self.res_dir, 'res_iter')
        self.__iter_res_file = os.path.join(self.__iter_res_dir, '{epoch:02d}-{val_loss:.4f}.unet.hdf5')
        
    def _dir_init(self):
        if not os.path.exists(self.res_dir):
            os.mkdir(self.res_dir)
        #iter clean
        if os.path.exists(self.__iter_res_dir):
            shutil.rmtree(self.__iter_res_dir)
        os.mkdir(self.__iter_res_dir)
    
    def save_meanstd(self):
        data = [self.mean, self.std]
        save_pickle(self.meanstd_path, data)
        
    @classmethod
    def load_meanstd(cls):
        print ('Load meanstd from %s' % cls.meanstd_path)
        mean, std = load_pickle(cls.meanstd_path)
        return mean, std
    
    @classmethod
    def save_valid_idx(cls, idx):
        save_pickle(cls.valid_data_path, idx)
        
    @classmethod
    def load_valid_idx(cls):
        return load_pickle(cls.valid_data_path)
    
    def _init_mean_std(self, data):
        data = data.astype('float32')
        self.mean, self.std = np.mean(data), np.std(data)
        self.save_meanstd()
        return data
    
    def get_object_existance(self, mask_array):
        return np.array([int(np.sum(mask_array[i, 0]) > 0) for i in xrange(len(mask_array))])

    def standartize(self, array, to_float=False):
        if to_float:
            array = array.astype('float32')
        if self.mean is None or self.std is None:
            raise ValueError, 'No mean/std is initialised'
        
        array -= self.mean
        array /= self.std
        return array

    @classmethod
    def norm_mask(cls, mask_array):
        mask_array = mask_array.astype('float32')
        mask_array /= 255.0
        return mask_array

    @classmethod
    def shuffle_train(cls, data, mask):
        perm = np.random.permutation(len(data))
        data = data[perm]
        mask = mask[perm]
        return data, mask

    @classmethod
    def split_train_and_valid_by_patient(cls, data, mask, validation_split, shuffle=False):
        print('Shuffle & split...')
        patient_nums = load_patient_num()
        patient_dict = count_enum(patient_nums)
        pnum = len(patient_dict)
        val_num = int(pnum * validation_split)
        patients = patient_dict.keys()
        if shuffle:
            random.shuffle(patients)
        val_p, train_p = patients[:val_num], patients[val_num:]
        train_indexes = [i for i, c in enumerate(patient_nums) if c in set(train_p)]
        val_indexes = [i for i, c in enumerate(patient_nums) if c in set(val_p)]
        x_train, y_train = data[train_indexes], mask[train_indexes]
        x_valid, y_valid = data[val_indexes], mask[val_indexes]
        cls.save_valid_idx(val_indexes)
        print ('val patients:', len(x_valid), val_p)
        print ('train patients:', len(x_train), train_p)
        return (x_train, y_train), (x_valid, y_valid)

    @classmethod
    def split_train_and_valid(cls, data, mask, validation_split, shuffle=False):
        print('Shuffle & split...')
        if shuffle:
            data, mask = cls.shuffle_train(data, mask)
        split_at = int(len(data) * (1. - validation_split))
        x_train, x_valid = (slice_X(data, 0, split_at), slice_X(data, split_at))
        y_train, y_valid = (slice_X(mask, 0, split_at), slice_X(mask, split_at))
        cls.save_valid_idx(range(len(data))[split_at:])
        return (x_train, y_train), (x_valid, y_valid)
        
    def test(self, model, batch_size=256):
        print('Loading and pre-processing test data...')
        imgs_test = load_test_data()
        imgs_test = preprocess(imgs_test)
        imgs_test = self.standartize(imgs_test, to_float=True)
    
        print('Loading best saved weights...')
        model.load_weights(self.best_weight_path)
        print('Predicting masks on test data and saving...')
        imgs_mask_test = model.predict(imgs_test, batch_size=batch_size, verbose=1)
        
        np.save(self.test_mask_res, imgs_mask_test[0])
        np.save(self.test_mask_exist_res, imgs_mask_test[1])
        
    def __pretrain_model_load(self, model, pretrained_path):
        if pretrained_path is not None:
            if not os.path.exists(pretrained_path):
                raise ValueError, 'No such pre-trained path exists'
            model.load_weights(pretrained_path)
            
            
    def augmentation(self, X, Y):
        print('Augmentation model...')
        total = len(X)
        x_train, y_train = [], []
        
        for i in xrange(total):
            if i % 100 == 0:
                print ('Aug', i)
            x, y = X[i], Y[i]
            #standart
            x_train.append(x)
            y_train.append(y)
        
            for _ in xrange(2):
                _x, _y = elastic_transform(x[0], y[0], 100, 20)
                x_train.append(_x.reshape((1,) + _x.shape))
                y_train.append(_y.reshape((1,) + _y.shape))
            
            #flip x
            x_train.append(flip_axis(x, 2))
            y_train.append(flip_axis(y, 2))
            #flip y
            x_train.append(flip_axis(x, 1))
            y_train.append(flip_axis(y, 1))
            continue
            #zoom
            for _ in xrange(1):
                _x, _y = random_zoom(x, y, (0.9, 1.1))
                x_train.append(_x)
                y_train.append(_y)
            #intentsity
            for _ in xrange(1):
                _x = random_channel_shift(x, 5.0)
                x_train.append(_x)
                y_train.append(y)
                
#        for j in xrange(5):
#            xs, ys = load_aug(j)
#            ys = self.norm_mask(ys)
#            (xn, yn), _ = self.split_train_and_valid_by_patient(xs, ys, validation_split=self.validation_split, shuffle=False)
#            for i in xrange(len(xn)):
#                x_train.append(xn[i])
#                y_train.append(yn[i])
    
        x_train = np.array(x_train)
        y_train = np.array(y_train)
        return x_train, y_train
        
    def fit(self, x_train, y_train, x_valid, y_valid, pretrained_path):
        print('Creating and compiling and fitting model...')
        print('Shape:', x_train.shape)
        #second output
        y_train_2 = self.get_object_existance(y_train)
        y_valid_2 = self.get_object_existance(y_valid)

        #load model
        optimizer = Adam(lr=0.0045)
        #model = get_unet(optimizer)
        model = self.model_func(optimizer)

        #checkpoints
        model_checkpoint = ModelCheckpoint(self.__iter_res_file, monitor='val_loss')
        model_save_best = ModelCheckpoint(self.best_weight_path, monitor='val_loss', save_best_only=True)
        early_s = EarlyStopping(monitor='val_loss', patience=10, verbose=1)
        #tb = TensorBoard(self.tensorboard_dir, histogram_freq=2, write_graph=True)
        #learning_rate_adapt = AdvancedLearnignRateScheduler(monitor='val_loss', patience=1, verbose=1, mode='min', decayRatio=0.5)
        learning_rate_adapt = LearningRateDecay(0.95, every_n=4, verbose=1)
        self.__pretrain_model_load(model, pretrained_path)
        #augment
        datagen = CustomImageDataGenerator(zoom_range=(0.9,1.1),
                                           horizontal_flip=True,
                                           vertical_flip=False, 
#                                           rotation_range=5,
                                           channel_shift_range=5.0,
                                           elastic=None #(100, 20)
                                           )
#        #fit
        model.fit_generator(datagen.flow(x_train, [y_train, y_train_2], batch_size=64),
                            samples_per_epoch=len(x_train),
                            nb_epoch=250,
                            verbose=1,
                            callbacks=[model_save_best, model_checkpoint, early_s, learning_rate_adapt],
                            validation_data=(x_valid, [y_valid, y_valid_2])
                            )
        return model

    def train_and_predict(self, pretrained_path=None, split_random=True):
        self._dir_init()
        print('Loading and preprocessing and standarize train data...')
        imgs_train, imgs_mask_train = load_train_data()
        
        imgs_train = preprocess(imgs_train)

        imgs_mask_train = preprocess(imgs_mask_train)
        
        imgs_mask_train = self.norm_mask(imgs_mask_train)
        #imgs_train = self.norm_mask(imgs_train) /255
        #shuffle and split
        split_func = split_random and self.split_train_and_valid or self.split_train_and_valid_by_patient
        (x_train, y_train), (x_valid, y_valid) = split_func(imgs_train, imgs_mask_train,
                                                        validation_split=self.validation_split)
        self._init_mean_std(x_train)
        x_train = self.standartize(x_train, True)
        x_valid = self.standartize(x_valid, True)
        #fit
        model = self.fit(x_train, y_train, x_valid, y_valid, pretrained_path)
        #test
        self.test(model)


def main():
    parser = OptionParser()
    parser.add_option("-m", "--model_name", action='store', type='str', dest='model_name', default = 'u_model')
    parser.add_option("-s", "--split_random", action='store', type='int', dest='split_random', default = 1)
    #
    options, _ = parser.parse_args()
    model_name = options.model_name
    split_random = options.split_random
    if model_name is None:
        raise ValueError, 'model_name is not defined'
    #
    import imp
    model_ = imp.load_source('model_', model_name + '.py')
    model_func = model_.get_unet
    #
    lr = Learner(model_func, validation_split=0.2)
    lr.train_and_predict(pretrained_path=None, split_random=split_random)
    print ('Results in ', lr.res_dir)

if __name__ == '__main__':
    sys.exit(main())


================================================
FILE: train_kfold.py
================================================
from optparse import OptionParser
import cv2, sys, os, shutil, random
import numpy as np
from keras.optimizers import Adam, SGD, RMSprop
from keras.callbacks import ModelCheckpoint, EarlyStopping
from keras.preprocessing.image import flip_axis, random_channel_shift
from keras.engine.training import slice_X
from keras_plus import LearningRateDecay
from u_model import get_unet, IMG_COLS as img_cols, IMG_ROWS as img_rows
from data import load_train_data, load_test_data, load_patient_num
from augmentation import CustomImageDataGenerator
from augmentation import random_zoom, elastic_transform, random_rotation
from utils import save_pickle, load_pickle, count_enum
from sklearn.cross_validation import KFold

_dir = os.path.join(os.path.realpath(os.path.dirname(__file__)), '')



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

class Learner(object):
    
    suffix = ''
    res_dir = os.path.join(_dir, 'res' + suffix)
    best_weight_path = os.path.join(res_dir, 'unet.hdf5')
    test_mask_res = os.path.join(res_dir, 'imgs_mask_test.npy')
    test_mask_exist_res = os.path.join(res_dir, 'imgs_mask_exist_test.npy')
    meanstd_path = os.path.join(res_dir, 'meanstd.dump')
    valid_data_path = os.path.join(res_dir, 'valid.npy')
    tensorboard_dir = os.path.join(res_dir, 'tb')
    
    def __init__(self, model_func, validation_split):
        self.model_func = model_func
        self.validation_split = validation_split
        self.__iter_res_dir = os.path.join(self.res_dir, 'res_iter')
        self.__iter_res_file = os.path.join(self.__iter_res_dir, '{epoch:02d}-{val_loss:.4f}.unet.hdf5')
        
    def _dir_init(self):
        if not os.path.exists(self.res_dir):
            os.mkdir(self.res_dir)
        #iter clean
        if os.path.exists(self.__iter_res_dir):
            shutil.rmtree(self.__iter_res_dir)
        os.mkdir(self.__iter_res_dir)
    
    def save_meanstd(self):
        data = [self.mean, self.std]
        save_pickle(self.meanstd_path, data)
        
    @classmethod
    def load_meanstd(cls):
        print ('Load meanstd from %s' % cls.meanstd_path)
        mean, std = load_pickle(cls.meanstd_path)
        return mean, std
    
    @classmethod
    def save_valid_idx(cls, idx):
        save_pickle(cls.valid_data_path, idx)
        
    @classmethod
    def load_valid_idx(cls):
        return load_pickle(cls.valid_data_path)
    
    def _init_mean_std(self, data):
        data = data.astype('float32')
        self.mean, self.std = np.mean(data), np.std(data)
        self.save_meanstd()
        return data
    
    def get_object_existance(self, mask_array):
        return np.array([int(np.sum(mask_array[i, 0]) > 0) for i in xrange(len(mask_array))])

    def standartize(self, array, to_float=False):
        if to_float:
            array = array.astype('float32')
        if self.mean is None or self.std is None:
            raise ValueError, 'No mean/std is initialised'
        
        array -= self.mean
        array /= self.std
        return array

    @classmethod
    def norm_mask(cls, mask_array):
        mask_array = mask_array.astype('float32')
        mask_array /= 255.0
        return mask_array

    @classmethod
    def shuffle_train(cls, data, mask):
        perm = np.random.permutation(len(data))
        data = data[perm]
        mask = mask[perm]
        return data, mask
        
    def __pretrain_model_load(self, model, pretrained_path):
        if pretrained_path is not None:
            if not os.path.exists(pretrained_path):
                raise ValueError, 'No such pre-trained path exists'
            model.load_weights(pretrained_path)
            
            
    def augmentation(self, X, Y):
        print('Augmentation model...')
        total = len(X)
        x_train, y_train = [], []
        
        for i in xrange(total):
            if i % 100 == 0:
                print ('Aug', i)
            x, y = X[i], Y[i]
            #standart
            x_train.append(x)
            y_train.append(y)
        
#            for _ in xrange(1):
#                _x, _y = elastic_transform(x[0], y[0], 100, 20)
#                x_train.append(_x.reshape((1,) + _x.shape))
#                y_train.append(_y.reshape((1,) + _y.shape))
            
            #flip x
            x_train.append(flip_axis(x, 2))
            y_train.append(flip_axis(y, 2))
            #flip y
            x_train.append(flip_axis(x, 1))
            y_train.append(flip_axis(y, 1))
            #continue
            #zoom
            for _ in xrange(1):
                _x, _y = random_zoom(x, y, (0.9, 1.1))
                x_train.append(_x)
                y_train.append(_y)
            for _ in xrange(0):
                _x, _y = random_rotation(x, y, 5)
                x_train.append(_x)
                y_train.append(_y)
            #intentsity
            for _ in xrange(1):
                _x = random_channel_shift(x, 5.0)
                x_train.append(_x)
                y_train.append(y)
    
        x_train = np.array(x_train)
        y_train = np.array(y_train)
        return x_train, y_train
        
    def fit(self, x_train, y_train, nfolds=8):
        print('Creating and compiling and fitting model...')
        print('Shape:', x_train.shape)
        random_state = 51
        kf = KFold(len(x_train), n_folds=nfolds, shuffle=True, random_state=random_state)
        for i, (train_index, test_index) in enumerate(kf):
            print 'Fold %d' % i
            X_train, X_valid = x_train[train_index], x_train[test_index]
            Y_train, Y_valid = y_train[train_index], y_train[test_index]
            Y_valid_2 = self.get_object_existance(Y_valid)
            X_train, Y_train = self.augmentation(X_train, Y_train)
            Y_train_2 = self.get_object_existance(Y_train)
            #
            optimizer = Adam(lr=0.0045)
            model = self.model_func(optimizer)
            model_checkpoint = ModelCheckpoint(self.__iter_res_file + '_%d.fold' % i, monitor='val_loss')
            model_save_best = ModelCheckpoint(self.best_weight_path + '_%d.fold' % i, monitor='val_loss',
                                               save_best_only=True)
            early_s = EarlyStopping(monitor='val_loss', patience=8, verbose=1)
            #
            model.fit(
                       X_train, [Y_train, Y_train_2], 
                       validation_data=(X_valid, [Y_valid, Y_valid_2]),
                       batch_size=128, nb_epoch=40,
                       verbose=1, shuffle=True,
                       callbacks=[model_save_best, model_checkpoint, early_s]
                       ) 
        
        #augment
        return model

    def train_and_predict(self, pretrained_path=None):
        self._dir_init()
        print('Loading and preprocessing and standarize train data...')
        imgs_train, imgs_mask_train = load_train_data()
        imgs_train = preprocess(imgs_train)
        imgs_mask_train = preprocess(imgs_mask_train)
        imgs_mask_train = self.norm_mask(imgs_mask_train)
        
        self._init_mean_std(imgs_train)
        imgs_train = self.standartize(imgs_train, True)
        self.fit(imgs_train, imgs_mask_train)


def main():
    parser = OptionParser()
    parser.add_option("-s", "--suffix", action='store', type='str', dest='suffix', default = None)
    parser.add_option("-m", "--model_name", action='store', type='str', dest='model_name', default = 'u_model')
    #
    options, _ = parser.parse_args()
    suffix = options.suffix
    model_name = options.model_name
    if model_name is None:
        raise ValueError, 'model_name is not defined'
#    if suffix is None:
#        raise ValueError, 'Please specify suffix option'
#    print ('Suffix: "%s"' % suffix )
    #
    import imp
    model_ = imp.load_source('model_', model_name + '.py')
    model_func = model_.get_unet
    #
    lr = Learner(model_func, validation_split=0.2)
    lr.train_and_predict(pretrained_path=None)
    print ('Results in ', lr.res_dir)

if __name__ == '__main__':
    sys.exit(main())


================================================
FILE: u_model.py
================================================
import sys
from keras.models import Model
from keras.layers import Input, merge, Convolution2D, MaxPooling2D, UpSampling2D, Dense
from keras.layers import BatchNormalization, Dropout, Flatten, Lambda
from keras.layers.advanced_activations import ELU, LeakyReLU
from metric import dice_coef, dice_coef_loss

IMG_ROWS, IMG_COLS = 80, 112 

def _shortcut(_input, residual):
    stride_width = _input._keras_shape[2] / residual._keras_shape[2]
    stride_height = _input._keras_shape[3] / residual._keras_shape[3]
    equal_channels = residual._keras_shape[1] == _input._keras_shape[1]

    shortcut = _input
    # 1 X 1 conv if shape is different. Else identity.
    if stride_width > 1 or stride_height > 1 or not equal_channels:
        shortcut = Convolution2D(nb_filter=residual._keras_shape[1], nb_row=1, nb_col=1,
                                 subsample=(stride_width, stride_height),
                                 init="he_normal", border_mode="valid")(_input)

    return merge([shortcut, residual], mode="sum")


def inception_block(inputs, depth, batch_mode=0, splitted=False, activation='relu'):
    assert depth % 16 == 0
    actv = activation == 'relu' and (lambda: LeakyReLU(0.0)) or activation == 'elu' and (lambda: ELU(1.0)) or None
    
    c1_1 = Convolution2D(depth/4, 1, 1, init='he_normal', border_mode='same')(inputs)
    
    c2_1 = Convolution2D(depth/8*3, 1, 1, init='he_normal', border_mode='same')(inputs)
    c2_1 = actv()(c2_1)
    if splitted:
        c2_2 = Convolution2D(depth/2, 1, 3, init='he_normal', border_mode='same')(c2_1)
        c2_2 = BatchNormalization(mode=batch_mode, axis=1)(c2_2)
        c2_2 = actv()(c2_2)
        c2_3 = Convolution2D(depth/2, 3, 1, init='he_normal', border_mode='same')(c2_2)
    else:
        c2_3 = Convolution2D(depth/2, 3, 3, init='he_normal', border_mode='same')(c2_1)
    
    c3_1 = Convolution2D(depth/16, 1, 1, init='he_normal', border_mode='same')(inputs)
    #missed batch norm
    c3_1 = actv()(c3_1)
    if splitted:
        c3_2 = Convolution2D(depth/8, 1, 5, init='he_normal', border_mode='same')(c3_1)
        c3_2 = BatchNormalization(mode=batch_mode, axis=1)(c3_2)
        c3_2 = actv()(c3_2)
        c3_3 = Convolution2D(depth/8, 5, 1, init='he_normal', border_mode='same')(c3_2)
    else:
        c3_3 = Convolution2D(depth/8, 5, 5, init='he_normal', border_mode='same')(c3_1)
    
    p4_1 = MaxPooling2D(pool_size=(3,3), strides=(1,1), border_mode='same')(inputs)
    c4_2 = Convolution2D(depth/8, 1, 1, init='he_normal', border_mode='same')(p4_1)
    
    res = merge([c1_1, c2_3, c3_3, c4_2], mode='concat', concat_axis=1)
    res = BatchNormalization(mode=batch_mode, axis=1)(res)
    res = actv()(res)
    return res
    

def rblock(inputs, num, depth, scale=0.1):    
    residual = Convolution2D(depth, num, num, border_mode='same')(inputs)
    residual = BatchNormalization(mode=2, axis=1)(residual)
    residual = Lambda(lambda x: x*scale)(residual)
    res = _shortcut(inputs, residual)
    return ELU()(res) 
    

def NConvolution2D(nb_filter, nb_row, nb_col, border_mode='same', subsample=(1, 1)):
    def f(_input):
        conv = Convolution2D(nb_filter=nb_filter, nb_row=nb_row, nb_col=nb_col, subsample=subsample,
                              border_mode=border_mode)(_input)
        norm = BatchNormalization(mode=2, axis=1)(conv)
        return ELU()(norm)

    return f

def BNA(_input):
    inputs_norm = BatchNormalization(mode=2, axis=1)(_input)
    return ELU()(inputs_norm)

def reduction_a(inputs, k=64, l=64, m=96, n=96):
    "35x35 -> 17x17"
    inputs_norm = BNA(inputs)
    pool1 = MaxPooling2D((3,3), strides=(2,2), border_mode='same')(inputs_norm)
    
    conv2 = Convolution2D(n, 3, 3, subsample=(2,2), border_mode='same')(inputs_norm)
    
    conv3_1 = NConvolution2D(k, 1, 1, subsample=(1,1), border_mode='same')(inputs_norm)
    conv3_2 = NConvolution2D(l, 3, 3, subsample=(1,1), border_mode='same')(conv3_1)
    conv3_2 = Convolution2D(m, 3, 3, subsample=(2,2), border_mode='same')(conv3_2)
    
    res = merge([pool1, conv2, conv3_2], mode='concat', concat_axis=1)
    return res


def reduction_b(inputs):
    "17x17 -> 8x8"
    inputs_norm = BNA(inputs)
    pool1 = MaxPooling2D((3,3), strides=(2,2), border_mode='same')(inputs_norm)
    #
    conv2_1 = NConvolution2D(64, 1, 1, subsample=(1,1), border_mode='same')(inputs_norm)
    conv2_2 = Convolution2D(96, 3, 3, subsample=(2,2), border_mode='same')(conv2_1)
    #
    conv3_1 = NConvolution2D(64, 1, 1, subsample=(1,1), border_mode='same')(inputs_norm)
    conv3_2 = Convolution2D(72, 3, 3, subsample=(2,2), border_mode='same')(conv3_1)
    #
    conv4_1 = NConvolution2D(64, 1, 1, subsample=(1,1), border_mode='same')(inputs_norm)
    conv4_2 = NConvolution2D(72, 3, 3, subsample=(1,1), border_mode='same')(conv4_1)
    conv4_3 = Convolution2D(80, 3, 3, subsample=(2,2), border_mode='same')(conv4_2)
    #
    res = merge([pool1, conv2_2, conv3_2, conv4_3], mode='concat', concat_axis=1)
    return res
    
    


def get_unet_inception_2head(optimizer):
    splitted = True
    act = 'elu'
    
    inputs = Input((1, IMG_ROWS, IMG_COLS), name='main_input')
    conv1 = inception_block(inputs, 32, batch_mode=2, splitted=splitted, activation=act)
    #conv1 = inception_block(conv1, 32, batch_mode=2, splitted=splitted, activation=act)
    
    #pool1 = MaxPooling2D(pool_size=(2, 2))(conv1)
    pool1 = NConvolution2D(32, 3, 3, border_mode='same', subsample=(2,2))(conv1)
    pool1 = Dropout(0.5)(pool1)
    
    conv2 = inception_block(pool1, 64, batch_mode=2, splitted=splitted, activation=act)
    #pool2 = MaxPooling2D(pool_size=(2, 2))(conv2)
    pool2 = NConvolution2D(64, 3, 3, border_mode='same', subsample=(2,2))(conv2)
    pool2 = Dropout(0.5)(pool2)
    
    conv3 = inception_block(pool2, 128, batch_mode=2, splitted=splitted, activation=act)
    #pool3 = MaxPooling2D(pool_size=(2, 2))(conv3)
    pool3 = NConvolution2D(128, 3, 3, border_mode='same', subsample=(2,2))(conv3)
    pool3 = Dropout(0.5)(pool3)
     
    conv4 = inception_block(pool3, 256, batch_mode=2, splitted=splitted, activation=act)
    #pool4 = MaxPooling2D(pool_size=(2, 2))(conv4)
    pool4 = NConvolution2D(256, 3, 3, border_mode='same', subsample=(2,2))(conv4)
    pool4 = Dropout(0.5)(pool4)
    
    conv5 = inception_block(pool4, 512, batch_mode=2, splitted=splitted, activation=act)
    #conv5 = inception_block(conv5, 512, batch_mode=2, splitted=splitted, activation=act)
    conv5 = Dropout(0.5)(conv5)
    
    #
    pre = Convolution2D(1, 1, 1, init='he_normal', activation='sigmoid')(conv5)
    pre = Flatten()(pre)
    aux_out = Dense(1, activation='sigmoid', name='aux_output')(pre) 
    #
    
    after_conv4 = rblock(conv4, 1, 256)
    up6 = merge([UpSampling2D(size=(2, 2))(conv5), after_conv4], mode='concat', concat_axis=1)
    conv6 = inception_block(up6, 256, batch_mode=2, splitted=splitted, activation=act)
    conv6 = Dropout(0.5)(conv6)
    
    after_conv3 = rblock(conv3, 1, 128)
    up7 = merge([UpSampling2D(size=(2, 2))(conv6), after_conv3], mode='concat', concat_axis=1)
    conv7 = inception_block(up7, 128, batch_mode=2, splitted=splitted, activation=act)
    conv7 = Dropout(0.5)(conv7)
    
    after_conv2 = rblock(conv2, 1, 64)
    up8 = merge([UpSampling2D(size=(2, 2))(conv7), after_conv2], mode='concat', concat_axis=1)
    conv8 = inception_block(up8, 64, batch_mode=2, splitted=splitted, activation=act)
    conv8 = Dropout(0.5)(conv8)
    
    after_conv1 = rblock(conv1, 1, 32)
    up9 = merge([UpSampling2D(size=(2, 2))(conv8), after_conv1], mode='concat', concat_axis=1)
    conv9 = inception_block(up9, 32, batch_mode=2, splitted=splitted, activation=act)
    #conv9 = inception_block(conv9, 32, batch_mode=2, splitted=splitted, activation=act)
    conv9 = Dropout(0.5)(conv9)

    conv10 = Convolution2D(1, 1, 1, init='he_normal', activation='sigmoid', name='main_output')(conv9)
    #print conv10._keras_shape

    model = Model(input=inputs, output=[conv10, aux_out])
    model.compile(optimizer=optimizer,
                  loss={'main_output': dice_coef_loss, 'aux_output': 'binary_crossentropy'},
                  metrics={'main_output': dice_coef, 'aux_output': 'acc'},
                  loss_weights={'main_output': 1., 'aux_output': 0.5})

    return model


get_unet = get_unet_inception_2head

def main():
    from keras.optimizers import Adam, RMSprop, SGD
    from metric import dice_coef, dice_coef_loss
    import numpy as np
    img_rows = IMG_ROWS
    img_cols = IMG_COLS
    
    optimizer = RMSprop(lr=0.045, rho=0.9, epsilon=1.0)
    model = get_unet(Adam(lr=1e-5))
    model.compile(optimizer=optimizer, loss=dice_coef_loss, metrics=[dice_coef])
    
    x = np.random.random((1, 1,img_rows,img_cols))
    res = model.predict(x, 1)
    print res
    #print 'res', res[0].shape
    print 'params', model.count_params()
    print 'layer num', len(model.layers)
    #


if __name__ == '__main__':
    sys.exit(main())



================================================
FILE: utils.py
================================================
import cPickle as pickle

def load_pickle(file_path):
    data = None
    with open (file_path,"rb") as dumpFile:
        data = pickle.load(dumpFile)
    return data

def save_pickle(file_path, data):
    with open (file_path,"wb") as dumpFile:
        pickle.dump(data, dumpFile, pickle.HIGHEST_PROTOCOL)

def count_enum(words):
    wdict = {}
    get = wdict.get
    for word in words:
        wdict[word] = get(word, 0) + 1
    return wdict
Download .txt
gitextract_l79q2ook/

├── README.md
├── __init__.py
├── augmentation.py
├── average_ensembles.py
├── current.py
├── current_ensemble.py
├── data.py
├── keras_plus.py
├── metric.py
├── submission.py
├── train.py
├── train_generator.py
├── train_kfold.py
├── u_model.py
└── utils.py
Download .txt
SYMBOL INDEX (114 symbols across 13 files)

FILE: augmentation.py
  function random_zoom (line 16) | def random_zoom(x, y, zoom_range, row_index=1, col_index=2, channel_inde...
  function random_rotation (line 37) | def random_rotation(x, y, rg, row_index=1, col_index=2, channel_index=0,
  function random_shear (line 51) | def random_shear(x, y, intensity, row_index=1, col_index=2, channel_inde...
  class CustomNumpyArrayIterator (line 65) | class CustomNumpyArrayIterator(Iterator):
    method __init__ (line 67) | def __init__(self, X, y, image_data_generator,
    method next (line 77) | def next(self):
  class CustomImageDataGenerator (line 93) | class CustomImageDataGenerator(object):
    method __init__ (line 94) | def __init__(self, zoom_range=(1,1), channel_shift_range=0, horizontal...
    method random_transform (line 111) | def random_transform(self, x, y, row_index=1, col_index=2, channel_ind...
    method flow (line 183) | def flow(self, X, Y, batch_size, shuffle=True, seed=None):
  function elastic_transform (line 189) | def elastic_transform(image, mask, alpha, sigma, alpha_affine=None, rand...
  function test (line 215) | def test():

FILE: average_ensembles.py
  function main (line 16) | def main():

FILE: current.py
  function zoom (line 17) | def zoom(x, zoom_range, row_index=1, col_index=2, channel_index=0,
  function run_test (line 39) | def run_test():
  function main (line 91) | def main():

FILE: current_ensemble.py
  function zoom (line 17) | def zoom(x, zoom_range, row_index=1, col_index=2, channel_index=0,
  function run_test (line 39) | def run_test():
  function main (line 115) | def main():

FILE: data.py
  function load_test_data (line 20) | def load_test_data():
  function load_test_ids (line 25) | def load_test_ids():
  function load_train_data (line 30) | def load_train_data():
  function load_patient_num (line 36) | def load_patient_num():
  function get_patient_nums (line 40) | def get_patient_nums(string):
  function create_train_data (line 45) | def create_train_data():
  function create_test_data (line 76) | def create_test_data():
  function main (line 103) | def main():

FILE: keras_plus.py
  class AdvancedLearnignRateScheduler (line 8) | class AdvancedLearnignRateScheduler(Callback):
    method __init__ (line 21) | def __init__(self, monitor='val_loss', patience=0,
    method on_epoch_end (line 51) | def on_epoch_end(self, epoch, logs={}):
  class LearningRateDecay (line 79) | class LearningRateDecay(Callback):
    method __init__ (line 87) | def __init__(self, decay, every_n=1, verbose=0):
    method on_epoch_end (line 93) | def on_epoch_end(self, epoch, logs={}):

FILE: metric.py
  function mean_length_error (line 7) | def mean_length_error(y_true, y_pred):
  function dice_coef (line 13) | def dice_coef(y_true, y_pred):
  function dice_coef_loss (line 19) | def dice_coef_loss(y_true, y_pred):
  function np_dice_coef (line 22) | def np_dice_coef(y_true, y_pred):
  function main (line 28) | def main():

FILE: submission.py
  function prep (line 9) | def prep(img):
  function run_length_enc (line 15) | def run_length_enc(label):
  function submission (line 30) | def submission():
  function main (line 70) | def main():

FILE: train.py
  function preprocess (line 18) | def preprocess(imgs, to_rows=None, to_cols=None):
  class Learner (line 28) | class Learner(object):
    method __init__ (line 39) | def __init__(self, model_func, validation_split):
    method _dir_init (line 45) | def _dir_init(self):
    method save_meanstd (line 53) | def save_meanstd(self):
    method load_meanstd (line 58) | def load_meanstd(cls):
    method save_valid_idx (line 64) | def save_valid_idx(cls, idx):
    method load_valid_idx (line 68) | def load_valid_idx(cls):
    method _init_mean_std (line 71) | def _init_mean_std(self, data):
    method get_object_existance (line 77) | def get_object_existance(self, mask_array):
    method standartize (line 80) | def standartize(self, array, to_float=False):
    method norm_mask (line 91) | def norm_mask(cls, mask_array):
    method shuffle_train (line 97) | def shuffle_train(cls, data, mask):
    method split_train_and_valid_by_patient (line 104) | def split_train_and_valid_by_patient(cls, data, mask, validation_split...
    method split_train_and_valid (line 124) | def split_train_and_valid(cls, data, mask, validation_split, shuffle=F...
    method test (line 134) | def test(self, model, batch_size=256):
    method __pretrain_model_load (line 148) | def __pretrain_model_load(self, model, pretrained_path):
    method augmentation (line 155) | def augmentation(self, X, Y):
    method fit (line 197) | def fit(self, x_train, y_train, x_valid, y_valid, pretrained_path):
    method train_and_predict (line 225) | def train_and_predict(self, pretrained_path=None, split_random=True):
  function main (line 250) | def main():

FILE: train_generator.py
  function preprocess (line 20) | def preprocess(imgs, to_rows=None, to_cols=None):
  class Learner (line 29) | class Learner(object):
    method __init__ (line 40) | def __init__(self, model_func, validation_split):
    method _dir_init (line 46) | def _dir_init(self):
    method save_meanstd (line 54) | def save_meanstd(self):
    method load_meanstd (line 59) | def load_meanstd(cls):
    method save_valid_idx (line 65) | def save_valid_idx(cls, idx):
    method load_valid_idx (line 69) | def load_valid_idx(cls):
    method _init_mean_std (line 72) | def _init_mean_std(self, data):
    method get_object_existance (line 78) | def get_object_existance(self, mask_array):
    method standartize (line 81) | def standartize(self, array, to_float=False):
    method norm_mask (line 92) | def norm_mask(cls, mask_array):
    method shuffle_train (line 98) | def shuffle_train(cls, data, mask):
    method split_train_and_valid_by_patient (line 105) | def split_train_and_valid_by_patient(cls, data, mask, validation_split...
    method split_train_and_valid (line 125) | def split_train_and_valid(cls, data, mask, validation_split, shuffle=F...
    method test (line 135) | def test(self, model, batch_size=256):
    method __pretrain_model_load (line 149) | def __pretrain_model_load(self, model, pretrained_path):
    method augmentation (line 156) | def augmentation(self, X, Y):
    method fit (line 204) | def fit(self, x_train, y_train, x_valid, y_valid, pretrained_path):
    method train_and_predict (line 242) | def train_and_predict(self, pretrained_path=None, split_random=True):
  function main (line 266) | def main():

FILE: train_kfold.py
  function preprocess (line 20) | def preprocess(imgs, to_rows=None, to_cols=None):
  class Learner (line 29) | class Learner(object):
    method __init__ (line 40) | def __init__(self, model_func, validation_split):
    method _dir_init (line 46) | def _dir_init(self):
    method save_meanstd (line 54) | def save_meanstd(self):
    method load_meanstd (line 59) | def load_meanstd(cls):
    method save_valid_idx (line 65) | def save_valid_idx(cls, idx):
    method load_valid_idx (line 69) | def load_valid_idx(cls):
    method _init_mean_std (line 72) | def _init_mean_std(self, data):
    method get_object_existance (line 78) | def get_object_existance(self, mask_array):
    method standartize (line 81) | def standartize(self, array, to_float=False):
    method norm_mask (line 92) | def norm_mask(cls, mask_array):
    method shuffle_train (line 98) | def shuffle_train(cls, data, mask):
    method __pretrain_model_load (line 104) | def __pretrain_model_load(self, model, pretrained_path):
    method augmentation (line 111) | def augmentation(self, X, Y):
    method fit (line 155) | def fit(self, x_train, y_train, nfolds=8):
    method train_and_predict (line 186) | def train_and_predict(self, pretrained_path=None):
  function main (line 199) | def main():

FILE: u_model.py
  function _shortcut (line 10) | def _shortcut(_input, residual):
  function inception_block (line 25) | def inception_block(inputs, depth, batch_mode=0, splitted=False, activat...
  function rblock (line 61) | def rblock(inputs, num, depth, scale=0.1):
  function NConvolution2D (line 69) | def NConvolution2D(nb_filter, nb_row, nb_col, border_mode='same', subsam...
  function BNA (line 78) | def BNA(_input):
  function reduction_a (line 82) | def reduction_a(inputs, k=64, l=64, m=96, n=96):
  function reduction_b (line 97) | def reduction_b(inputs):
  function get_unet_inception_2head (line 118) | def get_unet_inception_2head(optimizer):
  function main (line 190) | def main():

FILE: utils.py
  function load_pickle (line 3) | def load_pickle(file_path):
  function save_pickle (line 9) | def save_pickle(file_path, data):
  function count_enum (line 13) | def count_enum(words):
Condensed preview — 15 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (74K chars).
[
  {
    "path": "README.md",
    "chars": 3034,
    "preview": "# Ultrasound nerve segmentation using Keras (1.0.7)\nKaggle Ultrasound Nerve Segmentation competition [Keras]\n\n#Install ("
  },
  {
    "path": "__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "augmentation.py",
    "chars": 9022,
    "preview": "import sys, os\nimport numpy as np\nfrom keras.preprocessing.image import (transform_matrix_offset_center, apply_transform"
  },
  {
    "path": "average_ensembles.py",
    "chars": 1739,
    "preview": "import numpy as np\nimport sys\nfrom u_model import IMG_COLS as img_cols, IMG_ROWS as img_rows\nfrom train import Learner\n\n"
  },
  {
    "path": "current.py",
    "chars": 3407,
    "preview": "import numpy as np\nimport sys\nfrom data import load_test_data\nfrom u_model import get_unet\nfrom keras.optimizers import "
  },
  {
    "path": "current_ensemble.py",
    "chars": 4326,
    "preview": "import numpy as np\nimport sys\nfrom data import load_test_data\nfrom u_model import get_unet\nfrom keras.optimizers import "
  },
  {
    "path": "data.py",
    "chars": 3522,
    "preview": "from __future__ import print_function\nimport os, sys\nimport numpy as np\nimport cv2\n\nimage_rows = 420\nimage_cols = 580\n\n_"
  },
  {
    "path": "keras_plus.py",
    "chars": 3674,
    "preview": "from keras.callbacks import Callback\nfrom keras.callbacks import warnings\nimport sys\nimport numpy as np\nfrom keras impor"
  },
  {
    "path": "metric.py",
    "chars": 964,
    "preview": "import sys\nimport numpy as np\nfrom keras import backend as K\nsmooth = 1\n\n\ndef mean_length_error(y_true, y_pred):\n    y_t"
  },
  {
    "path": "submission.py",
    "chars": 2136,
    "preview": "from __future__ import print_function\nimport sys, os\nimport numpy as np\nimport cv2\nfrom data import image_cols, image_ro"
  },
  {
    "path": "train.py",
    "chars": 10502,
    "preview": "from __future__ import print_function\nfrom optparse import OptionParser\nimport cv2, sys, os, shutil, random\nimport numpy"
  },
  {
    "path": "train_generator.py",
    "chars": 11632,
    "preview": "from __future__ import print_function\nfrom optparse import OptionParser\nimport cv2, sys, os, shutil, random\nimport numpy"
  },
  {
    "path": "train_kfold.py",
    "chars": 8391,
    "preview": "from optparse import OptionParser\nimport cv2, sys, os, shutil, random\nimport numpy as np\nfrom keras.optimizers import Ad"
  },
  {
    "path": "u_model.py",
    "chars": 8965,
    "preview": "import sys\nfrom keras.models import Model\nfrom keras.layers import Input, merge, Convolution2D, MaxPooling2D, UpSampling"
  },
  {
    "path": "utils.py",
    "chars": 445,
    "preview": "import cPickle as pickle\n\ndef load_pickle(file_path):\n    data = None\n    with open (file_path,\"rb\") as dumpFile:\n      "
  }
]

About this extraction

This page contains the full source code of the EdwardTyantov/ultrasound-nerve-segmentation GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 15 files (70.1 KB), approximately 18.9k tokens, and a symbol index with 114 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!