Пример #1
0
    def build_network(self):
        '''
        This method builds the network architecture for the CNN model.
        Modify as needed.
        '''

        # Image Preprocessing
        img_preprocess = DataPreprocessing()
        img_preprocess.add_samplewise_zero_center()
        img_preprocess.add_featurewise_stdnorm()

        # Image Augmentation
        img_aug = ImageAugmentation()
        img_aug.add_random_flip_leftright()
        img_aug.add_random_rotation(max_angle=5.0)

        # Input Layer
        self.network = input_data(shape=[None, IMG_SIZE, IMG_SIZE, 1],
                                  data_preprocessing=img_preprocess,
                                  data_augmentation=img_aug)

        # Convolution Layer 1
        self.network = conv_2d(self.network, 64, 5, activation='relu')
        self.network = batch_normalization(self.network)
        self.network = max_pool_2d(self.network, 3, strides=2)

        # Convolution Layer 2
        self.network = conv_2d(self.network, 64, 5, activation='relu')
        self.network = batch_normalization(self.network)
        self.network = max_pool_2d(self.network, 3, strides=2)

        # Convolution Layer 3
        self.network = conv_2d(self.network, 128, 4, activation='relu')
        self.network = batch_normalization(self.network)
        self.network = dropout(self.network, 0.2)

        # Penultimate FC Layer
        self.network = fully_connected(self.network, 3072, activation='relu')
        self.network = batch_normalization(self.network)

        # Final FC Layer
        self.network = fully_connected(self.network,
                                       len(EMOTIONS),
                                       activation='softmax')

        # Create network
        optimizer = Momentum(learning_rate=0.01, lr_decay=0.99,
                             decay_step=250)  # Learning function
        self.network = regression(self.network,
                                  optimizer=optimizer,
                                  loss='categorical_crossentropy')

        # Create model
        self.model = tflearn.DNN(self.network,
                                 tensorboard_dir=TENSORBOARD_PATH,
                                 checkpoint_path=CHECKPOINT_PATH,
                                 max_checkpoints=1,
                                 tensorboard_verbose=1)
    def cnn(self):

        images = input_data(shape=[None, 48, 48, 1], name='input')
        images = conv_2d(images, 64, 3, padding='same', activation=self.activation)
        images = batch_normalization(images)
        #max pooling
        images = max_pool_2d(images, 3, strides=2)
        images = conv_2d(images, 128, 3, padding='same', activation=self.activation)
        images = max_pool_2d(images, 3, strides=2)
        images = conv_2d(images, 256, 3, padding='same', activation=self.activation)
        #maxpooling
        images = max_pool_2d(images, 3, strides=2)
        images = dropout(images, keep_prob=self.dropout)
        images = fully_connected(images, 4096, activation=self.activation)
        images = dropout(images, keep_prob=self.dropout)
        #fully connected layers
        images = fully_connected(images, 1024, activation=self.activation)
        images = fully_connected(images, 7, activation='softmax')

        if self.optimizer == 'momentum':

            optimizers = Momentum(
                learning_rate=self.learning_rate,
                momentum=self.optimizer_param,
                lr_decay=self.learning_rate_decay,
                decay_step=self.decay_step
            )
        elif self.optimizer == 'adam':

            optimizers = Adam(
                learning_rate=self.learning_rate,
                beta1=self.optimizer_param,
                beta2=self.learning_rate_decay,
            )
        else:
            print("Error Optimizer")

        network = regression(
            images,
            optimizer=optimizers,
            loss='categorical_crossentropy',
            learning_rate=self.learning_rate,
            name='output'
        )

        return network
