| 255 | |
| 256 | |
| 257 | class DCGAN: |
| 258 | def __init__(self, img_length, num_colors, d_sizes, g_sizes): |
| 259 | |
| 260 | # save for later |
| 261 | self.img_length = img_length |
| 262 | self.num_colors = num_colors |
| 263 | self.latent_dims = g_sizes['z'] |
| 264 | |
| 265 | # define the input data |
| 266 | self.X = T.tensor4('placeholderX') |
| 267 | self.Z = T.matrix('placeholderZ') |
| 268 | |
| 269 | # build the discriminator |
| 270 | p_real_given_real = self.build_discriminator(self.X, d_sizes) |
| 271 | |
| 272 | # build generator |
| 273 | self.sample_images = self.build_generator(self.Z, g_sizes) |
| 274 | |
| 275 | # get sample predictions |
| 276 | p_real_given_fake = self.d_forward(self.sample_images, True) |
| 277 | |
| 278 | # sample with batch norm in test mode |
| 279 | self.sample_images_test = self.g_forward(self.Z, False) |
| 280 | |
| 281 | # build costs |
| 282 | self.d_cost_real = T.nnet.binary_crossentropy( |
| 283 | output=p_real_given_real, |
| 284 | target=T.ones_like(p_real_given_real), |
| 285 | ) |
| 286 | self.d_cost_fake = T.nnet.binary_crossentropy( |
| 287 | output=p_real_given_fake, |
| 288 | target=T.zeros_like(p_real_given_fake), |
| 289 | ) |
| 290 | self.d_cost = T.mean(self.d_cost_real) + T.mean(self.d_cost_fake) |
| 291 | |
| 292 | self.g_cost = T.mean( |
| 293 | T.nnet.binary_crossentropy( |
| 294 | output=p_real_given_fake, |
| 295 | target=T.ones_like(p_real_given_fake), |
| 296 | ) |
| 297 | ) |
| 298 | real_predictions = T.sum(T.eq(T.round(p_real_given_real), 1)) |
| 299 | fake_predictions = T.sum(T.eq(T.round(p_real_given_fake), 0)) |
| 300 | num_predictions = 2.0*BATCH_SIZE |
| 301 | num_correct = real_predictions + fake_predictions |
| 302 | self.d_accuracy = num_correct / num_predictions |
| 303 | |
| 304 | |
| 305 | # optimizers |
| 306 | d_grads = T.grad(self.d_cost, self.d_params) |
| 307 | d_updates = adam(self.d_params, d_grads) |
| 308 | # add batch norm updates |
| 309 | for layer in self.d_convlayers + self.d_denselayers + [self.d_finallayer]: |
| 310 | d_updates += layer.updates |
| 311 | self.train_d = theano.function( |
| 312 | inputs=[self.X, self.Z], |
| 313 | outputs=[self.d_cost, self.d_accuracy], |
| 314 | updates=d_updates, |