示例#1
0
    def configurable_param(self, string):
        self.param_ops = {
            "decay": self.configurable_params_decay,
            "on": self.configurable_params_turn_on
        }
        if isinstance(string, str):
            if re.match("^\d+$", string):
                return int(string)
            if re.match("^\d+?\.\d+?$", string):
                return float(string)
            if "(" not in string:
                return string

            method_name, inner = string.split("(")
            inner = inner.replace(")", "")
            if method_name not in self.param_ops:
                raise ValidationException(
                    "configurable param cannot find method: " + method_name +
                    " in string " + string)
            args, options = self.parse_args(inner.split(" "))
            result = self.param_ops[method_name](args, options)
            if "metric" in options:
                self.add_metric(options["metric"], result)
            return result
        return string
示例#2
0
    def forward(self, input, context):
        output = None
        for layer, layer_name in zip(self.layers, self.layer_names):
            if layer_name == "self":
                layer_output = input
            elif isinstance(layer, hg.Layer):
                layer_output = layer(input, context)
            elif layer_name.split(" ")[0] == 'layer':
                layer_output = context[layer_name.split(" ")[1]]
            elif layer_name in context:
                layer_output = context[layer_name]
            else:
                layer_output = layer(input)
            if output is None:
                output = layer_output
            else:
                if self.operation == "+":
                    output = output + layer_output
                elif self.operation == "*":
                    output = output * layer_output
                elif self.operation == "cat":
                    output = torch.cat([output, layer_output], 1)
                else:
                    raise ValidationException("Unknown operation: "+ self.operation)
        if self.options.mean:
            output /= len(self.layers)

        return output
示例#3
0
 def height(self):
     if self._height:
         return self._height
     if self.inputs == None:
         raise ValidationException(
             "gan.height() requested but no inputs provided")
     return self.ops.shape(self.inputs.x)[1]
示例#4
0
 def batch_size(self):
     if self._batch_size:
         return self._batch_size
     if self.inputs == None:
         raise ValidationException(
             "gan.batch_size() requested but no inputs provided")
     return self.ops.shape(self.inputs.x)[0]
示例#5
0
 def channels(self):
     if self._channels:
         return self._channels
     if self.inputs == None:
         raise ValidationException(
             "gan.channels() requested but no inputs provided")
     return self.ops.shape(self.inputs.x)[-1]
示例#6
0
 def width(self):
     if self._width:
         return self._width
     if self.inputs == None:
         raise ValidationException(
             "gan.width() requested but no inputs provided")
     return self.ops.shape(self.inputs.x)[2]
示例#7
0
 def create_component(self, defn, *args, **kw_args):
     if defn == None:
         return None
     if defn['class'] == None:
         raise ValidationException("Component definition is missing '" + name + "'")
     gan_component = defn['class'](self, defn, *args, **kw_args)
     self.components.append(gan_component)
     return gan_component
示例#8
0
文件: cli.py 项目: halflife2/HyperGAN
    def new(self):
        template = self.args.directory + '.json'
        print("[hypergan] Creating new configuration file '"+template+"' based off of '"+self.config_name+".json'")
        if os.path.isfile(template):
            raise ValidationException("File exists: " + template)
        source_configuration = Configuration.find(self.config_name+".json")
        shutil.copyfile(source_configuration, template)

        return
 def source(self, name):
     name = name.replace("+", "").replace("-", "")
     if name == "mg":
         return self.gan.generator.sample
     if name == "mx":
         return self.gan.inputs.x
     if name[0:4] == "g(mz":
         return self.gan.latent.sample
     raise ValidationException("Unknown rolling type: " + name)