Пример #3
0
def get_network():
    biases = zeros(shape=[9, 19, 1, 192])
    biases2 = zeros(shape=[19, 19, 1])
    network = input_data(shape=[None, 19, 19, 2], name='input')
    network = conv_2d(network, 192, 5, activation='elu', weights_init=truncated_normal(stddev=stddev5), bias=False) + biases[0]
    network = conv_2d(network, 192, 3, activation='elu', weights_init=truncated_normal(stddev=stddev3), bias=False) + biases[1]
    network = conv_2d(network, 192, 3, activation='elu', weights_init=truncated_normal(stddev=stddev3), bias=False) + biases[2]
    network = conv_2d(network, 192, 3, activation='elu', weights_init=truncated_normal(stddev=stddev3), bias=False) + biases[3]
    network = conv_2d(network, 192, 3, activation='elu', weights_init=truncated_normal(stddev=stddev3), bias=False) + biases[4]
    network = conv_2d(network, 192, 3, activation='elu', weights_init=truncated_normal(stddev=stddev3), bias=False) + biases[5]
    network = conv_2d(network, 192, 3, activation='elu', weights_init=truncated_normal(stddev=stddev3), bias=False) + biases[6]
    network = conv_2d(network, 192, 3, activation='elu', weights_init=truncated_normal(stddev=stddev3), bias=False) + biases[7]
    network = conv_2d(network, 192, 3, activation='elu', weights_init=truncated_normal(stddev=stddev3), bias=False) + biases[8]
    network = conv_2d(network, 1, 3, activation='elu', weights_init=truncated_normal(stddev=stddev3), bias=False) + biases2
    network = fully_connected(network, 19*19, activation='softmax')
    momentum = Momentum(learning_rate=0.002)
    network = regression(network, optimizer=momentum, loss='categorical_crossentropy', name='target')
    return network
Пример #4
0
 def build_resnet(self):
     # Adapted resnet
     # Adaptation did not work
     print('[+] Building Resnet')
     # Residual blocks
     n = 5
     self.network = input_data(shape=[None, SIZE_FACE, SIZE_FACE, 1])
     self.network = conv_2d(self.network,
                            SIZE_FACE / 2,
                            3,
                            regularizer='L2',
                            weight_decay=0.0001)
     self.network = residual_block(self.network, n, SIZE_FACE / 2)
     self.network = residual_block(self.network,
                                   1,
                                   SIZE_FACE,
                                   downsample=True)
     self.network = residual_block(self.network, n - 1, SIZE_FACE)
     self.network = residual_block(self.network,
                                   1,
                                   SIZE_FACE * 2,
                                   downsample=True)
     self.network = residual_block(self.network, n - 1, SIZE_FACE * 2)
     self.network = batch_normalization(self.network)
     self.network = activation(self.network, 'relu')
     self.network = global_avg_pool(self.network)
     self.network = fully_connected(self.network,
                                    len(EMOTIONS),
                                    activation='softmax')
     self.momentum = Momentum(0.1,
                              lr_decay=0.1,
                              decay_step=32000,
                              staircase=True)
     self.network = regression(self.network,
                               optimizer=self.momentum,
                               loss='categorical_crossentropy')
     self.model = tflearn.DNN(self.network,
                              checkpoint_path=SAVE_DIRECTORY + RUN_NAME,
                              max_checkpoints=1,
                              tensorboard_verbose=0)
     return self.model
