tensorflow / neural-structured-learning

Training neural models with structured signals.
https://www.tensorflow.org/neural_structured_learning
Apache License 2.0
980 stars 189 forks source link

NSL for Regression #50

Closed santhoshkolloju closed 4 years ago

santhoshkolloju commented 4 years ago

I was able to integrate adversarial loss to my TensorFlow model, My input data has combination of categorical and continuous attributes. Is there any way to specify not to perturb categorical data while creating adversarial examples?

code:
x = tf.placeholder(tf.float32,shape=(None,20))
y = tf.placeholder(tf.float32,shape=(None,1))
#build a sample model
def model(x,y,is_training):
    with tf.variable_scope("regression_model",reuse=tf.AUTO_REUSE) as scope:
        layer0 = tf.layers.Dense(units=64,activation=tf.nn.relu)(x)
        layer1 = tf.layers.Dense(units=128,activation=tf.nn.relu)(layer0)
        output = tf.layers.Dense(units=1)(layer1)
        error = tf.subtract(y,output)
        print(error)
        loss = tf.reduce_mean(error,axis=0)
    return loss
#normal loss mean absolute error 
regular_loss = model(x,y,True)
adv_config = nsl.configs.AdvRegConfig()
adv_input,adv_weights = nsl.lib.gen_adv_neighbor(x,regular_loss,config=adv_config.adv_neighbor_config)
adv_loss = model(adv_input,y,True)
overall_loss = regular_loss + 0.2*adv_loss
train_step = optim.minimize(overall_loss)
tf.random.set_random_seed(100)
sess = tf.Session()
init_op = tf.global_variables_initializer()
sess.run(init_op)
X = np.random.random((32,20))#batch of 32
Y = np.random.random((32,1))
sess.run([train_step,adv_loss,regular_loss,overall_loss],feed_dict={x:X,y:Y})
aheydon-google commented 4 years ago

Hi, Santhosh.

Yes, in the AdvRegConfig, you can specify an AdvNeighborConfig via the AdvRegConfig.adv_neighbor_config field. The AdvNeighborConfig.feature_mask field can be used to control which of your input features to perturb: specify 0.0 in the feature_mask for your categorical features, and 1.0 for the continuous features. Here's the unit test that tests how feature masks are applied:

https://github.com/tensorflow/neural-structured-learning/blob/master/neural_structured_learning/lib/utils_test.py#L302

Hopefully, you'll be able to figure it out from that, but please let us know if you have any further questions!

By the way, you may find it convenient to use the make_adv_reg_config() function to construct your AdvRegConfig instance:

https://www.tensorflow.org/neural_structured_learning/api_docs/python/nsl/configs/make_adv_reg_config

santhoshkolloju commented 4 years ago

Thank you that worked

santhoshkolloju commented 4 years ago

I couldn't find any example for TensorFlow model in the API, Is this the right way to implement or do suggest any corrections

x = tf.placeholder(tf.float32,shape=(None,20))
y = tf.placeholder(tf.float32,shape=(None,1))
#build a sample model
def model(x,y,is_training):
    with tf.variable_scope("regression_model",reuse=tf.AUTO_REUSE) as scope:
        layer0 = tf.layers.Dense(units=64,activation=tf.nn.relu)(x)
        layer1 = tf.layers.Dense(units=128,activation=tf.nn.relu)(layer0)
        output = tf.layers.Dense(units=1)(layer1)
        error = tf.subtract(y,output)
        print(error)
        loss = tf.reduce_mean(error,axis=0)
    return loss
#normal loss mean absolute error 
regular_loss = model(x,y,True)
adv_config = nsl.configs.AdvRegConfig()
adv_input,adv_weights = nsl.lib.gen_adv_neighbor(x,regular_loss,config=adv_config.adv_neighbor_config)
adv_loss = model(adv_input,y,True)
overall_loss = regular_loss + 0.2*adv_loss
train_step = optim.minimize(overall_loss)
tf.random.set_random_seed(100)
sess = tf.Session()
init_op = tf.global_variables_initializer()
sess.run(init_op)
X = np.random.random((32,20))#batch of 32
Y = np.random.random((32,1))
sess.run([train_step,adv_loss,regular_loss,overall_loss],feed_dict={x:X,y:Y})
csferng commented 4 years ago

Hi Santhosh,

The overall structure of your code looks fine. One thing you might want to change is the loss. Instead of setting loss to the mean of (signed) errors, you might want it to be the mean of absolute errors tf.reduce_mean(tf.abs(error)), or squared errors tf.reduce_mean(error**2).

Besides, you may also consider using the Keras API to build and train models, which could simplify the code a bit. (See Keras guide for TF 2.x and for TF 1.x.) We also provide a convenient wrapper nsl.keras.AdversarialRegularization for adding adversarial regularization to Keras models (tutorial here). This is totally optional. Your code and model can work well with its current TensorFlow API use.

Hope this helps.