def test_bn_feature_net_3D_skip(self): receptive_field = 61 n_features = 3 n_dense_filters = 300 input_shape = (10, 32, 32, 1) n_skips = 1 for data_format in ('channels_first', 'channels_last'): with self.test_session(use_gpu=True): K.set_image_data_format(data_format) axis = 1 if data_format == 'channels_first' else -1 fgbg_model = featurenet.bn_feature_net_skip_3D( receptive_field=receptive_field, input_shape=input_shape, n_features=n_features, n_dense_filters=n_dense_filters, n_skips=n_skips, last_only=False) self.assertIsInstance(fgbg_model.output, list) self.assertEqual(len(fgbg_model.output), n_skips + 1) model = featurenet.bn_feature_net_skip_3D( receptive_field=receptive_field, input_shape=input_shape, fgbg_model=fgbg_model, n_features=n_features, n_dense_filters=n_dense_filters, n_skips=n_skips, last_only=True) self.assertEqual(len(model.output_shape), 5) self.assertEqual(model.output_shape[axis], n_features)
def resnet_trained_2(n_retrain_layers=0): K.set_image_data_format('channels_last') base_model = ResNet50(include_top=False, input_shape=(224, 224, 3)) features = GlobalAveragePooling2D()(base_model.output) model = Model(inputs=base_model.input, outputs=features) model = _set_n_retrain(model, n_retrain_layers, reinit=True) return model
def test_bn_feature_net_2D(self, include_top, padding, padding_mode, shape, dilated, multires, location, data_format): n_features = 3 n_dense_filters = 200 # BAD: dilated=True, include_top=False # BAD: inputs != None with self.cached_session(): K.set_image_data_format(data_format) model = featurenet.bn_feature_net_2D( include_top=include_top, dilated=dilated, input_shape=shape, n_features=n_features, n_dense_filters=n_dense_filters, padding=padding, padding_mode=padding_mode, multires=multires, VGG_mode=multires, location=location) self.assertEqual(len(model.output_shape), 4) output = n_features if include_top else n_dense_filters axis = 1 if data_format == 'channels_first' else -1 self.assertEqual(model.output_shape[axis], output)
def test_bn_feature_net_2D_skip(self, data_format): receptive_field = 61 n_features = 3 n_dense_filters = 300 input_shape = (256, 256, 1) n_skips = 1 with self.cached_session(): K.set_image_data_format(data_format) axis = 1 if data_format == 'channels_first' else -1 fgbg_model = featurenet.bn_feature_net_skip_2D( receptive_field=receptive_field, input_shape=input_shape, n_features=n_features, n_dense_filters=n_dense_filters, n_skips=n_skips, last_only=False) self.assertIsInstance(fgbg_model.output, list) self.assertEqual(len(fgbg_model.output), n_skips + 1) model = featurenet.bn_feature_net_skip_2D( receptive_field=receptive_field, input_shape=input_shape, fgbg_model=fgbg_model, n_features=n_features, n_dense_filters=n_dense_filters, n_skips=n_skips, last_only=True) self.assertEqual(len(model.output_shape), 4) self.assertEqual(model.output_shape[axis], n_features)
def main(): from tensorflow.python.keras.models import Model from tensorflow.python.keras.layers import Flatten, Dense, Dropout, Conv2D from tensorflow.python.keras.applications.inception_v3 import InceptionV3, preprocess_input data_format = 'channels_last' input_shape = (299, 299, 3) if data_format == 'channels_last' else (3, 299, 299) #input_shape = (2048, 2048, 3) if data_format == 'channels_last' else (3, 2048, 2048) K.set_image_data_format(data_format) net = InceptionV3(include_top=False, weights=None, input_tensor=None, input_shape=input_shape) x = net.output x = Conv2D(2, 8, activation='softmax', name='output')(x) model = Model(inputs=net.input, outputs=x) model.load_weights(h5_path, by_name=True) converted_output_node_names = [node.op.name for node in model.outputs] print(('Converted output node names are: %s', str(converted_output_node_names))) sess = K.get_session() constant_graph = graph_util.convert_variables_to_constants( sess, sess.graph.as_graph_def(), converted_output_node_names) graph_io.write_graph(constant_graph, save_path, 'model.pb', as_text=False) sess.close()
def test_bn_feature_net_3D(self, include_top, padding, padding_mode, shape, dilated, multires, location, data_format, temporal, residual, temporal_kernel_size): n_features = 3 n_dense_filters = 200 n_frames = 5 # input_shape = (10, 32, 32, 1) with self.cached_session(): K.set_image_data_format(data_format) model = featurenet.bn_feature_net_3D( include_top=include_top, dilated=dilated, n_frames=n_frames, input_shape=shape, n_features=n_features, n_dense_filters=n_dense_filters, padding=padding, padding_mode=padding_mode, multires=multires, VGG_mode=multires, location=location, temporal=temporal, residual=residual, temporal_kernel_size=temporal_kernel_size) self.assertEqual(len(model.output_shape), 5 if dilated else 2) channel_axis = 1 if data_format == 'channels_first' else -1 self.assertEqual(model.output_shape[channel_axis], n_features)
def test_distance_transform_2d(self): for img in _generate_test_masks(): K.set_image_data_format('channels_last') bins = 3 distance = transform_utils.distance_transform_2d(img, bins=bins) self.assertAllEqual(np.unique(distance), np.array([0, 1, 2])) self.assertEqual( np.expand_dims(distance, axis=-1).shape, img.shape) bins = 4 distance = transform_utils.distance_transform_2d(img, bins=bins) self.assertAllEqual(np.unique(distance), np.array([0, 1, 2, 3])) self.assertEqual( np.expand_dims(distance, axis=-1).shape, img.shape) K.set_image_data_format('channels_first') img = np.rollaxis(img, -1, 1) bins = 3 distance = transform_utils.distance_transform_2d(img, bins=bins) self.assertAllEqual(np.unique(distance), np.array([0, 1, 2])) self.assertEqual(np.expand_dims(distance, axis=1).shape, img.shape) bins = 4 distance = transform_utils.distance_transform_2d(img, bins=bins) self.assertAllEqual(np.unique(distance), np.array([0, 1, 2, 3])) self.assertEqual(np.expand_dims(distance, axis=1).shape, img.shape)
def test_distance_transform_3d(self): mask_stack = np.array(_generate_test_masks()) unique = np.zeros(mask_stack.shape) for i, mask in enumerate(_generate_test_masks()): unique[i] = label(mask) K.set_image_data_format('channels_last') bins = 3 distance = transform_utils.distance_transform_3d(unique, bins=bins) distance = np.expand_dims(distance, axis=-1) self.assertAllEqual(np.unique(distance), np.array([0, 1, 2])) self.assertEqual(distance.shape, unique.shape) bins = 4 distance = transform_utils.distance_transform_3d(unique, bins=bins) distance = np.expand_dims(distance, axis=-1) self.assertAllEqual(np.unique(distance), np.array([0, 1, 2, 3])) self.assertEqual(distance.shape, unique.shape) K.set_image_data_format('channels_first') unique = np.rollaxis(unique, -1, 1) bins = 3 distance = transform_utils.distance_transform_3d(unique, bins=bins) distance = np.expand_dims(distance, axis=1) self.assertAllEqual(np.unique(distance), np.array([0, 1, 2])) self.assertEqual(distance.shape, unique.shape) bins = 4 distance = transform_utils.distance_transform_3d(unique, bins=bins) distance = np.expand_dims(distance, axis=1) self.assertAllEqual(np.unique(distance), np.array([0, 1, 2, 3])) self.assertEqual(distance.shape, unique.shape)
def inception(n_retrain_layers=0): K.set_image_data_format('channels_last') base_model = InceptionV3(include_top=False, input_shape=(224, 224, 3)) features = GlobalAveragePooling2D()(base_model.output) model = Model(inputs=base_model.input, outputs=features) model = _set_n_retrain(model, n_retrain_layers) return model
def __init__(self, data_format='channels_last'): """Constructor function.""" # determine the input shape if data_format == 'channels_last': input_shape = (IMAGE_SIZE[0], IMAGE_SIZE[1], 3) elif data_format == 'channels_first': input_shape = (3, IMAGE_SIZE[0], IMAGE_SIZE[1]) else: raise ValueError('unrecognized data format: ' + data_format) # build the Inception-v3 backbone & final classification layer K.set_image_data_format(data_format) import ssl ssl._create_default_https_context = ssl._create_unverified_context # net = InceptionV3() # print("==============",net) net = InceptionV3(include_top=False, weights=None, input_tensor=None, input_shape=input_shape, backend=K) x = net.output x = Conv2D(NUM_CLASSES, 8, data_format=data_format, activation='softmax', name='output')(x) x = Flatten(data_format=data_format)(x) net_final = Model(inputs=net.input, outputs=x) # obtain input & output tensors self.inputs = net_final.inputs self.outputs = net_final.outputs
def wrapper(*args, **kwargs): for data_format in {'channels_first', 'channels_last'}: K.set_image_data_format(data_format) func(*args, **kwargs) if K.backend() == 'tensorflow': K.clear_session() tf.reset_default_graph()
def run_model(args): image_dim = args.image_size if args.channels_last: K.set_image_data_format('channels_last') input_shape = (image_dim, image_dim, 3) else: K.set_image_data_format('channels_first') input_shape = (3, image_dim, image_dim) num_classes = 15 batch_size = 1 resnet50 = tf.keras.applications.ResNet50(weights=None, include_top=True, input_shape=input_shape, classes=num_classes) if args.tensors_on_oom: run_options = tf.RunOptions(report_tensor_allocations_upon_oom=True) run_metadata = tf.RunMetadata() resnet50.compile(optimizer='rmsprop', loss='categorical_crossentropy', options=run_options, run_metadata=run_metadata) else: resnet50.compile(optimizer='rmsprop', loss='categorical_crossentropy') random_generator = random_image_generator(batch_size, num_classes, input_shape) steps_per_epoch = args.steps if dist_mod: steps_per_epoch = steps_per_epoch // dist_mod.size() verbose = 0 if dist_mod and dist_mod.rank() != 0 else 1 resnet50.fit_generator(random_generator, steps_per_epoch=steps_per_epoch, epochs=args.epochs, callbacks=get_callbacks(args), verbose=verbose)
def empty_resnet(): K.set_image_data_format('channels_last') base_model = ResNet50(weights=None, include_top=False, input_shape=(224, 224, 3)) features = GlobalAveragePooling2D()(base_model.output) model = Model(inputs=base_model.input, outputs=features) return model
def test_centroid_weighted_distance_transform_2d(self): centroid_dist = transform_utils.centroid_weighted_distance_transform_2d for img in _generate_test_masks(): K.set_image_data_format('channels_last') dist_x, dist_y = centroid_dist(img) self.assertEqual(str(dist_x.dtype), str(K.floatx())) self.assertEqual(dist_x.shape, img.shape) self.assertEqual(str(dist_y.dtype), str(K.floatx())) self.assertEqual(dist_y.shape, img.shape)
def load_digits8x8(): """Load image 8x8 dataset.""" data = load_digits() data.data = data.data.reshape([data.data.shape[0], 1, 8, 8]) / 16.0 # Convert NCHW to NHWC # Convert back to numpy or sklearn funcs (GridSearchCV, etc.) WILL fail data.data = np.transpose(data.data, [0, 2, 3, 1]) K.set_image_data_format("channels_last") return data
def test_get_backbone(self, backbone): with self.cached_session(): K.set_image_data_format('channels_last') inputs = Input(shape=(256, 256, 3)) model, output_dict = backbone_utils.get_backbone( backbone, inputs, return_dict=True) assert isinstance(output_dict, dict) assert all(k.startswith('C') for k in output_dict) assert isinstance(model, Model)
def test_pixelwise_transform_3d(self): frames = 10 img_list = [] for im in _generate_test_masks(): frame_list = [] for _ in range(frames): frame_list.append(label(im)) img_stack = np.array(frame_list) img_list.append(img_stack) with self.cached_session(): K.set_image_data_format('channels_last') # test single edge class maskstack = np.vstack(img_list) batch_count = maskstack.shape[0] // frames new_shape = tuple([batch_count, frames] + list(maskstack.shape[1:])) maskstack = np.reshape(maskstack, new_shape) for i in range(maskstack.shape[0]): img = maskstack[i, ...] img = np.squeeze(img) pw_img = transform_utils.pixelwise_transform( img, data_format=None, separate_edge_classes=False) pw_img_dil = transform_utils.pixelwise_transform( img, dilation_radius=2, data_format='channels_last', separate_edge_classes=False) self.assertEqual(pw_img.shape[-1], 3) self.assertEqual(pw_img_dil.shape[-1], 3) assert(np.all(np.equal(pw_img[..., 0] + pw_img[..., 1], img > 0))) self.assertGreater( pw_img_dil[..., 0].sum() + pw_img_dil[..., 1].sum(), pw_img[..., 0].sum() + pw_img[..., 1].sum()) # test separate edge classes maskstack = np.vstack(img_list) batch_count = maskstack.shape[0] // frames new_shape = tuple([batch_count, frames] + list(maskstack.shape[1:])) maskstack = np.reshape(maskstack, new_shape) for i in range(maskstack.shape[0]): img = maskstack[i, ...] img = np.squeeze(img) pw_img = transform_utils.pixelwise_transform( img, data_format=None, separate_edge_classes=True) pw_img_dil = transform_utils.pixelwise_transform( img, dilation_radius=2, data_format='channels_last', separate_edge_classes=True) self.assertEqual(pw_img.shape[-1], 4) self.assertEqual(pw_img_dil.shape[-1], 4) assert(np.all(np.equal(pw_img[..., 0] + pw_img[..., 1] + pw_img[..., 2], img > 0))) self.assertGreater( pw_img_dil[..., 0].sum() + pw_img_dil[..., 1].sum(), pw_img[..., 0].sum() + pw_img[..., 1].sum())
def test_distance_transform_continuous_2d(self): for img in _generate_test_masks(): K.set_image_data_format('channels_last') distance = transform_utils.distance_transform_continuous_2d(img) self.assertEqual(np.expand_dims(distance, axis=-1).shape, img.shape) K.set_image_data_format('channels_first') img = np.rollaxis(img, -1, 1) distance = transform_utils.distance_transform_continuous_2d(img) self.assertEqual(np.expand_dims(distance, axis=1).shape, img.shape)
def test_reshape_matrix(self): K.set_image_data_format('channels_last') X = np.zeros((1, 16, 16, 3)) y = np.zeros((1, 16, 16, 1)) new_size = 4 # test resize to smaller image, divisible new_X, new_y = data_utils.reshape_matrix(X, y, new_size) new_batch = np.ceil(16 / new_size)**2 self.assertEqual(new_X.shape, (new_batch, new_size, new_size, 3)) self.assertEqual(new_y.shape, (new_batch, new_size, new_size, 1)) # test reshape with non-divisible values. new_size = 5 new_batch = np.ceil(16 / new_size)**2 new_X, new_y = data_utils.reshape_matrix(X, y, new_size) self.assertEqual(new_X.shape, (new_batch, new_size, new_size, 3)) self.assertEqual(new_y.shape, (new_batch, new_size, new_size, 1)) # test reshape to bigger size with self.assertRaises(ValueError): new_X, new_y = data_utils.reshape_matrix(X, y, 32) # test wrong dimensions bigger = np.zeros((1, 16, 16, 3, 1)) smaller = np.zeros((1, 16, 16)) with self.assertRaises(ValueError): new_X, new_y = data_utils.reshape_matrix(smaller, y, new_size) with self.assertRaises(ValueError): new_X, new_y = data_utils.reshape_matrix(bigger, y, new_size) with self.assertRaises(ValueError): new_X, new_y = data_utils.reshape_matrix(X, smaller, new_size) with self.assertRaises(ValueError): new_X, new_y = data_utils.reshape_matrix(X, bigger, new_size) # channels_first K.set_image_data_format('channels_first') X = np.zeros((1, 3, 16, 16)) y = np.zeros((1, 1, 16, 16)) new_size = 4 # test resize to smaller image, divisible new_X, new_y = data_utils.reshape_matrix(X, y, new_size) new_batch = np.ceil(16 / new_size)**2 self.assertEqual(new_X.shape, (new_batch, 3, new_size, new_size)) self.assertEqual(new_y.shape, (new_batch, 1, new_size, new_size)) # test reshape with non-divisible values. new_size = 5 new_batch = np.ceil(16 / new_size)**2 new_X, new_y = data_utils.reshape_matrix(X, y, new_size) self.assertEqual(new_X.shape, (new_batch, 3, new_size, new_size)) self.assertEqual(new_y.shape, (new_batch, 1, new_size, new_size))
def test_get_img_shape_on_2d_image(): n = 5 channels = 4 dim1 = 1 dim2 = 2 K.set_image_data_format('channels_first') assert (n, channels, dim1, dim2) == utils.get_img_shape( K.ones(shape=(n, channels, dim1, dim2))) K.set_image_data_format('channels_last') assert (n, channels, dim1, dim2) == utils.get_img_shape( K.ones(shape=(n, dim1, dim2, channels)))
def test_retinanet(self, pooling, panoptic, location, frames, pyramid_levels, data_format): num_classes = 3 norm_method = None # not all backbones work with channels_first backbone = 'featurenet' # TODO: TimeDistributed is incompatible with channels_first if frames > 1 and data_format == 'channels_first': return with self.test_session(): K.set_image_data_format(data_format) if data_format == 'channels_first': axis = 1 input_shape = (1, 32, 32) else: axis = -1 input_shape = (32, 32, 1) num_semantic_classes = [3, 4] if frames > 1: # TODO: 3D and semantic heads is not implemented. num_semantic_classes = [] model = RetinaNet( backbone=backbone, num_classes=num_classes, input_shape=input_shape, norm_method=norm_method, location=location, pooling=pooling, panoptic=panoptic, frames_per_batch=frames, num_semantic_heads=len(num_semantic_classes), num_semantic_classes=num_semantic_classes, backbone_levels=['C3', 'C4', 'C5'], pyramid_levels=pyramid_levels, ) expected_size = 2 + panoptic * len(num_semantic_classes) self.assertIsInstance(model.output_shape, list) self.assertEqual(len(model.output_shape), expected_size) self.assertEqual(model.output_shape[0][-1], 4) self.assertEqual(model.output_shape[1][-1], num_classes) if panoptic: for i, n in enumerate(num_semantic_classes): self.assertEqual(model.output_shape[i + 2][axis], n)
def test_save_model_output(self): temp_dir = self.get_temp_dir() batches = 1 features = 3 img_w, img_h, frames = 30, 30, 5 # test channels_last K.set_image_data_format('channels_last') # test 2D output output = np.random.random((batches, img_w, img_h, features)) io_utils.save_model_output(output, temp_dir, 'test', channel=None) # test saving only one channel io_utils.save_model_output(output, temp_dir, 'test', channel=1) # test 3D output output = np.random.random((batches, frames, img_w, img_h, features)) io_utils.save_model_output(output, temp_dir, 'test', channel=None) # test saving only one channel io_utils.save_model_output(output, temp_dir, 'test', channel=1) # test channels_first 2D output = np.random.random((batches, features, img_w, img_h)) io_utils.save_model_output(output, temp_dir, 'test', channel=None, data_format='channels_first') # test channels_first 3D output = np.random.random((batches, features, frames, img_w, img_h)) io_utils.save_model_output(output, temp_dir, 'test', channel=None, data_format='channels_first') # test bad channel with self.assertRaises(ValueError): output = np.random.random((batches, features, img_w, img_h)) io_utils.save_model_output(output, temp_dir, 'test', channel=-1) io_utils.save_model_output(output, temp_dir, 'test', channel=features + 1) # test no output directory with self.assertRaises(IOError): bad_dir = os.path.join(temp_dir, 'test') io_utils.save_model_output(output, bad_dir, 'test', channel=None)
def test_trim_padding(self): # test 2d image K.set_image_data_format('channels_last') img_size = 512 win_x, win_y = 30, 30 x_trim = img_size - 2 * win_x y_trim = img_size - 2 * win_y K.set_image_data_format('channels_last') arr = np.zeros((1, img_size, img_size, 1)) arr_trim = data_utils.trim_padding(arr, win_x, win_y) self.assertEqual(arr_trim.shape, (1, x_trim, y_trim, 1)) # test channels_first K.set_image_data_format('channels_first') arr = np.zeros((1, 1, img_size, img_size)) arr_trim = data_utils.trim_padding(arr, win_x, win_y) self.assertEqual(arr_trim.shape, (1, 1, x_trim, y_trim)) # test 3d image stack img_size = 256 frames = 30 win_x, win_y = 20, 30 win_z = 2 x_trim = img_size - 2 * win_x y_trim = img_size - 2 * win_y z_trim = frames - 2 * win_z K.set_image_data_format('channels_last') arr = np.zeros((1, frames, img_size, img_size, 1)) # trim win_z arr_trim = data_utils.trim_padding(arr, win_x, win_y, win_z) self.assertEqual(arr_trim.shape, (1, z_trim, x_trim, y_trim, 1)) # don't trim win_z arr_trim = data_utils.trim_padding(arr, win_x, win_y) self.assertEqual(arr_trim.shape, (1, frames, x_trim, y_trim, 1)) # test channels_first K.set_image_data_format('channels_first') arr = np.zeros((1, 1, 30, img_size, img_size)) # trim win_z arr_trim = data_utils.trim_padding(arr, win_x, win_y, win_z) self.assertEqual(arr_trim.shape, (1, 1, z_trim, x_trim, y_trim)) # don't trim win_z arr_trim = data_utils.trim_padding(arr, win_x, win_y) self.assertEqual(arr_trim.shape, (1, 1, frames, x_trim, y_trim)) # test bad input with self.assertRaises(ValueError): small_arr = np.zeros((img_size, img_size, 1)) data_utils.trim_padding(small_arr, 10, 10) with self.assertRaises(ValueError): big_arr = np.zeros((1, 1, 30, img_size, img_size, 1)) data_utils.trim_padding(big_arr, 10, 10)
def test_get_featurenet3d_backbone(self, data_format): backbone = 'featurenet3d' input_shape = (40, 256, 256, 3) inputs = Input(shape=input_shape) with self.cached_session(): K.set_image_data_format(data_format) model, output_dict = backbone_utils.get_backbone( backbone, inputs, return_dict=True) assert isinstance(output_dict, dict) assert all(k.startswith('C') for k in output_dict) assert isinstance(model, Model) # No imagenet weights for featurenet backbone with self.assertRaises(ValueError): backbone_utils.get_backbone(backbone, inputs, use_imagenet=True)
def test_get_images_from_directory(self): temp_dir = self.get_temp_dir() _write_image(os.path.join(temp_dir, 'image.png'), 300, 300) # test channels_last K.set_image_data_format('channels_last') img = io_utils.get_images_from_directory(temp_dir, ['image']) self.assertIsInstance(img, list) self.assertEqual(len(img), 1) self.assertEqual(img[0].shape, (1, 300, 300, 1)) # test channels_last K.set_image_data_format('channels_first') img = io_utils.get_images_from_directory(temp_dir, ['image']) self.assertIsInstance(img, list) self.assertEqual(len(img), 1) self.assertEqual(img[0].shape, (1, 1, 300, 300))
def test_distance_transform_continuous_movie(self): mask_stack = np.array(_generate_test_masks()) img = np.zeros(mask_stack.shape) for i, mask in enumerate(_generate_test_masks()): img[i] = label(mask) K.set_image_data_format('channels_last') distance = transform_utils.distance_transform_continuous_movie(img) self.assertEqual(np.expand_dims(distance, axis=-1).shape, img.shape) K.set_image_data_format('channels_first') img = np.rollaxis(img, -1, 1) distance = transform_utils.distance_transform_continuous_movie(img) self.assertEqual(np.expand_dims(distance, axis=1).shape, img.shape)
def test_panopticnet(self, pooling, location, frames_per_batch, data_format, upsample_type, pyramid_levels): norm_method = None # not all backbones work with channels_first backbone = 'featurenet' # TODO: PanopticNet fails with channels_first and frames_per_batch > 1 if frames_per_batch > 1 and data_format == 'channels_first': return with self.cached_session(): K.set_image_data_format(data_format) if data_format == 'channels_first': axis = 1 input_shape = (1, 32, 32) else: axis = -1 input_shape = (32, 32, 1) num_semantic_classes = [1, 3] # temporal_mode=None, # lite=False, # interpolation='bilinear', model = PanopticNet( backbone=backbone, input_shape=input_shape, frames_per_batch=frames_per_batch, pyramid_levels=pyramid_levels, norm_method=norm_method, location=location, pooling=pooling, upsample_type=upsample_type, num_semantic_heads=len(num_semantic_classes), num_semantic_classes=num_semantic_classes, use_imagenet=False, ) self.assertIsInstance(model.output_shape, list) self.assertEqual(len(model.output_shape), len(num_semantic_classes)) for i, s in enumerate(num_semantic_classes): self.assertEqual(model.output_shape[i][axis], s)
def test_pixelwise_transform_2d(self): with self.cached_session(): K.set_image_data_format('channels_last') # test single edge class for img in _generate_test_masks(): img = label(img) img = np.squeeze(img) pw_img = transform_utils.pixelwise_transform( img, data_format=None, separate_edge_classes=False) pw_img_dil = transform_utils.pixelwise_transform( img, dilation_radius=1, data_format='channels_last', separate_edge_classes=False) self.assertEqual(pw_img.shape[-1], 3) self.assertEqual(pw_img_dil.shape[-1], 3) assert (np.all( np.equal(pw_img[..., 0] + pw_img[..., 1], img > 0))) self.assertGreater( pw_img_dil[..., 0].sum() + pw_img_dil[..., 1].sum(), pw_img[..., 0].sum() + pw_img[..., 1].sum()) # test separate edge classes for img in _generate_test_masks(): img = label(img) img = np.squeeze(img) pw_img = transform_utils.pixelwise_transform( img, data_format=None, separate_edge_classes=True) pw_img_dil = transform_utils.pixelwise_transform( img, dilation_radius=1, data_format='channels_last', separate_edge_classes=True) self.assertEqual(pw_img.shape[-1], 4) self.assertEqual(pw_img_dil.shape[-1], 4) assert (np.all( np.equal(pw_img[..., 0] + pw_img[..., 1] + pw_img[..., 2], img > 0))) self.assertGreater( pw_img_dil[..., 0].sum() + pw_img_dil[..., 1].sum(), pw_img[..., 0].sum() + pw_img[..., 1].sum())
def test_centroid_transform_continuous_movie(self): # TODO: not sure this is working properly! mask_stack = np.array(_generate_test_masks()) img = np.zeros(mask_stack.shape) for i, mask in enumerate(_generate_test_masks()): img[i] = label(mask) # pylint: disable=E1136 K.set_image_data_format('channels_last') centroids = transform_utils.centroid_transform_continuous_movie(img) print(centroids.shape) self.assertEqual(str(centroids.dtype), str(K.floatx())) self.assertEqual(centroids.shape, img.shape[:-1]) K.set_image_data_format('channels_first') centroids = transform_utils.centroid_transform_continuous_movie(img) self.assertEqual(str(centroids.dtype), str(K.floatx())) self.assertEqual(centroids.shape, img.shape[:-1])
def test_bn_feature_net_3D_skip(self, data_format): receptive_field = 61 n_features = 3 n_dense_filters = 300 input_shape = (10, 32, 32, 1) n_skips = 1 temporal = None residual = False temporal_kernel_size = 3 with self.cached_session(): K.set_image_data_format(data_format) axis = 1 if data_format == 'channels_first' else -1 fgbg_model = featurenet.bn_feature_net_skip_3D( receptive_field=receptive_field, input_shape=input_shape, n_features=n_features, n_dense_filters=n_dense_filters, n_skips=n_skips, last_only=False, temporal=temporal, residual=residual, temporal_kernel_size=temporal_kernel_size) self.assertIsInstance(fgbg_model.output, list) self.assertEqual(len(fgbg_model.output), n_skips + 1) model = featurenet.bn_feature_net_skip_3D( receptive_field=receptive_field, input_shape=input_shape, fgbg_model=fgbg_model, n_features=n_features, n_dense_filters=n_dense_filters, n_skips=n_skips, last_only=True, temporal=temporal, residual=residual, temporal_kernel_size=temporal_kernel_size) self.assertEqual(len(model.output_shape), 5) self.assertEqual(model.output_shape[axis], n_features)
def NASNet(input_shape=None, penultimate_filters=4032, num_blocks=6, stem_block_filters=96, skip_reduction=True, filter_multiplier=2, include_top=True, weights=None, input_tensor=None, pooling=None, classes=1000, default_size=None): """Instantiates a NASNet model. Note that only TensorFlow is supported for now, therefore it only works with the data format `image_data_format='channels_last'` in your Keras config at `~/.keras/keras.json`. Arguments: input_shape: Optional shape tuple, the input shape is by default `(331, 331, 3)` for NASNetLarge and `(224, 224, 3)` for NASNetMobile. It should have exactly 3 inputs channels, and width and height should be no smaller than 32. E.g. `(224, 224, 3)` would be one valid value. penultimate_filters: Number of filters in the penultimate layer. NASNet models use the notation `NASNet (N @ P)`, where: - N is the number of blocks - P is the number of penultimate filters num_blocks: Number of repeated blocks of the NASNet model. NASNet models use the notation `NASNet (N @ P)`, where: - N is the number of blocks - P is the number of penultimate filters stem_block_filters: Number of filters in the initial stem block skip_reduction: Whether to skip the reduction step at the tail end of the network. Set to `False` for CIFAR models. filter_multiplier: Controls the width of the network. - If `filter_multiplier` < 1.0, proportionally decreases the number of filters in each layer. - If `filter_multiplier` > 1.0, proportionally increases the number of filters in each layer. - If `filter_multiplier` = 1, default number of filters from the paper are used at each layer. include_top: Whether to include the fully-connected layer at the top of the network. weights: `None` (random initialization) or `imagenet` (ImageNet weights) input_tensor: Optional Keras tensor (i.e. output of `layers.Input()`) to use as image input for the model. pooling: Optional pooling mode for feature extraction when `include_top` is `False`. - `None` means that the output of the model will be the 4D tensor output of the last convolutional layer. - `avg` means that global average pooling will be applied to the output of the last convolutional layer, and thus the output of the model will be a 2D tensor. - `max` means that global max pooling will be applied. classes: Optional number of classes to classify images into, only to be specified if `include_top` is True, and if no `weights` argument is specified. default_size: Specifies the default image size of the model Returns: A Keras model instance. Raises: ValueError: In case of invalid argument for `weights`, invalid input shape or invalid `penultimate_filters` value. RuntimeError: If attempting to run this model with a backend that does not support separable convolutions. """ if K.backend() != 'tensorflow': raise RuntimeError('Only Tensorflow backend is currently supported, ' 'as other backends do not support ' 'separable convolution.') if not (weights in {'imagenet', None} or os.path.exists(weights)): raise ValueError('The `weights` argument should be either ' '`None` (random initialization), `imagenet` ' '(pre-training on ImageNet), ' 'or the path to the weights file to be loaded.') if weights == 'imagenet' and include_top and classes != 1000: raise ValueError('If using `weights` as ImageNet with `include_top` ' 'as true, `classes` should be 1000') if (isinstance(input_shape, tuple) and None in input_shape and weights == 'imagenet'): raise ValueError('When specifying the input shape of a NASNet' ' and loading `ImageNet` weights, ' 'the input_shape argument must be static ' '(no None entries). Got: `input_shape=' + str(input_shape) + '`.') if default_size is None: default_size = 331 # Determine proper input shape and default size. input_shape = _obtain_input_shape( input_shape, default_size=default_size, min_size=32, data_format=K.image_data_format(), require_flatten=False, weights=weights) if K.image_data_format() != 'channels_last': logging.warning('The NASNet family of models is only available ' 'for the input data format "channels_last" ' '(width, height, channels). ' 'However your settings specify the default ' 'data format "channels_first" (channels, width, height).' ' You should set `image_data_format="channels_last"` ' 'in your Keras config located at ~/.keras/keras.json. ' 'The model being returned right now will expect inputs ' 'to follow the "channels_last" data format.') K.set_image_data_format('channels_last') old_data_format = 'channels_first' else: old_data_format = None if input_tensor is None: img_input = Input(shape=input_shape) else: if not K.is_keras_tensor(input_tensor): img_input = Input(tensor=input_tensor, shape=input_shape) else: img_input = input_tensor if penultimate_filters % 24 != 0: raise ValueError( 'For NASNet-A models, the value of `penultimate_filters` ' 'needs to be divisible by 24. Current value: %d' % penultimate_filters) channel_dim = 1 if K.image_data_format() == 'channels_first' else -1 filters = penultimate_filters // 24 if not skip_reduction: x = Conv2D( stem_block_filters, (3, 3), strides=(2, 2), padding='valid', use_bias=False, name='stem_conv1', kernel_initializer='he_normal')( img_input) else: x = Conv2D( stem_block_filters, (3, 3), strides=(1, 1), padding='same', use_bias=False, name='stem_conv1', kernel_initializer='he_normal')( img_input) x = BatchNormalization( axis=channel_dim, momentum=0.9997, epsilon=1e-3, name='stem_bn1')( x) p = None if not skip_reduction: # imagenet / mobile mode x, p = _reduction_a_cell( x, p, filters // (filter_multiplier**2), block_id='stem_1') x, p = _reduction_a_cell( x, p, filters // filter_multiplier, block_id='stem_2') for i in range(num_blocks): x, p = _normal_a_cell(x, p, filters, block_id='%d' % (i)) x, p0 = _reduction_a_cell( x, p, filters * filter_multiplier, block_id='reduce_%d' % (num_blocks)) p = p0 if not skip_reduction else p for i in range(num_blocks): x, p = _normal_a_cell( x, p, filters * filter_multiplier, block_id='%d' % (num_blocks + i + 1)) x, p0 = _reduction_a_cell( x, p, filters * filter_multiplier**2, block_id='reduce_%d' % (2 * num_blocks)) p = p0 if not skip_reduction else p for i in range(num_blocks): x, p = _normal_a_cell( x, p, filters * filter_multiplier**2, block_id='%d' % (2 * num_blocks + i + 1)) x = Activation('relu')(x) if include_top: x = GlobalAveragePooling2D()(x) x = Dense(classes, activation='softmax', name='predictions')(x) else: if pooling == 'avg': x = GlobalAveragePooling2D()(x) elif pooling == 'max': x = GlobalMaxPooling2D()(x) # Ensure that the model takes into account # any potential predecessors of `input_tensor`. if input_tensor is not None: inputs = layer_utils.get_source_inputs(input_tensor) else: inputs = img_input model = Model(inputs, x, name='NASNet') # load weights if weights == 'imagenet': if default_size == 224: # mobile version if include_top: weight_path = NASNET_MOBILE_WEIGHT_PATH model_name = 'nasnet_mobile.h5' else: weight_path = NASNET_MOBILE_WEIGHT_PATH_NO_TOP model_name = 'nasnet_mobile_no_top.h5' weights_file = get_file(model_name, weight_path, cache_subdir='models') model.load_weights(weights_file) elif default_size == 331: # large version if include_top: weight_path = NASNET_LARGE_WEIGHT_PATH model_name = 'nasnet_large.h5' else: weight_path = NASNET_LARGE_WEIGHT_PATH_NO_TOP model_name = 'nasnet_large_no_top.h5' weights_file = get_file(model_name, weight_path, cache_subdir='models') model.load_weights(weights_file) else: raise ValueError('ImageNet weights can only be loaded with NASNetLarge' ' or NASNetMobile') elif weights is not None: model.load_weights(weights) if old_data_format: K.set_image_data_format(old_data_format) return model
def test_model_with_crossentropy_losses_channels_first(self): """Tests use of all crossentropy losses with `channels_first`. Tests `sparse_categorical_crossentropy`, `categorical_crossentropy`, and `binary_crossentropy`. Verifies that evaluate gives the same result with either `channels_first` or `channels_last` image_data_format. """ def prepare_simple_model(input_tensor, loss_name, target): axis = 1 if K.image_data_format() == 'channels_first' else -1 loss = None num_channels = None activation = None if loss_name == 'sparse_categorical_crossentropy': loss = lambda y_true, y_pred: K.sparse_categorical_crossentropy( # pylint: disable=g-long-lambda y_true, y_pred, axis=axis) num_channels = np.amax(target) + 1 activation = 'softmax' elif loss_name == 'categorical_crossentropy': loss = lambda y_true, y_pred: K.categorical_crossentropy( # pylint: disable=g-long-lambda y_true, y_pred, axis=axis) num_channels = target.shape[axis] activation = 'softmax' elif loss_name == 'binary_crossentropy': loss = lambda y_true, y_pred: K.binary_crossentropy(y_true, y_pred) # pylint: disable=unnecessary-lambda num_channels = target.shape[axis] activation = 'sigmoid' predictions = Conv2D(num_channels, 1, activation=activation, kernel_initializer='ones', bias_initializer='ones')(input_tensor) simple_model = keras.models.Model(inputs=input_tensor, outputs=predictions) simple_model.compile(optimizer='rmsprop', loss=loss) return simple_model if test.is_gpu_available(cuda_only=True): with test_util.use_gpu(): losses_to_test = ['sparse_categorical_crossentropy', 'categorical_crossentropy', 'binary_crossentropy'] data_channels_first = np.array([[[[8., 7.1, 0.], [4.5, 2.6, 0.55], [0.9, 4.2, 11.2]]]], dtype=np.float32) # Labels for testing 4-class sparse_categorical_crossentropy, 4-class # categorical_crossentropy, and 2-class binary_crossentropy: labels_channels_first = [np.array([[[[0, 1, 3], [2, 1, 0], [2, 2, 1]]]], dtype=np.float32), # pylint: disable=line-too-long np.array([[[[0, 1, 0], [0, 1, 0], [0, 0, 0]], [[1, 0, 0], [0, 0, 1], [0, 1, 0]], [[0, 0, 0], [1, 0, 0], [0, 0, 1]], [[0, 0, 1], [0, 0, 0], [1, 0, 0]]]], dtype=np.float32), # pylint: disable=line-too-long np.array([[[[0, 1, 0], [0, 1, 0], [0, 0, 1]], [[1, 0, 1], [1, 0, 1], [1, 1, 0]]]], dtype=np.float32)] # pylint: disable=line-too-long # Compute one loss for each loss function in the list `losses_to_test`: loss_channels_last = [0., 0., 0.] loss_channels_first = [0., 0., 0.] old_data_format = K.image_data_format() # Evaluate a simple network with channels last, with all three loss # functions: K.set_image_data_format('channels_last') data = np.moveaxis(data_channels_first, 1, -1) for index, loss_function in enumerate(losses_to_test): labels = np.moveaxis(labels_channels_first[index], 1, -1) inputs = keras.Input(shape=(3, 3, 1)) model = prepare_simple_model(inputs, loss_function, labels) loss_channels_last[index] = model.evaluate(x=data, y=labels, batch_size=1, verbose=0) # Evaluate the same network with channels first, with all three loss # functions: K.set_image_data_format('channels_first') data = data_channels_first for index, loss_function in enumerate(losses_to_test): labels = labels_channels_first[index] inputs = keras.Input(shape=(1, 3, 3)) model = prepare_simple_model(inputs, loss_function, labels) loss_channels_first[index] = model.evaluate(x=data, y=labels, batch_size=1, verbose=0) K.set_image_data_format(old_data_format) np.testing.assert_allclose(loss_channels_first, loss_channels_last, err_msg='{}{}'.format( 'Computed different losses for ', 'channels_first and channels_last'))
def Xception(include_top=True, weights='imagenet', input_tensor=None, input_shape=None, pooling=None, classes=1000): """Instantiates the Xception architecture. Optionally loads weights pre-trained on ImageNet. This model is available for TensorFlow only, and can only be used with inputs following the TensorFlow data format `(width, height, channels)`. You should set `image_data_format='channels_last'` in your Keras config located at ~/.keras/keras.json. Note that the default input image size for this model is 299x299. Arguments: include_top: whether to include the fully-connected layer at the top of the network. weights: one of `None` (random initialization), 'imagenet' (pre-training on ImageNet), or the path to the weights file to be loaded. input_tensor: optional Keras tensor (i.e. output of `layers.Input()`) to use as image input for the model. input_shape: optional shape tuple, only to be specified if `include_top` is False (otherwise the input shape has to be `(299, 299, 3)`. It should have exactly 3 inputs channels, and width and height should be no smaller than 71. E.g. `(150, 150, 3)` would be one valid value. pooling: Optional pooling mode for feature extraction when `include_top` is `False`. - `None` means that the output of the model will be the 4D tensor output of the last convolutional layer. - `avg` means that global average pooling will be applied to the output of the last convolutional layer, and thus the output of the model will be a 2D tensor. - `max` means that global max pooling will be applied. classes: optional number of classes to classify images into, only to be specified if `include_top` is True, and if no `weights` argument is specified. Returns: A Keras model instance. Raises: ValueError: in case of invalid argument for `weights`, or invalid input shape. RuntimeError: If attempting to run this model with a backend that does not support separable convolutions. """ if not (weights in {'imagenet', None} or os.path.exists(weights)): raise ValueError('The `weights` argument should be either ' '`None` (random initialization), `imagenet` ' '(pre-training on ImageNet), ' 'or the path to the weights file to be loaded.') if weights == 'imagenet' and include_top and classes != 1000: raise ValueError('If using `weights` as imagenet with `include_top`' ' as true, `classes` should be 1000') if K.image_data_format() != 'channels_last': logging.warning( 'The Xception model is only available for the ' 'input data format "channels_last" ' '(width, height, channels). ' 'However your settings specify the default ' 'data format "channels_first" (channels, width, height). ' 'You should set `image_data_format="channels_last"` in your Keras ' 'config located at ~/.keras/keras.json. ' 'The model being returned right now will expect inputs ' 'to follow the "channels_last" data format.') K.set_image_data_format('channels_last') old_data_format = 'channels_first' else: old_data_format = None # Determine proper input shape input_shape = _obtain_input_shape( input_shape, default_size=299, min_size=71, data_format=K.image_data_format(), require_flatten=False, weights=weights) if input_tensor is None: img_input = Input(shape=input_shape) else: if not K.is_keras_tensor(input_tensor): img_input = Input(tensor=input_tensor, shape=input_shape) else: img_input = input_tensor x = Conv2D( 32, (3, 3), strides=(2, 2), use_bias=False, name='block1_conv1')( img_input) x = BatchNormalization(name='block1_conv1_bn')(x) x = Activation('relu', name='block1_conv1_act')(x) x = Conv2D(64, (3, 3), use_bias=False, name='block1_conv2')(x) x = BatchNormalization(name='block1_conv2_bn')(x) x = Activation('relu', name='block1_conv2_act')(x) residual = Conv2D( 128, (1, 1), strides=(2, 2), padding='same', use_bias=False)( x) residual = BatchNormalization()(residual) x = SeparableConv2D( 128, (3, 3), padding='same', use_bias=False, name='block2_sepconv1')( x) x = BatchNormalization(name='block2_sepconv1_bn')(x) x = Activation('relu', name='block2_sepconv2_act')(x) x = SeparableConv2D( 128, (3, 3), padding='same', use_bias=False, name='block2_sepconv2')( x) x = BatchNormalization(name='block2_sepconv2_bn')(x) x = MaxPooling2D( (3, 3), strides=(2, 2), padding='same', name='block2_pool')( x) x = layers.add([x, residual]) residual = Conv2D( 256, (1, 1), strides=(2, 2), padding='same', use_bias=False)( x) residual = BatchNormalization()(residual) x = Activation('relu', name='block3_sepconv1_act')(x) x = SeparableConv2D( 256, (3, 3), padding='same', use_bias=False, name='block3_sepconv1')( x) x = BatchNormalization(name='block3_sepconv1_bn')(x) x = Activation('relu', name='block3_sepconv2_act')(x) x = SeparableConv2D( 256, (3, 3), padding='same', use_bias=False, name='block3_sepconv2')( x) x = BatchNormalization(name='block3_sepconv2_bn')(x) x = MaxPooling2D( (3, 3), strides=(2, 2), padding='same', name='block3_pool')( x) x = layers.add([x, residual]) residual = Conv2D( 728, (1, 1), strides=(2, 2), padding='same', use_bias=False)( x) residual = BatchNormalization()(residual) x = Activation('relu', name='block4_sepconv1_act')(x) x = SeparableConv2D( 728, (3, 3), padding='same', use_bias=False, name='block4_sepconv1')( x) x = BatchNormalization(name='block4_sepconv1_bn')(x) x = Activation('relu', name='block4_sepconv2_act')(x) x = SeparableConv2D( 728, (3, 3), padding='same', use_bias=False, name='block4_sepconv2')( x) x = BatchNormalization(name='block4_sepconv2_bn')(x) x = MaxPooling2D( (3, 3), strides=(2, 2), padding='same', name='block4_pool')( x) x = layers.add([x, residual]) for i in range(8): residual = x prefix = 'block' + str(i + 5) x = Activation('relu', name=prefix + '_sepconv1_act')(x) x = SeparableConv2D( 728, (3, 3), padding='same', use_bias=False, name=prefix + '_sepconv1')( x) x = BatchNormalization(name=prefix + '_sepconv1_bn')(x) x = Activation('relu', name=prefix + '_sepconv2_act')(x) x = SeparableConv2D( 728, (3, 3), padding='same', use_bias=False, name=prefix + '_sepconv2')( x) x = BatchNormalization(name=prefix + '_sepconv2_bn')(x) x = Activation('relu', name=prefix + '_sepconv3_act')(x) x = SeparableConv2D( 728, (3, 3), padding='same', use_bias=False, name=prefix + '_sepconv3')( x) x = BatchNormalization(name=prefix + '_sepconv3_bn')(x) x = layers.add([x, residual]) residual = Conv2D( 1024, (1, 1), strides=(2, 2), padding='same', use_bias=False)( x) residual = BatchNormalization()(residual) x = Activation('relu', name='block13_sepconv1_act')(x) x = SeparableConv2D( 728, (3, 3), padding='same', use_bias=False, name='block13_sepconv1')( x) x = BatchNormalization(name='block13_sepconv1_bn')(x) x = Activation('relu', name='block13_sepconv2_act')(x) x = SeparableConv2D( 1024, (3, 3), padding='same', use_bias=False, name='block13_sepconv2')( x) x = BatchNormalization(name='block13_sepconv2_bn')(x) x = MaxPooling2D( (3, 3), strides=(2, 2), padding='same', name='block13_pool')( x) x = layers.add([x, residual]) x = SeparableConv2D( 1536, (3, 3), padding='same', use_bias=False, name='block14_sepconv1')( x) x = BatchNormalization(name='block14_sepconv1_bn')(x) x = Activation('relu', name='block14_sepconv1_act')(x) x = SeparableConv2D( 2048, (3, 3), padding='same', use_bias=False, name='block14_sepconv2')( x) x = BatchNormalization(name='block14_sepconv2_bn')(x) x = Activation('relu', name='block14_sepconv2_act')(x) if include_top: x = GlobalAveragePooling2D(name='avg_pool')(x) x = Dense(classes, activation='softmax', name='predictions')(x) else: if pooling == 'avg': x = GlobalAveragePooling2D()(x) elif pooling == 'max': x = GlobalMaxPooling2D()(x) # Ensure that the model takes into account # any potential predecessors of `input_tensor`. if input_tensor is not None: inputs = get_source_inputs(input_tensor) else: inputs = img_input # Create model. model = Model(inputs, x, name='xception') # load weights if weights == 'imagenet': if include_top: weights_path = get_file( 'xception_weights_tf_dim_ordering_tf_kernels.h5', TF_WEIGHTS_PATH, cache_subdir='models', file_hash='0a58e3b7378bc2990ea3b43d5981f1f6') else: weights_path = get_file( 'xception_weights_tf_dim_ordering_tf_kernels_notop.h5', TF_WEIGHTS_PATH_NO_TOP, cache_subdir='models', file_hash='b0042744bf5b25fce3cb969f33bebb97') model.load_weights(weights_path) elif weights is not None: model.load_weights(weights) if old_data_format: K.set_image_data_format(old_data_format) return model
def MobileNet(input_shape=None, alpha=1.0, depth_multiplier=1, dropout=1e-3, include_top=True, weights='imagenet', input_tensor=None, pooling=None, classes=1000): """Instantiates the MobileNet architecture. To load a MobileNet model via `load_model`, import the custom objects `relu6` and pass them to the `custom_objects` parameter. E.g. model = load_model('mobilenet.h5', custom_objects={ 'relu6': mobilenet.relu6}) Arguments: input_shape: optional shape tuple, only to be specified if `include_top` is False (otherwise the input shape has to be `(224, 224, 3)` (with `channels_last` data format) or (3, 224, 224) (with `channels_first` data format). It should have exactly 3 inputs channels, and width and height should be no smaller than 32. E.g. `(200, 200, 3)` would be one valid value. alpha: controls the width of the network. - If `alpha` < 1.0, proportionally decreases the number of filters in each layer. - If `alpha` > 1.0, proportionally increases the number of filters in each layer. - If `alpha` = 1, default number of filters from the paper are used at each layer. depth_multiplier: depth multiplier for depthwise convolution (also called the resolution multiplier) dropout: dropout rate include_top: whether to include the fully-connected layer at the top of the network. weights: one of `None` (random initialization), 'imagenet' (pre-training on ImageNet), or the path to the weights file to be loaded. input_tensor: optional Keras tensor (i.e. output of `layers.Input()`) to use as image input for the model. pooling: Optional pooling mode for feature extraction when `include_top` is `False`. - `None` means that the output of the model will be the 4D tensor output of the last convolutional layer. - `avg` means that global average pooling will be applied to the output of the last convolutional layer, and thus the output of the model will be a 2D tensor. - `max` means that global max pooling will be applied. classes: optional number of classes to classify images into, only to be specified if `include_top` is True, and if no `weights` argument is specified. Returns: A Keras model instance. Raises: ValueError: in case of invalid argument for `weights`, or invalid input shape. RuntimeError: If attempting to run this model with a backend that does not support separable convolutions. """ if not (weights in {'imagenet', None} or os.path.exists(weights)): raise ValueError('The `weights` argument should be either ' '`None` (random initialization), `imagenet` ' '(pre-training on ImageNet), ' 'or the path to the weights file to be loaded.') if weights == 'imagenet' and include_top and classes != 1000: raise ValueError('If using `weights` as ImageNet with `include_top` ' 'as true, `classes` should be 1000') # Determine proper input shape and default size. if input_shape is None: default_size = 224 else: if K.image_data_format() == 'channels_first': rows = input_shape[1] cols = input_shape[2] else: rows = input_shape[0] cols = input_shape[1] if rows == cols and rows in [128, 160, 192, 224]: default_size = rows else: default_size = 224 input_shape = _obtain_input_shape( input_shape, default_size=default_size, min_size=32, data_format=K.image_data_format(), require_flatten=include_top, weights=weights) if K.image_data_format() == 'channels_last': row_axis, col_axis = (0, 1) else: row_axis, col_axis = (1, 2) rows = input_shape[row_axis] cols = input_shape[col_axis] if weights == 'imagenet': if depth_multiplier != 1: raise ValueError('If imagenet weights are being loaded, ' 'depth multiplier must be 1') if alpha not in [0.25, 0.50, 0.75, 1.0]: raise ValueError('If imagenet weights are being loaded, ' 'alpha can be one of' '`0.25`, `0.50`, `0.75` or `1.0` only.') if rows != cols or rows not in [128, 160, 192, 224]: if rows is None: rows = 224 logging.warning('MobileNet shape is undefined.' ' Weights for input shape (224, 224) will be loaded.') else: raise ValueError('If imagenet weights are being loaded, ' 'input must have a static square shape (one of ' '(128, 128), (160, 160), (192, 192), or (224, 224)).' ' Input shape provided = %s' % (input_shape,)) if K.image_data_format() != 'channels_last': logging.warning('The MobileNet family of models is only available ' 'for the input data format "channels_last" ' '(width, height, channels). ' 'However your settings specify the default ' 'data format "channels_first" (channels, width, height).' ' You should set `image_data_format="channels_last"` ' 'in your Keras config located at ~/.keras/keras.json. ' 'The model being returned right now will expect inputs ' 'to follow the "channels_last" data format.') K.set_image_data_format('channels_last') old_data_format = 'channels_first' else: old_data_format = None if input_tensor is None: img_input = Input(shape=input_shape) else: if not K.is_keras_tensor(input_tensor): img_input = Input(tensor=input_tensor, shape=input_shape) else: img_input = input_tensor x = _conv_block(img_input, 32, alpha, strides=(2, 2)) x = _depthwise_conv_block(x, 64, alpha, depth_multiplier, block_id=1) x = _depthwise_conv_block( x, 128, alpha, depth_multiplier, strides=(2, 2), block_id=2) x = _depthwise_conv_block(x, 128, alpha, depth_multiplier, block_id=3) x = _depthwise_conv_block( x, 256, alpha, depth_multiplier, strides=(2, 2), block_id=4) x = _depthwise_conv_block(x, 256, alpha, depth_multiplier, block_id=5) x = _depthwise_conv_block( x, 512, alpha, depth_multiplier, strides=(2, 2), block_id=6) x = _depthwise_conv_block(x, 512, alpha, depth_multiplier, block_id=7) x = _depthwise_conv_block(x, 512, alpha, depth_multiplier, block_id=8) x = _depthwise_conv_block(x, 512, alpha, depth_multiplier, block_id=9) x = _depthwise_conv_block(x, 512, alpha, depth_multiplier, block_id=10) x = _depthwise_conv_block(x, 512, alpha, depth_multiplier, block_id=11) x = _depthwise_conv_block( x, 1024, alpha, depth_multiplier, strides=(2, 2), block_id=12) x = _depthwise_conv_block(x, 1024, alpha, depth_multiplier, block_id=13) if include_top: if K.image_data_format() == 'channels_first': shape = (int(1024 * alpha), 1, 1) else: shape = (1, 1, int(1024 * alpha)) x = GlobalAveragePooling2D()(x) x = Reshape(shape, name='reshape_1')(x) x = Dropout(dropout, name='dropout')(x) x = Conv2D(classes, (1, 1), padding='same', name='conv_preds')(x) x = Activation('softmax', name='act_softmax')(x) x = Reshape((classes,), name='reshape_2')(x) else: if pooling == 'avg': x = GlobalAveragePooling2D()(x) elif pooling == 'max': x = GlobalMaxPooling2D()(x) # Ensure that the model takes into account # any potential predecessors of `input_tensor`. if input_tensor is not None: inputs = get_source_inputs(input_tensor) else: inputs = img_input # Create model. model = Model(inputs, x, name='mobilenet_%0.2f_%s' % (alpha, rows)) # load weights if weights == 'imagenet': if K.image_data_format() == 'channels_first': raise ValueError('Weights for "channels_first" format ' 'are not available.') if alpha == 1.0: alpha_text = '1_0' elif alpha == 0.75: alpha_text = '7_5' elif alpha == 0.50: alpha_text = '5_0' else: alpha_text = '2_5' if include_top: model_name = 'mobilenet_%s_%d_tf.h5' % (alpha_text, rows) weigh_path = BASE_WEIGHT_PATH + model_name weights_path = get_file(model_name, weigh_path, cache_subdir='models') else: model_name = 'mobilenet_%s_%d_tf_no_top.h5' % (alpha_text, rows) weigh_path = BASE_WEIGHT_PATH + model_name weights_path = get_file(model_name, weigh_path, cache_subdir='models') model.load_weights(weights_path) elif weights is not None: model.load_weights(weights) if old_data_format: K.set_image_data_format(old_data_format) return model