Пример #5
0
def gamornet_tl_tflearn(training_imgs,
                        training_labels,
                        validation_imgs,
                        validation_labels,
                        input_shape,
                        load_layers_bools=[True] * 8,
                        trainable_bools=[True] * 8,
                        model_load_path="./",
                        files_save_path="./",
                        epochs=100,
                        max_checkpoints=1,
                        batch_size=64,
                        lr=0.00001,
                        momentum=0.9,
                        decay=0.0,
                        nesterov=False,
                        loss='categorical_crossentropy',
                        save_model=True,
                        show_metric=True,
                        clear_session=False):
    """
    Performs Transfer Learning (TL) using a previously trained GaMorNet model.

    Parameters
    -----------

    training_imgs: Numpy ndarray [nsamples,x,y,ndim]
        The array of images which are to be used for the TL process. We insist on numpy arrays
        as many of the underlying deep learning frameworks work better with numpy arrays compared to
        other array-like elements.

    training_labels: Numpy ndarray [nsamples,label_arrays]
        The truth labels for each of the TL images. The supplied labels must be in the one-hot encoding
        format. We reproduce below what each individual label array should look like:-

        * Disk-dominated - ``[1,0,0]``
        * Indeterminate -  ``[0,1,0]``
        * Bulge-dominated - ``[0,0,1]``

    validation_imgs: Numpy ndarray [nsamples,x,y,ndim]
        The array of images which are to be used for the validation process. We insist on numpy arrays
        as many of the underlying deep learning frameworks work better with numpy arrays compared to
        other array-like elements.

    validation_labels: Numpy ndarray [nsamples,label_arrays]
        The truth labels for each of the validation images. The supplied labels must be in the one-hot encoding
        format. We reproduce below what each individual label array should look like:-

        * Disk-dominated - ``[1,0,0]``
        * Indeterminate -  ``[0,1,0]``
        * Bulge-dominated - ``[0,0,1]``

    input_shape: tuple of ints (x, y, ndim) or allowed str
        The shape of the images being used in the form of a tuple. 

        This parameter can also take the following special values:-

        * ``SDSS`` - Sets the input shape to be (167,167,1) as was used for the SDSS g-band images in Ghosh et. al. (2020)
        * ``CANDELS`` -  Sets the input shape to be (83,83,1) as was used for the CANDELS H-band images in Ghosh et. al. (2020)

    load_layers_bools: array of bools
        This variable is used to identify which of the 5 convolutional and 3 fully-connected layers of GaMorNet will be
        loaded during the transfer learning process from the supplied starting model. The rest of the layers will be
        initialized from scratch.

        The order of the bools correspond to the following layer numbers [2, 5, 8, 9, 10, 13, 15, 17] in GaMorNet. Please see
        Figure 4 and Table 2 of Ghosh et. al. (2020) to get more details. The first five layers are the convolutional
        layers and the last three are the fully connected layers.

        This parameter can also take the following special values which are handy when you are using our models to
        perform predictions:-

        * ``load_bools_SDSS`` - Sets the bools according to what was done for the SDSS data in Ghosh et. al. (2020)
        * ``load_bools_CANDELS``- Sets the bools according to what was done for the CANDELS data in Ghosh et. al. (2020)

    trainable_bools: array of bools
        This variable is used to identify which of the 5 convolutional and 3 fully-connected layers of GaMorNet will be
        trainable during the transfer learning process. The rest are frozen at the values loaded from the previous
        model.

        The order of the bools correspond to the following layer numbers [2, 5, 8, 9, 10, 13, 15, 17] in GaMorNet. Please see
        Figure 4 and Table 2 of Ghosh et. al. (2020) to get more details. The first five layers are the convolutional
        layers and the last three are the fully connected layers.

        This parameter can also take the following special values which are handy when you are using our models to
        perform predictions:-

        * ``train_bools_SDSS`` - Sets the bools according to what was done for the SDSS data in Ghosh et. al. (2020)
        * ``train_bools_CANDELS``- Sets the bools according to what was done for the CANDELS data in Ghosh et. al. (2020)

    model_load_path: str
        Path to the saved model, which will serve as the starting point for transfer learning. Note that
        tflearn models usually consist of three files in the format ``file_name.data``,
        ``file_name.index``, ``file_name.meta``. For this parameter, simply specify file_path/file_name.

        This parameter can also take the following special values

        * ``SDSS_sim`` -- Downloads and uses GaMorNet models trained on SDSS g-band simulations at z~0 from Ghosh et. al. (2020)
        * ``SDSS_tl`` -- Downloads and uses GaMorNet models trained on SDSS g-band simulations and real data at z~0 from Ghosh et. al. (2020)
        * ``CANDELS_sim`` -- Downloads and uses GaMorNet models trained on CANDELS H-band simulations at z~1 from Ghosh et. al. (2020)
        * ``CANDELS_tl`` -- Downloads and uses GaMorNet models trained on CANDELS H-band simulations and real data at z~1 from Ghosh et. al. (2020)

    files_save_path: str
        The full path to the location where the models generated during the training process are to be
        saved. The path should end with the name of the file. For eg. ``/path/checkpoint``. This
        will result in model files of the form ``checkpoint.meta``, ``checkpoint.data`` and
        ``checkpoint.index`` being saved.

        Set this to ``/dev/null`` on a unix system if you don't want to save the output.

    epochs: int
        The number of epochs for which you want to train the model.

    max_checkpoints: int
        TFLearn saves the model at the end of each epoch. This parameter controls how many of the
        most recent models are saved. For eg. setting this to 2, will save the model state during the
        most recent two epochs.

    batch_size: int
        This variable specifies how many images will be processed in a single batch. This is a
        hyperparameter. The default value is a good starting point

    lr: float
        This is the learning rate to be used during the training process. This is a
        hyperparameter that should be tuned during the training process. The default value is a good
        starting point.

    momentum: float
        The value of the momentum to be used in the gradient descent optimizer that is used to train GaMorNet.
        This must always be :math:`\geq 0`. This accelerates the gradient descent process. This is a
        hyperparameter. The default value is a good starting point.

    decay: float
        The amount of learning rate decay to be applied over each update.

    nesterov: bool
        Whether to apply Nesterov momentum or not.

    loss: allowed str or function
        The loss function to be used. If using the string option, you need to specify the name of
        the loss function. This can be set to be any loss available in ``tflearn``

    save_model: bool
        Whether you want to save the model files at each epoch during training. This
        parameter should be used in conjunction with  ``max_checkpoints`` to configure
        how many of the saved model files are preserved till the end.

    show_metric: bool
        Whether to display the training/testing metrics during training.

    clear_session: bool
        If set to True, this will clear the TensorFlow session currently running. This is handy while running GaMorNet in a
        notebook to avoid variable name confusions. (Sometimes, under the hood, TFLearn & Tensorflow reuse the same layer names
        leading to conflicts)

        Note that if set to True, you will lose access to any other graphs you may have run before.


    Returns
    --------

    Trained TFLearn Model: TFLearn ``models.dnn.DNN`` class

    """

    # TFLearn Loads graphs from memory by name, hence it's always advisable to
    # set this to True if using in a Notebook.
    if clear_session is True:
        K.clear_session()

    check_imgs_validity(training_imgs)
    check_imgs_validity(validation_imgs)
    check_labels_validity(training_labels)
    check_labels_validity(validation_labels)

    model = gamornet_build_model_tflearn(input_shape=input_shape,
                                         trainable_bools=trainable_bools,
                                         load_layers_bools=load_layers_bools)

    if nesterov is False:
        optimizer = Momentum(momentum=momentum, lr_decay=decay)
    else:
        optimizer = Nesterov(momentum=momentum, lr_decay=decay)

    model = regression(model, optimizer=optimizer, loss=loss, learning_rate=lr)

    model = tflearn.DNN(model,
                        checkpoint_path=files_save_path + "check",
                        max_checkpoints=max_checkpoints)

    model = gamornet_load_model_tflearn(model, model_load_path)

    model.fit(training_imgs,
              training_labels,
              n_epoch=epochs,
              validation_set=(validation_imgs, validation_labels),
              shuffle=True,
              show_metric=show_metric,
              batch_size=batch_size,
              snapshot_step=None,
              snapshot_epoch=save_model)

    return model
