{"id":16836342,"url":"https://github.com/aleju/face-generator","last_synced_at":"2025-07-06T23:05:25.149Z","repository":{"id":44035263,"uuid":"41510111","full_name":"aleju/face-generator","owner":"aleju","description":"Generate human faces with neural networks","archived":false,"fork":false,"pushed_at":"2017-12-18T18:33:00.000Z","size":859,"stargazers_count":313,"open_issues_count":3,"forks_count":69,"subscribers_count":15,"default_branch":"master","last_synced_at":"2025-04-10T00:18:28.805Z","etag":null,"topics":["deep-learning","face","gan","lua","torch"],"latest_commit_sha":null,"homepage":"","language":"Lua","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/aleju.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-08-27T20:37:37.000Z","updated_at":"2025-03-23T10:31:57.000Z","dependencies_parsed_at":"2022-09-13T14:40:50.480Z","dependency_job_id":null,"html_url":"https://github.com/aleju/face-generator","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/aleju/face-generator","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aleju%2Fface-generator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aleju%2Fface-generator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aleju%2Fface-generator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aleju%2Fface-generator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/aleju","download_url":"https://codeload.github.com/aleju/face-generator/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aleju%2Fface-generator/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":263986224,"owners_count":23539808,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["deep-learning","face","gan","lua","torch"],"created_at":"2024-10-13T12:13:10.212Z","updated_at":"2025-07-06T23:05:25.130Z","avatar_url":"https://github.com/aleju.png","language":"Lua","readme":"# About\n\nThis is a script to generate new images of human faces using the technique of generative adversarial networks (GAN), as described in the paper by [Ian J. Goodfellow](http://arxiv.org/abs/1406.2661).\nGANs train two networks at the same time: A Generator (G) that draws/creates new images and a Discriminator (D) that distinguishes between real and fake images. G learns to trick D into thinking that his images are real (i.e. learns to produce good looking images). D learns to prevent getting tricked (i.e. learns what real images look like).\nIdeally you end up with a G that produces beautiful images that look like real ones. On human faces that works reasonably well, probably because they contain a lot of structure (autoencoders work well on them too).\n\nThe code in this repository is a modified version of facebook's [eyescream project](https://github.com/facebook/eyescream).\n\n# Example images\n\nThe following images were generated by a model trained with `th train.lua --D_L1=0 --D_L2=0 --D_iterations=2`.\n\n![32x32 color](images/color_random1024.jpg?raw=true \"32x32 color\")\n\n*1024 randomly generated 32x32 face images.*\n\n![64 color images rated as good](images/color_best.jpg?raw=true \"64 color images rated as good\")\n\n*64 generated 32x32 images, rated by D as the best images among 1024 randomly generated ones.*\n\n![Nearest neighbours of generated 32x32 images](images/color_neighbours.jpg?raw=true \"Nearest neighbours of generated 32x32 images\")\n\n*16 generated images (each pair left) and their nearest neighbours from the training set (each pair right). Distance was measured by 2-Norm (`torch.dist()`). The 16 selected images were the \"best\" ones among 1024 images according to the rating by D, hence some similarity with the training set is expected.*\n\n# Requirements\n\nTo generate the dataset:\n* [Labeled Faces in the Wild](http://vis-www.cs.umass.edu/lfw/) (original dataset without funneling)\n* Python 2.7 (only tested with that version)\n  * Scipy\n  * Numpy\n  * scikit-image\n\nTo run the GAN part:\n* [Torch](http://torch.ch/) with the following libraries (most of them are probably already installed by default):\n  * `pl` (`luarocks install pl`)\n  * `nn` (`luarocks install nn`)\n  * `paths` (`luarocks install paths`)\n  * `image` (`luarocks install image`)\n  * `optim` (`luarocks install optim`)\n  * `cutorch` (`luarocks install cutorch`)\n  * `cunn` (`luarocks install cunn`)\n  * `cudnn` (`luarocks install cudnn`)\n  * `dpnn` (`luarocks install dpnn`)\n* [display](https://github.com/szym/display)\n* Nvidia GPU with \u003e= 4 GB memory\n* cudnn3\n\n# Usage\n\nBuilding the dataset:\n* Download [Labeled Faces in the Wild](http://vis-www.cs.umass.edu/lfw/) and extract it somewhere\n* In `dataset/` run `python generate_dataset.py --path=\"/foo/bar/lfw\"`, where `/foo/bar/lfw` is the path to your LFW dataset\n\nTo train a new model, follow these steps:\n* Start `display` with `~/.display/run.js \u0026`\n* Open `http://localhost:8000` to see the training progress\n* Train a 32x32 color generator with `th train.lua` (add `--grayscale` for grayscale images)\n* Sample images with `th sample.lua`. Add `--neighbours` to sample nearest neighbours (takes long). Add e.g. `--runs=10` to generate 10 times the amount of images.\n\nYou might have to work with the command line parameters `--D_iterations` and `--G_iterations` to get decent performance.\nSometimes you also might have to change `--D_L2` (D's L2 norm) or `--G_L2` (G's L2 norm). (Similar parameters are available for L1.)\n\n# Architecture\n\nG's architecture is mostly copied from the [blog post](http://torch.ch/blog/2015/11/13/gan.html) by Anders Boesen Lindbo Larsen and Søren Kaae Sønderby.\nIt is basically a full laplacian pyramid in one network.\nThe network starts with a small linear layer, which roughly generates 8x8 images.\nThat is followed by upsampling layers, which increase the image size to 16x16 and then 32x32 pixels.\n\n```lua\nlocal model = nn.Sequential()\nmodel:add(nn.Linear(noiseDim, 128*8*8))\nmodel:add(nn.View(128, 8, 8))\nmodel:add(nn.PReLU(nil, nil, true))\n\nmodel:add(nn.SpatialUpSamplingNearest(2))\nmodel:add(cudnn.SpatialConvolution(128, 256, 5, 5, 1, 1, (5-1)/2, (5-1)/2))\nmodel:add(nn.SpatialBatchNormalization(256))\nmodel:add(nn.PReLU(nil, nil, true))\n\nmodel:add(nn.SpatialUpSamplingNearest(2))\nmodel:add(cudnn.SpatialConvolution(256, 128, 5, 5, 1, 1, (5-1)/2, (5-1)/2))\nmodel:add(nn.SpatialBatchNormalization(128))\nmodel:add(nn.PReLU(nil, nil, true))\n\nmodel:add(cudnn.SpatialConvolution(128, dimensions[1], 3, 3, 1, 1, (3-1)/2, (3-1)/2))\nmodel:add(nn.Sigmoid())\n```\nwhere `noiseDim` is 100 and `dimensions[1]` is 3 (color mode) or 1 (grayscale mode).\n\nD is a standard convolutional neural net.\n\n```lua\nlocal conv = nn.Sequential()\nconv:add(nn.SpatialConvolution(dimensions[1], 64, 3, 3, 1, 1, (3-1)/2))\nconv:add(nn.PReLU(nil, nil, true))\nconv:add(nn.SpatialDropout(0.2))\nconv:add(nn.SpatialAveragePooling(2, 2, 2, 2))\n\nconv:add(nn.SpatialConvolution(64, 128, 3, 3, 1, 1, (3-1)/2))\nconv:add(nn.PReLU(nil, nil, true))\nconv:add(nn.SpatialDropout(0.2))\nconv:add(nn.SpatialAveragePooling(2, 2, 2, 2))\n\nconv:add(nn.SpatialConvolution(128, 256, 3, 3, 1, 1, (3-1)/2))\nconv:add(nn.PReLU(nil, nil, true))\nconv:add(nn.SpatialDropout(0.2))\nconv:add(nn.SpatialAveragePooling(2, 2, 2, 2))\n\nconv:add(nn.SpatialConvolution(256, 512, 3, 3, 1, 1, (3-1)/2))\nconv:add(nn.PReLU(nil, nil, true))\nconv:add(nn.SpatialDropout(0.2))\nconv:add(nn.SpatialAveragePooling(2, 2, 2, 2))\n\nconv:add(nn.View(512 * 0.25 * 0.25 * 0.25 * 0.25 * dimensions[2] * dimensions[3]))\nconv:add(nn.Linear(512 * 0.25 * 0.25 * 0.25 * 0.25 * dimensions[2] * dimensions[3], 512))\nconv:add(nn.PReLU(nil, nil, true))\nconv:add(nn.Dropout())\nconv:add(nn.Linear(512, 512))\nconv:add(nn.PReLU(nil, nil, true))\nconv:add(nn.Dropout())\nconv:add(nn.Linear(512, 1))\nconv:add(nn.Sigmoid())\n```\nwhere `dimensions[1]` is 3 (color) or 1 (grayscale), and `dimensions[2]` is the height of 32 (same as `dimensions[3]`).\n\nTraining is done with Adam (by default).\n\n# Command Line Parameters\n\nThe `train.lua` script has the following parameters:\n* `--batchSize` (default 16): The size of each batch, which will be split in two parts for G and D, making each one of them half-size. So a setting of 4 will create a batch of size of 2 for D (one image fake, one real) and another batch of size 2 for G. Because of that, the minimum size is 4 (and batches must be even sized).\n* `--save` (default \"logs\"): Directory to save the weights to.\n* `--saveFreq` (default 30): Save weights every N epochs.\n* `--network` (default \"\"): Name of a weights file in the save directory to load.\n* `--noplot`: Whether to NOT plot during training.\n* `--N_epoch` (default 1000): How many examples to use during each epoch (-1 means \"use the whole dataset\").\n* `--G_SGD_lr` (default 0.02): Learning rate for G's SGD, if SGD is used as the optimizer. (Note: There is no decay. You should use Adam or Adagrad.)\n* `--G_SGD_momentum` (default 0): Momentum for G's SGD.\n* `--D_SGD_lr` (default 0.02): Learning rate for D's SGD, if SGD is used as the optimizer. (Note: There is no decay. You should use Adam or Adagrad.)\n* `--D_SGD_momentum` (default 0): Momentum for D's SGD.\n* `--G_adam_lr` (default -1): Adam learning rate for G (-1 is automatic).\n* `--D_adam_lr` (default -1): Adam learning rate for D (-1 is automatic).\n* `--G_L1` (default 0): L1 penalty on the weights of G.\n* `--G_L2` (default 0): L2 penalty on the weights of G.\n* `--D_L1` (default 0): L1 penalty on the weights of D.\n* `--D_L2` (default 1e-4): L2 penalty on the weights of D.\n* `--D_iterations` (default 1): How often to optimize D per batch (e.g. 2 for D and 1 for G means that D will be trained twice as much).\n* `--G_iterations` (default 1): How often to optimize G per batch.\n* `--D_maxAcc` (default 1.01): Stop training of D roughly around that accuracy level until G has catched up. (Sounds good in theory, doesn't produce good results in practice.)\n* `--D_clamp` (default 1): To which value to clamp D's gradients (e.g. 5 means -5 to +5, 0 is off).\n* `--G_clamp` (default 5): To which value to clamp G's gradients (e.g. 5 means -5 to +5, 0 is off).\n* `--D_optmethod` (default \"adam\"): Optimizer to use for D, either \"sgd\" or \"adam\" or \"adagrad\".\n* `--G_optmethod` (default \"adam\"): Optimizer to use for D, either \"sgd\" or \"adam\" or \"adagrad\".\n* `--threads` (default 8): Number of threads.\n* `--gpu` (default 0): Index of the GPU to train on (0-4 or -1 for cpu). Nothing is optimized for CPU.\n* `--noiseDim` (default 100): Dimensionality of noise vector that will be fed into G.\n* `--window` (default 3): ID of the first plotting window (in display), will also use about 3 window-ids beyond that.\n* `--scale` (default 32): Scale of the images to train on (height, width). Loaded images will be converted to that size. Only optimized for 32.\n* `--seed` (default 1): Seed to use for the RNG.\n* `--weightsVisFreq` (default 0): How often to update the windows showing the activity of the network (only if \u003e0; implies starting with `qlua` instead of `th` if set to \u003e0).\n* `--grayscale`: Whether to activate grayscale mode on the images, i.e. training will happen on grayscale images.\n* `--denoise`: If added as parameter, the script will try to load a denoising autoencoder from `logs/denoiser_CxHxW.net`, where C is the number of image channels (1 or 3), H is the height of the images (see `--scale`) and W is the width. A denoiser can be trained using `train_denoiser.lua`.\n\n# Other\n\n* Training was done with Adam.\n* Batch size was 32.\n* The file `train_c2f.lua` is used to train a *coarse to fine* network of the laplacian pyramid. (Deprecated)\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faleju%2Fface-generator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faleju%2Fface-generator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faleju%2Fface-generator/lists"}