privacy icon indicating copy to clipboard operation
privacy copied to clipboard

Fails to train a Keras non-sequential model with DP optimizer

Open psitronic opened this issue 5 years ago • 4 comments

For a non-sequential model if number of examples is not a multiple of number of microbatches (see the data file below) the training with DPAdamOptimizer fails.

Numpy 1.14.4 Tensorflow 1.13.1

Error:

 6/13 [============>.................] - ETA: 0s - loss: 6.5262Traceback (most recent call last):
  File "/home/andrey/Documents/experiments/dp.py", line 114, in <module>
    epochs=epochs)
  File "/home/andrey/.local/lib/python3.6/site-packages/tensorflow/python/keras/engine/training.py", line 880, in fit
    validation_steps=validation_steps)
  File "/home/andrey/.local/lib/python3.6/site-packages/tensorflow/python/keras/engine/training_arrays.py", line 329, in model_iteration
    batch_outs = f(ins_batch)
  File "/home/andrey/.local/lib/python3.6/site-packages/tensorflow/python/keras/backend.py", line 3076, in __call__
    run_metadata=self.run_metadata)
  File "/home/andrey/.local/lib/python3.6/site-packages/tensorflow/python/client/session.py", line 1439, in __call__
    run_metadata_ptr)
  File "/home/andrey/.local/lib/python3.6/site-packages/tensorflow/python/framework/errors_impl.py", line 528, in __exit__
    c_api.TF_GetCode(self.status.status))
tensorflow.python.framework.errors_impl.InvalidArgumentError: Input to reshape is a tensor with 1 values, but the requested shape requires a multiple of 3
	 [[{{node training/TFOptimizer/Reshape}}]]
         [[{{node loss/mul}}]]

Code:

import tensorflow as tf
from tensorflow.keras import losses
from privacy.optimizers.dp_optimizer import DPAdamOptimizer
from privacy.optimizers.gaussian_query import GaussianAverageQuery

batch_size = 6
microbatches = 3

noise_multiplier = 1.1
l2_norm_clip = 1.0
epochs = 30

names = pd.read_csv('names.csv', delimiter=',')
names = names['ch1'].values
names.shape = names.shape + (1,)

my_input = tf.keras.layers.Input(shape=(1,))
my_dense = tf.keras.layers.Dense(7)(my_input)
model = tf.keras.Model(my_input, my_dense)

dp_average_query = GaussianAverageQuery(l2_norm_clip, l2_norm_clip * noise_multiplier,        microbatches)

optimizer = DPAdamOptimizer(dp_average_query,microbatches,learning_rate=learning_rate,    unroll_microbatches=True)

loss = losses.CategoricalCrossentropy(from_logits=False, reduction=tf.losses.Reduction.NONE)

model.fit(x=names,y=names,batch_size=batch_size,epochs=epochs)

Dataset - names.csv:

id,ch1
1,1
2,3
3,4
4,1
5,2
6,3
7,3
8,1
9,1
10,2
11,3
12,4
13,4

If there is only 12 examples in the dataset, the model trains for batch_size = 6 and microbatches = 3

psitronic avatar Mar 29 '19 11:03 psitronic

In addition: For batch_size = 6 and microbatches = 1 Process finished with exit code 0

But for batch_size = 8 and microbatches = 1 :

Traceback (most recent call last):
  File "/home/andrey/Documents/experiments/dp.py", line 53, in <module>
    epochs=epochs)
  File "/home/andrey/.local/lib/python3.6/site-packages/tensorflow/python/keras/engine/training.py", line 880, in fit
    validation_steps=validation_steps)
  File "/home/andrey/.local/lib/python3.6/site-packages/tensorflow/python/keras/engine/training_arrays.py", line 336, in model_iteration
    aggregator.aggregate(batch_outs, batch_start, batch_end)
  File "/home/andrey/.local/lib/python3.6/site-packages/tensorflow/python/keras/engine/training_utils.py", line 103, in aggregate
    self.results[0] += batch_outs[0] * (batch_end - batch_start)
ValueError: operands could not be broadcast together with shapes (8,) (5,) (8,) 
 8/13 [=================>............] - ETA: 0s - loss: 6.9150

psitronic avatar Mar 29 '19 15:03 psitronic

Thanks for bringing this to our attention. From your description, it appears that the model.fit method in Keras is having trouble padding the last batch of data to make it have the same batch size than previous batches. I don't use Keras but I'll ask around to see if we can find a solution that doesn't require changing the number of training examples or using tf.Estimator instead.

npapernot avatar Mar 29 '19 17:03 npapernot

It looks that in the case of ValueError: operands could not be broadcast together with shapes (8,) (5,) (8,) the problem is that the Keras MetricsAggregator class expects the argument batch_out as a list but receives a list of an array instead when diff privacy optimizer is used.

In Keras.training.engine.training_arrays.model_iteration if batch_outs = f(ins_batch) (line 329) is replaced with batch_outs = np.mean(f(ins_batch)[0]).tolist() the error vanishes and the loss is computed correctly.

psitronic avatar Apr 10 '19 14:04 psitronic

Im also having various problems with keras model.fit and it appears that i makes mistakes during validation steps

hammurabi-ds avatar May 14 '19 09:05 hammurabi-ds