I implemented Conditional GAN with chainer. Github - https://github.com/lyakaap/GAN/tree/master/ConditionalGAN
The implementation referred to the following article. http://qiita.com/ysasaki6023/items/55b8545c296ce32ac135
"Conditional GAN" is a kind of GAN, and it is a wonderful model that you can make the image generated by specifying a label of any class, while you could not control the image generated by the conventional GAN. .. In addition, the conditions to be specified can be other than labels, and various applications are possible. The difference from the main GAN is that it also passes the label data corresponding to the input of Generator and Discriminator.
As a consideration when implementing, "how to pass the label to the network" becomes important. Let's take MNIST with 10 classes as an example.
Generator
Use chainer's concat () to attach.
Specifically, when I write out each shape,
It has become. The "1" attached to the third dimension common to the above three tensors is the number of channels (naturally it becomes 3 when handling RGB images).
input represents the tensor that will eventually become the Generator's input, and is combined as ʻinput = F.concat ((z, l), axis = 1)`.
Discriminator
If it is based on DCGAN, the network is in the Convolution layer, so you cannot pass the one-hot label as it is. So I defined the Discriminator input as shown below.
In the example above, the input image is "2", so the corresponding second channel is filled. By treating the one-hot label like a 10-channel image in this way, it is also compatible with Convolution. Ultimately, the combined label and input image will be passed to the Discriminator input layer as an 11-channel 28x28 image (MNIST image size). The specific input shape is (Mini batch size, 10 + 1 channels, 28, 28) It looks like. Like Generator, concat () is used for binding.
I specified the label of the generated image line by line from the top and visualized the arranged ones.
It is a state of learning
You can see that we are learning to correspond to the specified label properly.
Also, as a bonus, I will post the image generated after 300 epoch when the origin of the input noise space is used as the input. (The output of the same number is, of course, the same)
Looking at the generated images, it is fun to see that the origins of the noise space are associated with each other so as to generate a clean and neutral image.
I also made a script that displays the corresponding image when you enter an arbitrary number as an argument. Even with the same number, various handwritten characters of handwriting are output.
$ python digit_generator.py --digits 20170710
It would be interesting to do it with a hiragana dataset.
I was surprised that chainer doesn't have a one-hot labeling function like in tensorflow. (Maybe I just overlooked it) You can use scikit-learn ...
By the way, my implementation looks like this.
def to_onehot(label, class_num):
return numpy.eye(class_num)[label]
If you pass the label and the number of classes, it will output a one-hot label based on the identity matrix.
Recommended Posts