コード例 #1
0
def export_all_contours(contours, data_path, crop_size, sax_series):
    shape = (len(contours), crop_size, crop_size, 1)
    images = np.zeros(shape)
    masks = np.zeros(shape)
    for idx, contour in enumerate(contours):
        img, mask = read_contour(contour, data_path, sax_series)
        images[idx] = center_crop(img, crop_size=crop_size)
        masks[idx] = center_crop(mask, crop_size=crop_size)

    return images, masks
def export_all_contours(contours, data_path, crop_size):
    print('\nProcessing {:d} images and labels ...\n'.format(len(contours)))
    images = np.zeros((len(contours), crop_size, crop_size, 1))
    masks = np.zeros((len(contours), crop_size, crop_size, 1))
    for idx, contour in enumerate(contours):
        img, mask = read_contour(contour, data_path)
        img = center_crop(img, crop_size=crop_size)
        mask = center_crop(mask, crop_size=crop_size)
        images[idx] = img
        masks[idx] = mask

    return images, masks
コード例 #3
0
def generate_all_contours(contours, chunk_size, crop_size, shuffle=False):
    num_iter = int(np.ceil(len(contours) / float(chunk_size)))
    while True:  # this flag yields an infinite generator
        if shuffle:
            print('\nShuffling data at each epoch\n')
            np.random.shuffle(contours)
        for i in range(num_iter):
            chunk = contours[(chunk_size * i):(chunk_size * (i + 1))]
            if len(chunk) == 0:
                break
            pool = Pool(8)
            results = pool.map(read_contour, chunk)
            pool.close()
            for (image, mask) in results:
                image = center_crop(image, crop_size=crop_size)
                mask = center_crop(mask, crop_size=crop_size)

                yield (image, mask)
コード例 #4
0
def export_all_contours(contours, data_path, overlay_path, crop_size,
                        contour_type):
    print('\nProcessing {:d} images and labels ...\n'.format(len(contours)))
    total_number = 0
    for volume_ctr in contours:
        total_number += volume_ctr.total_number

    images = np.zeros((total_number, crop_size, crop_size, 1))
    masks = np.zeros((total_number, crop_size, crop_size, num_classes))
    idx = 0
    for contour in contours:
        vol, vol_mask = read_contour(contour,
                                     data_path,
                                     return_mask=True,
                                     type=contour_type)
        #draw_contour(contour, data_path, overlay_path, type=contour_type)
        for i in range(0, vol.shape[2]):
            img = vol[:, :, i]
            mask = vol_mask[:, :, i]
            img = np.swapaxes(img, 0, 1)
            mask = np.swapaxes(mask, 0, 1)

            if img.ndim < 3:
                img = img[..., np.newaxis]
            if mask.ndim < 3:
                if contour_type != "a":
                    mask = mask[..., np.newaxis]
                elif contour_type == "a":
                    h, w = mask.shape
                    classify = np.zeros((h, w, num_classes), dtype="uint8")
                    classify[..., 1] = np.where(mask == 1, 1, 0)
                    classify[..., 2] = np.where(mask == 2, 1, 0)
                    classify[..., 3] = np.where(mask == 3, 1, 0)
                    classify[..., 0] = np.where(mask == 0, 1, 0)
                    mask = classify
            img = center_crop(img, crop_size=crop_size)
            mask = center_crop(mask, crop_size=crop_size)
            images[idx] = img
            masks[idx] = mask
            idx = idx + 1
    return images, masks