示例#10
0
    def create(self,
               directory,
               channels=3,
               format='jpg',
               width=64,
               height=64,
               crop=False,
               resize=False):
        directories = glob.glob(directory + "/*")
        directories = [d for d in directories if os.path.isdir(d)]

        if (len(directories) == 0):
            directories = [directory]

        # Create a queue that produces the filenames to read.
        if (len(directories) == 1):
            # No subdirectories, use all the images in the passed in path
            filenames = glob.glob(directory + "/*." + format)
        else:
            filenames = glob.glob(directory + "/**/*." + format)

        if (len(filenames) < self.frame_count):
            print("Error: Not enough frames in data folder ", directory)

        self.file_count = len(filenames)
        filenames = sorted(filenames, key=alphanum_key)
        if self.file_count == 0:
            raise ValidationException("No images found in '" + directory + "'")

        # creates arrays of filenames[:end], filenames[1:end-1], etc for serialized random batching
        if self.shuffle:
            frames = [
                tf.train.slice_input_producer([filenames], shuffle=True)[0]
                for i in range(self.frame_count)
            ]
        else:
            input_t = [
                filenames[i:i - self.frame_count]
                for i in range(self.frame_count)
            ]
            input_queue = tf.train.slice_input_producer(input_t, shuffle=True)
            frames = input_queue

        # Read examples from files in the filename queue.
        frames = [
            self.read_frame(frame, format, crop, resize) for frame in frames
        ]
        frames = self._get_data(frames)
        self.frames = frames

        x = tf.train.slice_input_producer([filenames], shuffle=True)[0]
        y = tf.train.slice_input_producer([filenames], shuffle=True)[0]
        self.x = self.read_frame(x, format, crop, resize)
        self.y = self.read_frame(y, format, crop, resize)
        self.x = self._get_data([self.x])
        self.y = self._get_data([self.y])
示例#11
0
文件: cli.py 项目: limberc/HyperGAN
    def new(self):
        if self.args.toml:
            config_format = '.toml'
        else:
            config_format = '.json'
        template = self.args.directory + config_format
        print("[hypergan] Creating new configuration file '"+template+"' based off of '"+self.config_name+config_format)
        if os.path.isfile(template):
            raise ValidationException("File exists: " + template)
        source_configuration = Configuration.find(self.config_name+config_format, config_format=config_format, prepackaged=True)
        shutil.copyfile(source_configuration, template)

        return
示例#12
0
    def forward_term(self, term):
        matching = {
                "gN(eN(xN))": self.geN,
                "gN(zN)": self.gzN,
                "xN": self.xN
                }
        for regex, method in matching.items():
            regex_subbed = regex.replace("(", '\(').replace(")", '\)').replace("N", "(\d+)?").replace(",options", "([-,=\w\d\.\(\)]+)?")
            regex = re.compile(regex_subbed)
            args = re.match(regex, term)
            if args:
                return method(*args.groups())

        raise ValidationException("Could not match term: " + term)
示例#13
0
    def forward(self, input, context={}):
        if self.get_device().index != input.device.index:
            input = input.to(self.get_device())
        for module, parsed, layer_shape in zip(self.net, self.parsed_layers,
                                               self.layer_shapes):
            try:
                options = parsed.parsed_options
                args = parsed.args
                layer_name = parsed.layer_name
                name = options.name
                if isinstance(module, hg.Layer):
                    input = module(input, context)
                elif layer_name == "adaptive_instance_norm":
                    input = module(input, context['w'])
                elif layer_name == "ez_norm":
                    input = module(input, context['w'])
                elif layer_name == "split":
                    input = torch.split(input, args[0], options.dim
                                        or -1)[args[1]]
                elif layer_name == "latent":
                    input = self.gan.latent.z  #sample()
                elif layer_name == "modulated_conv2d":
                    input = module(input, context['w'])
                elif layer_name == "pretrained":
                    in_zero_one = (input + self.const_one) / self.const_two
                    mean = torch.as_tensor([0.485, 0.456, 0.406],
                                           device='cuda:0').view(1, 3, 1, 1)
                    std = torch.as_tensor([0.229, 0.224, 0.225],
                                          device='cuda:0').view(1, 3, 1, 1)

                    input = module(input.clone().sub_(mean).div_(std))
                else:
                    input = module(input)
                if self.gan.steps == 0:
                    size = LayerShape(*list(input.shape[1:]))
                    if size.squeeze_dims() != layer_shape.squeeze_dims():
                        print("Error: Size error on", layer_name)
                        print("Error: Expected output size", layer_shape.dims)
                        print("Error: Actual output size", size.dims)
                        raise "Layer size error, cannot continue"
                    else:
                        pass
                if name is not None:
                    context[name] = input
            except:
                raise ValidationException(
                    "Error on " + parsed.layer_defn + " - input size " +
                    ",".join([str(x) for x in input.shape]))
        self.sample = input
        return input
