@ -24,6 +24,7 @@ from paddle.trainer.config_parser import logger
import py_paddle . swig_paddle as api
import matplotlib . pyplot as plt
def plot2DScatter ( data , outputfile ) :
'''
Plot the data as a 2 D scatter plot and save to outputfile
@ -41,9 +42,11 @@ def plot2DScatter(data, outputfile):
plt . scatter ( x , y )
plt . savefig ( outputfile , bbox_inches = ' tight ' )
def CHECK_EQ ( a , b ) :
assert a == b , " a= %s , b= %s " % ( a , b )
def copy_shared_parameters ( src , dst ) :
'''
copy the parameters from src to dst
@ -52,11 +55,9 @@ def copy_shared_parameters(src, dst):
: param dst : the destination of the parameters
: type dst : GradientMachine
'''
src_params = [ src . getParameter ( i )
for i in xrange ( src . getParameterSize ( ) ) ]
src_params = [ src . getParameter ( i ) for i in xrange ( src . getParameterSize ( ) ) ]
src_params = dict ( [ ( p . getName ( ) , p ) for p in src_params ] )
for i in xrange ( dst . getParameterSize ( ) ) :
dst_param = dst . getParameter ( i )
src_param = src_params . get ( dst_param . getName ( ) , None )
@ -68,14 +69,16 @@ def copy_shared_parameters(src, dst):
dst_value . copyFrom ( src_value )
dst_param . setValueUpdated ( )
def print_parameters ( src ) :
src_params = [ src . getParameter ( i )
for i in xrange ( src . getParameterSize ( ) ) ]
src_params = [ src . getParameter ( i ) for i in xrange ( src . getParameterSize ( ) ) ]
print " *************** "
for p in src_params :
print " Name is %s " % p . getName ( )
print " value is %s \n " % p . getBuf ( api . PARAMETER_VALUE ) . copyToNumpyArray ( )
print " value is %s \n " % p . getBuf ( api . PARAMETER_VALUE ) . copyToNumpyArray (
)
def load_mnist_data ( imageFile ) :
f = open ( imageFile , " rb " )
@ -93,6 +96,7 @@ def load_mnist_data(imageFile):
f . close ( )
return data . astype ( ' float32 ' )
def load_cifar_data ( cifar_path ) :
batch_size = 10000
data = numpy . zeros ( ( 5 * batch_size , 32 * 32 * 3 ) , dtype = " float32 " )
@ -106,11 +110,13 @@ def load_cifar_data(cifar_path):
data = data / 255.0 * 2.0 - 1.0
return data
# synthesize 2-D uniform data
def load_uniform_data ( ) :
data = numpy . random . rand ( 1000000 , 2 ) . astype ( ' float32 ' )
return data
def merge ( images , size ) :
if images . shape [ 1 ] == 28 * 28 :
h , w , c = 28 , 28 , 1
@ -124,6 +130,7 @@ def merge(images, size):
( ( images [ idx , : ] . reshape ( ( h , w , c ) , order = " F " ) . transpose ( 1 , 0 , 2 ) + 1.0 ) / 2.0 * 255.0 )
return img . astype ( ' uint8 ' )
def save_images ( images , path ) :
merged_img = merge ( images , [ 8 , 8 ] )
if merged_img . shape [ 2 ] == 1 :
@ -132,13 +139,16 @@ def save_images(images, path):
im = Image . fromarray ( merged_img , mode = " RGB " )
im . save ( path )
def get_real_samples ( batch_size , data_np ) :
return data_np [ numpy . random . choice ( data_np . shape [ 0 ] , batch_size ,
replace = False ) , : ]
return data_np [ numpy . random . choice (
data_np . shape [ 0 ] , batch_size , replace = False ) , : ]
def get_noise ( batch_size , noise_dim ) :
return numpy . random . normal ( size = ( batch_size , noise_dim ) ) . astype ( ' float32 ' )
def get_fake_samples ( generator_machine , batch_size , noise ) :
gen_inputs = api . Arguments . createArguments ( 1 )
gen_inputs . setSlotValue ( 0 , api . Matrix . createDenseFromNumpy ( noise ) )
@ -147,12 +157,14 @@ def get_fake_samples(generator_machine, batch_size, noise):
fake_samples = gen_outputs . getSlotValue ( 0 ) . copyToNumpyMat ( )
return fake_samples
def get_training_loss ( training_machine , inputs ) :
outputs = api . Arguments . createArguments ( 0 )
training_machine . forward ( inputs , outputs , api . PASS_TEST )
loss = outputs . getSlotValue ( 0 ) . copyToNumpyMat ( )
return numpy . mean ( loss )
def prepare_discriminator_data_batch_pos ( batch_size , data_np ) :
real_samples = get_real_samples ( batch_size , data_np )
labels = numpy . ones ( batch_size , dtype = ' int32 ' )
@ -161,6 +173,7 @@ def prepare_discriminator_data_batch_pos(batch_size, data_np):
inputs . setSlotIds ( 1 , api . IVector . createVectorFromNumpy ( labels ) )
return inputs
def prepare_discriminator_data_batch_neg ( generator_machine , batch_size , noise ) :
fake_samples = get_fake_samples ( generator_machine , batch_size , noise )
labels = numpy . zeros ( batch_size , dtype = ' int32 ' )
@ -169,6 +182,7 @@ def prepare_discriminator_data_batch_neg(generator_machine, batch_size, noise):
inputs . setSlotIds ( 1 , api . IVector . createVectorFromNumpy ( labels ) )
return inputs
def prepare_generator_data_batch ( batch_size , noise ) :
label = numpy . ones ( batch_size , dtype = ' int32 ' )
inputs = api . Arguments . createArguments ( 2 )
@ -193,10 +207,9 @@ def get_layer_size(model_conf, layer_name):
def main ( ) :
parser = argparse . ArgumentParser ( )
parser . add_argument ( " -d " , " --data_source " , help = " mnist or cifar or uniform " )
parser . add_argument ( " --use_gpu " , default = " 1 " ,
help = " 1 means use gpu for training " )
parser . add_argument ( " --gpu_id " , default = " 0 " ,
help = " the gpu_id parameter " )
parser . add_argument (
" --use_gpu " , default = " 1 " , help = " 1 means use gpu for training " )
parser . add_argument ( " --gpu_id " , default = " 0 " , help = " the gpu_id parameter " )
args = parser . parse_args ( )
data_source = args . data_source
use_gpu = args . use_gpu
@ -209,8 +222,9 @@ def main():
if not os . path . exists ( " ./ %s _params/ " % data_source ) :
os . makedirs ( " ./ %s _params/ " % data_source )
api . initPaddle ( ' --use_gpu= ' + use_gpu , ' --dot_period=10 ' , ' --log_period=100 ' ,
' --gpu_id= ' + args . gpu_id , ' --save_dir= ' + " ./ %s _params/ " % data_source )
api . initPaddle ( ' --use_gpu= ' + use_gpu , ' --dot_period=10 ' ,
' --log_period=100 ' , ' --gpu_id= ' + args . gpu_id ,
' --save_dir= ' + " ./ %s _params/ " % data_source )
if data_source == " uniform " :
conf = " gan_conf.py "
@ -220,7 +234,8 @@ def main():
num_iter = 1000
gen_conf = parse_config ( conf , " mode=generator_training,data= " + data_source )
dis_conf = parse_config ( conf , " mode=discriminator_training,data= " + data_source )
dis_conf = parse_config ( conf ,
" mode=discriminator_training,data= " + data_source )
generator_conf = parse_config ( conf , " mode=generator,data= " + data_source )
batch_size = dis_conf . opt_config . batch_size
noise_dim = get_layer_size ( gen_conf . model_config , " noise " )
@ -245,11 +260,9 @@ def main():
generator_machine = api . GradientMachine . createFromConfigProto (
generator_conf . model_config )
dis_trainer = api . Trainer . create (
dis_conf , dis_training_machine )
dis_trainer = api . Trainer . create ( dis_conf , dis_training_machine )
gen_trainer = api . Trainer . create (
gen_conf , gen_training_machine )
gen_trainer = api . Trainer . create ( gen_conf , gen_training_machine )
dis_trainer . startTrain ( )
gen_trainer . startTrain ( )
@ -272,21 +285,23 @@ def main():
noise = get_noise ( batch_size , noise_dim )
data_batch_dis_pos = prepare_discriminator_data_batch_pos (
batch_size , data_np )
dis_loss_pos = get_training_loss ( dis_training_machine , data_batch_dis_pos )
dis_loss_pos = get_training_loss ( dis_training_machine ,
data_batch_dis_pos )
data_batch_dis_neg = prepare_discriminator_data_batch_neg (
generator_machine , batch_size , noise )
dis_loss_neg = get_training_loss ( dis_training_machine , data_batch_dis_neg )
dis_loss_neg = get_training_loss ( dis_training_machine ,
data_batch_dis_neg )
dis_loss = ( dis_loss_pos + dis_loss_neg ) / 2.0
# Do forward pass in generator to get the gen_loss
data_batch_gen = prepare_generator_data_batch (
batch_size , noise )
data_batch_gen = prepare_generator_data_batch ( batch_size , noise )
gen_loss = get_training_loss ( gen_training_machine , data_batch_gen )
if i % 100 == 0 :
print " d_pos_loss is %s d_neg_loss is %s " % ( dis_loss_pos , dis_loss_neg )
print " d_pos_loss is %s d_neg_loss is %s " % ( dis_loss_pos ,
dis_loss_neg )
print " d_loss is %s g_loss is %s " % ( dis_loss , gen_loss )
# Decide which network to train based on the training history
@ -300,7 +315,8 @@ def main():
curr_strike = 1
dis_trainer . trainOneDataBatch ( batch_size , data_batch_dis_neg )
dis_trainer . trainOneDataBatch ( batch_size , data_batch_dis_pos )
copy_shared_parameters ( dis_training_machine , gen_training_machine )
copy_shared_parameters ( dis_training_machine ,
gen_training_machine )
else :
if curr_train == " gen " :
@ -311,7 +327,8 @@ def main():
gen_trainer . trainOneDataBatch ( batch_size , data_batch_gen )
# TODO: add API for paddle to allow true parameter sharing between different GradientMachines
# so that we do not need to copy shared parameters.
copy_shared_parameters ( gen_training_machine , dis_training_machine )
copy_shared_parameters ( gen_training_machine ,
dis_training_machine )
copy_shared_parameters ( gen_training_machine , generator_machine )
dis_trainer . finishTrainPass ( )
@ -319,11 +336,14 @@ def main():
# At the end of each pass, save the generated samples/images
fake_samples = get_fake_samples ( generator_machine , batch_size , noise )
if data_source == " uniform " :
plot2DScatter ( fake_samples , " ./ %s _samples/train_pass %s .png " % ( data_source , train_pass ) )
plot2DScatter ( fake_samples , " ./ %s _samples/train_pass %s .png " %
( data_source , train_pass ) )
else :
save_images ( fake_samples , " ./ %s _samples/train_pass %s .png " % ( data_source , train_pass ) )
save_images ( fake_samples , " ./ %s _samples/train_pass %s .png " %
( data_source , train_pass ) )
dis_trainer . finishTrain ( )
gen_trainer . finishTrain ( )
if __name__ == ' __main__ ' :
main ( )