Esempio n. 1
0
def cnn_model_fn(features, labels, mode):
    """Model function for a CNN."""

    # Define CNN architecture using tf.keras.layers.
    input_layer = tf.reshape(features['x'], [-1, 28, 28, 1])
    y = tf.keras.layers.Conv2D(16,
                               8,
                               strides=2,
                               padding='same',
                               activation='relu').apply(input_layer)
    y = tf.keras.layers.MaxPool2D(2, 1).apply(y)
    y = tf.keras.layers.Conv2D(32,
                               4,
                               strides=2,
                               padding='valid',
                               activation='relu').apply(y)
    y = tf.keras.layers.MaxPool2D(2, 1).apply(y)
    y = tf.keras.layers.Flatten().apply(y)
    y = tf.keras.layers.Dense(32, activation='relu').apply(y)
    logits = tf.keras.layers.Dense(10).apply(y)

    # Calculate loss as a vector and as its average across minibatch.
    vector_loss = tf.nn.sparse_softmax_cross_entropy_with_logits(labels=labels,
                                                                 logits=logits)
    scalar_loss = tf.reduce_mean(vector_loss)

    # Configure the training op (for TRAIN mode).
    if mode == tf.estimator.ModeKeys.TRAIN:
        # optimizer = tf.train.GradientDescentOptimizer(FLAGS.learning_rate)
        # opt_loss = scalar_loss
        global_step = tf.train.get_global_step()
        optimizer = DPGradientDescentGaussianOptimizer(
            l2_norm_clip=FLAGS.l2_norm_clip,
            noise_multiplier=FLAGS.noise_multiplier,
            num_microbatches=FLAGS.microbatches,
            learning_rate=FLAGS.learning_rate)
        opt_loss = vector_loss
        train_op = optimizer.minimize(loss=opt_loss, global_step=global_step)
        return tf.estimator.EstimatorSpec(mode=mode,
                                          loss=scalar_loss,
                                          train_op=train_op)

    # Add evaluation metrics (for EVAL mode).
    elif mode == tf.estimator.ModeKeys.EVAL:
        eval_metric_ops = {
            'accuracy':
            tf.metrics.accuracy(labels=labels,
                                predictions=tf.argmax(input=logits, axis=1))
        }
        return tf.estimator.EstimatorSpec(mode=mode,
                                          loss=scalar_loss,
                                          eval_metric_ops=eval_metric_ops)
