def build_model(): inputs = keras.Input(shape=(IMAGE_SIZE[0], IMAGE_SIZE[1], 3)) x = preprocessing.Rescaling(1.0 / 255)(inputs) x = layers.Conv2D(16, 3, activation="relu", padding="same")(x) x = layers.Conv2D(16, 3, activation="relu", padding="same")(x) x = layers.MaxPool2D()(x) x = conv_block(32, x) x = conv_block(64, x) x = conv_block(128, x) x = layers.Dropout(0.2)(x) x = conv_block(256, x) x = layers.Dropout(0.2)(x) x = layers.Flatten()(x) x = dense_block(512, 0.7, x) x = dense_block(128, 0.5, x) x = dense_block(64, 0.3, x) outputs = layers.Dense(1, activation="sigmoid")(x) model = keras.Model(inputs=inputs, outputs=outputs) return model
def prepare_model(input_shape, learning_rate, architecture='mobilenetv2'): """Prepare CNN classifier for training.""" if architecture == 'mobilenetv2': # Load MobileNetV2 trained on ImageNet for transfer learning base_model = keras.applications.MobileNetV2(input_shape=input_shape, include_top=False, weights='imagenet') # Unlock all weights for retraining base_model.trainable = True # Add bottom and top layers model = keras.Sequential([ # Rescaling layer for faster preprocessing preprocessing.Rescaling(1.0 / 255), base_model, layers.GlobalAveragePooling2D(), layers.Dense(1, activation='sigmoid') ]) else: raise ValueError('chosen architecture is not available') # Specify optimizer and loss function model.compile(optimizer=keras.optimizers.Adam(lr=learning_rate), loss=keras.losses.BinaryCrossentropy(), metrics=[ keras.metrics.BinaryAccuracy(name='accuracy'), keras.metrics.Precision(name='precision'), keras.metrics.Recall(name='recall') ]) return model
def save(self, path): if not self.is_automl: model = self.model.export()#.load_weights(path) else: model = self.model.export_model()#.load_weights(path) # pop input layer # model._layers.pop(0) model.layers.pop(0) # pop last layer # model.summary() if self.args.DATA.RANDOM_CROP: height = self.args.DATA.RANDOM_CROP_SIZE[1] width = self.args.DATA.RANDOM_CROP_SIZE[0] else: height = self.args.DATA.SIZE[1] width = self.args.DATA.SIZE[0] # print(f'shape: h: {height}, w: {width}') # model.summary() input = tf.keras.Input(shape=(height, width, 3)) x = preprocessing.Rescaling(1./255)(input) normalized_input = x - [[self.args.DATA.MEAN]] normalized_input = normalized_input / [[self.args.DATA.STD]] new_output = model(normalized_input) # model.summary() model = tf.keras.models.Model(inputs=input, outputs=new_output) self.model = model self.compile() self.model.summary() # self.model.save(path) tf.saved_model.save(self.model, path)
def create_model(self, pretrained_model, downstream_model=None, add_output_layer=True): self.pretrained_model = pretrained_model inputs = layers.Input(shape=self.INPUT_SHAPE, name='input_layer') if self.data_augment: x = self._get_data_augment_layer()(inputs) else: x = inputs if self.scale: x = KerasPreprocessing.Rescaling(self.SCALING_FACTOR)(x) self.pretrained_model.trainable = False features = self.pretrained_model(x) if downstream_model is None: self.downstream_model = self._get_default_downstream_model() else: self.downstream_model = downstream_model final_hidden = self.downstream_model(features) if add_output_layer: outputs = layers.Dense(self.n_classes, activation='softmax', name='output_layer')(final_hidden) else: outputs = final_hidden self.model = tf.keras.models.Model(inputs, outputs) self.set_training_mode(self.mode)
def build_model(num_classes, img_size=image_size[0], top_dropout=0.3): """Creates a classifier based on pre-trained MobileNetV2. Arguments: num_classes: Int, number of classese to use in the softmax layer. img_size: Int, square size of input images (defaults is 224). top_dropout: Int, value for dropout layer (defaults is 0.3). Returns: Uncompiled Keras model. """ # Create input and pre-processing layers for MobileNetV2 inputs = layers.Input(shape=(img_size, img_size, 3)) x = preprocessing.Rescaling(scale=1.0 / 127.5, offset=-1)(inputs) model = keras.applications.MobileNetV2(include_top=False, weights="imagenet", input_tensor=x) # Freeze the pretrained weights model.trainable = False # Rebuild top x = layers.GlobalAveragePooling2D(name="avg_pool")(model.output) x = layers.Dropout(top_dropout)(x) outputs = layers.Dense(num_classes, activation="softmax")(x) model = keras.Model(inputs, outputs) print("Trainable weights:", len(model.trainable_weights)) print("Non_trainable weights:", len(model.non_trainable_weights)) return model
def export(self): output = self.model.output output = self.fc(output) if self.cfg.MODEL.TEMPERATURE_SCALING != 1: output = preprocessing.Rescaling( 1. / self.cfg.MODEL.TEMPERATURE_SCALING)(output) output = self.softmax(output) return Model(inputs=self.model.input, outputs=output)
def get_augmenter(min_area, brightness, jitter): zoom_factor = 1.0 - tf.sqrt(min_area) return keras.Sequential([ keras.Input(shape=(image_size, image_size, image_channels)), preprocessing.Rescaling(1 / 255), preprocessing.RandomFlip("horizontal"), preprocessing.RandomTranslation(zoom_factor / 2, zoom_factor / 2), preprocessing.RandomZoom((-zoom_factor, 0.0), (-zoom_factor, 0.0)), RandomColorAffine(brightness, jitter), ])
def get_binary_vector_input(name, dataset): rescaling = exp_preprocessing.Rescaling(scale=2, offset=-1) # Prepare a Dataset that only yields our feature. feature_ds = dataset.map(lambda x, y: x[name]) # Learn the statistics of the data. rescaling.adapt(feature_ds) return rescaling
def build_model(num_classes, img_shape=(32, None, 3)): img_input = keras.Input(shape=img_shape) x = preprocessing.Rescaling(1.0 / 255)(img_input) x = vgg_style(x) x = layers.Bidirectional(layers.LSTM(units=256, return_sequences=True), name='bi_lstm1')(x) x = layers.Bidirectional(layers.LSTM(units=256, return_sequences=True), name='bi_lstm2')(x) logits = layers.Dense(units=num_classes, name='logits')(x) return keras.Model(inputs=img_input, outputs=logits, name='CRNN')
def define_model(layers: List[int], img_height: int, img_width: int, data_augmentation_layers: Optional[List[PreprocessingLayer]] = None, dropout: Optional[int] = None, batch_normalization: bool = False, activation_function: str = "relu"): """ Creates the CNN model. :param layers: A list of filter sizes. For each entry, an additional Conv2D layers with the specified filter and a MaxPooling2D layer will be added. :param img_height: The height of each image. Images that do not match this weight will be rescaled. :param img_width: The width of each image. Images that do not match this width will be rescaled. :param data_augmentation_layers: The list of data augmentation strategies to apply. :param dropout: The dropout value to use [0, 1]. 0 to disable. :param batch_normalization: Whether to apply batch normalization to each combination. :param activation_function: The activation function to use in the final layer. :return: The compiled model. """ print("Creating CNN...") model = Sequential() if data_augmentation_layers is not None: for data_augmentation_layer in data_augmentation_layers: model.add(data_augmentation_layer) # Scale the input images to [0-1] instead of [0-255] to improve performance a bit. model.add(preprocessing.Rescaling(1. / 255, input_shape=(img_height, img_width, 3))) for filter_size in layers: model.add(Conv2D(filters=filter_size, kernel_size=3, activation="relu", padding="SAME")) if batch_normalization: model.add(BatchNormalization()) model.add(MaxPooling2D()) if dropout is not None: model.add(Dropout(dropout)) model.add(Flatten()) model.add(Dense(128, activation="relu")), model.add(Dense(10, activation=activation_function)) model.compile( optimizer=tf.optimizers.Adam(), loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True), metrics=["accuracy"] ) return model
def get_test_data(category, batch_size=32, image_size=128, patch_size=128): test_data_dir = f'data/mvtec-ad/{category}/test/' dataset_kwargs = dict(image_size=(image_size, image_size), batch_size=batch_size, shuffle=False) rescale = P.Rescaling(scale=1. / 127.5, offset=-1) # scale from [0, 255] to [-1, 1] ### test dataset # load and resize images (load also labels for test dataset) test_dataset = image_dataset_from_directory(test_data_dir, **dataset_kwargs) test_labels = test_dataset.class_names # rescale pixel range, cache test_dataset = test_dataset.map(lambda x, y: (rescale(x), y), num_parallel_calls=AUTOTUNE) test_dataset = test_dataset.cache() test_dataset = test_dataset.prefetch(buffer_size=AUTOTUNE) return test_dataset, test_labels
def build_efficient_net_model(block_specs, nn_spec): import tensorflow.keras.layers as L _kernel_initializer = tf.keras.initializers.VarianceScaling( scale=2.0, mode='fan_out', distribution='normal') _dense_kernel_initializer = tf.keras.initializers.VarianceScaling( scale=1. / 3, mode='fan_out', distribution='uniform') inputs = tf.keras.Input(shape=(224, 224, 3)) x = preprocessing.Rescaling(1. / 255)(inputs) x = preprocessing.Normalization()(x) x = L.Conv2D(round_filters(32, nn_spec.w, nn_spec.depth_divisor), kernel_size=3, strides=2, kernel_initializer=_kernel_initializer, padding='same', use_bias=False, name='stem_conv')(x) x = L.BatchNormalization(name='stem_bn')(x) x = L.Activation(nn_spec.activation, name='stem_nonlinear')(x) # Several stages of MobileNetV2 blocks block_num_sum = sum( round_repeats(block_spec.repeat_num, nn_spec.d) for block_spec in block_specs) * 1. block_index = 0 for block_stage, block_spec in enumerate(block_specs): block_spec = block_spec._replace( input_nf=round_filters(block_spec.input_nf, nn_spec.w, nn_spec.depth_divisor), output_nf=round_filters(block_spec.output_nf, nn_spec.w, nn_spec.depth_divisor), repeat_num=round_repeats(block_spec.repeat_num, nn_spec.d)) for sub_block_index in range(block_spec.repeat_num): block_spec = block_spec._replace( drop_conn_rate=nn_spec.drop_conn_rate * block_index / block_num_sum, prefix='block{}{}_'.format(block_stage + 1, chr(sub_block_index + 97))) if sub_block_index > 0: block_spec = block_spec._replace(dw_strides=1, input_nf=block_spec.output_nf) x = mobilenet_v2_block(x, block_spec) # self._building_blocks.append(block_spec) block_index += 1 # cnn head x = tf.keras.layers.Conv2D(round_filters(1280, nn_spec.w, nn_spec.depth_divisor), kernel_size=1, strides=1, kernel_initializer=_kernel_initializer, padding='same', use_bias=False, name='head_conv')(x) x = L.BatchNormalization(name='head_bn')(x) x = L.Activation(nn_spec.activation, name='head_nonlinear')(x) if nn_spec.include_top: x = L.GlobalAveragePooling2D(name='top_pooling')(x) if nn_spec.dropout_rate > 0: x = L.Dropout(nn_spec.dropout_rate, name='top_dropout')(x) x = tf.keras.layers.Dense(nn_spec.classes, activation='softmax', kernel_initializer=_dense_kernel_initializer, name='probs')(x) else: if nn_spec.pooling == 'avg': x = tf.keras.layers.GlobalAveragePooling2D(name='top_pooling')(x) elif nn_spec.pooling == 'max': x = tf.keras.layers.GlobalMaxPool2D(name='top_pooling')(x) else: pass model = tf.keras.Model(inputs=[inputs], outputs=[x]) return model
] ) # Load some data (x_train, y_train), _ = keras.datasets.cifar10.load_data() input_shape = x_train.shape[1:] classes = 10 # Create a tf.data pipeline of augmented images (and their labels) train_dataset = tf.data.Dataset.from_tensor_slices((x_train, y_train)) train_dataset = train_dataset.batch(16).map(lambda x, y: (data_augmentation(x), y)) # Create a model and train it on the augmented image data inputs = keras.Input(shape=input_shape) x = preprocessing.Rescaling(1.0 / 255)(inputs) # Rescale inputs outputs = keras.applications.ResNet50( # Add the rest of the model weights=None, input_shape=input_shape, classes=classes )(x) model = keras.Model(inputs, outputs) model.compile(optimizer="rmsprop", loss="sparse_categorical_crossentropy") model.fit(train_dataset, steps_per_epoch=5) """ You can see a similar setup in action in the example [image classification from scratch](https://keras.io/examples/vision/image_classification_from_scratch/). """ """ ### Normalizing numerical features """
}, } # load STL10 dataset batch_size, train_dataset, labeled_train_dataset, test_dataset = prepare_dataset( steps_per_epoch) # select an algorithm Algorithm = SimCLR # SimCLR, BarlowTwins, MoCo, DINO # architecture model = Algorithm( contrastive_augmenter=keras.Sequential( [ layers.Input(shape=(96, 96, 3)), preprocessing.Rescaling(1 / 255), preprocessing.RandomFlip("horizontal"), RandomResizedCrop(scale=(0.2, 1.0), ratio=(3 / 4, 4 / 3)), RandomColorJitter( brightness=0.5, contrast=0.5, saturation=0.5, hue=0.2), ], name="contrastive_augmenter", ), classification_augmenter=keras.Sequential( [ layers.Input(shape=(96, 96, 3)), preprocessing.Rescaling(1 / 255), preprocessing.RandomFlip("horizontal"), RandomResizedCrop(scale=(0.5, 1.0), ratio=(3 / 4, 4 / 3)), RandomColorJitter( brightness=0.2, contrast=0.2, saturation=0.2, hue=0.1),
def save(self, path): if not self.is_automl: model = self.model.export() #.load_weights(path) else: model = self.model.export_model() #.load_weights(path) # pop input layer # model._layers.pop(0) model.layers.pop(0) # pop last layer # model.summary() if self.args.DATA.RANDOM_CROP: height = self.args.DATA.RANDOM_CROP_SIZE[1] width = self.args.DATA.RANDOM_CROP_SIZE[0] else: height = self.args.DATA.SIZE[1] width = self.args.DATA.SIZE[0] # print(f'shape: h: {height}, w: {width}') # model.summary() input = tf.keras.Input(shape=(height, width, 3)) x = preprocessing.Rescaling(1. / 255)(input) normalized_input = x - [[self.args.DATA.MEAN]] normalized_input = normalized_input / [[self.args.DATA.STD]] new_output = model(normalized_input) pred_box, logits, centerness = new_output logits = logits * tf.math.sigmoid(centerness) # postprocessing for inference # bs, max value per each image max_value = tf.math.reduce_max(tf.reshape(logits, [tf.shape(logits)[0], -1]), axis=-1) # bs, h, w label = tf.math.argmax(logits, axis=-1) # bs, h, w logits = tf.math.reduce_max(logits, axis=-1) # bs, h, w mask = logits == tf.expand_dims(tf.expand_dims(max_value, axis=-1), axis=-1) # mask = tf.logical_and(mask, logits > self.args.INFERENCE_THRESHOLD) grid_cell = self.model.grid_cell(self.args.FEATURE_SHAPE[1], self.args.FEATURE_SHAPE[0]) boxes = tf.stack([ grid_cell[..., 0] - pred_box[..., 0], grid_cell[..., 1] - pred_box[..., 1], pred_box[..., 2] + grid_cell[..., 2], pred_box[..., 3] + grid_cell[..., 3] ], axis=-1) boxes = tf.boolean_mask(boxes, mask) # boxes = tf.reshape(boxes, [-1, 4]) # boxes = boxes[mask].reshape([-1, 4]) label = tf.boolean_mask(label, mask) # label = tf.reshape(label, [-1]) boxes = tf.clip_by_value(boxes, clip_value_min=0, clip_value_max=1) outputs = { 'detection_boxes': boxes, 'detection_scores': max_value, 'detection_classes': label } model = tf.keras.models.Model(inputs=input, outputs=outputs) self.model = model self.compile() self.model.summary() # self.model.save(path) tf.saved_model.save(self.model, path)
def get_train_data(category, batch_size=32, image_size=128, patch_size=128, rotation_range=(0, 0), n_batches=50_000, seed=42): train_data_dir = f'data/mvtec-ad/{category}/train/' dataset_kwargs = dict(image_size=(image_size, image_size), batch_size=1, shuffle=False, seed=seed) rescale = P.Rescaling(scale=1. / 127.5, offset=-1) # scale from [0, 255] to [-1, 1] ### train dataset loading os.makedirs('cache', exist_ok=True) cache_file = f'cache/{category}_train_dataset_i{image_size}_p{patch_size}_r{rotation_range[0]}-{rotation_range[1]}_s{seed}.npy' if not os.path.exists(cache_file): # check cache (only texture are cached) # load and resize images train_dataset = image_dataset_from_directory(train_data_dir, label_mode=None, **dataset_kwargs) n_train_images = len(train_dataset) # scale pixel range train_dataset = train_dataset.map(rescale, num_parallel_calls=AUTOTUNE)
# Create a data augmentation stage with horizontal flipping, rotations, zooms data_augmentation = keras.Sequential([ preprocessing.RandomFlip("horizontal"), preprocessing.RandomRotation(0.1), preprocessing.RandomZoom(0.1), ]) # Create a model that includes the augmentation stage input_shape = (32, 32, 3) classes = 10 inputs = keras.Input(shape=input_shape) # Augment images x = data_augmentation(inputs) # Rescale image values to [0, 1] x = preprocessing.Rescaling(1.0 / 255)(x) # Add the rest of the model outputs = keras.applications.ResNet50(weights=None, input_shape=input_shape, classes=classes)(x) model = keras.Model(inputs, outputs) """ You can see a similar setup in action in the example [image classification from scratch](https://keras.io/examples/vision/image_classification_from_scratch/). """ """ ### Normalizing numerical features """ # Load some data (x_train, y_train), _ = keras.datasets.cifar10.load_data()
for x, y in train_gen_data.take(1): print(x.shape, y.shape) from tensorflow.keras.layers.experimental import preprocessing from tensorflow.keras import Sequential # Doing preprocessing inside the model # Standardization # Data augmentation augmentations = Sequential([ preprocessing.RandomFlip("horizontal"), preprocessing.RandomRotation(0.1), preprocessing.RandomZoom(0.1), ]) scaling = preprocessing.Rescaling(1.0 / 255) model_ = Sequential([ augmentations, scaling, model ]) plt.figure(figsize=(10, 10)) for i in range(9): plt.subplot(3, 3, i + 1) aug_img = model_(tf.expand_dims(x_train[i], 0)) plt.imshow(aug_img[0, ...].numpy()) plt.grid(False) plt.axis("off") plt.title(class_names[y_train[i].item()])