kosta-pmf / dnn-audio-watermarking

DNN-based audio watermarking
GNU General Public License v3.0
40 stars 10 forks source link

The model only work on messages taken from the pool. #6

Closed my-yy closed 1 year ago

my-yy commented 1 year ago

I found that if the message was taken from the pool file (samples/message_pool.npy), the model performed very well (BER=0). But if the message doesn't come from the pool, it behaves like a random guess. Here's my test code:

import pdb
from evaluation import restore_model
import librosa
from main import embed
from main import detect, random_message
import numpy as np
import config
import tensorflow as tf
from config import MESSAGE_POOL

embedder_model = restore_model("embedder_model")
detector_model = restore_model("detector_model")

def expand_message(a):
    # (1,512) ===> (1, 16, 2, 512)
    repeats = [16, 1]
    a_tiled = tf.tile(a, repeats)
    a_expanded = tf.expand_dims(a_tiled, axis=1)
    a_final = tf.tile(a_expanded, [1, 2, 1])
    a_expanded2 = tf.expand_dims(a_final, axis=0)
    return a_expanded2

def fun1(watermark):
    # load signal
    config.HOP_LENGTH = 490
    signal, sr = librosa.load('samples/example1.wav', sr=16000)
    signal = np.expand_dims(signal, axis=0)

    # encode:
    watermark_expanded = expand_message(watermark)
    signal_wmd = embed(embedder_model, signal, message=watermark_expanded)

    # decode:
    detector_output = detect(detector_model, signal_wmd).numpy().squeeze()
    watermark_detected_bit = tf.where(tf.greater_equal(detector_output, 0.5), 1, 0).numpy().squeeze()

    # calculate BER:
    watermark_npy = watermark.numpy().squeeze()
    ber = (watermark_npy != watermark_detected_bit).sum() / len(watermark_detected_bit)
    return ber

if __name__ == "__main__":
    watermark_from_pool = random_message()
    print("pool-message :", fun1(watermark_from_pool))
    print("1 - pool-message :", fun1(1 - watermark_from_pool))

    # random message
    watermark_from_np = np.random.randint(2, size=512)
    watermark_from_np_tensor = tf.expand_dims(tf.constant(watermark_from_np), axis=0)
    print("random message:", fun1(watermark_from_np_tensor))

and the BER output is:

pool-message : 0.0
1 - pool-message : 0.47265625
random message: 0.47265625

Also, there is a typo for the restore_model function in the evaluation.py, with an 's' missing from the statement keras.model:

restored_model = keras.model.load_model(model_path)

===>

restored_model = keras.models.load_model(model_path)

kosta-pmf commented 1 year ago

Your comment is correct. The model embeds the message it was trained for. We had to reduce the number of messages in order to achieve resistance to desynchronization attacks. In the meantime, we have managed to train a model to embed an arbitrary message, but it will be a while before we publish it. We hope that you will continue to follow our progress and stay updated on the latest developments and want to express our gratitude for your interest in our work.