Пример #6
0
def build_modelB(optimizer=HYPERPARAMS.optimizer,
                 optimizer_param=HYPERPARAMS.optimizer_param,
                 learning_rate=HYPERPARAMS.learning_rate,
                 keep_prob=HYPERPARAMS.keep_prob,
                 learning_rate_decay=HYPERPARAMS.learning_rate_decay,
                 decay_step=HYPERPARAMS.decay_step):

    images_network = input_data(
        shape=[None, NETWORK.input_size, NETWORK.input_size, 1], name='input1')
    images_network = conv_2d(images_network,
                             64,
                             3,
                             activation=NETWORK.activation)
    #images_network = local_response_normalization(images_network)
    if NETWORK.use_batchnorm_after_conv_layers:
        images_network = batch_normalization(images_network)
    images_network = max_pool_2d(images_network, 3, strides=2)
    images_network = conv_2d(images_network,
                             128,
                             3,
                             activation=NETWORK.activation)
    if NETWORK.use_batchnorm_after_conv_layers:
        images_network = batch_normalization(images_network)
    images_network = max_pool_2d(images_network, 3, strides=2)
    images_network = conv_2d(images_network,
                             256,
                             3,
                             activation=NETWORK.activation)
    if NETWORK.use_batchnorm_after_conv_layers:
        images_network = batch_normalization(images_network)
    images_network = max_pool_2d(images_network, 3, strides=2)
    images_network = dropout(images_network, keep_prob=keep_prob)
    images_network = fully_connected(images_network,
                                     4096,
                                     activation=NETWORK.activation)
    images_network = dropout(images_network, keep_prob=keep_prob)
    images_network = fully_connected(images_network,
                                     1024,
                                     activation=NETWORK.activation)
    if NETWORK.use_batchnorm_after_fully_connected_layers:
        images_network = batch_normalization(images_network)

    if NETWORK.use_landmarks or NETWORK.use_hog_and_landmarks:
        if NETWORK.use_hog_sliding_window_and_landmarks:
            landmarks_network = input_data(shape=[None, 2728], name='input2')
        elif NETWORK.use_hog_and_landmarks:
            landmarks_network = input_data(shape=[None, 208], name='input2')
        else:
            landmarks_network = input_data(shape=[None, 68, 2], name='input2')
        landmarks_network = fully_connected(landmarks_network,
                                            1024,
                                            activation=NETWORK.activation)
        if NETWORK.use_batchnorm_after_fully_connected_layers:
            landmarks_network = batch_normalization(landmarks_network)
        landmarks_network = fully_connected(landmarks_network,
                                            128,
                                            activation=NETWORK.activation)
        if NETWORK.use_batchnorm_after_fully_connected_layers:
            landmarks_network = batch_normalization(landmarks_network)
        images_network = fully_connected(images_network,
                                         128,
                                         activation=NETWORK.activation)
        network = merge([images_network, landmarks_network], 'concat', axis=1)
    else:
        network = images_network
    network = fully_connected(network,
                              NETWORK.output_size,
                              activation='softmax')

    if optimizer == 'momentum':
        optimizer = Momentum(learning_rate=learning_rate,
                             momentum=optimizer_param,
                             lr_decay=learning_rate_decay,
                             decay_step=decay_step)
    elif optimizer == 'adam':
        optimizer = Adam(learning_rate=learning_rate,
                         beta1=optimizer_param,
                         beta2=learning_rate_decay)
    else:
        print("Unknown optimizer: {}".format(optimizer))
    network = regression(network,
                         optimizer=optimizer,
                         loss=NETWORK.loss,
                         learning_rate=learning_rate,
                         name='output')

    return network