コード例 #5
0
ファイル: submit_rvsc.py プロジェクト: mad2001/cardiac_ucla
def create_submission(contours, data_path):
    if contour_type == 'i':
        weights = 'weights/rvsc_i.h5'
    elif contour_type == 'o':
        weights = 'weights/rvsc_o.h5'
    else:
        sys.exit('\ncontour type "%s" not recognized\n' % contour_type)

    crop_size = 200
    images = np.zeros((len(contours), crop_size, crop_size, 1))
    for idx, contour in enumerate(contours):
        img, _ = read_contour(contour, data_path, return_mask=False)
        img = center_crop(img, crop_size=crop_size)
        images[idx] = img

    input_shape = (crop_size, crop_size, 1)
    num_classes = 2
    model = fcn_model(input_shape, num_classes, weights=weights)
    pred_masks = model.predict(images, batch_size=32, verbose=1)
    
    save_dir = data_path + '_auto_contours'
    num = 0
    for idx, ctr in enumerate(contours):
        img, _ = read_contour(ctr, data_path, return_mask=False)
        h, w, d = img.shape
        tmp = reshape(pred_masks[idx], to_shape=(h, w, d))
        assert img.shape == tmp.shape, 'Shape of prediction does not match'
        tmp = np.where(tmp > 0.5, 255, 0).astype('uint8')
        tmp2, coords, hierarchy = cv2.findContours(tmp.copy(), cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE)
        if not coords:
            print('No detection: %s' % ctr.ctr_path)
            coords = np.ones((1, 1, 1, 2), dtype='int')
        if len(coords) > 1:
            print('Multiple detections: %s' % ctr.ctr_path)

            #cv2.imwrite('multiple_dets/'+contour_type+'{:04d}.png'.format(idx), tmp)
            
            lengths = []
            for coord in coords:
                lengths.append(len(coord))
            coords = [coords[np.argmax(lengths)]]
            num += 1
        filename = 'P{:s}-{:s}-'.format(ctr.patient_no, ctr.img_no)+contour_type+'contour-auto.txt'
        full_path = os.path.join(save_dir, 'P{:s}'.format(ctr.patient_no)+'contours-auto')
        if not os.path.exists(full_path):
            os.makedirs(full_path)
        with open(os.path.join(full_path, filename), 'w') as f:
            for coord in coords:
                coord = np.squeeze(coord, axis=(1,))
                coord = np.append(coord, coord[:1], axis=0)
                np.savetxt(f, coord, fmt='%i', delimiter=' ')
    
    print('Num of files with multiple detections: {:d}'.format(num))
コード例 #6
0
def export_all_contours(contours, data_path, crop_size):
    print("contours here", len(list(contours)))
    print('\nProcessing {:d} images and labels ...\n'.format(
        len(list(contours))))
    images = np.zeros((len(list(contours)), crop_size, crop_size, 1))
    masks = np.zeros((len(list(contours)), crop_size, crop_size, 1))
    for idx, contour in enumerate(contours):
        #print(idx)

        img, mask = read_contour(contour, data_path)
        if (not (img.shape == (256, 256, 1))):
            img = center_crop(img, crop_size)
            mask = center_crop(mask, crop_size)
            images[idx] = img
            masks[idx] = mask
            continue
        #pdb.set_trace()
        mask_temp = np.squeeze(mask)
        pos_pred = np.array(np.where(mask_temp == 1))
        #pdb.set_trace()
        # get the center of the mask
        X_min, Y_min = pos_pred[0, :].min(), pos_pred[1, :].min()
        X_max, Y_max = pos_pred[0, :].max(), pos_pred[1, :].max()
        X_middle = X_min + (X_max - X_min) / 2
        Y_middle = Y_min + (Y_max - Y_min) / 2
        # Find ROI coordinates
        X_top = int(X_middle - 50)
        Y_top = int(Y_middle - 50)
        X_down = int(X_middle + 50)
        Y_down = int(Y_middle + 50)
        img1 = img[X_top:X_down, Y_top:Y_down, :]
        mask1 = mask[X_top:X_down, Y_top:Y_down, :]
        #img1=np.squeeze(img1)
        #mask=np.squeeze(mask1)
        images[idx] = img1
        masks[idx] = mask1

    return images, masks