示例#14
0
 def layer_pretrained(self, net, args, options):
     model = getattr(torchvision.models, args[0])(pretrained=True)
     model.train(True)
     if options.layer:
         layers = list(model.children())[:options.layer]
         if options.sublayer:
             layers[-1] = nn.Sequential(*layers[-1][:options.sublayer])
     else:
         layers = [model]
         print("List of pretrained layers:", layers)
         raise ValidationException(
             "layer=-1 required for pretrained, sublayer=-1 optional.  Layers outputted above."
         )
     return nn.Sequential(*layers)
示例#15
0
文件: cli.py 项目: limberc/HyperGAN
    def run(self):
        if self.method == 'train':
            self.train()
        elif self.method == 'build':
            self.gan = hg.GAN(config=self.gan_config, inputs=self.create_input(blank=True))
            if not self.gan.load(self.save_file):
                raise ValidationException("Could not load model: "+ self.save_file)
            self.build()
        elif self.method == 'new':
            self.new()
        elif self.method == 'sample':
            self.gan = hg.GAN(config=self.gan_config, inputs=self.create_input(blank=False))
            if not self.gan.load(self.save_file):
                print("Initializing new model")

            self.sample_forever()
示例#16
0
    def create(self):
        config = self.config

        with tf.device(self.device):
            self.session = self.ops.new_session(self.ops_config)
            self.latent = self.create_component(config.z_distribution
                                                or config.latent)
            self.uniform_distribution = self.latent

            z_shape = self.ops.shape(self.latent.sample)
            self.android_input = tf.reshape(self.latent.sample, [-1])

            direction, slider = self.create_controls(
                self.ops.shape(self.android_input))
            self.slider = slider
            self.direction = direction
            z = self.android_input + slider * direction
            z = tf.maximum(-1., z)
            z = tf.minimum(1., z)
            z = tf.reshape(z, z_shape)
            self.control_z = z

            self.generator = self.create_component(config.generator,
                                                   name="generator",
                                                   input=z)
            self.autoencoded_x = self.generator.sample

            x, g = self.inputs.x, self.generator.sample
            if self.ops.shape(x) == self.ops.shape(g):
                self.discriminator = self.create_component(
                    config.discriminator,
                    name="discriminator",
                    input=tf.concat([x, g], axis=0))
            else:
                print("X size", self.ops.shape(x))
                print("G size", self.ops.shape(g))
                raise ValidationException("X and G sizes differ")
            self.loss = self.create_component(config.loss,
                                              discriminator=self.discriminator)
            self.trainer = self.create_component(config.trainer)

            self.android_output = tf.reshape(self.generator.sample, [-1])

            self.session.run(tf.global_variables_initializer())
    def sw(self, var, name):
        def calculate(dscore):
            swx = dscore
            swx = tf.reshape(swx, [-1])
            _, swx = tf.nn.top_k(swx,
                                 k=(self.config.top_k or 1),
                                 sorted=True,
                                 name=None)
            swx = tf.one_hot(swx, self.gan.batch_size(), dtype=tf.float32)
            swx = tf.reduce_sum(swx, reduction_indices=0)
            swx = tf.reshape(swx, [self.gan.batch_size(), 1, 1, 1])
            return swx

        def create_disc(var):
            return self.gan.create_component(self.gan.config.discriminator,
                                             name="discriminator",
                                             input=tf.concat([var, var],
                                                             axis=0),
                                             features=[self.gan.features],
                                             reuse=True)

        d = create_disc(var)
        l = self.gan.create_component(self.gan.config.loss, discriminator=d)

        if name == "mg-":
            return calculate(-l.d_fake)
        if name == "mg+":
            return calculate(l.d_fake)
        if name == "mx-":
            return calculate(-l.d_real)
        if name == "mx+":
            return calculate(l.d_real)

        if name == "g(mz-)":
            return calculate(-l.d_fake)
        if name == "g(mz+)":
            return calculate(l.d_fake)

        raise ValidationException("Unknown rolling type: " + name)