Пример #7
0
conv3_1 = conv_2d(pool2, 256, 3, activation='relu', name="conv3_1")
conv3_2 = conv_2d(conv3_1, 256, 3, activation='relu', name="conv3_2")
conv3_3 = conv_2d(conv3_2, 256, 3, activation='relu', name="conv3_3")
pool3 = max_pool_2d(conv3_3, 2, strides=2)

conv4_1 = conv_2d(pool3, 512, 3, activation='relu', name="conv4_1")
conv4_2 = conv_2d(conv4_1, 512, 3, activation='relu', name="conv4_2")
conv4_3 = conv_2d(conv4_2, 512, 3, activation='relu', name="conv4_3")
pool4 = max_pool_2d(conv4_3, 2, strides=2)

conv5_1 = conv_2d(pool4, 512, 3, activation='relu', name="conv5_1")
conv5_2 = conv_2d(conv5_1, 512, 3, activation='relu', name="conv5_2")
conv5_3 = conv_2d(conv5_2, 512, 3, activation='relu', name="conv5_3")
pool5 = max_pool_2d(conv5_3, 2, strides=2)

fc6 = fully_connected(pool5, 4096, activation='relu', name="fc6")
fc6_dropout = dropout(fc6, 0.5)

fc7 = fully_connected(fc6_dropout, 4096, activation='relu', name="fc7")
fc7_droptout = dropout(fc7, 0.5)