def main(unused_argv):
    tf.logging.set_verbosity(tf.logging.INFO)
    if FLAGS.dpsgd and FLAGS.batch_size % FLAGS.microbatches != 0:
        raise ValueError(
            'Number of microbatches should divide evenly batch_size')

    # Load training and test data.
    train_data, train_labels, test_data, test_labels = load_mnist()

    # Define a sequential Keras model
    model = tf.keras.Sequential([
        tf.keras.layers.Conv2D(16,
                               8,
                               strides=2,
                               padding='same',
                               activation='relu',
                               input_shape=(28, 28, 1)),
        tf.keras.layers.MaxPool2D(2, 1),
        tf.keras.layers.Conv2D(32,
                               4,
                               strides=2,
                               padding='valid',
                               activation='relu'),
        tf.keras.layers.MaxPool2D(2, 1),
        tf.keras.layers.Flatten(),
        tf.keras.layers.Dense(32, activation='relu'),
        tf.keras.layers.Dense(10)
    ])

    if FLAGS.dpsgd:
        optimizer = DPGradientDescentGaussianOptimizer(
            l2_norm_clip=FLAGS.l2_norm_clip,
            noise_multiplier=FLAGS.noise_multiplier,
            num_microbatches=FLAGS.num_microbatches,
            learning_rate=FLAGS.learning_rate,
            unroll_microbatches=True)
        # Compute vector of per-example loss rather than its mean over a minibatch.
        loss = tf.keras.losses.CategoricalCrossentropy(
            from_logits=True, reduction=tf.losses.Reduction.NONE)
    else:
        optimizer = GradientDescentOptimizer(learning_rate=FLAGS.learning_rate)
        loss = tf.keras.losses.CategoricalCrossentropy(from_logits=True)

    # Compile model with Keras
    model.compile(optimizer=optimizer, loss=loss, metrics=['accuracy'])

    # Train model with Keras
    model.fit(train_data,
              train_labels,
              epochs=FLAGS.epochs,
              validation_data=(test_data, test_labels),
              batch_size=FLAGS.batch_size)

    # Compute the privacy budget expended.
    if FLAGS.dpsgd:
        eps = compute_epsilon(FLAGS.epochs * 60000 // FLAGS.batch_size)
        print('For delta=1e-5, the current epsilon is: %.2f' % eps)
    else:
        print('Trained with vanilla non-private SGD optimizer')
Esempio n. 3
0
def main(_):
    if FLAGS.dpsgd and FLAGS.batch_size % FLAGS.microbatches != 0:
        raise ValueError(
            'Number of microbatches should divide evenly batch_size')

    # Fetch the mnist data
    train, test = tf.keras.datasets.mnist.load_data()
    train_images, train_labels = train
    test_images, test_labels = test

    # Create a dataset object and batch for the training data
    dataset = tf.data.Dataset.from_tensor_slices(
        (tf.cast(train_images[..., tf.newaxis] / 255,
                 tf.float32), tf.cast(train_labels, tf.int64)))
    dataset = dataset.shuffle(1000).batch(FLAGS.batch_size)

    # Create a dataset object and batch for the test data
    eval_dataset = tf.data.Dataset.from_tensor_slices(
        (tf.cast(test_images[..., tf.newaxis] / 255,
                 tf.float32), tf.cast(test_labels, tf.int64)))
    eval_dataset = eval_dataset.batch(10000)

    # Define the model using tf.keras.layers
    mnist_model = tf.keras.Sequential([
        tf.keras.layers.Conv2D(16,
                               8,
                               strides=2,
                               padding='same',
                               activation='relu'),
        tf.keras.layers.MaxPool2D(2, 1),
        tf.keras.layers.Conv2D(32, 4, strides=2, activation='relu'),
        tf.keras.layers.MaxPool2D(2, 1),
        tf.keras.layers.Flatten(),
        tf.keras.layers.Dense(32, activation='relu'),
        tf.keras.layers.Dense(10)
    ])

    # Instantiate the optimizer
    if FLAGS.dpsgd:
        opt = DPGradientDescentGaussianOptimizer(
            l2_norm_clip=FLAGS.l2_norm_clip,
            noise_multiplier=FLAGS.noise_multiplier,
            num_microbatches=FLAGS.microbatches,
            learning_rate=FLAGS.learning_rate)
    else:
        opt = GradientDescentOptimizer(learning_rate=FLAGS.learning_rate)

    # Training loop.
    steps_per_epoch = 60000 // FLAGS.batch_size
    for epoch in range(FLAGS.epochs):
        # Train the model for one epoch.
        for (_, (images, labels)) in enumerate(dataset.take(-1)):
            with tf.GradientTape(persistent=True) as gradient_tape:
                # This dummy call is needed to obtain the var list.
                logits = mnist_model(images, training=True)
                var_list = mnist_model.trainable_variables

                # In Eager mode, the optimizer takes a function that returns the loss.
                def loss_fn():
                    logits = mnist_model(images, training=True)  # pylint: disable=undefined-loop-variable,cell-var-from-loop
                    loss = tf.nn.sparse_softmax_cross_entropy_with_logits(
                        labels=labels, logits=logits)  # pylint: disable=undefined-loop-variable,cell-var-from-loop
                    # If training without privacy, the loss is a scalar not a vector.
                    if not FLAGS.dpsgd:
                        loss = tf.reduce_mean(loss)
                    return loss

                if FLAGS.dpsgd:
                    grads_and_vars = opt.compute_gradients(
                        loss_fn, var_list, gradient_tape=gradient_tape)
                else:
                    grads_and_vars = opt.compute_gradients(loss_fn, var_list)

            opt.apply_gradients(grads_and_vars)

        # Evaluate the model and print results
        for (_, (images, labels)) in enumerate(eval_dataset.take(-1)):
            logits = mnist_model(images, training=False)
            correct_preds = tf.equal(tf.argmax(logits, axis=1), labels)
        test_accuracy = np.mean(correct_preds.numpy())
        print('Test accuracy after epoch %d is: %.3f' % (epoch, test_accuracy))

        # Compute the privacy budget expended so far.
        if FLAGS.dpsgd:
            eps = compute_epsilon((epoch + 1) * steps_per_epoch)
            print('For delta=1e-5, the current epsilon is: %.2f' % eps)
        else:
            print('Trained with vanilla non-private SGD optimizer')
def train(dataset, model_name, mode='nn'):
    with tf.device('gpu:0'):
        tf.logging.set_verbosity(tf.logging.INFO)
        # Load training and test data.
        train_data, train_labels, test_data, test_labels = dataset
        logfile = FLAGS.dataset + "_dp" if FLAGS.dpsgd else FLAGS.dataset
        if mode == "softmax":
            FLAGS.learning_rate = 0.01
            epochs = FLAGS.softmax_epochs
            logfile = logfile + "\\softmax_" + str(epochs) + "\\" + model_name
            num_classes = 2
            train_labels = tf.keras.utils.to_categorical(
                train_labels, num_classes)
            test_labels = tf.keras.utils.to_categorical(
                test_labels, num_classes)
        else:
            epochs = FLAGS.epochs
            logfile = logfile + "\\sgd_" + str(epochs) + "\\" + model_name
        # Create logs path
        if os.path.exists(".\\logs\\" + logfile):
            print("FOLDER IS EXISTS")
            i = 1
            while os.path.exists(".\\logs\\" + logfile + '_' + str(i)):
                i += 1
            logfile = logfile + '_' + str(i)

        tb_callbacks = tf.keras.callbacks.TensorBoard(
            log_dir=".\\logs\\{}".format(logfile))
        if FLAGS.dpsgd and FLAGS.batch_size % FLAGS.microbatches != 0:
            raise ValueError(
                'Number of microbatches should divide evenly batch_size')

        # Define a sequential Keras model
        input_shape = train_data[1].shape
        # input(input_shape)
        model = get_model_stucture(mode, input_shape)

        if FLAGS.dpsgd:
            optimizer = DPGradientDescentGaussianOptimizer(
                # optimizer = DPGradientDescentOptimizer(
                l2_norm_clip=FLAGS.l2_norm_clip,
                noise_multiplier=FLAGS.noise_multiplier,
                num_microbatches=FLAGS.microbatches,
                learning_rate=FLAGS.learning_rate)
            # Compute vector of per-example loss rather than its mean over a minibatch.
            loss = tf.keras.losses.CategoricalCrossentropy(
                from_logits=True, reduction=tf.losses.Reduction.NONE)
        else:
            optimizer = GradientDescentOptimizer(
                learning_rate=FLAGS.learning_rate)
            # input(train_labels[0])
            # input(type(train_labels[0]))
            # input(type(train_labels[0]) == "numpy.ndarray")
            # if (model_name=="mnist"):
            loss = tf.keras.losses.CategoricalCrossentropy(from_logits=True)
            # else:
            #   loss = tf.keras.losses.sparse_categorical_crossentropy(from_logits=True)
        # Compile model with Keras
        model.compile(optimizer=optimizer, loss=loss, metrics=['accuracy'])

        # Train model with Keras
        if FLAGS.dpsgd:
            history = model.fit(train_data,
                                train_labels,
                                epochs=epochs,
                                validation_data=(test_data, test_labels),
                                batch_size=FLAGS.batch_size)
            # list all data in history
            print(history.history.keys())
            # summarize history for accuracy
            plt.plot(history.history['acc'])
            plt.plot(history.history['val_acc'])
            plt.title('model accuracy')
            plt.ylabel('accuracy')
            plt.xlabel('epoch')
            plt.legend(['train', 'test'], loc='upper left')
            plt.show()
            # summarize history for loss
            plt.plot(history.history['loss'])
            plt.plot(history.history['val_loss'])
            plt.title('model loss')
            plt.ylabel('loss')
            plt.xlabel('epoch')
            plt.legend(['train', 'test'], loc='upper left')
            plt.show()
        else:
            history = model.fit(train_data,
                                train_labels,
                                epochs=epochs,
                                validation_data=(test_data, test_labels),
                                batch_size=FLAGS.batch_size,
                                callbacks=[tb_callbacks])
        # Compute the privacy budget expended.
        model_stats_dir = ".\\model_stats\\" + logfile + ".txt"
        save_model_stats(model_stats_dir, history.history)
        if FLAGS.dpsgd:
            eps = compute_epsilon(FLAGS.epochs * 60000 // FLAGS.batch_size)
            f = open(model_stats_dir, "a")
            f.write("Eps: " + str(eps))
            f.close()
            print('For delta=1e-5, the current epsilon is: %.2f' % eps)
        else:
            print('Trained with vanilla non-private SGD optimizer')

        # serialize model to JSON
        model_json = model.to_json()
        create_folder_if_not_exist(".\\logs\\" + logfile + ".json")
        with open(".\\logs\\" + logfile + ".json", "w") as json_file:
            json_file.write(model_json)
        # serialize weights to HDF5
        model.save_weights(".\\logs\\" + logfile + ".h5")
        print("Saved model to disk")
        return model