示例#18
0
    def build_layers(self, component, args, options):
        options = hc.Config(options)
        layers = []
        layer_names = []
        layer_shapes = []

        for arg in args:
            component.current_size = self.size
            if arg == 'self':
                layers.append(None)
                layer_names.append("self")
                layer_shapes.append(self.size)
            elif arg == 'noise':
                layers.append(LearnedNoise())
                layer_names.append(None)
                layer_shapes.append(self.size)
            elif arg in component.named_layers:
                layers.append(None)
                layer_names.append("layer "+arg)
                layer_shapes.append(component.layer_output_sizes[arg])
            elif arg in component.gan.named_layers:
                layers.append(component.gan.named_layers[arg])
                layer_names.append(None)
                layer_shapes.append(component.layer_output_sizes[arg])
            elif arg in component.context_shapes:
                layers.append(None)
                layer_names.append(arg)
                layer_shapes.append(component.context_shapes[arg])
            elif type(arg) == pyparsing.ParseResults and type(arg[0]) == hg.parser.Pattern:
                parsed = arg[0]
                parsed.parsed_options = hc.Config(parsed.options)
                layer = component.build_layer(parsed.layer_name, parsed.args, parsed.parsed_options)
                layers.append(layer)
                layer_names.append(parsed.layer_name)
                layer_shapes.append(component.current_size)
            else:
                raise ValidationException("Could not parse operation layer '" + arg + "'")
        return layers, layer_names, layer_shapes
示例#19
0
 def lazy_create(self):
     if (self.sampler == None):
         self.sampler = CLI.sampler_for(self.sampler_name)(self.gan)
         if (self.sampler == None):
             raise ValidationException("No sampler found by the name '" +
                                       self.sampler_name + "'")
示例#20
0
    def create(self,
               directory,
               channels=3,
               format='jpg',
               width=64,
               height=64,
               crop=False,
               resize=False,
               sequential=False):
        directories = glob.glob(directory + "/*")
        directories = [d for d in directories if os.path.isdir(d)]

        if (len(directories) == 0):
            directories = [directory]

        # Create a queue that produces the filenames to read.
        if (len(directories) == 1):
            # No subdirectories, use all the images in the passed in path
            filenames = glob.glob(directory + "/*." + format)
        else:
            filenames = glob.glob(directory + "/**/*." + format)

        filenames = natsorted(filenames)

        print("[loader] ImageLoader found", len(filenames))
        self.file_count = len(filenames)
        if self.file_count == 0:
            raise ValidationException("No images found in '" + directory + "'")
        filenames = tf.convert_to_tensor(filenames, dtype=tf.string)

        def parse_function(filename):
            image_string = tf.read_file(filename)
            if format == 'jpg':
                image = tf.image.decode_jpeg(image_string, channels=channels)
            elif format == 'png':
                image = tf.image.decode_png(image_string, channels=channels)
            else:
                print("[loader] Failed to load format", format)
            image = tf.cast(image, tf.float32)
            # Image processing for evaluation.
            # Crop the central [height, width] of the image.
            if crop:
                image = hypergan.inputs.resize_image_patch.resize_image_with_crop_or_pad(
                    image, height, width, dynamic_shape=True)
            elif resize:
                image = tf.image.resize_images(image, [height, width], 1)

            image = image / 127.5 - 1.
            tf.Tensor.set_shape(image, [height, width, channels])

            return image

        # Generate a batch of images and labels by building up a queue of examples.
        dataset = tf.data.Dataset.from_tensor_slices(filenames)
        if not sequential:
            print("Shuffling data")
            dataset = dataset.shuffle(self.file_count)
        dataset = dataset.map(parse_function, num_parallel_calls=4)
        dataset = dataset.batch(self.batch_size, drop_remainder=True)
        dataset = dataset.repeat()
        dataset = dataset.prefetch(1)

        self.dataset = dataset

        self.iterator = self.dataset.make_one_shot_iterator()
        self.x = tf.reshape(self.iterator.get_next(),
                            [self.batch_size, height, width, channels])