fc8 = fully_connected(fc7_droptout, 1000, activation='softmax', name="fc8")

mm = Momentum(learning_rate=0.01, momentum=0.9, lr_decay=0.1, decay_step=1000)

network = regression(fc8, optimizer=mm, loss='categorical_crossentropy', restore=False)

model = tflearn.DNN(network)
model.fit(X, y, n_epoch=74, shuffle=True, show_metric=True, batch_size=256, snapshot_step=500, run_id='vgg16_imagenet')

model.save("vgg16_weights.tflearn")
Пример #8
0
def build_model(optimizer=HYPERPARAMS.optimizer, optimizer_param=HYPERPARAMS.optimizer_param, 
    learning_rate=HYPERPARAMS.learning_rate, keep_prob=HYPERPARAMS.keep_prob,
    learning_rate_decay=HYPERPARAMS.learning_rate_decay, decay_step=HYPERPARAMS.decay_step):

    images_input = input_data(shape=[None, NETWORK.input_size, NETWORK.input_size, 1], name='input1')
    
    images_network = conv_2d(images_input, 16, 3, activation='relu')
    if NETWORK.use_batchnorm_after_conv_layers:
        images_network = batch_normalization(images_network)
    images_network = conv_2d(images_network, 16, 3, activation='relu')
    if NETWORK.use_batchnorm_after_conv_layers:
        images_network = batch_normalization(images_network)
    images_network = max_pool_2d(images_network, 2, strides=2)  #24*24*16
    
    
    images_network = conv_2d(images_network, 32, 3, activation='relu')
    if NETWORK.use_batchnorm_after_conv_layers:
        images_network = batch_normalization(images_network)
    images_network = conv_2d(images_network, 32, 3, activation='relu')
    if NETWORK.use_batchnorm_after_conv_layers:
        images_network = batch_normalization(images_network)
    images_network = max_pool_2d(images_network, 2, strides=2)    #12*12*32
    
    images_network=tf.pad(images_network,[[0,0],[18,18],[18,18],[0,0]],'CONSTANT')
    images_network = merge([images_network, images_input], 'concat', axis=3)              #48*48*33
    
    images_network = conv_2d(images_network, 64, 3, activation='relu')
    if NETWORK.use_batchnorm_after_conv_layers:
        images_network = batch_normalization(images_network)
    images_network = conv_2d(images_network, 64, 3, activation='relu')
    if NETWORK.use_batchnorm_after_conv_layers:
        images_network = batch_normalization(images_network)
    images_network = conv_2d(images_network, 64, 3, activation='relu')
    if NETWORK.use_batchnorm_after_conv_layers:
        images_network = batch_normalization(images_network)
    images_network = max_pool_2d(images_network, 2, strides=2)       #24*24*64
    
    
    images_network = conv_2d(images_network, 128, 3, activation='relu')
    if NETWORK.use_batchnorm_after_conv_layers:
        images_network = batch_normalization(images_network)
    images_network = conv_2d(images_network, 128, 3, activation='relu')
    if NETWORK.use_batchnorm_after_conv_layers:
        images_network = batch_normalization(images_network)
    images_network = conv_2d(images_network, 128, 3, activation='relu')
    if NETWORK.use_batchnorm_after_conv_layers:
        images_network = batch_normalization(images_network)
    images_network = max_pool_2d(images_network, 2, strides=2)      #12*12*128
