Пример #1
0
def build_network(state_dim):
    state_input = Input((state_dim,))
    h1 = Dense(64, activation='relu')(state_input)
    h2 = Dense(32, activation='relu')(h1)
    h3 = Dense(16, activation='relu')(h2)
    v_output = Dense(1, activation='linear')(h3)
    model = Model(state_input, v_output)
    #model.summary()
    model._make_predict_function()  # class 안에서 def가 정의되면 필요없음
    return model
def build_network(state_dim, action_dim, action_bound):
    state_input = Input((state_dim, ))
    h1 = Dense(64, activation='relu')(state_input)
    h2 = Dense(32, activation='relu')(h1)
    h3 = Dense(16, activation='relu')(h2)
    out_mu = Dense(action_dim, activation='tanh')(h3)
    std_output = Dense(action_dim, activation='softplus')(h3)

    # Scale output to [-action_bound, action_bound]
    mu_output = Lambda(lambda x: x * action_bound)(out_mu)
    model = Model(state_input, [mu_output, std_output])
    # model.summary()
    model._make_predict_function()  # class 안에서 def가 정의되면 필요없음
    return model
Пример #3
0
import pickle
import numpy as np
import datetime
import warnings
warnings.filterwarnings("ignore")



model = load_model('./model_weights/model_9.h5')
model._make_predict_function()

model_temp = ResNet50(weights="imagenet", input_shape=(224,224,3))

# Create a new model, by removing the last layer (output layer of 1000 classes) from the resnet50
model_resnet = Model(model_temp.input, model_temp.layers[-2].output)
model_resnet._make_predict_function()


    
# Load the word_to_idx and idx_to_word from disk

with open("./storage/word_to_idx.pkl", "rb") as w2i:
    word_to_idx = pickle.load(w2i)

with open("./storage/idx_to_word.pkl", "rb") as i2w:
    idx_to_word = pickle.load(i2w)
    

max_len = 35

Пример #4
0
# Add skip connection
fcn20_skip_connected = Add(name="fcn20_plus_vgg_layer4")([fcn20, layer4])
# Upsample again
fcn21 = Conv2DTranspose(filters=2,
                        kernel_size=16,
                        strides=(8, 8),
                        padding='same',
                        name="fcn21",
                        activation="softmax")(fcn20_skip_connected)
model1 = Model(inputs=mbl.input, outputs=fcn21)
model1.compile(loss="categorical_crossentropy",
               optimizer='adam',
               metrics=['accuracy'])
model1.load_weights(path + 'model-mobilenetv2-round1' + '.h5')
model1._make_predict_function()
print("Finish")
s2s = SegmentToSteer(roi=0.45, margin=10)
pre_turn_left = False
pre_turn_right = False
obstacle_time = 0.0
rects = []


def callback(data):
    global end, i_left, i_right, rects, ratio, skip
    if skip > 0:
        skip -= 1
        return
    try:
        # global image, color_image
Пример #5
0
class HTRModel:
    def __init__(self,
                 inputs,
                 outputs,
                 greedy=False,
                 beam_width=100,
                 top_paths=1):
        """
        Initialization of a HTR Model.
        :param inputs: Input layer of the neural network
            outputs: Last layer of the neural network before CTC (e.g. a TimeDistributed Dense)
            greedy, beam_width, top_paths: Parameters of the CTC decoding (see ctc decoding tensorflow for more details)
        """
        self.model_train = None
        self.model_pred = None

        if not isinstance(inputs, list):
            self.inputs = [inputs]
        else:
            self.inputs = inputs
        if not isinstance(outputs, list):
            self.outputs = [outputs]
        else:
            self.outputs = outputs

        self.greedy = greedy
        self.beam_width = beam_width
        self.top_paths = top_paths

    def summary(self, output=None, target=None):
        """Show/Save model structure (summary)"""

        if target is not None:
            os.makedirs(output, exist_ok=True)

            with open(os.path.join(output, target), "w") as f:
                with redirect_stdout(f):
                    self.model_train.summary()
        self.model_train.summary()

    def load_checkpoint(self, target):
        """ Load a model with checkpoint file"""

        if os.path.isfile(target):
            if self.model_train is None:
                self.compile()

            self.model_train.load_weights(target, by_name=True)
            self.model_pred.load_weights(target, by_name=True)

    def get_callbacks(self, logdir, hdf5, monitor="val_loss", verbose=0):
        """Setup the list of callbacks for the model"""

        callbacks = [
            CSVLogger(filename=os.path.join(logdir, "epochs.log"),
                      separator=";",
                      append=True),
            TensorBoard(log_dir=logdir,
                        histogram_freq=10,
                        profile_batch=0,
                        write_graph=True,
                        write_images=False,
                        update_freq="epoch"),
            ModelCheckpoint(filepath=os.path.join(logdir, hdf5),
                            monitor=monitor,
                            save_best_only=True,
                            save_weights_only=True,
                            verbose=verbose),
            EarlyStopping(monitor=monitor,
                          min_delta=0,
                          patience=20,
                          restore_best_weights=True,
                          verbose=verbose),
            ReduceLROnPlateau(monitor=monitor,
                              min_delta=0,
                              factor=0.2,
                              patience=10,
                              verbose=verbose)
        ]

        return callbacks

    def compile(self, optimizer):
        """
        Configures the HTR Model for training.

        There is 2 Tensorflow Keras models:
            - one for training
            - one for predicting/evaluate

        Lambda layers are used to compute:
            - the CTC loss function
            - the CTC decoding

        :param optimizer: The optimizer used during training
        """

        # Others inputs for the CTC approach
        labels = Input(name="labels", shape=[None])
        input_length = Input(name="input_length", shape=[1])
        label_length = Input(name="label_length", shape=[1])

        # Lambda layer for computing the loss function
        loss_out = Lambda(self.ctc_loss_lambda_func,
                          output_shape=(1, ),
                          name="CTCloss")(self.outputs +
                                          [labels, input_length, label_length])

        # Lambda layer for the decoding function
        out_decoded_dense = Lambda(self.ctc_complete_decoding_lambda_func,
                                   output_shape=(None, None),
                                   name="CTCdecode",
                                   arguments={
                                       "greedy": self.greedy,
                                       "beam_width": self.beam_width,
                                       "top_paths": self.top_paths
                                   },
                                   dtype="float32")(self.outputs +
                                                    [input_length])

        # create Tensorflow Keras models
        self.model_train = Model(inputs=self.inputs +
                                 [labels, input_length, label_length],
                                 outputs=loss_out)
        self.model_pred = Model(inputs=self.inputs + [input_length],
                                outputs=out_decoded_dense)

        # Compile models
        self.model_train.compile(loss={
            "CTCloss": lambda yt, yp: yp
        },
                                 optimizer=optimizer)
        self.model_pred.compile(loss={
            "CTCdecode": lambda yt, yp: yp
        },
                                optimizer=optimizer)

    def fit_generator(self,
                      generator,
                      steps_per_epoch,
                      epochs=1,
                      verbose=1,
                      callbacks=None,
                      validation_data=None,
                      validation_steps=None,
                      class_weight=None,
                      max_queue_size=10,
                      workers=1,
                      shuffle=True,
                      initial_epoch=0):
        """
        Model training on data yielded batch-by-batch by a Python generator.

        The generator is run in parallel to the model, for efficiency.
        For instance, this allows you to do real-time data augmentation on images on CPU in parallel to training your model on GPU.

        A major modification concerns the generator that must provide x data of the form:
          [input_sequences, label_sequences, inputs_lengths, labels_length]
        (in a similar way than for using CTC in tensorflow)

        :param: See tensorflow.keras.engine.Model.fit_generator()
        :return: A History object
        """
        out = self.model_train.fit_generator(generator,
                                             steps_per_epoch,
                                             epochs=epochs,
                                             verbose=verbose,
                                             callbacks=callbacks,
                                             validation_data=validation_data,
                                             validation_steps=validation_steps,
                                             class_weight=class_weight,
                                             max_queue_size=max_queue_size,
                                             workers=workers,
                                             shuffle=shuffle,
                                             initial_epoch=initial_epoch)

        self.model_pred.set_weights(self.model_train.get_weights())
        return out

    def predict_generator(self,
                          generator,
                          steps,
                          max_queue_size=10,
                          workers=1,
                          use_multiprocessing=False,
                          verbose=0):
        """Generates predictions for the input samples from a data generator.
        The generator should return the same kind of data as accepted by `predict_on_batch`.

        generator = DataGenerator class that returns:
            x = Input data as a 3D Tensor (batch_size, max_input_len, dim_features)
            x_len = 1D array with the length of each data in batch_size

        # Arguments
            generator: Generator yielding batches of input samples
                    or an instance of Sequence (tensorflow.keras.utils.Sequence)
                    object in order to avoid duplicate data
                    when using multiprocessing.
            steps:
                Total number of steps (batches of samples)
                to yield from `generator` before stopping.
            max_queue_size:
                Maximum size for the generator queue.
            workers: Maximum number of processes to spin up
                when using process based threading
            use_multiprocessing: If `True`, use process based threading.
                Note that because this implementation relies on multiprocessing,
                you should not pass non picklable arguments to the generator
                as they can't be passed easily to children processes.
            verbose:
                verbosity mode, 0 or 1.

        # Returns
            A numpy array(s) of predictions.

        # Raises
            ValueError: In case the generator yields
                data in an invalid format.
        """

        self.model_pred._make_predict_function()
        is_sequence = isinstance(generator, Sequence)

        allab_outs = []
        steps_done = 0
        enqueuer = None

        try:
            if is_sequence:
                enqueuer = OrderedEnqueuer(
                    generator, use_multiprocessing=use_multiprocessing)
            else:
                enqueuer = GeneratorEnqueuer(
                    generator, use_multiprocessing=use_multiprocessing)

            enqueuer.start(workers=workers, max_queue_size=max_queue_size)
            output_generator = enqueuer.get()

            if verbose == 1:
                progbar = Progbar(target=steps)

            while steps_done < steps:
                x = next(output_generator)
                outs = self.predict_on_batch(x)

                if not isinstance(outs, list):
                    outs = [outs]

                for i, out in enumerate(outs):
                    allab_outs.append([int(c) for c in out])

                steps_done += 1
                if verbose == 1:
                    progbar.update(steps_done)

        finally:
            if enqueuer is not None:
                enqueuer.stop()

        return allab_outs

    def predict_on_batch(self, x):
        """Returns predictions for a single batch of samples.
            # Arguments
                x: [Input samples as a Numpy array, Input length as a numpy array]
            # Returns
                Numpy array(s) of predictions.
        """

        out = self.model_pred.predict_on_batch(x)
        output = [[pr for pr in pred if pr != -1] for pred in out]

        return output

    def get_loss_on_batch(self, inputs, verbose=0):
        """
        Computation the loss
        inputs is a list of 4 elements:
            x_features, y_label, x_len, y_len (similarly to the CTC in tensorflow)
        :return: Probabilities (output of the TimeDistributedDense layer)
        """

        x = inputs[0]
        x_len = inputs[2]
        y = inputs[1]
        y_len = inputs[3]

        no_lab = True if 0 in y_len else False

        if no_lab is False:
            loss_data = self.model_train.predict_on_batch([x, y, x_len, y_len])

        return np.sum(loss_data), loss_data

    @staticmethod
    def ctc_loss_lambda_func(args):
        """
        Function for computing the ctc loss (can be put in a Lambda layer)
        :param args:
            y_pred, labels, input_length, label_length
        :return: CTC loss
        """
        y_pred, labels, input_length, label_length = args
        return K.ctc_batch_cost(labels, y_pred, input_length, label_length)

    @staticmethod
    def ctc_complete_decoding_lambda_func(args, **arguments):
        """
        Complete CTC decoding using Tensorflow Keras (function K.ctc_decode)
        :param args:
            y_pred, input_length
        :param arguments:
            greedy, beam_width, top_paths
        :return:
            K.ctc_decode with dtype="float32"
        """

        y_pred, input_length = args
        my_params = arguments

        assert (K.backend() == "tensorflow")

        return K.cast(K.ctc_decode(y_pred,
                                   tf.squeeze(input_length),
                                   greedy=my_params["greedy"],
                                   beam_width=my_params["beam_width"],
                                   top_paths=my_params["top_paths"])[0][0],
                      dtype="float32")