示例#21
0
    def apply_gradients(self, grads_and_vars, global_step=None, name=None):
        d_vars = []
        g_vars = []
        d_grads = []
        g_grads = []
        for grad, var in grads_and_vars:
            if var in self.gan.d_vars():
                d_vars += [var]
                d_grads += [grad]
            elif var in self.gan.g_vars():
                g_vars += [var]
                g_grads += [grad]
            else:
                raise ValidationException(
                    "Couldn't find var in g_vars or d_vars " + var.name)
        all_grads = d_grads + g_grads
        var_list = d_vars + g_vars

        with ops.init_scope():
            initial_f1 = [
                tf.constant(self.config.initial_constraint or 0.0,
                            shape=self.gan.ops.shape(v)) for v in var_list
            ]
            f1 = [
                self._get_or_make_slot(v, f, "f", self._name)
                for f, v in zip(initial_f1, var_list)
            ]
            v1 = [
                self._get_or_make_slot(v, v, "v1", self._name)
                for v in var_list
            ]
            if self.config.include_slots:
                for name in self.optimizer.get_slot_names():
                    for var in self.optimizer.variables():
                        self._zeros_slot(var, "pm", "pm")
        self._prepare()

        f1 = [self.get_slot(v, "f") for v in var_list]
        v1 = [self.get_slot(v, "v1") for v in var_list]
        slots_list = []
        slots_vars = []
        if self.config.include_slots:
            for name in self.optimizer.get_slot_names():
                for var in self.optimizer.variables():
                    slots_vars += [var]
                    slots_list.append(self._zeros_slot(var, "pm", "pm"))

        current_vars = var_list + slots_vars
        tmp_vars = v1 + slots_list

        diff = [tf.square(v - t) for v, t in zip(current_vars, tmp_vars)]

        f_accum = []
        f_decay = self.gan.configurable_param(self.config.f_decay or 0.95)
        gradient_scale = self.gan.configurable_param(self.config.gradient_scale
                                                     or 1.0)
        for v, f, g in zip(var_list, f1, all_grads):
            opts = self.gan.layer_options(v)
            if opts is not None and "ewc_f_decay" in opts:
                f_decay = self.gan.configurable_param(opts["ewc_f_decay"])
                print("Setting f_decay to ", f_decay, " for ", v)

            if opts is not None and "ewc_gradient_scale" in opts:
                gradient_scale = self.gan.configurable_param(
                    opts["ewc_gradient_scale"])
                print("Setting gradient_scale to ", gradient_scale, " for ", v)
            f_accum += [f_decay * f + gradient_scale * tf.square(g)]
        #f_accum = [tf.where(tf.is_nan(_f), tf.zeros_like(_f), _f) for _f in f_accum]
        #f_accum = [tf.where(tf.is_inf(_f), tf.zeros_like(_f), _f) for _f in f_accum]
        self.gan.add_metric('f1',
                            tf.reduce_sum([tf.reduce_sum(f) for f in f_accum]))

        reg = [tf.multiply(f, d) for f, d in zip(f1, diff)]
        #reg = [tf.where(tf.is_nan(_f), tf.zeros_like(_f), _f) for _f in reg]
        ewc_loss = self.gan.configurable_param(
            self.config.lam or 17.5) / 2.0 * tf.reduce_sum(
                tf.add_n([tf.reduce_sum(r) for r in reg]))
        self.gan.add_metric('ewc', ewc_loss)

        save_weights = tf.group(*[
            tf.assign(w, v) for w, v in zip(tmp_vars, current_vars)
        ])  # store variables

        if isinstance(self.loss, list):
            if self.config.add_ewc_loss_gradients:
                newloss = [ewc_loss, ewc_loss]
            else:
                newloss = [self.loss[0] + ewc_loss, self.loss[1] + ewc_loss]

            new_grads = tf.gradients(newloss[0], d_vars) + tf.gradients(
                newloss[1], g_vars)
            self.optimizer.loss = [
                ewc_loss + self.loss[0], ewc_loss + self.loss[1]
            ]
        else:
            if self.config.add_ewc_loss_gradients:
                newloss = ewc_loss
            else:
                newloss = self.loss + ewc_loss

            new_grads = tf.gradients(newloss, current_vars)
            self.optimizer.loss = ewc_loss + self.loss

        if self.config.add_ewc_loss_gradients:
            new_grads = [_g + _ng for _g, _ng in zip(all_grads, new_grads)]

        for g, oldg, v in zip(new_grads, all_grads, current_vars):
            if (self.gan.ops.shape(g) != self.gan.ops.shape(oldg)):
                print("[ERROR] Shape change on gradients for", v, g, "old g",
                      oldg)
                raise "Gradient change error"
        step = self.optimizer.apply_gradients(list(zip(new_grads,
                                                       current_vars)).copy(),
                                              global_step=global_step,
                                              name=name)

        store_f = tf.group(*[tf.assign(w, v) for w, v in zip(f1, f_accum)])
        with tf.get_default_graph().control_dependencies([store_f]):
            with tf.get_default_graph().control_dependencies([step]):
                with tf.get_default_graph().control_dependencies(
                    [save_weights]):
                    return tf.no_op()
