anishathalye/neural-style: TensorFlow Neural Style Transfer You Run Locally
Neural style in TensorFlow! 🎨
At a glance
- What is it?
- A small TensorFlow implementation of the Gatys neural style algorithm. It optimizes a single image against a pre-trained VGG-19 network, and it needs a local GPU or patience.
- Who is it for?
- Adopt it if you want to read or modify the optimization loop rather than call a hosted API, and you already have TensorFlow working. Skip it if you need batch throughput: this is per-image optimization, not a feed-forward model like lengstrom/fast-style-transfer.
- Can I use it commercially?
- Yes, with conditions. GPL-3.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
- Is it still maintained?
- Yes. The repository last received commits 165 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What anishathalye/neural-style actually does
This is an implementation of neural style, the Gatys et al. method, written in TensorFlow. It takes a content photograph and one or more style paintings and produces a new image that keeps the content's structure while borrowing the style's texture and brushwork. It is for people who want the algorithm in readable Python, not a product. The README is explicit that the point is simplicity: "This implementation is a lot simpler than a lot of the other ones out there, thanks to TensorFlow's really nice API and automatic differentiation." That sentence is the whole design brief. The repository is one script, neural_style.py, plus a vgg.py module that builds the network, and a stylize.py helper. There is no service, no queue, no model training step.
How the optimization loop works
There is no trained style model here. The stylized image is the variable being optimized. The script loads the pre-trained VGG network, feeds the content image, the style image and a generated image through it, and computes two losses from intermediate activations: a content loss that compares feature maps against the content image, and a style loss that compares Gram-matrix statistics against the style image. Gradient descent then nudges the generated image's pixels until the combined loss drops. The README notes one deliberate deviation: "TensorFlow doesn't support L-BFGS (which is what the original authors used), so we use Adam." The README warns this "may require a little bit more hyperparameter tuning to get nice results." That is the central trade-off of the port. You get a shorter, more readable implementation, and you inherit Adam's sensitivity to learning rate and loss weights.
Installing it with uv and running a first transfer
The project uses uv as its package manager, so the README's first step is installing uv itself, for example with brew install uv. You also need the pre-trained VGG network file before anything runs. The README says to put it in the top level of the repository, or point at it with --network. Once both are in place, the invocation is a single command. The default is 1000 iterations; the README states that a 512x512 content file takes 90 seconds on an M3 MacBook Pro and significantly less on a more powerful NVIDIA GPU. Checkpoints are opt-in through --checkpoint-output and --checkpoint-iterations, which is worth setting on a first run so you can stop early and still have an image.
brew install uvThe README gives that as one way to install uv, following the uv installation instructions it links. After that, the run command takes a content file, one or more style files and an output path.
uv run neural_style.py --content <content file> --styles <style file> --output <output file>That is the README's own invocation, with its placeholders left as placeholders. Run help to see the full option list, which is how you discover --iterations, --content-weight, --style-weight and --learning-rate without guessing.
uv run neural_style.py --helpIf you are on a machine without a GPU, expect the run to take considerably longer than the M3 figure.
Style blending and the tuning flags that matter
Two of the flags change the output more than the rest. --style-layer-weight-exp controls how abstract the transfer looks: lower values favour finer features, higher values favour coarser ones, and the default of 1.0 treats all layers equally. --content-weight-blend takes a value in [0.0, 1.0]; the default 1.0 preserves finer content detail, and the README's example drops it to 0.1 for "more abstract picture." --pooling accepts max or avg. The README explains the difference plainly: the original VGG topology uses max pooling, the style transfer paper suggests average pooling, and max pooling "in general tends to have finer detail style transfer, but could have troubles at lower-freqency detail level." Finally, --preserve-colors adds a post-processing step that combines the original image's colour with the stylized image's luma in YCbCr space. Style blending works by passing multiple --styles files with per-style weights, as in the README's second example, which used 0.8 and 0.2.
Where this implementation falls short
The biggest limitation is speed and shape of the workload. Every output image requires its own optimization run, so producing a thousand stylized frames means a thousand VGG forward and backward passes. That is the opposite of a feed-forward approach, and it is why the README points readers to lengstrom/fast-style-transfer for the fast variant. The second limitation is the missing L-BFGS optimizer, which the README itself frames as a reason you may need extra tuning. Third, the setup is not self-contained: the VGG-19 file is a separate download from vlfeat.org, and the README gives its SHA256 (abdb57167f82a2a1fbab1e1c16ad9373411883f262a1a37ee5db2e6fb0044695) but no automated fetch. If your environment cannot install TensorFlow, nothing here helps you. The README does not document a CPU-only fallback path, a Docker image, or any rollback procedure.
How it differs from fast-style-transfer
The README's Related Projects section names lengstrom/fast-style-transfer as an implementation of fast (feed-forward) neural style in TensorFlow. The difference is architectural, not cosmetic. Fast style transfer trains a separate network per style ahead of time; after that, stylizing an image is one forward pass, which is what makes real-time and video use possible. This project skips the training phase entirely and optimizes each image from scratch, which means it can blend arbitrary styles at run time with no retraining, and it cannot compete on throughput. If you are experimenting with a single image and want to change a weight and rerun, this repository is the more direct tool. If you are building anything that processes a stream, the feed-forward route is the one to take.
Licence, maintenance and what upgrading costs
The project is released under GPL-3.0, with the README stating "Copyright (c) Anish Athalye. Released under GPLv3." That is a copyleft licence, so if you distribute a modified version or link it into a larger work, the obligations apply to the whole distributed work. Whether your specific use counts as distribution is a question for a lawyer, not for this article. The last push to the repository was on 2026-04-18, so it has seen changes within the last six months. There are no retrieved releases, so there is no versioned upgrade path to follow; the pyproject.toml declares version 0.1.0 and pins loose lower bounds (numpy>=2.1.3, pillow>=11.2.1, scipy>=1.15.3, tensorflow>=2.19.0, plus tensorflow-metal on macOS). Loose bounds mean a fresh uv sync can pull newer TensorFlow than the author last ran, and TensorFlow minor releases have historically broken model-loading code. requires-python is >=3.10.
Editorial conclusion
Adopt it if you want to read or modify the optimization loop rather than call a hosted API, and you already have TensorFlow working. Skip it if you need batch throughput: this is per-image optimization, not a feed-forward model like lengstrom/fast-style-transfer. Before committing, download the VGG-19 file and confirm the SHA256 abdb57167f82a2a1fbab1e1c16ad9373411883f262a1a37ee5db2e6fb0044695, then run the default 1000 iterations on your own 512x512 image and time it on your hardware.
Frequently asked questions
What is neural style transfer?
It is the method this repository implements: combining the content of one image with the style of another by optimizing a generated image against a pre-trained VGG network. The README links the original Gatys paper for the full explanation.
Is there a free tool for AI style transfer?
anishathalye/neural-style is free software under GPL-3.0 and runs locally, so there is no per-image fee. The README also links a browser-based demo of fast neural style that requires no installation.
How do I install anishathalye/neural-style?
Install uv, download the pre-trained VGG network file into the top level of the repository, then run the script through uv run. The README gives brew install uv as one way to get uv.
Can anishathalye/neural-style use more than one style image at once?
Yes. The README's second example blends Picasso's Dora Maar and Starry Night by passing multiple styles with style blend weights of 0.8 and 0.2.
How many iterations does anishathalye/neural-style need for a good result?
The default is 1000 iterations, and the README says 500 to 2000 iterations seem to produce nice results. It also notes that certain images or output sizes may need tuning of --content-weight, --style-weight and --learning-rate.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/anishathalye-neural-style)