예제 #1
0
def reset_eddl_net_params(net, weight='zeros', bias='zeros'):
    layers = net.layers
    for l in layers:
        name = l.name
        params = l.params

        w_np = None
        b_np = None

        for index, p in enumerate(params):
            if index == 0:
                if weight == 'zeros':
                    w_np = np.zeros_like(p.getdata())
                else:
                    w_np = np.ones_like(p.getdata())

            if index == 1:
                if bias == 'zeros':
                    b_np = np.zeros_like(p.getdata())
                else:
                    b_np = np.ones_like(p.getdata())

        w_np_t = Tensor.fromarray(w_np)
        b_np_t = Tensor.fromarray(b_np)

        # Update of the parameters
        l.update_weights(w_np_t, b_np_t)
        eddl.distributeParams(l)
예제 #2
0
def read_input(filename, split_ratio=0.7):
    data = np.load(filename)['d']
    # shuffle data
    sel_index = np.arange(data.shape[0])
    np.random.shuffle(sel_index)
    
    shuffled_data = data[sel_index]
    shuffled_data = np.c_[shuffled_data, np.zeros(shuffled_data.shape[0])] # Add column for two class labels
    shuffled_data[:,4][shuffled_data[:,3] == 0] = 1.  ## [1] -> [1 0], [0]-->[0 1]
    shuffled_data[:,[3,4]] = shuffled_data[:,[4,3]]   ## Swap last two columns [1] --> [0 1], [0] --> [1 0]

    # Split train test
    n_train = int (shuffled_data.shape[0] * split_ratio )
    
    train = shuffled_data[0:n_train]
    test = shuffled_data[n_train:]
    x_trn = train[:,:3]
    y_trn = train[:,3:]
    x_test = test[:,:3]
    y_test = test[:,3:]
    
    # Tensor creation
    x_train_t = Tensor.fromarray(x_trn.astype(np.float32))
    y_train_t = Tensor.fromarray(y_trn.astype(np.float32))
    x_test_t = Tensor.fromarray(x_test.astype(np.float32))
    y_test_t = Tensor.fromarray(y_test.astype(np.float32))

    return x_train_t, y_train_t, x_test_t, y_test_t
예제 #3
0
def update_eddl_net_params(keras_params_d, net, include_top=True):
    if include_top:
        layers_l = [(l.name, l.params[0].getShape(), l.params[1].getShape(), l)
                    for l in net.layers
                    if 'conv' in l.name or 'dense' in l.name]
        keras_l = [k for k in sorted(keras_params_d.keys())]
    else:
        layers_l = [(l.name, l.params[0].getShape(), l.params[1].getShape(), l)
                    for l in net.layers if 'conv' in l.name]
        keras_l = [k for k in sorted(keras_params_d.keys()) if 'conv' in k]

    for index, k in enumerate(keras_l):
        w_np = keras_params_d[k]['w']
        b_np = keras_params_d[k]['b']

        l = layers_l[index]

        # Transpose to match eddl tensor shape for convolutional layer
        if 'conv' in l[0]:
            print("Conv before transpose", w_np.shape)
            w_np = np.transpose(w_np, (3, 2, 0, 1))

        # dense layer immediatly after the flattening. he order of weight is different because previous feature maps are channel last in Keras
        # but EDDL expects as they are channel first
        if l[0] == 'dense1':
            x = keras_params_d[keras_l[index - 1]]['w'].shape[0]
            y = keras_params_d[keras_l[index - 1]]['w'].shape[1]
            n_ch = keras_params_d[keras_l[index - 1]]['w'].shape[3]
            print('After flattening. #Channels of previous layers is: %d' %
                  n_ch)
            # Converting w_np as the previous feature maps was channel first
            outputs = w_np.shape[1]
            print(w_np.shape)

            w_np_ch_f = np.zeros_like(w_np)

            for o in range(outputs):
                for offset in range(n_ch):
                    lll = w_np[offset::n_ch, o].shape[0]
                    w_np_ch_f[offset:offset + lll, o] = w_np[offset::n_ch, o]

        # Shapes check
        eddl_w_shape = np.array(l[1])
        eddl_b_shape = np.array(l[2])

        print(l[0], k)
        print(eddl_w_shape, w_np.shape)
        print(eddl_b_shape, b_np.shape)

        # converting numpy arrays to tensor
        w_np_t = Tensor.fromarray(w_np)
        b_np_t = Tensor.fromarray(b_np)

        # Update of the parameters
        l[3].update_weights(w_np_t, b_np_t)
        eddl.distributeParams(l[3])
