Code Monkey home page Code Monkey logo

davidbau / rewriting Goto Github PK

View Code? Open in Web Editor NEW
537.0 20.0 77.0 102.7 MB

Rewriting a Deep Generative Model, ECCV 2020 (oral). Interactive tool to directly edit the rules of a GAN to synthesize scenes with objects added, removed, or altered. Change StyleGANv2 to make extravagant eyebrows, or horses wearing hats.

Home Page: https://rewriting.csail.mit.edu/

License: MIT License

Python 66.23% Shell 0.61% C 0.51% C++ 1.42% Cuda 5.31% Jupyter Notebook 25.66% HTML 0.25%
vision machine-learning graphics hci gans deep-learning research

rewriting's Introduction

Rewriting a Deep Generative Model

In this paper, we ask if a deep network can be reprogrammed to follow different rules, by enabling a user to directly change the weights, instead of training with a data set.


Directly rewriting the weights of a StyleGANv2 to reprogram horses to have hats.

What is model rewriting?

We present the task of model rewriting, which aims to add, remove, and alter the semantic and physical rules of a pre-trained deep network. While modern image editing tools achieve a user-specified goal by manipulating individual input images, we enable a user to synthesize an unbounded number of new images by editing a generative model to carry out modified rules.

Why rewrite a model?

There are two reasons to want to rewrite a deep network directly:

  1. To gain insight about how a deep network organizes its knowledge.
  2. To enable creative users to quickly make novel models for which there is no existing data set.

Model rewriting envisions a way to construct deep networks according to a user's intentions. Rather than limiting networks to imitating data that we already have, rewriting allows deep networks to model a world that follows new rules that a user wishes to have.

Rewriting a Deep Generative Model.
David Bau, Steven Liu, Tongzhou Wang, Jun-Yan Zhu, Antonio Torralba.
ECCV 2020 (oral).
MIT CSAIL and Adobe Research.


2 minute
Video Preview

ECCV 2020
Preprint

ECCV 2020
Talk Video

Presentation
Slides

Website

Demo Colab
Notebook

Our method rewrites the weights of a generator to change generative rules. Instead of editing individual images, our method edits the generator, so an infinite set of images can be potentially synthesized and manipulated using the altered rules. Rules can be changed in various ways, such as removing patterns like watermarks, adding objects such as people, or replacing definitions such as making trees grow out of towers.

Our method is based on the hypothesis that the weights of a generator act as linear associative memory. A layer stores a map between keys, which denote meaningful context, and values, which determine output.

Example Results

The results below show changes of a single rule within StyleGANv2. In each case, four examples chosen by the user (center of the top row) establish the context for the rule begin rewritten, and the "copy and paste" examples (left and right of top row) indicate how the user wishes to change the model.

The grid below shows pairs of outputs: for each pair, the first is the output of the original unmodified StyleGANv2. The second is the output of the modified StyleGANv2, applying the user's intention using our method.


First: changing the rule defining kids' eyebrows to make them look like a bushy mustache.


Altering the rule for pointy tower tops to make them into trees.


Changing the rule for tops of horses heads, to put hats on horses.


Changing frowns into smiles.


Removing the main window in a building by changing the rule to draw a blank wall.

Tips

The code runs using PyTorch.

  • The method and interface can be found in /rewrite
  • Notebooks are in /notebooks: see rewriting-interface.ipynb for the demonstration UI.
  • Quantitative experiments in /metrics, dissection utilities in /utils. Experiments from section 5.1 can be repoduced by /experiments.sh, and section 5.2 can be reproduced by /watermarks.sh. The experiment in section 5.3 runs in ithe notebook /notebooks/reflection-rule-change.ipynb.

Setup

It's designed to use a recent version of PyTorch (1.4+) on python (3.6), using cuda 10.1 and cudnn 7.6.0. Run setup/setup_renv.sh to create a conda environment that has the needed dependencies.

Rewriting your own models

To edit your own models, do the following:

# Resolution (size) and style dimensionality (style_dim and n_mlp) are
# the architecture dimensions as you trained them.  The truncation trick can be
# applied here if desired (truncation=1.0 if not).
# Note that mconv='seq' splits apart the optimized modulated convolution into
# separate operations that the rewriter can examine the underlying
# convolution directly.
model = SeqStyleGAN2(size=256, style_dim=512, n_mlp=8, truncation=0.5, mconv='seq')

# load the exponential moving average model weights, put it on the GPU.
state_dict = torch.load('your_model.pt')
model.load_state_dict(state_dict['g_ema'], latent_avg=state_dict['latent_avg'])
model.cuda()
  • Create a ganrewrite.SeqStyleGanRewriter instance to edit your model
layernum = 8 # or which ever layer you wish to modify
sample_size = 1000 # a small sample of images for computing statistics
zds = zdataset.z_dataset_for_model(model, size=sample_size)
gw = SeqStyleGanRewriter(
    model, zds, layernum,
    cachedir='experiments')
  • Finally, to specify and create changes, you can use the rewriteapp.GanRewriteApp interface (assumes you are running in a notebook. This interface can be used to try edits and save and load json files with stored model edit specifications.
savedir = 'masks'
interface = rewriteapp.GanRewriteApp(gw, size=256, mask_dir=savedir, num_canvases=32)
  • To bulk-generate images from an edited model (notebook UI not needed), you can do the following, then sample the output of the modified model as usual. See metrics/sample_edited.py for an example.
saved_edit = 'masks/my_edit.json'
gw.apply_edit(json.load(saved_edit), rank=1)

rewriting's People

Contributors

davidbau avatar junyanz avatar ssnl avatar stevliu avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

rewriting's Issues

Rendering in isolation from neighbouring features

Hi, I found the idea of seeing weights as associative memory very interesting. Could you please explain in some more detail what do you mean by rendering feature patch in isolation from neighboring features?

For example, if a network generates an output of 256x256 and I want to generate an isolated patch of 32x32. If we are analyzing a layer L with feature maps with spatial size 32x32, should the features excluding a 4x4 patch be set to 0 and so on for other layers to get final output?

How to choose best layer and rank update for custom dataset

Hi David, thanks for the great work so far. I trained a custom dataset with StyleGAN2 and converted the weight to pytorch. Then I tried on rewriting some of the features, but it proves to be quite challenging.

For example, here I tried to add an extra bottle holder, but it only changed very few of the output.
bike_bottle

And here, I tried changing the back wheel to black, but it changed both wheels instead, and although it changed most of the output, some are not.
black_wheel

I also tried changing some of the other features such as the frame shape and the seat location but failed to give the changes I wanted. I assume this is because I do not choose the best layer to dissect or the wrong value for rank update and the learning parameter.

My question is, how do you choose the best layer and rank update for your previous sample? Especially if I don't have any segmentation labels for the object.

It'd be great if you can make a Colab tutorial on dissecting the network and finding the best layer and other parameters for the features that we selected.

Thanks,

[Question] Question about labwidget

Hello, first of all, great work but even better way of using Colab for the demo. I am having a lot of fun changing things into trees and horse mouths.

I could not find a license for labwidget or this repo in general on both Github and the linked MIT website. Is it possible for me to use labwidget for some of my notebooks with proper citations/credit? I've wanted to host stylegan models on the web but Heroku doesn't provide GPUs and the ones that do cost money while Colab is free.

how to select a proper location?

Hi Dr. Bau,

Fistly thanks for all you talk and great work. Perhaps here is not a right place, but I have this question and wanted to ask at one of your workshop, but never get a chance due to time. I greatly apprecite if you could please give me a hint before closing this issue.
My question:

I understand it what it means when you say: to activate and deactivate neurons directly. But cannot figure it out how turning on neurons in a specific location?? I mean, what's the method to select a region?? For example, how to select wall in a generated image?

This is something that is vague when reading your related papers, and seeing talk. Maybe this part is quite easy that nobody metion how to do so.

Thank you very much for your time.
Mike

How to get v_*i

In you paper,
image
I am confused how to get v_*i?
Through gan inversion optimization to find the v_*i correspond to x_*iļ¼Ÿ
I can't find in your code, so sorry to bother you.

rewriting-interface.ipynb exceeds IOPub data rate with faces

Issue:

rewriting's rewriting-interface.ipynb exceeds colab's IOPub data rate with faces

While in google colab, as directed in the last cell, I changed modelname to faces with no other changes. While executing, the runtime disconnects with no error displayed. When running print(interface._repr_html_()) the following error is displayed:

IOPub data rate exceeded.
The notebook server will temporarily stop sending output
to the client in order to avoid crashing it.
To change this limit, set the config variable
`--NotebookApp.iopub_data_rate_limit`.

Current values:
NotebookApp.iopub_data_rate_limit=1000000.0 (bytes/sec)
NotebookApp.rate_limit_window=3.0 (secs)

As far as I'm able to tell, there are no ways to change the data rate limit in colab.

Steps to reproduce:

Change modelname to faces in the last cell of rewriting-interface.ipynb in google colab

UI doesn't show up in colab when using the faces dataset

Hi! Thanks for making this code available. I saw your lecture in Ali Jahanian's class on yt and wanted to try this out with faces.

However, when changing the colab to use faces instead of church, the UI doesn't show up when the cell completes. There's no error or anything as far as I can tell, execution just ends without anything happening. Things work correctly when I leave the modelname as church though.

Thanks again for the help!

How to rewrite on other dataset

sorry to disturb you. As a beginner, I am very interested in your work, and I would like to ask how to rewrite on other dataset

Unable to run custom model on Colab

When attempting to load a custom mode, the following errors are raised:

Error(s) in loading state_dict for SeqStyleGAN2:
	Missing key(s) in state_dict: "noises.noise_0", "noises.noise_1", "noises.noise_2", "noises.noise_3", "noises.noise_4", "noises.noise_5", "noises.noise_6", "noises.noise_7", "noises.noise_8", "noises.noise_9", "noises.noise_10", "noises.noise_11", "noises.noise_12", "noises.noise_13", "noises.noise_14". 

I've tried setting the strict argument of load_state_dict to False but to no avail. After commenting out the noise layers in SeqStyleGAN2, everything runs until:
gw = ganrewrite.SeqStyleGanRewriter(g, zds, layernum, cachedir='experiments') which then complains that the selected layer (e.g. layer 8) is not a Sequential layer. Any ideas?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    šŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. šŸ“ŠšŸ“ˆšŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ā¤ļø Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.