コード例 #7
0
ファイル: submit_lvsc.py プロジェクト: mad2001/cardiac_ucla
def create_submission(dcm_list, data_path):
    crop_size = 200
    input_shape = (crop_size, crop_size, 1)
    num_classes = 2

    oweights = 'weights/lvsc_o.h5'
    iweights = 'weights/lvsc_i.h5'
    omodel = fcn_model(input_shape, num_classes, weights=oweights)
    imodel = fcn_model(input_shape, num_classes, weights=iweights)

    images = np.zeros((len(dcm_list), crop_size, crop_size, 1))
    for idx, dcm_path in enumerate(dcm_list):
        img = read_dicom(dcm_path)
        img = center_crop(img, crop_size=crop_size)
        images[idx] = img
    opred_masks = omodel.predict(images, batch_size=32, verbose=1)
    ipred_masks = imodel.predict(images, batch_size=32, verbose=1)

    save_dir = data_path + '_auto_contours'
    prefix = 'MYFCN_'  # change prefix to your unique initials
    for idx, dcm_path in enumerate(dcm_list):
        img = read_dicom(dcm_path)
        h, w, d = img.shape
        otmp = reshape(opred_masks[idx], to_shape=(h, w, d))
        otmp = np.where(otmp > 0.5, 255, 0).astype('uint8')
        itmp = reshape(ipred_masks[idx], to_shape=(h, w, d))
        itmp = np.where(itmp > 0.5, 255, 0).astype('uint8')
        assert img.shape == otmp.shape, 'Prediction does not match shape'
        assert img.shape == itmp.shape, 'Prediction does not match shape'
        tmp = otmp - itmp
        tmp = np.squeeze(tmp, axis=(2, ))
        sub_dir = dcm_path[dcm_path.find('CAP_'):dcm_path.rfind('DET')]
        filename = prefix + dcm_path[dcm_path.rfind('DET'):].replace(
            '.dcm', '.png')
        full_path = os.path.join(save_dir, sub_dir)
        if not os.path.exists(full_path):
            os.makedirs(full_path)
        cv2.imwrite(os.path.join(full_path, filename), tmp)
        in_ = cv2.imread(os.path.join(full_path, filename),
                         cv2.IMREAD_GRAYSCALE)
        if not np.allclose(in_, tmp):
            raise AssertionError('File read error: {:s}'.format(
                os.path.join(full_path, filename)))
コード例 #8
0
    if is_all_valid_slice:
        for slice_idx in range(num_slices):
            img_no = center_no + (slice_idx -
                                  int(num_slices / 2)) * num_phases_in_cycle
            if img_no not in volume_map[case]:
                return [], []

    for slice_idx in range(num_slices):
        img_no = center_no + (slice_idx -
                              int(num_slices / 2)) * num_phases_in_cycle
        if img_no < img_no_min:
            img_no = img_no_min
        if img_no > img_no_max:
            img_no = img_no_max
        img = read_image(img_no, data_path, case)
        img = center_crop(img, crop_size)
        images[:, :, slice_idx, :] = img
        if img_no in volume_map[case]:
            mask = read_mask(volume_map[case][img_no], data_path, num_classes)
            mask = center_crop(mask, crop_size)
            masks[:, :, slice_idx, :] = mask

    return images, masks


def map_all_contours(contour_path):
    endo = []
    epi = []
    p1 = []
    p2 = []
    p3 = []
コード例 #9
0
def evaluate(model_data_path, image_path, split_path):

    # Default input size
    height = 228
    width = 304
    channels = 3  #5
    #num_test_images = 654
    batch_size = 64

    #Load Sun 3D dataset
    sun_imgs, sun_gts, dataset_label, indices_size = utils.sun3Ddataset()

    abs_rels = []
    rmses = []
    log_errs = []

    # Create a placeholder for the input image
    input_node = tf.placeholder(tf.float32,
                                shape=(None, height, width, channels))

    # Construct the network
    net = ResNet50UpProj({'data': input_node}, batch_size, 1, False)
    step = 1
    #print(indices_size)

    #get pre calculated metric coordinates for all sub datasets
    orig_metric_cord, crop_metric_cord, res_size = Intrinsic.findSun3DMetricCoords(
    )

    #Testing in batches
    while step * batch_size <= indices_size:  #indices.size:

        inp_batch = []
        gt_batch = []

        #res_size = [[423,564], [375, 500], [354, 472]] # 90%, 80%, 75% crop
        crops = len(res_size['NYUdata'])
        #print('Value ' + str(int(batch_size/(crops+1))))

        # Get the image and ground truth numpy arrays for entire batch
        for index in range((step - 1) * int(batch_size / (crops + 1)),
                           step * int(batch_size / (crops + 1))):
            print('Index: ' + str((step - 1) * int(batch_size / (crops + 1))) +
                  ' --->   ' + str(step * int(batch_size / (crops + 1))))
            img = Image.open(sun_imgs[index])
            border = (8, 6, 8, 6)  # left, up, right, bottom
            cropped_img = ImageOps.crop(img, border)
            resized_img = cropped_img.resize((304, 228), Image.BILINEAR)
            #transfrmd_img = np.concatenate((np.asarray(resized_img), orig_metric_cord[dataset_label[index]]), axis = 2)

            inp_batch.append(np.asarray(resized_img))
            #inp_batch.append(transfrmd_img)

            dpth = Image.open(sun_gts[index])
            cropped_dpth = ImageOps.crop(dpth, border)
            resized_dpth = cropped_dpth.resize((160, 128), Image.NEAREST)
            resized_dpth = np.expand_dims(resized_dpth, axis=3)
            gt_batch.append(resized_dpth)
            #gt_batch = np.array(gt_batch)

            crop_img = []
            col_cj = []
            row_ci = []
            resize_img = []
            crop_transfrmd_img = []
            crop_dpth = []
            resize_dpth = []

            #print('crops ' + str(range(crops)))
            for i in range(crops):
                cropinfo = Intrinsic.center_crop(
                    np.asarray(cropped_img),
                    res_size[dataset_label[index]][i])  #Random or center crop
                crop_img.append(cropinfo[0])
                col_cj.append(cropinfo[1])
                row_ci.append(cropinfo[2])
                resize_img.append(
                    Image.fromarray(crop_img[i].astype(np.uint8),
                                    'RGB').resize((304, 228), Image.BILINEAR))
                #crop_transfrmd_img.append( np.concatenate((np.asarray(resize_img[i]), crop_metric_cord[dataset_label[index]][i]), axis = 2))
                crop_dpth.append(
                    np.asarray(cropped_dpth)
                    [row_ci[i]:row_ci[i] +
                     res_size[dataset_label[index]][i][0],
                     col_cj[i]:col_cj[i] +
                     res_size[dataset_label[index]][i][1]])
                resize_dpth.append(
                    Image.fromarray(crop_dpth[i]).resize((160, 128),
                                                         Image.NEAREST))
                resize_dpth_temp = np.array(resize_dpth[i]) / 10000.
                resize_dpth[i] = np.expand_dims(resize_dpth_temp, axis=3)

                inp_batch.append(np.asarray(
                    resize_img[i]))  #crop_transfrmd_img[i]
                gt_batch.append(np.asarray(resize_dpth[i]))

        print('-------Batch: ' + str(step) + ' Images: ' +
              str(step * batch_size) + '-----------------')
        #print('Shape ' + str(np.squeeze(np.array(inp_batch), axis=1).shape))
        print('Shape ' + str(np.array(inp_batch).shape))
        #print('Shape ' + str(np.array(gt_batch).shape))

        with tf.Session() as sess:

            # load from trained ckpt file
            saver = tf.train.Saver()
            saver.restore(sess, model_data_path)

            # Predict depth for entire batch
            #pred = sess.run(net.get_output(), feed_dict={input_node: np.squeeze(np.array(inp_batch), axis=1)})
            pred = sess.run(net.get_output(),
                            feed_dict={input_node: np.array(inp_batch)})
            print('The predicted depth map shape: ' + str(pred.shape))

        #Calculate error values for all predictions in the batch
        for ind in range(batch_size):

            mask = np.array(gt_batch)[ind] > 0.5  #assuming you have meters
            numpix = np.sum(mask)
            gt_masked = mask * np.array(gt_batch)[ind]
            print('The ground truth shape: ' +
                  str(np.array(gt_batch)[ind].shape))
            pred_masked = mask * np.array(pred)[ind]
            epsilon = 0.00001
            #print('Min value ' + str(np.min(np.array(pred)[ind])))

            #abs_rel = np.mean(np.abs(np.array(gt_batch)[ind] - pred[ind]) / np.array(gt_batch)[ind])
            abs_rel = np.sum(
                np.abs(gt_masked - pred_masked) /
                (gt_masked + epsilon)) / numpix
            rmse = (np.array(gt_batch)[ind] - pred[ind])**2
            rmse = np.sqrt(rmse.mean())
            log_10 = (np.abs(
                np.log10(np.array(gt_batch)[ind] + 0.0000000001) -
                np.log10(pred[ind] + 0.0000000001))).mean()

            #Appending to Error arrays
            abs_rels.append(abs_rel)
            rmses.append(rmse)
            log_errs.append(log_10)

        step += 1

    #Finding mean of errors from entire test set
    print('--------------------------------------------------------')
    print('Relative mean error: ' + str(np.mean(np.array(abs_rels))))
    print('RMS mean error: ' + str(np.mean(np.array(rmses))))
    print('Log 10 mean error: ' + str(np.mean(np.array(log_errs))))