示例#22
0
 def _step(self, feed_dict={}):
     if self.trainer == None:
         raise ValidationException("gan.trainer is missing.  Cannot train.")
     return self.trainer.step(feed_dict)
示例#23
0
文件: cli.py 项目: limberc/HyperGAN
 def lazy_create(self):
     if(self.sampler == None):
         self.sampler = self.gan.sampler_for(self.sampler_name)(self.gan, samples_per_row=self.args.width)
         if(self.sampler == None):
             raise ValidationException("No sampler found by the name '"+self.sampler_name+"'")
示例#24
0
文件: cli.py 项目: halflife2/HyperGAN
 def validate(self):
     if(self.sampler == None):
         raise ValidationException("No sampler found by the name '"+self.sampler_name+"'")
示例#25
0
 def create(self):
     raise ValidationException(
         "BaseGAN.create() called directly.  Please override")
示例#26
0
 def create(self):
     if self.created:
         raise ValidationException(
             "gan.create already called. Cowardly refusing to create graph twice"
         )
     self.created = True
示例#27
0
    def create(self, directory, channels=3, format='jpg', width=64, height=64, crop=False, resize=False):
        directories = glob.glob(directory+"/*")
        directories = [d for d in directories if os.path.isdir(d)]

        if(len(directories) == 0):
            directories = [directory] 
        labels,total_labels = self.build_labels(sorted(filter(os.path.isdir, directories)))

        # Create a queue that produces the filenames to read.
        if(len(directories) == 1):
            # No subdirectories, use all the images in the passed in path
            filenames = glob.glob(directory+"/*."+format)
            classes = [0 for f in filenames]
        else:
            filenames = glob.glob(directory+"/**/*."+format)
            classes = [labels[f.split('/')[-2]] for f in filenames]

        print("[loader] ImageLoader found", len(filenames), "images with", total_labels, "different class labels")
        self.file_count = len(filenames)
        if self.file_count == 0:
            raise ValidationException("No images found in '" + directory + "'")
        filenames = tf.convert_to_tensor(filenames, dtype=tf.string)
        classes = tf.convert_to_tensor(classes, dtype=tf.int32)

        input_queue = tf.train.slice_input_producer([filenames, classes])

        # Read examples from files in the filename queue.
        value = tf.read_file(input_queue[0])

        if format == 'jpg':
            img = tf.image.decode_jpeg(value, channels=channels)
        elif format == 'png':
            img = tf.image.decode_png(value, channels=channels)
        else:
            print("[loader] Failed to load format", format)
        img = tf.cast(img, tf.float32)

        label = input_queue[1]

      # Image processing for evaluation.
      # Crop the central [height, width] of the image.
        if crop:
            resized_image = hypergan.inputs.resize_image_patch.resize_image_with_crop_or_pad(img, height, width, dynamic_shape=True)
        elif resize:
            resized_image = tf.image.resize_images(img, [height, width], 1)
        else: 
            resized_image = img

        tf.Tensor.set_shape(resized_image, [height,width,channels])

        # This moves the image to a range of -1 to 1.
        float_image = resized_image / 127.5 - 1.

        # Ensure that the random shuffling has good mixing properties.
        min_fraction_of_examples_in_queue = 0.4

        # Generate a batch of images and labels by building up a queue of examples.
        x,y = self._get_data(float_image, label)

        y = tf.cast(y, tf.int64)
        y = tf.one_hot(y, total_labels, 1.0, 0.0)
        self.x = x
        self.y = y
        return x, y