예제 #4
0
def test_py_metric():
    shape = [8, 10]
    a = np.random.random(shape).astype(np.float32)
    b = np.random.random(shape).astype(np.float32)
    t, y = Tensor.fromarray(a), Tensor.fromarray(b)
    v = MSEMetric().value(t, y)
    exp_v = eddl.getMetric("mse").value(t, y)
    assert v == pytest.approx(exp_v)
    v = CategoricalAccuracy().value(t, y)
    exp_v = eddl.getMetric("categorical_accuracy").value(t, y)
    assert v == pytest.approx(exp_v)
예제 #5
0
def test_py_loss():
    shape = [8, 10]
    a = np.random.random(shape).astype(np.float32)
    b = np.random.random(shape).astype(np.float32)
    t, y = Tensor.fromarray(a), Tensor.fromarray(b)
    z = Tensor(shape)
    exp_z = Tensor(shape)
    py_mse_loss = MSELoss()
    mse_loss = eddl.getLoss("mse")
    mse_loss.delta(t, y, exp_z)
    py_mse_loss.delta(t, y, z)
    c = np.array(z, copy=False)
    exp_c = np.array(exp_z, copy=False)
    assert np.array_equal(c, exp_c)
    v = py_mse_loss.value(t, y)
    exp_v = mse_loss.value(t, y)
    assert v == pytest.approx(exp_v)
예제 #6
0
def preprocess_input_resnet34(input_, target_size):
    mean_vec = Tensor.fromarray(
        np.array([0.485, 0.456, 0.406], dtype=np.float32), input_.device)
    std_vec = Tensor.fromarray(
        np.array([0.229, 0.224, 0.225], dtype=np.float32), input_.device)
    if input_.ndim not in {3, 4}:
        raise RuntimeError("Input tensor must be 3D or 4D")
    if input_.ndim == 3:
        input_.unsqueeze_(0)  # convert to 4D
    new_input = input_.scale(target_size)  # (height, width)
    # Normalization [0..1]
    new_input.mult_(1 / 255.0)
    # Standardization: (X - mean) / std
    mean = Tensor.broadcast(mean_vec, new_input)
    std = Tensor.broadcast(std_vec, new_input)
    new_input.sub_(mean)
    new_input.div_(std)
    return new_input
예제 #7
0
def read_slide(slide_fn, level=4):
    levels = ecvl.OpenSlideGetLevels(slide_fn)
    dims = [0, 0] + levels[level]
    img = ecvl.OpenSlideRead(slide_fn, level, dims)
    t = ecvl.ImageToTensor(img)
    t_np = t.getdata()
    s = t_np.shape
    t_np = t_np.transpose((1, 2, 0)).reshape(
        (s[1] * s[2], 3))  # Channel last and reshape
    t_eval = Tensor.fromarray(t_np)
    print(t_eval.getShape())
    return t_eval, s
예제 #8
0
def read_input(filename, split_ratio=0.7):
    data = np.load(filename)['d']
    # shuffle data
    sel_index = np.arange(data.shape[0])
    np.random.shuffle(sel_index)
    
    shuffled_data = data[sel_index]
    shuffled_data = np.c_[shuffled_data, np.zeros(shuffled_data.shape[0])] # Add column for two class labels
    shuffled_data[:,4][shuffled_data[:,3] == 0] = 1.  ## [1] -> [1 0], [0]-->[0 1]
    shuffled_data[:,[3,4]] = shuffled_data[:,[4,3]]   ## Swap last two columns [1] --> [0 1], [0] --> [1 0]

    # Split train test
    n_train = int (shuffled_data.shape[0] * split_ratio )
    
    train = shuffled_data[0:n_train]
    test = shuffled_data[n_train:]
    x_trn = train[:,:3]
    y_trn = train[:,3:]
    
    # Class balancing of validation set
    test_0 = test[test[:, 3] == 1]
    test_1 = test[test[:, 4] == 1]
    c0_size = test_0.shape[0]
    c1_size = test_1.shape[0]

    c_size = min(c0_size, c1_size)
    
    test_bal = np.concatenate((test_0[:c_size], test_1[:c_size]),axis=0)
    x_test = test_bal[:,:3]
    y_test = test_bal[:,3:]

    # Tensor creation
    x_train_t = Tensor.fromarray(x_trn.astype(np.float32))
    y_train_t = Tensor.fromarray(y_trn.astype(np.int32))
    x_test_t = Tensor.fromarray(x_test.astype(np.float32))
    y_test_t = Tensor.fromarray(y_test.astype(np.int32))
    
    return x_train_t, y_train_t, x_test_t, y_test_t