#     
    images_network = conv_2d(images_network, 128, 3, activation='relu')
    if NETWORK.use_batchnorm_after_conv_layers:
        images_network = batch_normalization(images_network)
    images_network = conv_2d(images_network, 128, 3, activation='relu')
    if NETWORK.use_batchnorm_after_conv_layers:
        images_network = batch_normalization(images_network)
    images_network = conv_2d(images_network, 128, 3, activation='relu')
    if NETWORK.use_batchnorm_after_conv_layers:
        images_network = batch_normalization(images_network)
    images_network = max_pool_2d(images_network, 2, strides=2)     #6*6*128
     
    images_network = fully_connected(images_network, 1024, activation='relu')
    images_network = dropout(images_network,keep_prob=keep_prob)
    if NETWORK.use_batchnorm_after_fully_connected_layers:
        images_network = batch_normalization(images_network)
    images_network = fully_connected(images_network, 1024, activation='relu')
    images_network = dropout(images_network, keep_prob=keep_prob)
    if NETWORK.use_batchnorm_after_fully_connected_layers:
        images_network = batch_normalization(images_network)

    if NETWORK.use_landmarks or NETWORK.use_hog_and_landmarks:
        if NETWORK.use_hog_sliding_window_and_landmarks:
            landmarks_network = input_data(shape=[None, 2728], name='input2')
        elif NETWORK.use_hog_and_landmarks:
            landmarks_network = input_data(shape=[None, 208], name='input2')
        else:
            landmarks_network = input_data(shape=[None, 68, 2], name='input2')
        landmarks_network = fully_connected(landmarks_network, 1024, activation=NETWORK.activation)
        if NETWORK.use_batchnorm_after_fully_connected_layers:
            landmarks_network = batch_normalization(landmarks_network)
        landmarks_network = fully_connected(landmarks_network, 40, activation=NETWORK.activation)
        if NETWORK.use_batchnorm_after_fully_connected_layers:
            landmarks_network = batch_normalization(landmarks_network)
        images_network = fully_connected(images_network, 40, activation=NETWORK.activation)
        network = merge([images_network, landmarks_network], 'concat', axis=1)
    else:
        network = images_network
    network = fully_connected(network, NETWORK.output_size, activation='softmax')

    if optimizer == 'momentum':
        # FIXME base_lr * (1 - iter/max_iter)^0.5, base_lr = 0.01
        optimizer = Momentum(learning_rate=learning_rate, momentum=optimizer_param,
                    lr_decay=learning_rate_decay, decay_step=decay_step)
    elif optimizer == 'adam':
        optimizer = Adam(learning_rate=learning_rate, beta1=optimizer_param, beta2=learning_rate_decay)
    else:
        print("Unknown optimizer: {}".format(optimizer))
    network = regression(network, optimizer=optimizer, loss=NETWORK.loss, learning_rate=learning_rate, name='output')

    return network
    model = None
    if in_args.architecture == 'VGG16':

        if not _is_valid_size(224, in_args.patch_size, in_args.extract_level):
            raise RuntimeError("Real size of extracted patch less than network input size!")

        img_prep.add_random_crop((224, 224))
        cnn_network = input_data(shape=[None, 224, 224, 3],
                                 data_preprocessing=img_prep,
                                 data_augmentation=img_aug)

        cnn_network = create_vgg16_network( cnn_network, num_classes=n_classes,
                                            normalize_batch=apply_batchnorm,
                                            add_color_transfer=apply_colortransform)

        MomOpt = Momentum(learning_rate=0.01, lr_decay=0.8, decay_step=200)
        cnn_network = regression(cnn_network, optimizer=MomOpt,
                                 loss='categorical_crossentropy')

    elif in_args.architecture == 'simple':

        if not _is_valid_size(28, in_args.patch_size, in_args.extract_level):
            raise RuntimeError("Real size of extracted patch less than network input size!")

        img_prep.add_random_crop((28, 28))
        cnn_network = input_data(shape=[None, 28, 28, 3],
                                 data_preprocessing=img_prep,
                                 data_augmentation=img_aug)

        cnn_network = create_simple_network( cnn_network, num_classes=n_classes)