class HTRModel:

    def __init__(self, inputs, outputs, charset, greedy=False, beam_width=100, top_paths=1):
        """
        Initialization of a HTR Model.
        :param inputs: Input layer of the neural network
            outputs: Last layer of the neural network before CTC (e.g. a TimeDistributed Dense)
            greedy, beam_width, top_paths: Parameters of the CTC decoding (see ctc decoding tensorflow for more details)
            charset: labels related to the input of the CTC approach
        """
        self.model_train = None
        self.model_pred = None

        if not isinstance(inputs, list):
            self.inputs = [inputs]
        else:
            self.inputs = inputs
        if not isinstance(outputs, list):
            self.outputs = [outputs]
        else:
            self.outputs = outputs

        self.charset = charset
        self.greedy = greedy
        self.beam_width = beam_width
        self.top_paths = top_paths

    def compile(self, optimizer):
        """
        Configures the HTR Model for training.

        There is 2 Tensorflow Keras models:
            - one for training
            - one for predicting/evaluate

        Lambda layers are used to compute:
            - the CTC loss function
            - the CTC decoding

        :param optimizer: The optimizer used during training
        """

        # Others inputs for the CTC approach
        labels = Input(name="labels", shape=[None])
        input_length = Input(name="input_length", shape=[1])
        label_length = Input(name="label_length", shape=[1])

        # Lambda layer for computing the loss function
        loss_out = Lambda(self.ctc_loss_lambda_func, output_shape=(1,), name="CTCloss")(
            self.outputs + [labels, input_length, label_length])

        # Lambda layer for the decoding function
        out_decoded_dense = Lambda(self.ctc_complete_decoding_lambda_func, output_shape=(None, None), name="CTCdecode",
                                   arguments={"greedy": self.greedy, "beam_width": self.beam_width, "top_paths": self.top_paths},
                                   dtype="float32")(self.outputs + [input_length])

        # create Tensorflow Keras models
        self.model_init = Model(inputs=self.inputs, outputs=self.outputs)
        self.model_train = Model(inputs=self.inputs + [labels, input_length, label_length], outputs=loss_out)
        self.model_pred = Model(inputs=self.inputs + [input_length], outputs=out_decoded_dense)

        # Compile models
        self.model_train.compile(loss={"CTCloss": lambda yt, yp: yp}, optimizer=optimizer)
        self.model_pred.compile(loss={"CTCdecode": lambda yt, yp: yp}, optimizer=optimizer)

    def fit_generator(self,
                      generator,
                      steps_per_epoch,
                      epochs=1,
                      verbose=1,
                      callbacks=None,
                      validation_data=None,
                      validation_steps=None,
                      class_weight=None,
                      max_queue_size=10,
                      workers=1,
                      shuffle=True,
                      initial_epoch=0):
        """
        Model training on data yielded batch-by-batch by a Python generator.

        The generator is run in parallel to the model, for efficiency.
        For instance, this allows you to do real-time data augmentation on images on CPU in parallel to training your model on GPU.

        A major modification concerns the generator that must provide x data of the form:
          [input_sequences, label_sequences, inputs_lengths, labels_length]
        (in a similar way than for using CTC in tensorflow)

        :param: See tensorflow.keras.engine.Model.fit_generator()
        :return: A History object
        """
        out = self.model_train.fit_generator(generator, steps_per_epoch, epochs=epochs, verbose=verbose,
                                             callbacks=callbacks, validation_data=validation_data,
                                             validation_steps=validation_steps, class_weight=class_weight,
                                             max_queue_size=max_queue_size, workers=workers, shuffle=shuffle,
                                             initial_epoch=initial_epoch)

        self.model_pred.set_weights(self.model_train.get_weights())
        return out

    def predict_generator(self,
                          generator,
                          steps,
                          max_queue_size=10,
                          workers=1,
                          use_multiprocessing=False,
                          verbose=0):
        """Generates predictions for the input samples from a data generator.
        The generator should return the same kind of data as accepted by `predict_on_batch`.

        generator = DataGenerator class that returns:
            x = Input data as a 3D Tensor (batch_size, max_input_len, dim_features)
            x_len = 1D array with the length of each data in batch_size

        # Arguments
            generator: Generator yielding batches of input samples
                    or an instance of Sequence (tensorflow.keras.utils.Sequence)
                    object in order to avoid duplicate data
                    when using multiprocessing.
            steps:
                Total number of steps (batches of samples)
                to yield from `generator` before stopping.
            max_queue_size:
                Maximum size for the generator queue.
            workers: Maximum number of processes to spin up
                when using process based threading
            use_multiprocessing: If `True`, use process based threading.
                Note that because this implementation relies on multiprocessing,
                you should not pass non picklable arguments to the generator
                as they can't be passed easily to children processes.
            verbose:
                verbosity mode, 0 or 1.

        # Returns
            A numpy array(s) of predictions.

        # Raises
            ValueError: In case the generator yields
                data in an invalid format.
        """

        self.model_pred._make_predict_function()
        is_sequence = isinstance(generator, Sequence)

        allab_outs = []
        steps_done = 0
        enqueuer = None

        try:
            if is_sequence:
                enqueuer = OrderedEnqueuer(generator, use_multiprocessing=use_multiprocessing)
            else:
                enqueuer = GeneratorEnqueuer(generator, use_multiprocessing=use_multiprocessing)

            enqueuer.start(workers=workers, max_queue_size=max_queue_size)
            output_generator = enqueuer.get()

            if verbose == 1:
                progbar = Progbar(target=steps)

            while steps_done < steps:
                x = next(output_generator)
                outs = self.predict_on_batch(x)

                if not isinstance(outs, list):
                    outs = [outs]

                for i, out in enumerate(outs):
                    encode = [valab_out for valab_out in out if valab_out != -1]
                    allab_outs.append([int(c) for c in encode])

                steps_done += 1
                if verbose == 1:
                    progbar.update(steps_done)

        finally:
            if enqueuer is not None:
                enqueuer.stop()

        return allab_outs

    def predict_on_batch(self, x):
        """Returns predictions for a single batch of samples.
            # Arguments
                x: [Input samples as a Numpy array, Input length as a numpy array]
            # Returns
                Numpy array(s) of predictions.
        """

        out = self.model_pred.predict_on_batch(x)
        output = [[pr for pr in pred if pr != -1] for pred in out]

        return output

    def get_loss_on_batch(self, inputs, verbose=0):
        """
        Computation the loss
        inputs is a list of 4 elements:
            x_features, y_label, x_len, y_len (similarly to the CTC in tensorflow)
        :return: Probabilities (output of the TimeDistributedDense layer)
        """

        x = inputs[0]
        x_len = inputs[2]
        y = inputs[1]
        y_len = inputs[3]

        no_lab = True if 0 in y_len else False

        if no_lab is False:
            loss_data = self.model_train.predict_on_batch([x, y, x_len, y_len])

        return np.sum(loss_data), loss_data

    def save_model(self, path, charset=None):
        """ Save a model in path
        save model_train, model_pred in json
        save inputs and outputs in json
        save model CTC parameters in a pickle

        :param path: directory where the model architecture will be saved
        :param charset: set of labels (useful to keep the label order)
        """

        model_json = self.model_train.to_json()
        with open(path + "/model_train.json", "w") as json_file:
            json_file.write(model_json)

        model_json = self.model_pred.to_json()
        with open(path + "/model_pred.json", "w") as json_file:
            json_file.write(model_json)

        model_json = self.model_init.to_json()
        with open(path + "/model_init.json", "w") as json_file:
            json_file.write(model_json)

        param = {"greedy": self.greedy, "beam_width": self.beam_width, "top_paths": self.top_paths, "charset": self.charset}

        output = open(path + "/model_param.pkl", "wb")
        p = pickle.Pickler(output)
        p.dump(param)
        output.close()

    def load_checkpoint(self, target):
        """ Load a model with checkpoint file"""

        if os.path.isfile(target):
            self.model_train.load_weights(target)
            self.model_pred.set_weights(self.model_train.get_weights())

    def load_model(self, path, optimizer, init_archi=True, file_weights=None, change_parameters=False,
                   init_last_layer=False, add_layers=None, trainable=False, removed_layers=2):
        """ Load a model in path
        load model_train, model_pred from json
        load inputs and outputs from json
        load model CTC parameters from a pickle

        :param path: directory where the model is saved
        :param optimizer: The optimizer used during training
        :param init_archi: load an architecture from json. Otherwise, the network archtiecture muste be initialized.
        :param file_weights: weights to load (None = default parameters are returned).
        :param init_last_layer: reinitialize the last layer using self.charset to get the number of labels.
        :param add_layers: add some layers. None for no change in the network architecture. Otherwise, add_layers contains
        a list of layers to add after the last layer of the current architecture.
        :param trainable: in case of add_layers, lower layers can be not trained again.
        :param removed_layers: remove the last layers of the current architecture. It is applied before adding new layers using add_layers.
        """

        if init_archi:
            json_file = open(path + "/model_train.json", "r")
            loaded_model_json = json_file.read()
            json_file.close()
            self.model_train = model_from_json(loaded_model_json)

            json_file = open(path + "/model_pred.json", "r")
            loaded_model_json = json_file.read()
            json_file.close()
            self.model_pred = model_from_json(loaded_model_json, custom_objects={"tf": tf})

            json_file = open(path + "/model_init.json", "r")
            loaded_model_json = json_file.read()
            json_file.close()
            self.model_init = model_from_json(loaded_model_json, custom_objects={"tf": tf})

            self.inputs = self.model_init.inputs
            self.outputs = self.model_init.outputs

            input = open(path + "/model_param.pkl", "rb")
            p = pickle.Unpickler(input)
            param = p.load()
            input.close()

            if not change_parameters:
                self.greedy = param["greedy"] if "greedy" in param.keys() else self.greedy
                self.beam_width = param["beam_width"] if "beam_width" in param.keys() else self.beam_width
                self.top_paths = param["top_paths"] if "top_paths" in param.keys() else self.top_paths
            self.charset = param["charset"] if "charset" in param.keys() and self.charset is None else self.charset

        self.compile(optimizer)

        if file_weights is not None:
            if os.path.exists(file_weights):
                self.model_train.load_weights(file_weights)
                self.model_pred.set_weights(self.model_train.get_weights())
            elif os.path.exists(path + file_weights):
                self.model_train.load_weights(path + file_weights)
                self.model_pred.set_weights(self.model_train.get_weights())

        # add layers after transfer
        if add_layers is not None:
            labels = Input(name="labels", shape=[None])
            input_length = Input(name="input_length", shape=[1])
            label_length = Input(name="label_length", shape=[1])

            new_layer = Input(name="input", shape=self.model_init.layers[0].output_shape[1:])
            self.inputs = [new_layer]
            for layer in self.model_init.layers[1:-removed_layers]:
                print(layer)
                new_layer = layer(new_layer)
                layer.trainable = trainable
            for layer in add_layers:
                new_layer = layer(new_layer)
                layer.trainable = True

            self.outputs = [new_layer]
            loss_out = Lambda(self.ctc_loss_lambda_func, output_shape=(1,), name="CTCloss")(
                self.outputs + [labels, input_length, label_length])

            # Lambda layer for the decoding function
            out_decoded_dense = Lambda(self.ctc_complete_decoding_lambda_func, output_shape=(None, None),
                                       name="CTCdecode", arguments={"greedy": self.greedy,
                                                                    "beam_width": self.beam_width,
                                                                    "top_paths": self.top_paths}, dtype="float32")(
                self.outputs + [input_length])

            # create Tensorflow Keras models
            self.model_init = Model(inputs=self.inputs, outputs=self.outputs)
            self.model_train = Model(inputs=self.inputs + [labels, input_length, label_length], outputs=loss_out)
            self.model_pred = Model(inputs=self.inputs + [input_length], outputs=out_decoded_dense)

            # Compile models
            self.model_train.compile(loss={"CTCloss": lambda yt, yp: yp}, optimizer=optimizer)
            self.model_pred.compile(loss={"CTCdecode": lambda yt, yp: yp}, optimizer=optimizer)

        elif init_last_layer:
            labels = Input(name="labels", shape=[None])
            input_length = Input(name="input_length", shape=[1])
            label_length = Input(name="label_length", shape=[1])

            new_layer = Input(name="input", shape=self.model_init.layers[0].output_shape[1:])
            self.inputs = [new_layer]
            for layer in self.model_init.layers[1:-2]:
                new_layer = layer(new_layer)
            new_layer = TimeDistributed(Dense(len(self.charset) + 1), name="DenseSoftmax")(new_layer)
            new_layer = Activation("softmax", name="Softmax")(new_layer)

            self.outputs = [new_layer]

            # Lambda layer for computing the loss function
            loss_out = Lambda(self.ctc_loss_lambda_func, output_shape=(1,), name="CTCloss")(
                self.outputs + [labels, input_length, label_length])

            # Lambda layer for the decoding function
            out_decoded_dense = Lambda(self.ctc_complete_decoding_lambda_func, output_shape=(None, None),
                                       name="CTCdecode", arguments={"greedy": self.greedy,
                                                                    "beam_width": self.beam_width,
                                                                    "top_paths": self.top_paths}, dtype="float32")(
                self.outputs + [input_length])

            # create Tensorflow Keras models
            self.model_init = Model(inputs=self.inputs, outputs=self.outputs)
            self.model_train = Model(inputs=self.inputs + [labels, input_length, label_length], outputs=loss_out)
            self.model_pred = Model(inputs=self.inputs + [input_length], outputs=out_decoded_dense)

            # Compile models
            self.model_train.compile(loss={"CTCloss": lambda yt, yp: yp}, optimizer=optimizer)
            self.model_pred.compile(loss={"CTCdecode": lambda yt, yp: yp}, optimizer=optimizer)

    def summary(self, output=None, target=None):
        """Show/Save model structure (summary)"""

        if target is not None:
            os.makedirs(output, exist_ok=True)

            with open(os.path.join(output, target), "w") as f:
                with redirect_stdout(f):
                    self.model_train.summary()
        self.model_train.summary()

    @staticmethod
    def ctc_loss_lambda_func(args):
        """
        Function for computing the ctc loss (can be put in a Lambda layer)
        :param args:
            y_pred, labels, input_length, label_length
        :return: CTC loss
        """
        y_pred, labels, input_length, label_length = args
        return K.ctc_batch_cost(labels, y_pred, input_length, label_length)

    @staticmethod
    def ctc_complete_decoding_lambda_func(args, **arguments):
        """
        Complete CTC decoding using Tensorflow Keras (function K.ctc_decode)
        :param args:
            y_pred, input_length
        :param arguments:
            greedy, beam_width, top_paths
        :return:
            K.ctc_decode with dtype="float32"
        """

        y_pred, input_length = args
        my_params = arguments

        assert (K.backend() == "tensorflow")

        return K.cast(K.ctc_decode(y_pred, tf.squeeze(input_length), greedy=my_params["greedy"],
                      beam_width=my_params["beam_width"], top_paths=my_params["top_paths"])[0][0],
                      dtype="float32")
class Fusion():
    def __init__(self):
        self.IMG_HEIGHT = 150
        self.IMG_WIDTH = 150
        self.night = False
        self.image = np.zeros((900, 1600, 3))
        self.image_lidar = np.zeros((600, 600, 3))
        self.sub = rospy.Subscriber("/cam_front/raw", Image, self.image_cb)
        self.lidar_sub = rospy.Subscriber("image_lidar", Image,
                                          self.lidar_image_cb)
        self._session = tf.Session()
        self.bridge = cv_bridge.CvBridge()

        self.input_image = keras.Input(shape=(self.IMG_HEIGHT, self.IMG_WIDTH,
                                              3))
        self.input_lidar = keras.Input(shape=(self.IMG_HEIGHT, self.IMG_WIDTH,
                                              3))

        self.x = Conv2D(16, 3, padding='same',
                        activation='relu')(self.input_image)
        self.output_image = MaxPooling2D()(self.x)

        self.model_image = keras.Model(inputs=self.input_image,
                                       outputs=self.output_image,
                                       name='image_input')
        self.model_image.summary()

        self.y = Conv2D(16, 3, padding='same',
                        activation='relu')(self.input_lidar)
        self.output_lidar = MaxPooling2D()(self.y)

        self.model_lidar = keras.Model(inputs=self.input_lidar,
                                       outputs=self.output_lidar,
                                       name='lidar_input')
        self.model_lidar.summary()

        self.combined = concatenate(
            [self.model_image.output, self.model_lidar.output])

        self.z = Conv2D(32, 3, padding='same',
                        activation='relu')(self.combined)
        self.z = MaxPooling2D()(self.z)
        self.z = Conv2D(64, 3, padding='same', activation='relu')(self.z)
        self.z = MaxPooling2D()(self.z)
        self.z = Conv2D(16, 3, padding='same', activation='relu')(self.z)
        self.z = MaxPooling2D()(self.z)
        self.z = Flatten()(self.z)
        self.z = Dense(512, activation='relu')(self.z)
        self.z = Dense(128, activation='relu')(self.z)
        self.z = Dense(1, activation="linear")(self.z)
        self.fusion = Model(
            inputs=[self.model_lidar.input, self.model_image.input],
            outputs=self.z)
        #keras.utils.plot_model(fusion, 'fusion.png', show_shapes=True)
        self.fusion.load_weights('./checkpoints/my_checkpoint')
        self.fusion.compile(
            optimizer='adam',
            loss=tf.keras.losses.BinaryCrossentropy(from_logits=True),
            metrics=['accuracy'])
        self.fusion.load_weights('./checkpoints/my_checkpoint')
        self.fusion._make_predict_function()

    def create_model(self):
        model = Sequential([
            Conv2D(16,
                   3,
                   padding='same',
                   activation='relu',
                   input_shape=(150, 150, 3)),
            MaxPooling2D(),
            Conv2D(32, 3, padding='same', activation='relu'),
            MaxPooling2D(),
            Conv2D(64, 3, padding='same', activation='relu'),
            MaxPooling2D(),
            Flatten(),
            Dense(512, activation='relu'),
            Dense(1)
        ])
        model.compile(
            optimizer='adam',
            loss=tf.keras.losses.BinaryCrossentropy(from_logits=True),
            metrics=['accuracy'])
        return model

    def image_cb(self, msg):
        self.image = self.bridge.imgmsg_to_cv2(msg)
        # if(False):
        # 	self.night=True

    def lidar_image_cb(self, msg):
        self.image_lidar = np.zeros((600, 600, 3))
        self.image_lidar = self.bridge.imgmsg_to_cv2(msg)
        self.prediction()
        # if(self.night==False):
        # 	self.prediction()
        # else:
        # 	model=self.create_model()
        # 	model.load_weights('./checkpoints/lidar_checkpoint')
        # 	image_mod_lidar=cv2.resize(self.image_lidar,(150,150))
        # 	val=model.predict(image_mod_lidar.reshape(-1,150,150,3))
        # 	if(val[0][0]>0):
        # 		print("person")
        # 	else:
        # 		print("car")

    def prediction(self):
        image_mod = cv2.resize(self.image, (150, 150))
        image_mod_lidar = cv2.resize(self.image_lidar, (150, 150))
        val = self.fusion.predict([
            image_mod.reshape(-1, 150, 150, 3),
            image_mod_lidar.reshape(-1, 150, 150, 3)
        ])
        if (val[0][0] > 0):
            print("person")
        else:
            print("car")
from keras.applications.resnet50 import ResNet50
from keras.preprocessing import image
from keras.applications.resnet50 import preprocess_input
from tensorflow.keras.models import Model
from keras.models import load_model
import numpy as np
import pickle
model = ResNet50(weights="imagenet", input_shape=(224, 224, 3))
new_model = Model(model.input, model.layers[-2].output)
new_model._make_predict_function()
with open('term_dict.pickle', 'rb') as handle:
    vocabulary = pickle.load(handle)
model = load_model("model_6.h5")
model._make_predict_function()
glove_embedding = {}
with open("glove.6B.50d.txt", 'r', encoding="utf8") as f:
    for i in f:
        ax = i.split()
        glove_embedding[ax[0]] = np.array(ax[1:], dtype='float')
embedding_dim = 50

import numpy as np


def preprocess_img(img_path):
    img = image.load_img(img_path, target_size=(224, 224))
    x = image.img_to_array(img)
    x = np.expand_dims(x, axis=0)
    x = preprocess_input(x)
    return x
Пример #9
0
class LSTMMorphoAnalysis:
    def __init__(self, language: str):
        self.language = language  # type: str
        self.morph = MorphAnalyzer() if language == "ru" else None  # type: MorphAnalyzer
        self.converter = converters.converter('opencorpora-int', 'ud14') if self.language == "ru" else None
        self.grammeme_vectorizer_input = GrammemeVectorizer()  # type: GrammemeVectorizer
        self.grammeme_vectorizer_output = GrammemeVectorizer()  # type: GrammemeVectorizer
        self.word_vocabulary = WordVocabulary()  # type: WordVocabulary
        self.char_set = ""  # type: str
        self.train_model = None  # type: Model
        self.eval_model = None  # type: Model

    def prepare(self, gram_dump_path_input: str, gram_dump_path_output: str,
                word_vocabulary_dump_path: str, char_set_dump_path: str,
                file_names: List[str] = None) -> None:
        """
        Подготовка векторизатора грамматических значений и словаря слов по корпусу.
        """
        if os.path.exists(gram_dump_path_input):
            self.grammeme_vectorizer_input.load(gram_dump_path_input)
        if os.path.exists(gram_dump_path_output):
            self.grammeme_vectorizer_output.load(gram_dump_path_output)
        if os.path.exists(word_vocabulary_dump_path):
            self.word_vocabulary.load(word_vocabulary_dump_path)
        if os.path.exists(char_set_dump_path):
            with open(char_set_dump_path, 'r', encoding='utf-8') as f:
                self.char_set = f.read().rstrip()
        if self.grammeme_vectorizer_input.is_empty() or \
                self.grammeme_vectorizer_output.is_empty() or \
                self.word_vocabulary.is_empty() or\
                not self.char_set:
            loader = Loader(self.language)
            loader.parse_corpora(file_names)

            self.grammeme_vectorizer_input = loader.grammeme_vectorizer_input
            self.grammeme_vectorizer_input.save(gram_dump_path_input)
            self.grammeme_vectorizer_output = loader.grammeme_vectorizer_output
            self.grammeme_vectorizer_output.save(gram_dump_path_output)
            self.word_vocabulary = loader.word_vocabulary
            self.word_vocabulary.save(word_vocabulary_dump_path)
            self.char_set = loader.char_set
            with open(char_set_dump_path, 'w', encoding='utf-8') as f:
                f.write(self.char_set)

    def save(self, model_config_path: str, model_weights_path: str,
             eval_model_config_path: str, eval_model_weights_path: str):
        if self.eval_model is not None:
            with open(eval_model_config_path, "w", encoding='utf-8') as f:
                f.write(self.eval_model.to_yaml())
            self.eval_model.save_weights(eval_model_weights_path)
        if self.train_model is not None:
            with open(model_config_path, "w", encoding='utf-8') as f:
                f.write(self.train_model.to_yaml())
            self.train_model.save_weights(model_weights_path)

    def load_train(self, config: BuildModelConfig, model_config_path: str=None, model_weights_path: str=None):
        with open(model_config_path, "r", encoding='utf-8') as f:
            if config.use_crf:
                from tensorflow.keras_contrib.layers import CRF
                custom_objects = {'ReversedLSTM': ReversedLSTM, 'CRF': CRF}
                self.train_model = model_from_yaml(f.read(), custom_objects=custom_objects)
            else:
                custom_objects = {'ReversedLSTM': ReversedLSTM}
                self.train_model = model_from_yaml(f.read(), custom_objects=custom_objects)
        self.train_model.load_weights(model_weights_path)

        loss = {}
        metrics = {}
        if config.use_crf:
            out_layer_name = 'crf'
            offset = 0
            if config.use_pos_lm:
                offset += 2
            if config.use_word_lm:
                offset += 2
            loss[out_layer_name] = self.train_model.layers[-1-offset].loss_function
            metrics[out_layer_name] = self.train_model.layers[-1-offset].accuracy
        else:
            out_layer_name = 'main_pred'
            loss[out_layer_name] = 'sparse_categorical_crossentropy'
            metrics[out_layer_name] = 'accuracy'

        if config.use_pos_lm:
            prev_layer_name = 'shifted_pred_prev'
            next_layer_name = 'shifted_pred_next'
            loss[prev_layer_name] = loss[next_layer_name] = 'sparse_categorical_crossentropy'
            metrics[prev_layer_name] = metrics[next_layer_name] = 'accuracy'
        self.train_model.compile(Adam(clipnorm=5.), loss=loss, metrics=metrics)

        self.eval_model = Model(inputs=self.train_model.inputs, outputs=self.train_model.outputs[0])

    def load_eval(self, config: BuildModelConfig, eval_model_config_path: str,
                  eval_model_weights_path: str) -> None:
        with open(eval_model_config_path, "r", encoding='utf-8') as f:
            if config.use_crf:
                from tensorflow.keras_contrib.layers import CRF
                custom_objects = {'ReversedLSTM': ReversedLSTM, 'CRF': CRF}
                self.eval_model = model_from_yaml(f.read(), custom_objects=custom_objects)
            else:
                custom_objects = {'ReversedLSTM': ReversedLSTM}
                self.eval_model = model_from_yaml(f.read(), custom_objects=custom_objects)
        self.eval_model.load_weights(eval_model_weights_path)
        self.eval_model._make_predict_function()
        
    def build(self, config: BuildModelConfig, word_embeddings=None):
        """
        Описание модели.

        :param config: конфиг модели.
        :param word_embeddings: матрица словных эмбеддингов.
        """
        inputs = []
        embeddings = []

        if config.use_word_embeddings and word_embeddings is not None:
            words = Input(shape=(None,), name='words')
            word_vocabulary_size = word_embeddings.size.shape[0]
            word_embeddings_dim = word_embeddings.size.shape[1]
            words_embedding = Embedding(word_vocabulary_size, word_embeddings_dim, name='word_embeddings')(words)
            embeddings.append(words_embedding)

        if config.use_gram:
            grammemes_input = Input(shape=(None, self.grammeme_vectorizer_input.grammemes_count()), name='grammemes')
            grammemes_embedding = Dropout(config.gram_dropout)(grammemes_input)
            grammemes_embedding = Dense(config.gram_hidden_size, activation='relu')(grammemes_embedding)
            inputs.append(grammemes_input)
            embeddings.append(grammemes_embedding)

        if config.use_chars:
            chars_input = Input(shape=(None, config.char_max_word_length), name='chars')

            char_layer = build_dense_chars_layer(
                max_word_length=config.char_max_word_length,
                char_vocab_size=len(self.char_set)+1,
                char_emb_dim=config.char_embedding_dim,
                hidden_dim=config.char_function_hidden_size,
                output_dim=config.char_function_output_size,
                dropout=config.char_dropout)
            if config.use_trained_char_embeddings:
                char_layer = get_char_model(
                    char_layer=char_layer,
                    max_word_length=config.char_max_word_length,
                    embeddings=word_embeddings,
                    model_config_path=config.char_model_config_path,
                    model_weights_path=config.char_model_weights_path,
                    vocabulary=self.word_vocabulary,
                    char_set=self.char_set)
            chars_embedding = char_layer(chars_input)
            inputs.append(chars_input)
            embeddings.append(chars_embedding)

        if len(embeddings) > 1:
            layer = concatenate(embeddings, name="LSTM_input")
        else:
            layer = embeddings[0]

        lstm_input = Dense(config.rnn_input_size, activation='relu')(layer)
        lstm_forward_1 = LSTM(config.rnn_hidden_size, dropout=config.rnn_dropout,
                              recurrent_dropout=config.rnn_dropout, return_sequences=True,
                              name='LSTM_1_forward')(lstm_input)

        lstm_backward_1 = ReversedLSTM(config.rnn_hidden_size, dropout=config.rnn_dropout,
                                       recurrent_dropout=config.rnn_dropout, return_sequences=True,
                                       name='LSTM_1_backward')(lstm_input)
        layer = concatenate([lstm_forward_1, lstm_backward_1], name="BiLSTM_input")

        for i in range(config.rnn_n_layers-1):
            layer = Bidirectional(LSTM(
                config.rnn_hidden_size,
                dropout=config.rnn_dropout,
                recurrent_dropout=config.rnn_dropout,
                return_sequences=True,
                name='LSTM_'+str(i)))(layer)

        layer = TimeDistributed(Dense(config.dense_size))(layer)
        layer = TimeDistributed(Dropout(config.dense_dropout))(layer)
        layer = TimeDistributed(BatchNormalization())(layer)
        layer = TimeDistributed(Activation('relu'))(layer)

        outputs = []
        loss = {}
        metrics = {}
        num_of_classes = self.grammeme_vectorizer_output.size() + 1

        if config.use_crf:
            from tensorflow.keras_contrib.layers import CRF
            out_layer_name = 'crf'
            crf_layer = CRF(num_of_classes, sparse_target=True, name=out_layer_name)
            outputs.append(crf_layer(layer))
            loss[out_layer_name] = crf_layer.loss_function
            metrics[out_layer_name] = crf_layer.accuracy
        else:
            out_layer_name = 'main_pred'
            outputs.append(Dense(num_of_classes, activation='softmax', name=out_layer_name)(layer))
            loss[out_layer_name] = 'sparse_categorical_crossentropy'
            metrics[out_layer_name] = 'accuracy'

        if config.use_pos_lm:
            prev_layer_name = 'shifted_pred_prev'
            next_layer_name = 'shifted_pred_next'
            prev_layer = Dense(num_of_classes, activation='softmax', name=prev_layer_name)
            next_layer = Dense(num_of_classes, activation='softmax', name=next_layer_name)
            outputs.append(prev_layer(Dense(config.dense_size, activation='relu')(lstm_backward_1)))
            outputs.append(next_layer(Dense(config.dense_size, activation='relu')(lstm_forward_1)))
            loss[prev_layer_name] = loss[next_layer_name] = 'sparse_categorical_crossentropy'
            metrics[prev_layer_name] = metrics[next_layer_name] = 'accuracy'

        if config.use_word_lm:
            out_layer_name = 'out_embedding'
            out_embedding = Dense(word_embeddings.shape[0],
                                  weights=[word_embeddings.T, np.zeros(word_embeddings.shape[0])],
                                  activation='softmax', name=out_layer_name, trainable=False)
            outputs.append(out_embedding(Dense(word_embeddings.shape[1], activation='relu')(lstm_backward_1)))
            outputs.append(out_embedding(Dense(word_embeddings.shape[1], activation='relu')(lstm_forward_1)))
            loss[out_layer_name] = 'sparse_categorical_crossentropy'
            metrics[out_layer_name] = 'accuracy'

        self.train_model = Model(inputs=inputs, outputs=outputs)
        self.train_model.compile(Adam(clipnorm=5.), loss=loss, metrics=metrics)
        self.eval_model = Model(inputs=inputs, outputs=outputs[0])
        print(self.train_model.summary())

    def train(self, file_names: List[str], train_config: TrainConfig, build_config: BuildModelConfig) -> None:
        np.random.seed(train_config.random_seed)
        sample_counter = self.count_samples(file_names)
        train_idx, val_idx = self.get_split(sample_counter, train_config.val_part)
        for big_epoch in range(train_config.epochs_num):
            print('------------Big Epoch {}------------'.format(big_epoch))
            batch_generator = BatchGenerator(
                language=self.language,
                file_names=file_names,
                config=train_config,
                grammeme_vectorizer_input=self.grammeme_vectorizer_input,
                grammeme_vectorizer_output=self.grammeme_vectorizer_output,
                build_config=build_config,
                indices=train_idx,
                word_vocabulary=self.word_vocabulary,
                char_set=self.char_set)
            for epoch, (inputs, target) in enumerate(batch_generator):
                self.train_model.fit(inputs, target, batch_size=train_config.batch_size, epochs=1, verbose=2)
                if epoch != 0 and epoch % train_config.dump_model_freq == 0:
                    self.save(train_config.train_model_config_path, train_config.train_model_weights_path,
                              train_config.eval_model_config_path, train_config.eval_model_weights_path)
            self.evaluate(
                file_names=file_names,
                val_idx=val_idx,
                train_config=train_config,
                build_config=build_config)

    @staticmethod
    def count_samples(file_names: List[str]):
        """
        Считает количество предложений в выборке.

        :param file_names: файлы выборки.
        :return: количество предложений.
        """
        sample_counter = 0
        for filename in file_names:
            with open(filename, "r", encoding='utf-8') as f:
                for line in f:
                    line = line.strip()
                    if len(line) == 0:
                        sample_counter += 1
        return sample_counter

    @staticmethod
    def get_split(sample_counter: int, val_part: float) -> Tuple[np.array, np.array]:
        """
        Выдаёт индексы предложений, которые становятся train или val выборкой.

        :param sample_counter: количество предложений.
        :param val_part: часть выборки, которая станет val.
        :return: индексы выборок.
        """
        perm = np.random.permutation(sample_counter)
        border = int(sample_counter * (1 - val_part))
        train_idx = perm[:border]
        val_idx = perm[border:]
        return train_idx, val_idx

    def evaluate(self, file_names, val_idx, train_config: TrainConfig, build_config: BuildModelConfig) -> None:
        """
        Оценка на val выборке.

        :param file_names: файлы выборки.
        :param val_idx: val индексы.
        :param train_config: конфиг обучения.
        :param build_config: конфиг модели.
        """
        word_count = 0
        word_errors = 0
        sentence_count = 0
        sentence_errors = 0
        batch_generator = BatchGenerator(
            language=self.language,
            file_names=file_names,
            config=train_config,
            grammeme_vectorizer_input=self.grammeme_vectorizer_input,
            grammeme_vectorizer_output=self.grammeme_vectorizer_output,
            build_config=build_config,
            indices=val_idx,
            word_vocabulary=self.word_vocabulary,
            char_set=self.char_set)
        for epoch, (inputs, target) in enumerate(batch_generator):
            predicted_y = self.eval_model.predict(inputs, batch_size=train_config.batch_size, verbose=0)
            for i, sentence in enumerate(target[0]):
                sentence_has_errors = False
                count_zero = sum([1 for num in sentence if num == [0]])
                real_sentence_tags = sentence[count_zero:]
                answer = []
                for grammeme_probs in predicted_y[i][count_zero:]:
                    num = np.argmax(grammeme_probs)
                    answer.append(num)
                for tag, predicted_tag in zip(real_sentence_tags, answer):
                    tag = tag[0]
                    word_count += 1
                    if tag != predicted_tag:
                        word_errors += 1
                        sentence_has_errors = True
                sentence_count += 1
                if sentence_has_errors:
                    sentence_errors += 1

        print("Word accuracy: ", 1.0 - float(word_errors) / word_count)
        print("Sentence accuracy: ", 1.0 - float(sentence_errors) / sentence_count)

    def predict_probabilities(self, sentences: List[List[str]], batch_size: int,
                              build_config: BuildModelConfig) -> List[List[List[float]]]:
        """
        Предсказание полных PoS-тегов по предложению с вероятностями всех вариантов.

        :param sentences: массив предложений (которые являются массивом слов).
        :param build_config: конфиг архитектуры модели.
        :param batch_size: размер батча.
        :return: вероятности тегов.
        """
        max_sentence_len = max([len(sentence) for sentence in sentences])
        if max_sentence_len == 0:
            return [[] for _ in sentences]
        n_samples = len(sentences)

        words = np.zeros((n_samples, max_sentence_len), dtype=np.int)
        grammemes = np.zeros((n_samples, max_sentence_len, self.grammeme_vectorizer_input.grammemes_count()),
                             dtype=np.float)
        chars = np.zeros((n_samples, max_sentence_len, build_config.char_max_word_length), dtype=np.int)

        for i, sentence in enumerate(sentences):
            if not sentence:
                continue
            word_indices, gram_vectors, char_vectors = BatchGenerator.get_sample(
                sentence,
                language=self.language,
                converter=self.converter,
                morph=self.morph,
                grammeme_vectorizer=self.grammeme_vectorizer_input,
                max_word_len=build_config.char_max_word_length,
                word_vocabulary=self.word_vocabulary,
                word_count=build_config.word_max_count,
                char_set=self.char_set)
            words[i, -len(sentence):] = word_indices
            grammemes[i, -len(sentence):] = gram_vectors
            chars[i, -len(sentence):] = char_vectors

        inputs = []
        if build_config.use_word_embeddings:
            inputs.append(words)
        if build_config.use_gram:
            inputs.append(grammemes)
        if build_config.use_chars:
            inputs.append(chars)
        with sess.as_default():
            with graph.as_default() as g:
                return self.eval_model.predict(inputs, batch_size=batch_size)
Пример #10
0
class Brain:
    MIN_BATCH = 25
    def __init__(self, flags, summary_writer):
        self.lr = flags.learning_rate
        self.er = flags.entropy_rate
        self.flags = flags
        self.summary_writer = summary_writer
        self.N_STEP_RETURN = 40
        self.GAMMA = .99
        self.LAMBDA = 1
        self.eps = .2
        self.ssize = 32
        self.isize = len(U.useful_actions)
        self.custom_input_size = 1 + len(U.useful_actions)
        self.stop_signal = False

        self.lock_queue = threading.Lock()
        self.train_queue = [[], [], [], [], [], [], [], []]


        self.counter_lock = threading.Lock()
        self.training_counter = 0

        config = tf.ConfigProto(allow_soft_placement=True)
        config.gpu_options.allow_growth = True
        self.session = tf.Session(config=config)
        K.set_session(self.session)
        K.manual_variable_initialization(True)
        self.build_net('/gpu:0')
        self.build_model('/gpu:0')
        self.session.run(tf.global_variables_initializer())
        self.default_graph = tf.get_default_graph()
        self.default_graph.finalize()
        self.summary_writer.add_graph(self.default_graph)
        # self.debug = np.array([])

    def stop(self):
        self.stop_signal = True

    def getPredictFeedDict(self, obs, hState, cState):
        screen = np.array(obs.observation['feature_screen'], dtype=np.float32)
        screen = np.expand_dims(U.preprocess_screen(screen), axis=0)
        info = np.zeros([1, len(U.useful_actions)], dtype=np.float32)
        info[0, U.compressActions(obs.observation['available_actions'])] = 1
        custom_inputs = np.expand_dims(
            np.array(obs.observation.custom_inputs, dtype=np.float32), axis=0)
        hState = np.expand_dims(np.array(hState), axis=0)
        cState = np.expand_dims(np.array(cState), axis=0)
        return {
            self.screen: screen,
            self.info: info,
            self.custom_inputs: custom_inputs,
            self.hStateInput: hState,
            self.cStateInput: cState }

    def getTrainFeedDict(self, obs, action, attributed_act_id):
        screen = np.array(obs.observation['feature_screen'], dtype=np.float32)
        screen = U.preprocess_screen(screen)
        info = np.zeros([len(U.useful_actions)], dtype=np.float32)
        info[U.compressActions(obs.observation['available_actions'])] = 1
        valid_spatial_action = 0
        valid_action = np.zeros([len(U.useful_actions)], dtype=np.float32)

        custom_inputs = np.array(obs.observation.custom_inputs, dtype=np.float32)

        act_id = action.function
        net_act_id = attributed_act_id
        act_args = action.arguments

        player_relative = obs.observation.feature_screen.player_relative
        valid_actions = obs.observation["available_actions"]
        valid_actions = U.compressActions(valid_actions)
        valid_action[valid_actions] = 1

        args = actions.FUNCTIONS[act_id].args
        for arg, act_arg in zip(args, act_args):
            if arg.name in ('screen', 'minimap', 'screen2') and (not self.flags.force_focus_fire or (act_id != 12 and act_id != 2)):
                valid_spatial_action = 1

        return {
            self.screen: screen, # yes
            self.info: info, # yes
            self.custom_inputs: custom_inputs, #yes
            self.valid_spatial_action: valid_spatial_action, #yes
            self.valid_action: valid_action, # yes
        }

    def predict(self, feed):
        with self.session.as_default():
            v, policy, spatialPolicy, hS, cS, _ = self.model.predict([
                feed[self.screen],
                feed[self.info],
                feed[self.custom_inputs],
                feed[self.hStateInput],
                feed[self.cStateInput],
            ])

            return policy, spatialPolicy, v, hS, cS


    def train(self, feed):
        feed[self.learning_rate] = self.lr
        feed[self.entropy_rate] = self.er

        _, summary = self.session.run([self.train_op, self.summary_op], feed_dict=feed)
        with self.counter_lock:
            local_counter = self.training_counter
            self.training_counter = self.training_counter + 1
        if self.flags.use_tensorboard:
            self.summary_writer.add_summary(summary, local_counter)
            self.summary_writer.flush()
            if local_counter % self.flags.snapshot_step == 1 or local_counter >= self.flags.max_train_steps:
                self.save_model('./snapshot/'+self.flags.map, local_counter)
                print("Snapshot of model saved at", local_counter)

            if local_counter >= self.flags.max_train_steps:
                print("Reached step %d, training complete." % local_counter)
                self.stop()

    def add_train(self, batch):
        with self.lock_queue:
            for i in range(len(self.train_queue)):
                self.train_queue[i] = self.train_queue[i] + batch[i]

            if len(self.train_queue[0]) > (5000 * Brain.MIN_BATCH):
                print("Training queue too large; optimizer likely crashed")
                exit()

    def optimize(self):
        time.sleep(0.001)

        with self.lock_queue:
            if len(self.train_queue[0]) < Brain.MIN_BATCH:
                return

            batch = self.train_queue
            self.train_queue = [[],[],[],[],[],[],[],[]]


        batch_train_feed = {
            self.value_target:np.squeeze(np.array(batch[0], dtype=np.float32)),
            self.screen:np.asarray([x[self.screen] for x in batch[1]],dtype=np.float32),
            self.info:np.asarray([x[self.info] for x in batch[1]],dtype=np.float32),
            self.custom_inputs:np.asarray([x[self.custom_inputs] for x in batch[1]],dtype=np.float32),
            self.valid_spatial_action:np.asarray([x[self.valid_spatial_action] for x in batch[1]],dtype=np.float32),
            self.valid_action:np.asarray([x[self.valid_action] for x in batch[1]],dtype=np.float32),
            self.action_selected:np.array(batch[2], dtype=np.float32),
            self.spatial_action_selected:np.array(batch[3], dtype=np.float32),
            self.advantage:np.array(batch[4], dtype=np.float32),
            self.hStateInput:np.array(batch[5], dtype=np.float32),
            self.cStateInput:np.array(batch[6], dtype=np.float32),
            self.roach_location:np.array(batch[7], dtype=np.float32)
        }

        self.train(batch_train_feed)

    def getPolicyLoss(self, action_probability, advantage):
        return -tf.log(action_probability + 1e-10) * advantage

    def getValueLoss(self, difference):
        return tf.square(difference)

    def getEntropy(self, policy, spatial_policy, valid_spatial):
        return tf.reduce_sum(policy * tf.log(policy + 1e-10), axis=1)# + valid_spatial * tf.reduce_sum(spatial_policy * tf.log(spatial_policy + 1e-10), axis=1)

    def getMinRoachLoss(self, roach_target, roach_prediction):
        return K.categorical_crossentropy(roach_target,roach_prediction)

    def build_model(self, dev):
        with tf.variable_scope('a3c') and tf.device(dev):
            self.valid_spatial_action = tf.placeholder(
                tf.float32, [None], name='valid_spatial_action')
            self.spatial_action_selected = tf.placeholder(
                tf.float32, [None, self.ssize**2], name='spatial_action_selected')
            self.valid_action = tf.placeholder(
                tf.float32, [None, len(U.useful_actions)], name='valid_action')
            self.action_selected = tf.placeholder(
                tf.float32, [None, len(U.useful_actions)], name='action_selected')
            self.value_target = tf.placeholder(
                tf.float32, [None], name='value_target')
            self.entropy_rate = tf.placeholder(
                tf.float32, None, name='entropy_rate')
            self.advantage = tf.placeholder(tf.float32, [None], name='advantage')
            self.learning_rate = tf.placeholder(tf.float32, None, name='learning_rate')
            self.screen = tf.placeholder(
                tf.float32, [None, U.screen_channel(), self.ssize, self.ssize], name='screen')
            self.info = tf.placeholder(
                tf.float32, [None, self.isize], name='info')
            self.custom_inputs = tf.placeholder(
                tf.float32, [None, self.custom_input_size], name='custom_input')
            self.hStateInput = tf.placeholder(
                tf.float32, [None, self.NUM_LSTM], name='h_state_input')
            self.cStateInput = tf.placeholder(
                tf.float32, [None, self.NUM_LSTM], name='c_state_input')
            self.roach_location = tf.placeholder(
                tf.float32, [None, self.ssize ** 2], name='roach_location'
            )

            self.value, self.policy, self.spatial_policy, _, _, self.roachPrediction = self.model([self.screen, self.info, self.custom_inputs, self.hStateInput, self.cStateInput])
            # This will get the probability of choosing a valid action. Given that we force it to choose from
            # the set of valid actions. The probability of an action is the probability the policy chooses
            # divided by the probability of a valid action
            valid_action_prob = tf.reduce_sum(
                self.valid_action * self.policy+1e-10, axis=1)
            action_prob = tf.reduce_sum(
                self.action_selected * self.policy+1e-10, axis=1) / valid_action_prob

            # Here we compute the probability of the spatial action. If the action selected was non spactial,
            # the probability will be one.
            # TODO: Make this use vectorized things (using a constant "valid_spatial_action" seems fishy to me, but maybe it's fine)
            spatial_action_prob = (self.valid_spatial_action * tf.reduce_sum(
                self.spatial_policy * self.spatial_action_selected, axis=1)) + (1.0 - self.valid_spatial_action)+1e-10

            # The probability of the action will be the the product of the non spatial and the spatial prob
            combined_action_probability = action_prob * spatial_action_prob

            # The advantage function, which will represent how much better this action was than what was expected from this state


            policy_loss = self.getPolicyLoss(combined_action_probability, self.advantage)
            value_loss = self.getValueLoss(self.value_target - self.value)
            entropy = self.getEntropy(
                self.policy, self.spatial_policy, self.valid_spatial_action)
            roachLoss = self.getMinRoachLoss(
                self.roach_location, self.roachPrediction
            )


            loss = tf.reduce_mean(policy_loss + value_loss * .5 + entropy * .01 + .5 * roachLoss)
            # Build the optimizer
            global_step = tf.Variable(0)
            learning_rate_decayed = tf.train.exponential_decay(self.learning_rate,
                                                               global_step,10000, .95)

            opt = tf.train.AdamOptimizer(self.learning_rate)
            grads, vars = zip(*opt.compute_gradients(loss))
            grads, glob_norm = tf.clip_by_global_norm(grads, 40.0)
            self.train_op = opt.apply_gradients(zip(grads, vars), global_step=global_step)
            if self.flags.use_tensorboard:
                summary = []
                summary.append(tf.summary.scalar(
                    'policy_loss', tf.reduce_mean(policy_loss)))
                summary.append(tf.summary.scalar(
                    'glob_norm', glob_norm))
                summary.append(tf.summary.scalar(
                    'value_loss', tf.reduce_mean(value_loss)))
                summary.append(tf.summary.scalar(
                    'entropy_loss', tf.reduce_mean(entropy)))
                summary.append(tf.summary.scalar(
                    'advantage', tf.reduce_mean(self.advantage)))
                summary.append(tf.summary.scalar(
                    'loss', tf.reduce_mean(loss)))
                summary.append(tf.summary.scalar(
                    'roachLoss', tf.reduce_mean(roachLoss)))
                self.summary_op = tf.summary.merge(summary)
            else:
                self.summary_op = []
            self.saver = tf.train.Saver(max_to_keep=100)

            # debug graph:
            self.summary_writer.add_graph(self.session.graph)

    def broadcast(self, nonSpatialInput):
        nonSpatialInput = K.expand_dims(nonSpatialInput, axis=1)
        nonSpatialInput = K.expand_dims(nonSpatialInput, axis=2)
        return K.tile(nonSpatialInput,(1, self.ssize, self.ssize, 1))

    def expand_dims(self, x):
        return K.expand_dims(x, 1)

    def Squeeze(self, x):
        return K.squeeze(x,axis=-1)

    def build_net(self, dev):
         with tf.variable_scope('a3c') and tf.device(dev):
            screenInput = Input(
                shape=(U.screen_channel(), self.ssize, self.ssize),
                name='screenInput',
            )

            permutedScreenInput = Permute((2,3,1))(screenInput)
            conv1 = Conv2D(16, kernel_size=5, strides=(1,1), padding='same',name='conv1')(permutedScreenInput)
            conv2 = Conv2D(32, kernel_size=3, strides=(1,1), padding='same',name='conv2')(conv1)

            infoInput = Input(
                shape=(self.isize,),
                name='infoInput',
            )

            customInput = Input(
                shape=(self.custom_input_size,),
                name='customInput',
            )

            nonSpatialInput = Concatenate(name='nonSpatialInputConcat')([infoInput, customInput])

            broadcasted = Lambda(self.broadcast,name='broadcasting')(nonSpatialInput)

            combinedSpatialNonSpatial = Concatenate(name='combinedConcat')([broadcasted, conv2])

            conv3 = Conv2D(1, kernel_size=1, strides=(1,1), padding='same',name='conv3')(combinedSpatialNonSpatial)

            flatConv3 = Flatten(name='flatConv3')(conv3)

            lstmInput = Lambda(self.expand_dims, name='lstmInput')(flatConv3)

            self.NUM_LSTM = 100

            hStateInput = Input(
                shape=(self.NUM_LSTM,),
                name='hStateInput'
            )

            cStateInput = Input(
                shape=(self.NUM_LSTM,),
                name='cStateInput'
            )

            lstm, hStates, cStates = LSTM(self.NUM_LSTM, return_state=True)(lstmInput, initial_state=[hStateInput, cStateInput])

            fc1 = Dense(256, activation='relu',name='dense1')(lstm)
            fc2 = Dense(1, activation='linear',name='fc2')(fc1)
            value = Lambda(self.Squeeze,name='value')(fc2)
            policy = Dense(self.isize, activation='softmax',name='policy')(fc1)


            broadcastLstm = Lambda(self.broadcast, name='breadcastLstm')(lstm)

            spatialLstm = Concatenate(name='spatialLstm')([conv3, broadcastLstm])

            conv4 = Conv2D(1,kernel_size=1, strides=(1,1), padding='same',name='conv4')(spatialLstm)
            flatConv4 = Flatten(name='flattenedConv3')(conv4)
            spatialPolicy = Softmax(name='spatialPolicy')(flatConv4)

            conv5 = Conv2D(1, kernel_size=1, strides=(1,1), padding='same',name='conv5')(spatialLstm)
            flatConv5 = Flatten(name='flattenedConv5')(conv5)
            bestRoach = Softmax(name='bestRoach')(flatConv5)

            self.model = Model(
                inputs=[screenInput, infoInput, customInput, hStateInput, cStateInput],
                outputs=[value, policy, spatialPolicy, hStates, cStates, bestRoach]
            )
            self.model._make_predict_function()


    def save_model(self, path, count):
        self.saver.save(self.session, path + '/model.pkl', count)

    def load_model(self, path):
        ckpt = tf.train.get_checkpoint_state(path)
        self.saver.restore(self.session, ckpt.model_checkpoint_path)
        self.training_counter = int(ckpt.model_checkpoint_path.split('-')[-1])
Пример #11
0
class Brain:
    MIN_BATCH = 25

    def __init__(self, flags, summary_writer, input_shape, output_shape):
        self.lr = flags.learning_rate
        self.er = flags.entropy_rate
        self.flags = flags
        self.summary_writer = summary_writer
        self.N_STEP_RETURN = 20
        self.GAMMA = .99
        self.LAMBDA = 1
        self.stop_signal = False
        self.input_shape = input_shape
        self.output_shape = output_shape

        self.lock_queue = threading.Lock()
        self.train_queue = [[], [], [], [], [], []]

        self.counter_lock = threading.Lock()
        self.training_counter = 0

        config = tf.ConfigProto(allow_soft_placement=True)
        config.gpu_options.allow_growth = True
        self.session = tf.Session(config=config)
        K.set_session(self.session)
        K.manual_variable_initialization(True)
        self.build_net('/gpu:0')
        self.build_model('/gpu:0')
        self.session.run(tf.global_variables_initializer())
        self.default_graph = tf.get_default_graph()
        self.default_graph.finalize()
        self.summary_writer.add_graph(self.default_graph)

    def stop(self):
        self.stop_signal = True

    def getPredictFeedDict(self, observation, hState, cState):
        input = np.expand_dims(np.array(self.preprocess(observation),
                                        dtype=np.float32),
                               axis=0)
        hState = np.expand_dims(np.array(hState), axis=0)
        cState = np.expand_dims(np.array(cState), axis=0)
        return {
            self.input: input,
            self.hStateInput: hState,
            self.cStateInput: cState
        }

    def predict(self, feed):
        with self.session.as_default():
            policy, value, hs, cs = self.model.predict([
                feed[self.input],
                feed[self.hStateInput],
                feed[self.cStateInput],
            ])
            return policy, value, hs, cs

    def preprocess(self, data):
        if len(data.shape) == 1:
            return data
        stacks = []
        for obs in data:
            cropped = obs[34:194, :, :]
            reduced = cropped[0:-1:2, 0:-1:2]
            grayscale = np.sum(reduced, axis=2)
            bw = np.zeros(grayscale.shape)
            bw[grayscale != 233] = 1
            expand = np.expand_dims(bw, axis=2)
            stacks.append(expand)
        return np.concatenate(stacks, axis=2)

    def train(self, feed):
        feed[self.learning_rate] = self.lr
        feed[self.entropy_rate] = self.er

        _, summary = self.session.run([self.train_op, self.summary_op],
                                      feed_dict=feed)
        if self.flags.use_tensorboard:
            with self.counter_lock:
                self.training_counter = self.training_counter + 1
                self.summary_writer.add_summary(summary, self.training_counter)
                self.summary_writer.flush()

    def add_train(self, batch):
        with self.lock_queue:
            for i in range(len(self.train_queue)):
                self.train_queue[i] = self.train_queue[i] + batch[i]
            if len(self.train_queue[0]) > (5000 * Brain.MIN_BATCH):
                print("Training queue too large; optimizer likely crashed %d" %
                      len(self.train_queue[0]))
                exit()

    def optimize(self):
        time.sleep(0.001)

        with self.lock_queue:
            if len(
                    self.train_queue[0]
            ) < Brain.MIN_BATCH:  # more thread could have passed without lock
                return  # we can't yield inside lock

            batch = self.train_queue
            self.train_queue = [[], [], [], [], [], []]

        batch_train_feed = {
            self.value_target: np.squeeze(np.array(batch[0],
                                                   dtype=np.float32)),
            self.input: np.array(batch[1], dtype=np.float32),
            self.action_selected: np.array(batch[2], dtype=np.float32),
            self.advantage: np.array(batch[3], dtype=np.float32),
            self.hStateInput: np.array(batch[4], dtype=np.float32),
            self.cStateInput: np.array(batch[5], dtype=np.float32)
        }
        self.train(batch_train_feed)

    def getPolicyLoss(self, action_probability, advantage):
        return -tf.log(action_probability + 1e-10) * advantage

    def getValueLoss(self, difference):
        return tf.square(difference)

    def getEntropy(self, policy):
        return tf.reduce_sum(policy * tf.log(policy + 1e-10), axis=1)

    def build_model(self, dev):
        # Set targets and masks
        with tf.variable_scope('a3c'):
            self.action_selected = tf.placeholder(tf.float32,
                                                  [None, self.output_shape[0]],
                                                  name='action_selected')
            self.value_target = tf.placeholder(tf.float32, [None],
                                               name='value_target')
            self.entropy_rate = tf.placeholder(tf.float32,
                                               None,
                                               name='entropy_rate')
            self.learning_rate = tf.placeholder(tf.float32,
                                                None,
                                                name='learning_rate')
            self.advantage = tf.placeholder(tf.float32, [None],
                                            name='advantage')
            if len(self.input_shape) > 1:
                self.input = tf.placeholder(tf.float32, [None, 80, 80, 1],
                                            name='input')
            else:
                self.input = tf.placeholder(tf.float32,
                                            [None, self.input_shape[0]],
                                            name='input')
            self.hStateInput = tf.placeholder(tf.float32,
                                              [None, self.NUM_LSTM],
                                              name='h_state_input')
            self.cStateInput = tf.placeholder(tf.float32,
                                              [None, self.NUM_LSTM],
                                              name='c_state_input')

            self.policy, self.value, _, _ = self.model(
                [self.input, self.hStateInput, self.cStateInput])

            # This will get the probability of choosing a valid action. Given that we force it to choose from
            # the set of valid actions. The probability of an action is the probability the policy chooses
            # divided by the probability of a valid action
            action_probability = tf.reduce_sum(self.action_selected *
                                               self.policy,
                                               axis=1)

            policy_loss = self.getPolicyLoss(action_probability,
                                             self.advantage)
            value_loss = self.getValueLoss(self.value_target - self.value)
            entropy = self.getEntropy(self.policy)

            loss = tf.reduce_mean(policy_loss + value_loss * .5 +
                                  entropy * .01)

            global_step = tf.Variable(0)
            learning_rate_decayed = tf.train.exponential_decay(
                self.learning_rate, global_step, 10000, .95, staircase=True)

            # Build the optimizer
            opt = tf.train.AdamOptimizer(learning_rate_decayed)
            grads, vars = zip(*opt.compute_gradients(loss))
            grads, glob_norm = tf.clip_by_global_norm(grads, 40.0)
            self.train_op = opt.apply_gradients(zip(grads, vars),
                                                global_step=global_step)
            if self.flags.use_tensorboard:
                summary = []
                summary.append(
                    tf.summary.scalar('policy_loss',
                                      tf.reduce_mean(policy_loss)))
                summary.append(tf.summary.scalar('glob_norm', glob_norm))
                summary.append(
                    tf.summary.scalar('value_loss',
                                      tf.reduce_mean(value_loss)))
                summary.append(
                    tf.summary.scalar('entropy_loss', tf.reduce_mean(entropy)))
                summary.append(
                    tf.summary.scalar('advantage',
                                      tf.reduce_mean(self.advantage)))
                summary.append(tf.summary.scalar('loss', tf.reduce_mean(loss)))
                self.summary_op = tf.summary.merge(summary)
            else:
                self.summary_op = []

    def expand_dims(self, x):
        return K.expand_dims(x, 1)

    def Squeeze(self, x):
        return K.squeeze(x, axis=-1)

    def build_net(self, dev):
        with tf.variable_scope('a3c'):
            if len(self.input_shape) > 1:
                input = Input(shape=(80, 80, 1), name='Input')
                conv1 = Conv2D(32,
                               kernel_size=8,
                               strides=(4, 4),
                               padding='same',
                               activation='relu',
                               name='conv1')(input)
                conv2 = Conv2D(64,
                               kernel_size=4,
                               strides=(2, 2),
                               padding='same',
                               activation='relu',
                               name='conv2')(conv1)
                conv3 = Conv2D(64,
                               kernel_size=3,
                               strides=(1, 1),
                               padding='same',
                               activation='relu',
                               name='conv3')(conv2)
                flatConv3 = Flatten(name='flatConv3')(conv3)
                fc1 = Dense(512, activation='relu')(flatConv3)
            else:
                input = Input(shape=(self.input_shape[0], ), name='Input')
                fc1 = Dense(512, activation='relu')(input)

            LSTMIN = Lambda(self.expand_dims, name='expandFc1')(fc1)

            self.NUM_LSTM = 100
            hStateInput = Input(shape=(self.NUM_LSTM, ), name='hStateInput')

            cStateInput = Input(shape=(self.NUM_LSTM, ), name='cStateInput')

            lstm, hStates, cStates = LSTM(self.NUM_LSTM, return_state=True)(
                LSTMIN, initial_state=[hStateInput, cStateInput])

            fc2 = Dense(256, activation='relu', name='fc2')(lstm)
            vFc3 = Dense(1, activation='linear', name='vFc3')(fc2)

            value = Lambda(self.Squeeze, name='value')(vFc3)
            policy = Dense(self.output_shape[0],
                           activation='softmax',
                           name='policy')(fc2)

            self.model = Model(inputs=[input, hStateInput, cStateInput],
                               outputs=[policy, value, hStates, cStates])
            self.model._make_predict_function()