コード例 #10
0
import dicom
import cv2
import matplotlib.pyplot as plt
weights = 'rvsc_o_epoch_20.h5'

crop_size = (200,200,1)
num_class = 2

model = fcn_model(crop_size,num_class,weights)

# file name 'eval.dcm'
img_file = 'eval.dcm'

img = dicom.read_file(img_file)
img = img.pixel_array.astype('int32')
img = img.reshape(img.shape[0],img.shape[1],1)

img = center_crop(img,crop_size = 200)

plt.imshow(img.reshape((200,200)))
plt.show()


result = model.predict(img.reshape((1,200,200,1)))

plt.imshow(result.reshape((200,200)))
plt.show()



コード例 #11
0
def evaluate(model_data_path, image_path, split_path):
  
    # Default input size
    height = 228
    width = 304
    channels = 5 #3
    num_test_images = 654
    batch_size = 64
    
    #Load NYU images
    f = h5py.File(image_path)
    official_split = scipy.io.loadmat(split_path) 
    indices = np.squeeze(official_split['testNdxs'], axis = 1) #indices from official NYU split
    
    abs_rels = []
    rmses = []
    log_errs = []
    
    # Create a placeholder for the input image
    input_node = tf.placeholder(tf.float32, shape=(None, height, width, channels))
    
    # Construct the network
    net = ResNet50UpProj({'data': input_node}, batch_size, 1, False)
    step = 1
    #print(indices)
    
    #Get initial metric coordinates
    fx, fy ,cx, cy = Intrinsic.initIntrinsic()
    final_fx, final_fy ,final_cx, final_cy = Intrinsic.resizeIntrinsic(228, 304 ,fx, fy ,cx, cy, 2.0) 
    orig_metric_cord = Intrinsic.findMetricCordinates(final_fx, final_fy ,final_cx, final_cy, 304, 228)
    
    # 3 crops and resize all crops to 304x228
    crop1_fx, crop1_fy ,crop1_cx, crop1_cy = Intrinsic.crop_and_resizeIntrinsic(423, 567, 468, 624,fx, fy ,cx, cy, 1.85) # 90% crop
    crop2_fx, crop2_fy ,crop2_cx, crop2_cy = Intrinsic.crop_and_resizeIntrinsic(375, 500, 468, 624,fx, fy ,cx, cy, 1.64) # 80% crop
    crop3_fx, crop3_fy ,crop3_cx, crop3_cy = Intrinsic.crop_and_resizeIntrinsic(354, 472, 468, 624,fx, fy ,cx, cy, 1.55) # 75% crop 
    
    #Get metric coordinates for cropped pics
    crop_metric_cord = []
    crop_metric_cord.append(Intrinsic.findMetricCordinates(crop1_fx, crop1_fy ,crop1_cx, crop1_cy, 304, 228))
    crop_metric_cord.append(Intrinsic.findMetricCordinates(crop2_fx, crop2_fy ,crop2_cx, crop2_cy, 304, 228))
    crop_metric_cord.append(Intrinsic.findMetricCordinates(crop3_fx, crop3_fy ,crop3_cx, crop3_cy, 304, 228))
    
    #Testing in batches
    while step * batch_size <= indices.size: #indices_size: 
        
        inp_batch = []
        gt_batch = []
        
        res_size = [[423,564], [375, 500], [354, 472]] # 90%, 80%, 75% crop
        crops = len(res_size)
        #print('Value ' + str(int(batch_size/(crops+1))))
        
        # Get the image and ground truth numpy arrays for entire batch 
        for index in indices[(step - 1) * int(batch_size/(crops+1)) : step * int(batch_size/(crops+1))]:
        #for index in range((step - 1) * int(batch_size/(crops+1)), step * int(batch_size/(crops+1))):
        
            img_file = f['images'][index-1]
            img_reshaped = np.transpose(img_file, (2, 1, 0))
            img = Image.fromarray(img_reshaped.astype(np.uint8), 'RGB')
            border = (8, 6, 8, 6) # left, up, right, bottom
            cropped_img = ImageOps.crop(img, border)
            resized_img = cropped_img.resize((304, 228), Image.BILINEAR)
            #img = np.asarray(resized_img).reshape(1, height, width, channels)
            transfrmd_img = np.concatenate((np.asarray(resized_img), orig_metric_cord), axis = 2)   
            
            #inp_batch.append(np.asarray(resized_img))
            inp_batch.append(transfrmd_img)
            #inp_batch = np.squeeze(np.array(inp_batch), axis=1)
            
            dpth_file = f['depths'][index-1].T
            #dpth = Image.open(sun_gts[index])
            dpth = Image.fromarray(dpth_file.astype(np.float64))
            cropped_dpth = ImageOps.crop(dpth, border)
            resized_dpth = cropped_dpth.resize((160, 128), Image.NEAREST)
            resized_dpth = np.expand_dims(resized_dpth, axis = 3)
            gt_batch.append(resized_dpth)
            #gt_batch = np.array(gt_batch)
            
            crop_img = []
            col_cj= []
            row_ci = []
            resize_img = []
            crop_transfrmd_img = []
            crop_dpth = []
            resize_dpth = []
            
            #print('crops ' + str(range(crops)))
            for i in range(crops):
                cropinfo = Intrinsic.center_crop(np.asarray(cropped_img), res_size[i]) #Random or center crop
                crop_img.append(cropinfo[0])
                col_cj.append(cropinfo[1])
                row_ci.append(cropinfo[2])
                resize_img.append( Image.fromarray(crop_img[i].astype(np.uint8), 'RGB').resize((304, 228), Image.BILINEAR))
                crop_transfrmd_img.append( np.concatenate((np.asarray(resize_img[i]), crop_metric_cord[i]), axis = 2))
                crop_dpth.append(np.asarray(cropped_dpth)[ row_ci[i]:row_ci[i]+res_size[i][0], col_cj[i]: col_cj[i] + res_size[i][1] ])
                resize_dpth.append(Image.fromarray(crop_dpth[i]).resize((160, 128), Image.NEAREST))
                resize_dpth[i] = np.expand_dims(resize_dpth[i], axis = 3)
                inp_batch.append(np.asarray(crop_transfrmd_img[i])) #crop_transfrmd_img[i]
                gt_batch.append(np.asarray(resize_dpth[i]))
            
        print('-------Batch: ' + str(step) + ' Images: ' + str(step * batch_size) + '-----------------')
        #print('Shape ' + str(np.squeeze(np.array(inp_batch), axis=1).shape))
        print('Shape ' + str(np.array(inp_batch).shape))
        #print('Shape ' + str(np.array(gt_batch).shape))
        
        with tf.Session() as sess:

            # load from trained ckpt file
            saver = tf.train.Saver()     
            saver.restore(sess, model_data_path)

            # Predict depth for entire batch
            #pred = sess.run(net.get_output(), feed_dict={input_node: np.squeeze(np.array(inp_batch), axis=1)})
            pred = sess.run(net.get_output(), feed_dict={input_node: np.array(inp_batch)})
            #print( 'The predicted depth map shape: ' + str(pred.shape))
            
        #Calculate error values for all predictions in the batch
        for ind in range(batch_size):
            
            mask = np.array(gt_batch)[ind] > 0.5 #assuming you have meters
            numpix = np.sum(mask)
            gt_masked = mask * np.array(gt_batch)[ind]
            pred_masked = mask * np.array(pred)[ind]
            epsilon = 0.00001
            #print('Min value ' + str(np.min(np.array(pred)[ind])))
            
            #abs_rel = np.mean(np.abs(np.array(gt_batch)[ind] - pred[ind]) / np.array(gt_batch)[ind])
            #Calculate error metrics
            abs_rel = np.sum(np.abs(gt_masked - pred_masked) / (gt_masked + epsilon)) / numpix
            rmse = (np.array(gt_batch)[ind] - pred[ind]) ** 2
            rmse = np.sqrt(rmse.mean())
            log_10 = (np.abs(np.log10(np.array(gt_batch)[ind]+0.0000000001)-np.log10(pred[ind]+0.0000000001))).mean()
            
            #Appending to Error arrays
            abs_rels.append(abs_rel)
            rmses.append(rmse)
            log_errs.append(log_10)
            
        step+=1
    
    #Finding mean of errors from entire test set
    print('--------------------------------------------------------')
    print('Relative mean error: ' + str(np.mean(np.array(abs_rels))))
    print('RMS mean error: ' + str(np.mean(np.array(rmses)))) 
    print('Log 10 mean error: ' + str(np.mean(np.array(log_errs))))