Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hash given here differs from hash in nnhash.py? #4

Closed
lambdaTotoro opened this issue Aug 21, 2021 · 4 comments
Closed

Hash given here differs from hash in nnhash.py? #4

lambdaTotoro opened this issue Aug 21, 2021 · 4 comments

Comments

@lambdaTotoro
Copy link

I have the following two images:

I then ask nnhash.py from AsuharietYgvar/AppleNeuralHash2ONNX for the NeuralHash of the second picture (as instructed by the README in this repo) and get a result.

$ python3 nnhash.py model.onnx neuralhash_128x96_seed1.dat ../images/target/palpatine_square.png 
e34b2da852103c3c0828fbd1

I then run the collider as instructed with that result as target hash and seem to find a collision:

$ python3 collide.py --image ../images/source/picard_square.png --target e34b2da852103c3c0828fbd1
[.../snip/...]
iteration: 221/1000, best: 0, hash: e34b2da852103c3c0828fbd1, distance: 0, loss: 7.484


Seems like everything worked fine, the hash displayed is equal to the target!
But! If I now run nnhash.py on one of the saved pictures, it gives me a slightly different hash than the target?

$ python3 nnhash.py model.onnx neuralhash_128x96_seed1.dat out_iter\=00220_dist\=00.png 
e24b2da85210343c0828fbd1

e34b2da852103c3c0828fbd1
e24b2da85210343c0828fbd1


Is this expected behaviour that I don't understand? Do the two bytes not make a difference, somehow? Or is this only producing near-collisions instead of proper collisions?

@anishathalye
Copy link
Owner

Thank you for opening this issue.

A couple things contribute to the bug you described. One is that the optimization represents images with 32-bit floats per channel, whereas the saved image has 8 bits per channel. The adversarial example that is found is not necessarily "robust", so quantization could cause slight changes in the hash output. Another issue was that there was a bug in the code, where it did the gradient descent update step before saving the image, so the hash that as computed during the forward pass was not the hash of the saved image. These two issues should be fixed in 3cc3c19. With those changes, the issue is fixed with your example.

$ python collide.py --image picard.png --target e34b2da852103c3c0828fbd1
...
iteration: 216/1000, best: 0, hash: e34b2da852103c3c0828fbd1, distance: 0, loss: 7.517
...
$ python nnhash.py out_iter=00216_dist=00.png
e34b2da852103c3c0828fbd1

out_iter=00216_dist=00

For more on the topic of robust adversarial examples, you could take a look at this blog post or this paper. If I have some free time this weekend, I could try incorporating those techniques into this repo and maybe also address some of the other limitations mentioned in the README.

@lambdaTotoro
Copy link
Author

Can confirm, this has fixed the issue, I'll close it. Thanks for your swift and helpful reply! =)

@anishathalye
Copy link
Owner

By the way, I've implemented a couple of those techniques I mentioned above, so you can get a slightly nicer looking image now. See here for examples: https://github.com/anishathalye/neural-hash-collider#examples

@lambdaTotoro
Copy link
Author

Very cool, thanks for the update!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants