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

Fast Style Transfer #38

Merged
merged 12 commits into from
Jan 23, 2018
Merged

Fast Style Transfer #38

merged 12 commits into from
Jan 23, 2018

Conversation

yining1023
Copy link
Member

This PR -

  • adds TransformNet class, and TransformNet.setStyle() and TransformNet.predict() methods
  • adds a simple example of Fast Style Transfer with one model about wave style

I will create a demo of Fast Style Transfer with a few other styles and host it on my GitHub, because it is a large folder of all the models with different styles.

You can check out a demo here.

Simple example of Fast Style Transfer:
screen shot 2018-01-18 at 2 25 41 am

Copy link
Member

@shiffman shiffman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is so amazing @yining1023!!! I left a few review comments. Also, similarly to what we did with LSTMs, could we add a README with documentation about training your own model?

* @param inputImg HTMLImageElement of input img
* @return Array3D containing pixels of output img
*/
outputImgData = net.predict(inputImg);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's tricky b/c I think the library should be able to be "p5 independent" and work with plain JS or other JS frameworks, however, for beginners using p5 it would be nice to be able to pass in a p5.Image or valid p5.Element/p5.MediaElement and receive a p5.Image back.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I totally agree. I added another function called array3DToP5Image(imageData) which takes an Array3D and returns a p5.Image. I left this array3DToP5Image in the example code. I was going to include it in the p5ml library, but in order to do that, I need to add p5.js as a dependency to p5.ml. And I'm not sure if p5ml should depend on p5.js. I think this is a question that worth discussion. So I left the function in the example code for now.

for (let i = 0; i < width; i++) {
for (let j = 0; j < height; j++) {
k = (i + j * height) * 3;
let r = Math.round(255 * data[k + 0]);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe p5 has a round() function so Math is not necessary. Also, would floor() and 256 be more correct here? Tiny minor point! And perhaps irrelevant if we refactor based on my other comment above.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right!


function setup() {
createCanvas(252, 252);
net = new p5ml.TransformNet(modelLoaded, 'udnie', 'models/udnie/');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there an option to use this with preload()? Also I think the convention is to have the callback last? Is it possible to load more than one style model into the same p5ml.TransformNet instance? Is that way a name is required? Would it be simpler to just create multiple p5ml.TransformNet instances with different model directories?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems like p5's preload() only waits for its native methods, like loadImage(). I think using a callback might be more generic, and works outside of p5.js.

It's possible to load more than one style model in one instance, but it's simpler to create multiple p5ml.TransformNet instance, and a name is not required in this case. so it will be net1 = new p5ml.TransformNet('models/udnie/', callback) and net2 = new p5ml.TransformNet('models/wave/', callback).

@yining1023
Copy link
Member Author

Thank you!! I left comments under each of your comments. About the documentation to train your model with other styles, I want to train one myself and then write something. For now, all models are from deeplearn.js 's demo.

I changed the method to be net = new p5ml.TransformNet('models/udnie/', callback). And added anther style in the example.
screen shot 2018-01-19 at 2 54 33 am

@shiffman
Copy link
Member

Looks great to me, thank you! @cvalenzuela any comments before I merge?

@yining1023
Copy link
Member Author

I also added an image utility to convert array3d to HTML image element: let img = p5ml.array3DToImage(_array3d_); so it can be friendly to beginners and "p5 independent". It's in my last commit: c313d40.

@cvalenzuela
Copy link
Member

Looks good to me!, I will merge and add a documentation and example page in the website

@cvalenzuela cvalenzuela merged commit 10eb05b into ml5js:master Jan 23, 2018
joeyklee pushed a commit that referenced this pull request Jun 2, 2019
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

Successfully merging this pull request may close these issues.

None yet

3 participants