예제 #9
0
    def get_tissue_mask(self,
                        np_img,
                        channel_first=True,
                        BGR=False,
                        get_prob=False):
        """
        @np_img: numpy array of a PIL image (x,y,4) if alpha channel is present 
                 or (x, y, 3) if alpha channel not present
        @channel_first: boolean to specify if the image is channel first (3,x,y) 
                        or channel last (x,y,3) (3 is replaced by 4 if alpha is present)
        
        returns a (x,y) numpy array with binary values (0:bg, 1:tissue)
        """

        if channel_first:
            np_img = np_img.transpose((1, 2, 0))  # Convert to channel last

        if BGR:
            np_img = np_img[
                ..., ::
                -1]  # Convert from BGR to RGB assuming a channel_last image

        s = np_img.shape
        n_px = s[0] * s[1]
        np_img = np_img[:, :, :3].reshape(n_px, 3)

        if not self.model:
            print("Cannot make predictions without a model. Please, load one!")
            return None

        ## From numpy array to eddl tensor to predict
        t_eval = Tensor.fromarray(np_img)

        output_l = eddl.predict(self.model,
                                [t_eval])  # Prediction.. get probabilities

        if get_prob:
            output_np_l = [
                i.getdata()[:, 1] for i in output_l
            ]  ## Create a list  f numpy array from output tensors
        else:
            output_np_l = self.__get_binary_mask(
                output_l, self.th)  ## Get the actual mask (binarization)

        mask_values = np.vstack(output_np_l)
        mask = mask_values.reshape((s[0], s[1]))

        return mask
예제 #10
0
def main(args):
    
    """
        Test a model of a patient in the detection of seizures.
    """

    # Arguments
    index_test = [args.index]
    patient_id = args.id
    model_id = args.model
    batch_size = args.batch_size
    gpus = args.gpus
    exp_dir = args.dir

    # Create Data Generator object for the test set
    print('Creating Test Data Generator...', file=sys.stderr)
    dg_test = RawRecurrentDataGenerator(index_filenames=index_test,
                          window_length = 1,
                          shift = 0.5, 
                          timesteps = 19,
                          sampling_rate = 256, # in Hz
                          batch_size=batch_size,
                          in_training_mode=False,
                          patient_id=patient_id)
    #

    model_dir = os.path.join(exp_dir, 'models')

    # Find best model in the models directory
    best_model = dict()  # {epoch: model_filename}
    for file in os.listdir(model_dir):
        if 'best' in file:
            w = file.split('_')
            for i in range(len(w)):
                if w[i] == 'epoch':
                    epoch = int(w[i + 1])
                    break
            #
            best_model[epoch] = file
    #
    # Get the highest epoch model filename - which is the best model -
    best_model_name = best_model[max(best_model.keys())]

    print(f'Evaluating best model with the test set -> {best_model_name}', file=sys.stderr)

    model_filename = os.path.join(model_dir, best_model_name)

    # Load the model in the eddl
    print('Loading the model...', file=sys.stderr)
    net = create_model(model_id=model_id,
                       input_shape=None, # Not needed if we are loading
                       num_classes=2,
                       filename=model_filename,
                       gpus=gpus)
    #


    # Get predictions for the test set with the best model
    print('Testing the model with the test signals...', file=sys.stderr)
    Y_true_single_channel = list()
    Y_pred_single_channel = list()
    Y_true = list()
    Y_pred = list()

    for j in tqdm(range(len(dg_test))):
        x, y = dg_test[j]
        
        channels_y_pred = list()
        for channel in range(x.shape[3]):
            x_channel = x[:, :, :, channel]

            channel_tensor_batch = Tensor.fromarray(x_channel)
            # Forward and backward of the channel through the net
            (y_pred, ) = eddl.predict(net, [channel_tensor_batch])

            y_pred = y_pred.getdata()
            
            channels_y_pred.append(y_pred)
            Y_pred_single_channel += y_pred.argmax(axis=1).tolist()
            Y_true_single_channel += y.tolist()
        
        channels_y_pred = numpy.array(channels_y_pred)
        # (23, batch_size, 2)
        channels_y_pred = numpy.sum(channels_y_pred, axis=0)
        # print(channels_y_pred.shape) -> (batch_size, 2)
        
        Y_true += y.tolist()
        Y_pred += channels_y_pred.argmax(axis=1).tolist()
    #

    y_true = numpy.array(Y_true) * 1.0
    y_pred = numpy.array(Y_pred) * 1.0
    y_true_single_channel = numpy.array(Y_true_single_channel) * 1.0
    y_pred_single_channel = numpy.array(Y_pred_single_channel) * 1.0

    
    # Calculate and print basic metrics

    test_accuracy_single_channel = sum(y_true_single_channel == y_pred_single_channel) / len(y_true_single_channel)
    cnf_matrix = confusion_matrix(y_true_single_channel, y_pred_single_channel)
    report = classification_report(y_true_single_channel, y_pred_single_channel)
    fscore_single_channel = f1_score(y_true_single_channel, y_pred_single_channel, labels=[0, 1], average='macro')
    
    print('***************************************************************\n', file=sys.stderr)
    print(f'Test results\n', file=sys.stderr)
    print(' -- Single channel results (no combination of channels) --\n', file=sys.stderr)
    print(f'Test accuracy : {test_accuracy_single_channel}', file=sys.stderr)
    print(f'Test macro f1-score : {fscore_single_channel}', file=sys.stderr)
    print('Confussion matrix:', file=sys.stderr)
    print(f'{cnf_matrix}\n', file=sys.stderr)
    print('Classification report:', file=sys.stderr)
    print(report, file=sys.stderr)

    print('\n--------------------------------------------------------------\n', file=sys.stderr)

    test_accuracy = sum(y_true == y_pred) / len(y_true)
    cnf_matrix = confusion_matrix(y_true, y_pred)
    report = classification_report(y_true, y_pred)
    fscore = f1_score(y_true, y_pred, labels=[0, 1], average='macro')

    print(' -- All channels involved (combined for each timestamp) --\n', file=sys.stderr)
    print(f'Test accuracy : {test_accuracy}', file=sys.stderr)
    print(f'Test macro f1-score : {fscore}', file=sys.stderr)
    print('Confussion matrix:', file=sys.stderr)
    print(f'{cnf_matrix}\n', file=sys.stderr)
    print('Classification report:', file=sys.stderr)
    print(report, file=sys.stderr)
    
    print('\n--------------------------------------------------------------\n', file=sys.stderr)

    # Calculate and print other metrics: 
    acc_window, latency, fp_h, recall = calculate_detection_metrics(
                                        y_true,
                                        y_pred,
                                        sample_shift=args.sample_shift,
                                        sliding_window_length=args.window_length,
                                        alpha_pos=args.alpha_pos,
                                        alpha_neg=args.alpha_neg,
                                        detection_threshold=args.detection_threshold
                                        )

    print('Global metrics after inference\n\n', file=sys.stderr)
    print(f'Accuracy of the sliding window: {acc_window * 100.0:.4f}', file=sys.stderr)
    print(f'Percentage of detected seizures: {recall * 100.0:.4f}', file=sys.stderr)
    print(f'Average latency: {latency} seconds', file=sys.stderr)
    print(f'False Alarms per Hour: {fp_h}', file=sys.stderr)

    print('***************************************************************\n\n', file=sys.stderr)
예제 #11
0
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

import os
from urllib.request import urlretrieve

import numpy as np
from pyeddl.tensor import Tensor

# Convert array to tensor and save to "bin" format
a = np.arange(6).reshape([2, 3]).astype(np.float32)
print(a)
t = Tensor.fromarray(a)
t.save("./a.bin", "bin")
t1 = Tensor.load("a.bin", "bin")
a1 = t1.getdata()
print(a1)

print()

# Read numpy data and convert to tensors
FNAME = "mnist.npz"
LOC = "https://storage.googleapis.com/tensorflow/tf-keras-datasets"
if not os.path.exists(FNAME):
    fname, _ = urlretrieve("%s/%s" % (LOC, FNAME), FNAME)
    print("Downloaded", fname)
print("loading", FNAME)
with np.load(FNAME) as f:
def main(args):
    """
    Train a model on epilepsy detection with recurrent neural networks.
    """

    index_training = [args.index]
    index_validation = [args.index_val]
    patient_id = args.id
    model_id = args.model
    epochs = args.epochs
    batch_size = args.batch_size
    resume_dir = args.resume
    starting_epoch = args.starting_epoch
    gpus = args.gpus

    model_checkpoint = None

    # Create dirs for the experiment
    if resume_dir is None:
        os.makedirs('experiments', exist_ok=True)
        exp_name = f'detection_recurrent_{patient_id}_LSTM'
        exp_dir = f'experiments/{exp_name}'
        os.makedirs(exp_dir, exist_ok=False)
        os.makedirs(exp_dir + '/models')
    else:
        exp_dir = resume_dir
        model_dir = exp_dir + '/models'
        for f in os.listdir(model_dir):
            if 'last' in f:
                model_checkpoint = os.path.join(model_dir, f)
        #
        if model_checkpoint is None:
            raise Exception(f'Last model not found in {model_dir}')
        #

    log_file = open(f'{exp_dir}/training_log.txt', 'w')
    log_file.write('epoch, train_loss, train_acc, val_acc_single_channel,' +
                   ' val_f1score_single_channel, val_acc, val_f1score\n')
    log_file.flush()

    # Data Generator Object for training
    print('\n\nCreating Training Data Generator...', file=sys.stderr)
    dg = RawRecurrentDataGenerator(
        index_filenames=index_training,
        window_length=args.window_length,  # in seconds
        shift=args.shift,  # in seconds
        timesteps=args.timesteps,  # in seconds
        sampling_rate=256,  # in Hz
        batch_size=batch_size,
        in_training_mode=True,
        balance_batches=True,
        patient_id=patient_id)
    #

    print('\n\nCreating Validation Data Generator...', file=sys.stderr)
    dg_val = RawRecurrentDataGenerator(
        index_filenames=index_validation,
        window_length=args.window_length,
        shift=args.shift,
        timesteps=args.timesteps,
        sampling_rate=256,  # in Hz
        batch_size=batch_size,
        in_training_mode=False,
        patient_id=patient_id)

    net = create_model(model_id,
                       dg.input_shape,
                       num_classes=2,
                       filename=model_checkpoint,
                       gpus=gpus)
    #

    best_val_acc = 0.0

    for epoch in range(starting_epoch, epochs):

        print(f'\nTraining epoch {epoch+1} of {epochs}...', file=sys.stderr)
        dg.shuffle_data()
        # TRAINING STAGE
        eddl.reset_loss(net)

        # Set a progress bar for the training loop
        pbar = tqdm(range(len(dg)))

        for i in pbar:
            # Load batch of data
            x, y = dg[i]

            _y_ = numpy.zeros([len(y), 2])
            for i in range(2):
                _y_[y == i, i] = 1
            _y_ = _y_.reshape((len(y), 1, 2))
            y = Tensor.fromarray(_y_)

            for channel in range(x.shape[3]):
                x_channel = x[:, :, :, channel]

                channel_tensor_batch = Tensor.fromarray(x_channel)
                # Forward and backward of the channel through the net
                eddl.train_batch(net, [channel_tensor_batch], [y])

                losses = eddl.get_losses(net)
                #metrics = eddl.get_metrics(net)

                pbar.set_description(
                    f'Training[loss={losses[0]:.5f}, acc=Not Available]')

        print()

        # VALIDATION
        print(f'\nValidation epoch {epoch+1}', file=sys.stderr)

        Y_true_single_channel = list()
        Y_pred_single_channel = list()
        Y_true = list()
        Y_pred = list()

        for j in tqdm(range(len(dg_val))):
            x, y = dg_val[j]

            channels_y_pred = list()
            for channel in range(x.shape[3]):
                x_channel = x[:, :, :, channel]

                channel_tensor_batch = Tensor.fromarray(x_channel)
                # Forward and backward of the channel through the net
                (y_pred, ) = eddl.predict(net, [channel_tensor_batch])

                y_pred = y_pred.getdata()

                channels_y_pred.append(y_pred)
                Y_pred_single_channel += y_pred.argmax(axis=1).tolist()
                Y_true_single_channel += y.tolist()

            channels_y_pred = numpy.array(channels_y_pred)
            # (23, batch_size, 2)
            channels_y_pred = numpy.sum(channels_y_pred, axis=0)
            channels_y_pred = channels_y_pred / 23.0
            # print(channels_y_pred.shape) -> (batch_size, 2)

            Y_true += y.tolist()
            Y_pred += channels_y_pred.argmax(axis=1).tolist()
        #

        y_true = numpy.array(Y_true) * 1.0
        y_pred = numpy.array(Y_pred) * 1.0
        y_true_single_channel = numpy.array(Y_true_single_channel) * 1.0
        y_pred_single_channel = numpy.array(Y_pred_single_channel) * 1.0

        val_accuracy_single_channel = sum(
            y_true_single_channel == y_pred_single_channel) / len(
                y_true_single_channel)
        cnf_matrix = confusion_matrix(y_true_single_channel,
                                      y_pred_single_channel)
        report = classification_report(y_true_single_channel,
                                       y_pred_single_channel)
        fscore_single_channel = f1_score(y_true_single_channel,
                                         y_pred_single_channel,
                                         labels=[0, 1],
                                         average='macro')

        print(
            '***************************************************************\n',
            file=sys.stderr)
        print(f'Epoch {epoch + 1}: Validation results\n', file=sys.stderr)
        print(' -- Single channel results (no combination of channels) --\n',
              file=sys.stderr)
        print(f'Validation acc : {val_accuracy_single_channel}',
              file=sys.stderr)
        print(f'Validation macro f1-score : {fscore_single_channel}',
              file=sys.stderr)
        print('Confussion matrix:', file=sys.stderr)
        print(f'{cnf_matrix}\n', file=sys.stderr)
        print('Classification report:', file=sys.stderr)
        print(report, file=sys.stderr)

        print(
            '\n--------------------------------------------------------------\n',
            file=sys.stderr)

        val_accuracy = sum(y_true == y_pred) / len(y_true)
        cnf_matrix = confusion_matrix(y_true, y_pred)
        report = classification_report(y_true, y_pred)
        fscore = f1_score(y_true, y_pred, labels=[0, 1], average='macro')

        print(' -- All channels involved (combined for each timestamp) --\n',
              file=sys.stderr)
        print(f'Validation acc : {val_accuracy}', file=sys.stderr)
        print(f'Validation macro f1-score : {fscore}', file=sys.stderr)
        print('Confussion matrix:', file=sys.stderr)
        print(f'{cnf_matrix}\n', file=sys.stderr)
        print('Classification report:', file=sys.stderr)
        print(report, file=sys.stderr)
        print(
            '***************************************************************\n\n',
            file=sys.stderr)

        log_file.write('%d,%d,%g,%g,%g,%g,%g\n' %
                       (epoch, -1, losses[0], val_accuracy_single_channel,
                        fscore_single_channel, val_accuracy, fscore))

        log_file.flush()

        # Save best model
        if (val_accuracy > best_val_acc):
            best_val_acc = val_accuracy
            eddl.save_net_to_onnx_file(
                net,
                f'{exp_dir}/models/best_model_epoch_{epoch:04d}_val_acc_{val_accuracy:.4f}.onnx'
            )

        eddl.save_net_to_onnx_file(net, f'{exp_dir}/models/last.onnx')

    #
    log_file.close()