Пример #1
0
class GameModel:
    def __init__(self, config: Config):
        self.config = config
        self.model = None  # type: Model
        self.digest = None

    def build(self):
        mc = self.config.model
        in_x = x = Input((4, 3, 3))

        # (batch, channels, height, width)
        x = Conv2D(filters=mc.cnn_filter_num,
                   kernel_size=mc.cnn_filter_size,
                   padding="same",
                   data_format="channels_first",
                   kernel_regularizer=l2(mc.l2_reg))(x)
        x = BatchNormalization(axis=1)(x)
        x = Activation("relu")(x)

        for _ in range(mc.res_layer_num):
            x = self._build_residual_block(x)

        res_out = x
        # for policy output
        x = Conv2D(filters=4,
                   kernel_size=1,
                   data_format="channels_first",
                   kernel_regularizer=l2(mc.l2_reg))(res_out)
        x = BatchNormalization(axis=1)(x)
        x = Activation("relu")(x)
        x = Flatten()(x)
        # no output for 'pass'
        policy_out = Dense(self.config.n_labels,
                           kernel_regularizer=l2(mc.l2_reg),
                           activation="softmax",
                           name="policy_out")(x)

        # for value output
        x = Conv2D(filters=16,
                   kernel_size=1,
                   data_format="channels_first",
                   kernel_regularizer=l2(mc.l2_reg))(res_out)
        x = BatchNormalization(axis=1)(x)
        x = Activation("relu")(x)
        x = Flatten()(x)
        x = Dense(mc.value_fc_size,
                  kernel_regularizer=l2(mc.l2_reg),
                  activation="relu")(x)
        value_out = Dense(1,
                          kernel_regularizer=l2(mc.l2_reg),
                          activation="tanh",
                          name="value_out")(x)

        self.model = Model(in_x, [policy_out, value_out], name="game_model")

        #Print Model to PNG


##        from keras.utils import plot_model
##        plot_model(self.model, to_file='model.png', show_shapes=True)

    def _build_residual_block(self, x):
        mc = self.config.model
        in_x = x
        x = Conv2D(filters=mc.cnn_filter_num,
                   kernel_size=mc.cnn_filter_size,
                   padding="same",
                   data_format="channels_first",
                   kernel_regularizer=l2(mc.l2_reg))(x)
        x = BatchNormalization(axis=1)(x)
        x = Activation("relu")(x)
        x = Conv2D(filters=mc.cnn_filter_num,
                   kernel_size=mc.cnn_filter_size,
                   padding="same",
                   data_format="channels_first",
                   kernel_regularizer=l2(mc.l2_reg))(x)
        x = BatchNormalization(axis=1)(x)
        x = Add()([in_x, x])
        x = Activation("relu")(x)
        return x

    @staticmethod
    def fetch_digest(weight_path):
        if os.path.exists(weight_path):
            m = hashlib.sha256()
            with open(weight_path, "rb") as f:
                m.update(f.read())
            return m.hexdigest()

    def load(self, config_path, weight_path):
        if os.path.exists(config_path) and os.path.exists(weight_path):
            print("loading model from ", config_path)
            with open(config_path, "rt") as f:
                self.model = Model.from_config(json.load(f))
            self.model.load_weights(weight_path)
            self.digest = self.fetch_digest(weight_path)
            print("loaded model digest = ", self.digest)
            return True
        else:
            print("model files does not exist at ", config_path, " and ",
                  weight_path)
            return False

    def save(self, config_path, weight_path):
        print("save model to ", config_path)
        with open(config_path, "wt") as f:
            json.dump(self.model.get_config(), f)
            self.model.save_weights(weight_path)
        self.digest = self.fetch_digest(weight_path)
        print("saved model digest ", self.digest)
Пример #2
0
class RenjuModel:

    def __init__(self, config):
        self.config = config
        self.model = None

    #predict a game basedon game_state.
    #the value is based on the current player. the higher, the better position the current player is in.
    def predict(self, gamestates):
        policy, value = self.model.predict(gamestates)
        return policy,value

    def build(self):
        #build the model.
        mc = self.config.model
        width = mc.input_size
        in_x = x = Input((2, width, width))  # [own(8x8), enemy(8x8)]

        # (batch, channels, height, width)
        x = Conv2D(filters=mc.cnn_filter_num, kernel_size=mc.cnn_filter_size, padding="same",
                   data_format="channels_first", kernel_regularizer=l2(mc.l2_reg))(x)
        x = BatchNormalization(axis=1)(x)
        x = Activation("relu")(x)

        for _ in range(mc.res_layer_num):
            x = self._build_residual_block(x)

        res_out = x
        # for policy output
        x = Conv2D(filters=2, kernel_size=1, data_format="channels_first", kernel_regularizer=l2(mc.l2_reg))(res_out)
        x = BatchNormalization(axis=1)(x)
        x = Activation("relu")(x)
        x = Flatten()(x)
        # no output for 'pass'
        policy_out = Dense(width*width, kernel_regularizer=l2(mc.l2_reg), activation="softmax", name="policy_out")(x)

        # for value output
        x = Conv2D(filters=1, kernel_size=1, data_format="channels_first", kernel_regularizer=l2(mc.l2_reg))(res_out)
        x = BatchNormalization(axis=1)(x)
        x = Activation("relu")(x)
        x = Flatten()(x)
        x = Dense(mc.value_fc_size, kernel_regularizer=l2(mc.l2_reg), activation="relu")(x)
        value_out = Dense(1, kernel_regularizer=l2(mc.l2_reg), activation="tanh", name="value_out")(x)

        self.model = Model(in_x, [policy_out, value_out], name="reversi_model")

    def _build_residual_block(self, x):
        mc = self.config.model
        in_x = x
        x = Conv2D(filters=mc.cnn_filter_num, kernel_size=mc.cnn_filter_size, padding="same",
                   data_format="channels_first", kernel_regularizer=l2(mc.l2_reg))(x)
        x = BatchNormalization(axis=1)(x)
        x = Activation("relu")(x)
        x = Conv2D(filters=mc.cnn_filter_num, kernel_size=mc.cnn_filter_size, padding="same",
                   data_format="channels_first", kernel_regularizer=l2(mc.l2_reg))(x)
        x = BatchNormalization(axis=1)(x)
        x = Add()([in_x, x])
        x = Activation("relu")(x)
        return x

    def save(self,path):
        if not os.path.exists(path):
            os.mkdir(path)
        self.model.save_weights(path + '/model.h5')
        model_json = self.model.to_json()
        with open(path + '/model.json', "w") as json_file:
            json_file.write(model_json)
    
    def load(self,path, old = False):
        if old:
            self.model = load_model(path,custom_objects={
                "objective_function_for_policy" : objective_function_for_policy,
                "objective_function_for_value" : objective_function_for_value
            })
        else:
            json_file = open(path + '/model.json', 'r')
            loaded_model_json = json_file.read()
            json_file.close()
            self.model = model_from_json(loaded_model_json,custom_objects={
                "objective_function_for_policy" : objective_function_for_policy,
                "objective_function_for_value" : objective_function_for_value
            })
            self.model.load_weights(path + '/model.h5')
Пример #3
0
def build_CNN_model(inputType, do_training=False, model_inputs=None, loss_func='binary_crossentropy',
                    optimize_proc='adam', is_IntermediateModel=False, load_weight_path=None, **kwargs):
    """

    :param inputType:
    :param do_training:
    :param model_inputs:
    :param loss_func:
    :param optimize_proc:
    :param is_IntermediateModel:
    :param load_weight_path:
    :param kwargs:
    :return:
    """

    # assert not do_training and model_inputs, "if do_training then must pass in model_inputs dictionary"

    EMBEDDING_TYPE = 'embeddingMatrix'
    ONEHOT_TYPE = '1hotVector'

    defined_input_types = {EMBEDDING_TYPE, ONEHOT_TYPE}

    assert inputType in defined_input_types, "unknown input type {0}".format(inputType)

    if inputType is ONEHOT_TYPE:

        review_input = Input(shape=(modelParameters.MaxLen_w,), dtype='float32',
                             name="ONEHOT_INPUT")

        layer = Embedding(modelParameters.VocabSize_w + modelParameters.INDEX_FROM, embedding_dims,
                          embeddings_initializer=embedding_init, embeddings_regularizer=embedding_reg,
                          input_length=modelParameters.MaxLen_w, name='1hot_embeddingLayer')(review_input)

        layer = SpatialDropout1D(0.50)(layer)

    elif inputType is EMBEDDING_TYPE:
        review_input = Input(shape=(modelParameters.MaxLen_w, embedding_dims), dtype="float32", name="EMBEDDING_INPUT")
        layer = review_input

    else:
        raise ValueError("Bad inputType arg to build_CNN_model")

    layer = Convolution1D(filters=num_filters1,
                          kernel_size=filter_length1,
                          padding=region,
                          strides=1,
                          activation=conv_activation1,
                          kernel_initializer='glorot_uniform',
                          bias_initializer='zeros',
                          kernel_regularizer=conv_reg1,
                          dilation_rate=1,
                          name='ConvLayer1')(layer)

    layer = SpatialDropout1D(0.50)(layer)

    layer = MaxPooling1D(pool_size=pool_len1)(layer)

    # layer = Convolution1D(filters=num_filters2,
    #                       kernel_size=filter_length2,
    #                       padding=region,
    #                       strides=1,
    #                       activation=conv_activation2,
    #                       kernel_initializer=conv_init2,
    #                       kernel_regularizer=conv_reg2,
    #                       dilation_rate=1,
    #                       name='ConvLayer2')(layer)
    #
    # layer = SpatialDropout1D(0.50)(layer)
    #
    # layer = MaxPooling1D(pool_size=pool_len2)(layer)

    # layer = Convolution1D(filters=num_filters3,
    #                       kernel_size=filter_length3,
    #                       padding=region,
    #                       activation=conv_activation3,
    #                       kernel_initializer=conv_init3,
    #                       kernel_regularizer=conv_reg3,
    #                       dilation_rate=1,
    #                       name='ConvLayer3')(layer)
    #
    # layer = SpatialDropout1D(0.50)(layer)
    #
    # layer = MaxPooling1D(pool_size=pool_len3)(layer)



    # #layer = GlobalMaxPool1D()(layer)
    #
    # layer = Convolution1D(filters=num_filters4,
    #                       kernel_size=filter_length4,
    #                       padding=region,
    #                       activation=conv_activation4,
    #                       kernel_initializer=conv_init4,
    #                       kernel_regularizer=conv_reg4,
    #                       dilation_rate=1,
    #                       name='ConvLayer4')(layer)
    #
    # #layer = leaky_relu(layer)
    #
    # layer = SpatialDropout1D(0.50)(layer)
    #
    # layer = MaxPooling1D(pool_size=pool_len4)(layer)
    # #layer = GlobalMaxPool1D()(layer)
    #
    # # layer = BatchNormalization()(layer)

    layer = Flatten()(layer)

    layer = Dense(dense_dims0, activation=dense_activation0, kernel_regularizer=dense_reg0,
                  kernel_initializer='glorot_normal', bias_initializer='zeros',
                  name='dense0')(layer)

    layer = Dropout(0.50)(layer)

    layer = Dense(dense_dims1, activation=dense_activation1, kernel_regularizer=dense_reg1,
                  kernel_initializer='glorot_normal', bias_initializer='zeros',
                  name='dense1')(layer)

    layer = Dropout(0.50)(layer)

    # layer = Dense(dense_dims2, activation=dense_activation2, kernel_regularizer=dense_reg2,
    #               kernel_initializer=dense_init2,
    #               name='dense2')(layer)
    #
    #
    # layer = Dropout(0.50)(layer)
    #
    # layer = Dense(dense_dims3, activation=dense_activation3, kernel_regularizer=dense_reg3,
    #               kernel_initializer=dense_init3,
    #               name='dense3_outA')(layer)
    # #layer = leaky_relu(layer)
    #
    if is_IntermediateModel:
        return Model(inputs=[review_input], outputs=[layer], name="CNN_model")

    #
    # layer = Dropout(0.5)(layer)

    layer = Dense(dense_dims_final, activation=dense_activation_final, kernel_initializer=dense_init_final,
                  kernel_regularizer=dense_reg0,
                  name='output_Full')(layer)

    CNN_model = Model(inputs=[review_input], outputs=[layer], name="CNN_model")

    CNN_model.compile(optimizer=Adam(lr=0.001, decay=0.0), loss=loss_func, metrics=[binary_accuracy])

    if load_weight_path is not None:
        CNN_model.load_weights(load_weight_path)

    hist = ""
    if do_training:
        weightPath = os.path.join(modelParameters.WEIGHT_PATH, filename)
        configPath = os.path.join(modelParameters.WEIGHT_PATH, filename_config)

        with open(configPath + ".json", 'wb') as f:
            f.write(CNN_model.to_json())

        checkpoint = ModelCheckpoint(weightPath + '_W.{epoch:02d}-{val_loss:.4f}.hdf5',
                                     verbose=1, save_best_only=True, save_weights_only=False, monitor='val_loss')

        earlyStop = EarlyStopping(patience=3, verbose=1, monitor='val_loss')

        LRadjuster = ReduceLROnPlateau(monitor='val_loss', factor=0.30, patience=0, verbose=1, cooldown=1,
                                       min_lr=0.00001, epsilon=1e-2)

        call_backs = [checkpoint, earlyStop, LRadjuster]

        CNN_model.summary()

        hist = CNN_model.fit(*model_inputs['training'],
                             batch_size=batch_size,
                             epochs=nb_epoch, verbose=1,
                             validation_data=model_inputs['dev'],
                             callbacks=call_backs)

    return {"model": CNN_model, "hist": hist}
Пример #4
0
class AdditionNPIModel(NPIStep):
    model = None
    f_enc = None

    def __init__(self,
                 system: RuntimeSystem,
                 model_path: str = None,
                 program_set: AdditionProgramSet = None):
        self.system = system
        self.model_path = model_path
        self.program_set = program_set
        self.batch_size = 1
        self.build()
        self.weight_loaded = False
        self.load_weights()

    def build(self):
        enc_size = self.size_of_env_observation()
        argument_size = IntegerArguments.size_of_arguments
        input_enc = InputLayer(batch_input_shape=(self.batch_size, enc_size),
                               name='input_enc')
        input_arg = InputLayer(batch_input_shape=(self.batch_size,
                                                  argument_size),
                               name='input_arg')
        input_prg = Embedding(input_dim=PROGRAM_VEC_SIZE,
                              output_dim=PROGRAM_KEY_VEC_SIZE,
                              input_length=1,
                              batch_input_shape=(self.batch_size, 1))

        f_enc = Sequential(name='f_enc')
        f_enc.add(Merge([input_enc, input_arg], mode='concat'))
        f_enc.add(MaxoutDense(128, nb_feature=4))
        self.f_enc = f_enc

        program_embedding = Sequential(name='program_embedding')
        program_embedding.add(input_prg)

        f_enc_convert = Sequential(name='f_enc_convert')
        f_enc_convert.add(f_enc)
        f_enc_convert.add(RepeatVector(1))

        f_lstm = Sequential(name='f_lstm')
        f_lstm.add(Merge([f_enc_convert, program_embedding], mode='concat'))
        f_lstm.add(
            LSTM(256,
                 return_sequences=False,
                 stateful=True,
                 W_regularizer=l2(0.0000001)))
        f_lstm.add(Activation('relu', name='relu_lstm_1'))
        f_lstm.add(RepeatVector(1))
        f_lstm.add(
            LSTM(256,
                 return_sequences=False,
                 stateful=True,
                 W_regularizer=l2(0.0000001)))
        f_lstm.add(Activation('relu', name='relu_lstm_2'))
        # plot(f_lstm, to_file='f_lstm.png', show_shapes=True)

        f_end = Sequential(name='f_end')
        f_end.add(f_lstm)
        f_end.add(Dense(1, W_regularizer=l2(0.001)))
        f_end.add(Activation('sigmoid', name='sigmoid_end'))

        f_prog = Sequential(name='f_prog')
        f_prog.add(f_lstm)
        f_prog.add(Dense(PROGRAM_KEY_VEC_SIZE, activation="relu"))
        f_prog.add(Dense(PROGRAM_VEC_SIZE, W_regularizer=l2(0.0001)))
        f_prog.add(Activation('softmax', name='softmax_prog'))
        # plot(f_prog, to_file='f_prog.png', show_shapes=True)

        f_args = []
        for ai in range(1, IntegerArguments.max_arg_num + 1):
            f_arg = Sequential(name='f_arg%s' % ai)
            f_arg.add(f_lstm)
            f_arg.add(Dense(IntegerArguments.depth, W_regularizer=l2(0.0001)))
            f_arg.add(Activation('softmax', name='softmax_arg%s' % ai))
            f_args.append(f_arg)
        # plot(f_arg, to_file='f_arg.png', show_shapes=True)

        self.model = Model([input_enc.input, input_arg.input, input_prg.input],
                           [f_end.output, f_prog.output] +
                           [fa.output for fa in f_args],
                           name="npi")
        self.compile_model()
        plot(self.model, to_file='model.png', show_shapes=True)

    def reset(self):
        super(AdditionNPIModel, self).reset()
        for l in self.model.layers:
            if type(l) is LSTM:
                l.reset_states()

    def compile_model(self, lr=0.0001, arg_weight=1.):
        arg_num = IntegerArguments.max_arg_num
        optimizer = Adam(lr=lr)
        loss = ['binary_crossentropy', 'categorical_crossentropy'
                ] + ['categorical_crossentropy'] * arg_num
        self.model.compile(optimizer=optimizer,
                           loss=loss,
                           loss_weights=[0.25, 0.25] + [arg_weight] * arg_num)

    def fit(self, steps_list, epoch=3000):
        # 过滤一些问题
        def filter_question(condition_func):
            sub_steps_list = []
            for steps_dict in steps_list:
                question = steps_dict['q']
                if condition_func(question['in1'], question['in2']):
                    sub_steps_list.append(steps_dict)
            return sub_steps_list

        if not self.weight_loaded:
            self.train_f_enc(
                filter_question(lambda a, b: 10 <= a < 100 and 10 <= b < 100),
                epoch=100)
        self.f_enc.trainable = False

        self.update_learning_rate(0.0001)

        q_type = "training questions of a<100 and b<100"
        print(q_type)
        pr = 0.8
        all_ok = self.fit_to_subset(
            filter_question(lambda a, b: a < 100 and b < 100), pass_rate=pr)
        print("%s is pass_rate >= %s: %s" % (q_type, pr, all_ok))

        while True:
            if self.test_and_learn([10, 100, 1000]):
                break

            q_type = "training questions of ALL"
            print(q_type)

            q_num = 100
            skip_correct = False
            pr = 1.0
            questions = filter_question(lambda a, b: True)
            np.random.shuffle(questions)
            questions = questions[:q_num]
            all_ok = self.fit_to_subset(questions,
                                        pass_rate=pr,
                                        skip_correct=skip_correct)
            print("%s is pass_rate >= %s: %s" % (q_type, pr, all_ok))

    def fit_to_subset(self, steps_list, pass_rate=1.0, skip_correct=False):
        for i in range(10):
            all_ok = self.do_learn(steps_list,
                                   100,
                                   pass_rate=pass_rate,
                                   skip_correct=skip_correct)
            if all_ok:
                return True
        return False

    def test_and_learn(self, num_questions):
        for num in num_questions:
            print("test all type of %d questions" % num)
            cc, wc, wrong_questions = self.test_to_subset(
                create_random_questions(num))
            acc_rate = cc / (cc + wc)
            print("Accuracy %s(OK=%d, NG=%d)" % (acc_rate, cc, wc))
            if wc > 0:
                self.fit_to_subset(wrong_questions,
                                   pass_rate=1.0,
                                   skip_correct=False)
                return False
        return True

    def test_to_subset(self, questions):
        addition_env = AdditionEnv(FIELD_ROW, FIELD_WIDTH, FIELD_DEPTH)
        teacher = AdditionTeacher(self.program_set)
        npi_runner = TerminalNPIRunner(None, self)
        teacher_runner = TerminalNPIRunner(None, teacher)
        correct_count = wrong_count = 0
        wrong_steps_list = []
        for idx, question in enumerate(questions):
            question = copy(question)
            if self.question_test(addition_env, npi_runner, question):
                correct_count += 1
            else:
                self.question_test(addition_env, teacher_runner, question)
                wrong_steps_list.append({
                    "q": question,
                    "steps": teacher_runner.step_list
                })
                wrong_count += 1
        return correct_count, wrong_count, wrong_steps_list

    @staticmethod
    def dict_to_str(d):
        return str(tuple([(k, d[k]) for k in sorted(d)]))

    def do_learn(self, steps_list, epoch, pass_rate=1.0, skip_correct=False):
        addition_env = AdditionEnv(FIELD_ROW, FIELD_WIDTH, FIELD_DEPTH)
        npi_runner = TerminalNPIRunner(None, self)
        last_weights = None
        correct_count = Counter()
        no_change_count = 0
        last_loss = 1000
        for ep in range(1, epoch + 1):
            correct_new = wrong_new = 0
            losses = []
            ok_rate = []
            np.random.shuffle(steps_list)
            for idx, steps_dict in enumerate(steps_list):
                question = copy(steps_dict['q'])
                question_key = self.dict_to_str(question)
                if self.question_test(addition_env, npi_runner, question):
                    if correct_count[question_key] == 0:
                        correct_new += 1
                    correct_count[question_key] += 1
                    print("GOOD!: ep=%2d idx=%3d :%s CorrectCount=%s" %
                          (ep, idx, self.dict_to_str(question),
                           correct_count[question_key]))
                    ok_rate.append(1)
                    cc = correct_count[question_key]
                    if skip_correct or int(math.sqrt(cc))**2 != cc:
                        continue
                else:
                    ok_rate.append(0)
                    if correct_count[question_key] > 0:
                        print(
                            "Degraded: ep=%2d idx=%3d :%s CorrectCount=%s -> 0"
                            % (ep, idx, self.dict_to_str(question),
                               correct_count[question_key]))
                        correct_count[question_key] = 0
                        wrong_new += 1

                steps = steps_dict['steps']
                xs = []
                ys = []
                ws = []
                for step in steps:
                    xs.append(self.convert_input(step.input))
                    y, w = self.convert_output(step.output)
                    ys.append(y)
                    ws.append(w)

                self.reset()

                for i, (x, y, w) in enumerate(zip(xs, ys, ws)):
                    loss = self.model.train_on_batch(x, y, sample_weight=w)
                    if not np.isfinite(loss):
                        print("Loss is not finite!, Last Input=%s" %
                              ([i, (x, y, w)]))
                        self.print_weights(last_weights, detail=True)
                        raise RuntimeError("Loss is not finite!")
                    losses.append(loss)
                    last_weights = self.model.get_weights()
            if losses:
                cur_loss = np.average(losses)
                print(
                    "ep=%2d: ok_rate=%.2f%% (+%s -%s): ave loss %s (%s samples)"
                    % (ep, np.average(ok_rate) * 100, correct_new, wrong_new,
                       cur_loss, len(steps_list)))
                # self.print_weights()
                if correct_new + wrong_new == 0:
                    no_change_count += 1
                else:
                    no_change_count = 0

                if math.fabs(1 - cur_loss /
                             last_loss) < 0.001 and no_change_count > 5:
                    print(
                        "math.fabs(1 - cur_loss/last_loss) < 0.001 and no_change_count > 5:"
                    )
                    return False
                last_loss = cur_loss
                print("=" * 80)
            self.save()
            if np.average(ok_rate) >= pass_rate:
                return True
        return False

    def update_learning_rate(self, learning_rate, arg_weight=1.):
        print("Re-Compile Model lr=%s aw=%s" % (learning_rate, arg_weight))
        self.compile_model(learning_rate, arg_weight=arg_weight)

    def train_f_enc(self, steps_list, epoch=50):
        print("training f_enc")
        f_add0 = Sequential(name='f_add0')
        f_add0.add(self.f_enc)
        f_add0.add(Dense(FIELD_DEPTH))
        f_add0.add(Activation('softmax', name='softmax_add0'))

        f_add1 = Sequential(name='f_add1')
        f_add1.add(self.f_enc)
        f_add1.add(Dense(FIELD_DEPTH))
        f_add1.add(Activation('softmax', name='softmax_add1'))

        env_model = Model(self.f_enc.inputs, [f_add0.output, f_add1.output],
                          name="env_model")
        env_model.compile(optimizer='adam',
                          loss=['categorical_crossentropy'] * 2)

        for ep in range(epoch):
            losses = []
            for idx, steps_dict in enumerate(steps_list):
                prev = None
                for step in steps_dict['steps']:
                    x = self.convert_input(step.input)[:2]
                    env_values = step.input.env.reshape((4, -1))
                    in1 = np.clip(env_values[0].argmax() - 1, 0, 9)
                    in2 = np.clip(env_values[1].argmax() - 1, 0, 9)
                    carry = np.clip(env_values[2].argmax() - 1, 0, 9)
                    y_num = in1 + in2 + carry
                    now = (in1, in2, carry)
                    if prev == now:
                        continue
                    prev = now
                    y0 = to_one_hot_array((y_num % 10) + 1, FIELD_DEPTH)
                    y1 = to_one_hot_array((y_num // 10) + 1, FIELD_DEPTH)
                    y = [yy.reshape((self.batch_size, -1)) for yy in [y0, y1]]
                    loss = env_model.train_on_batch(x, y)
                    losses.append(loss)
            print("ep %3d: loss=%s" % (ep, np.average(losses)))
            if np.average(losses) < 1e-06:
                break

    def question_test(self, addition_env, npi_runner, question):
        addition_env.reset()
        self.reset()
        try:
            run_npi(addition_env, npi_runner, self.program_set.ADD, question)
            if question['correct']:
                return True
        except StopIteration:
            pass
        return False

    def convert_input(self, p_in: StepInput):
        x_pg = np.array((p_in.program.program_id, ))
        x = [
            xx.reshape((self.batch_size, -1))
            for xx in (p_in.env, p_in.arguments.values, x_pg)
        ]
        return x

    def convert_output(self, p_out: StepOutput):
        y = [np.array((p_out.r, ))]
        weights = [[1.]]
        if p_out.program:
            arg_values = p_out.arguments.values
            arg_num = len(p_out.program.args or [])
            y += [p_out.program.to_one_hot(PROGRAM_VEC_SIZE)]
            weights += [[1.]]
        else:
            arg_values = IntegerArguments().values
            arg_num = 0
            y += [np.zeros((PROGRAM_VEC_SIZE, ))]
            weights += [[1e-10]]

        for v in arg_values:  # split by each args
            y += [v]
        weights += [[1.]] * arg_num + [[1e-10]] * (len(arg_values) - arg_num)
        weights = [np.array(w) for w in weights]
        return [yy.reshape((self.batch_size, -1)) for yy in y], weights

    def step(self, env_observation: np.ndarray, pg: Program,
             arguments: IntegerArguments) -> StepOutput:
        x = self.convert_input(StepInput(env_observation, pg, arguments))
        results = self.model.predict(
            x, batch_size=1)  # if batch_size==1, returns single row

        r, pg_one_hot, arg_values = results[0], results[1], results[2:]
        program = self.program_set.get(pg_one_hot.argmax())
        ret = StepOutput(r, program,
                         IntegerArguments(values=np.stack(arg_values)))
        return ret

    def save(self):
        self.model.save_weights(self.model_path, overwrite=True)

    def load_weights(self):
        if os.path.exists(self.model_path):
            self.model.load_weights(self.model_path)
            self.weight_loaded = True

    def print_weights(self, weights=None, detail=False):
        weights = weights or self.model.get_weights()
        for w in weights:
            print("w%s: sum(w)=%s, ave(w)=%s" %
                  (w.shape, np.sum(w), np.average(w)))
        if detail:
            for w in weights:
                print("%s: %s" % (w.shape, w))

    @staticmethod
    def size_of_env_observation():
        return FIELD_ROW * FIELD_DEPTH
Пример #5
0
def ResNet50(include_top=True,
             weights='imagenet',
             input_tensor=None,
             input_shape=None,
             pooling=None,
             classes=1000):
    if weights not in {'imagenet', None}:
        raise ValueError('The `weights` argument should be either '
                         '`None` (random initialization) or `imagenet` '
                         '(pre-training on ImageNet).')

    if weights == 'imagenet' and include_top and classes != 1000:
        raise ValueError('If using `weights` as imagenet with `include_top`'
                         ' as true, `classes` should be 1000')

    if input_tensor is None:
        img_input = Input(shape=input_shape)
    else:
        if not K.is_keras_tensor(input_tensor):
            img_input = Input(tensor=input_tensor, shape=input_shape)
        else:
            img_input = input_tensor
    if K.image_data_format() == 'channels_last':
        bn_axis = 3
    else:
        bn_axis = 1

    x = Conv2D(64, (7, 7), strides=(2, 2), padding='same',
               name='conv1')(img_input)
    x = BatchNormalization(axis=bn_axis, name='bn_conv1')(x)
    x = Activation('relu')(x)
    x = MaxPooling2D((3, 3), strides=(2, 2), padding="same")(x)

    x = conv_block(x, 3, [64, 64, 256], stage=2, block='a', strides=(1, 1))
    x = identity_block(x, 3, [64, 64, 256], stage=2, block='b')
    x = identity_block(x, 3, [64, 64, 256], stage=2, block='c')

    x = conv_block(x, 3, [128, 128, 512], stage=3, block='a')
    x = identity_block(x, 3, [128, 128, 512], stage=3, block='b')
    x = identity_block(x, 3, [128, 128, 512], stage=3, block='c')
    x = identity_block(x, 3, [128, 128, 512], stage=3, block='d')

    x = conv_block(x, 3, [256, 256, 1024], stage=4, block='a')
    x = identity_block(x, 3, [256, 256, 1024], stage=4, block='b')
    x = identity_block(x, 3, [256, 256, 1024], stage=4, block='c')
    x = identity_block(x, 3, [256, 256, 1024], stage=4, block='d')
    x = identity_block(x, 3, [256, 256, 1024], stage=4, block='e')
    x = identity_block(x, 3, [256, 256, 1024], stage=4, block='f')

    x = conv_block(x, 3, [512, 512, 2048], stage=5, block='a')
    x = identity_block(x, 3, [512, 512, 2048], stage=5, block='b')
    x = identity_block(x, 3, [512, 512, 2048], stage=5, block='c')
    #     x = AveragePooling2D((7, 7), name='avg_pool')(x)

    #     if include_top:
    #         x = Flatten()(x)
    #         x = Dense(classes, activation='softmax', name='fc1000')(x)
    #     else:
    #         if pooling == 'avg':
    #             x = GlobalAveragePooling2D()(x)
    #         elif pooling == 'max':
    #             x = GlobalMaxPooling2D()(x)

    # Ensure that the model takes into account
    # any potential predecessors of `input_tensor`.
    if input_tensor is not None:
        inputs = get_source_inputs(input_tensor)
    else:
        inputs = img_input
    # Create model.
    model = Model(inputs, x, name='resnet50')

    # load weights
    if weights == 'imagenet':
        if include_top:
            weights_path = get_file(
                'resnet50_weights_tf_dim_ordering_tf_kernels.h5',
                WEIGHTS_PATH,
                cache_subdir='models',
                md5_hash='a7b3fe01876f51b976af0dea6bc144eb')
        else:
            weights_path = get_file(
                'resnet50_weights_tf_dim_ordering_tf_kernels_notop.h5',
                WEIGHTS_PATH_NO_TOP,
                cache_subdir='models',
                md5_hash='a268eb855778b3df3c7506639542a6af')
        model.load_weights(weights_path, by_name=True)
    return model
Пример #6
0
class PolicyNet():
    """policy network """
    def __init__(self,
                 board_width,
                 board_height,
                 model_file=None,
                 pretrained_file=None):
        self.board_width = board_width
        self.board_height = board_height
        self.l2_const = 1e-4  # coef of l2 penalty
        self.build_net()
        self._loss_train_op(0.001)

        if model_file:
            self.model.load_weights(model_file)
        if pretrained_file:
            self.model.load_weights(pretrained_file, by_name=True)

    def build_net(self):
        """create the policy value network """
        in_x = network = Input((2, self.board_width, self.board_height))

        # conv layers
        network = Conv2D(filters=32,
                         kernel_size=(3, 3),
                         padding="same",
                         data_format="channels_first",
                         activation="relu",
                         kernel_regularizer=l2(self.l2_const))(network)
        network = Conv2D(filters=64,
                         kernel_size=(3, 3),
                         padding="same",
                         data_format="channels_first",
                         activation="relu",
                         kernel_regularizer=l2(self.l2_const))(network)
        network = Conv2D(filters=128,
                         kernel_size=(3, 3),
                         padding="same",
                         data_format="channels_first",
                         activation="relu",
                         kernel_regularizer=l2(self.l2_const))(network)
        # action policy layers
        policy_net = Conv2D(filters=4,
                            kernel_size=(1, 1),
                            data_format="channels_first",
                            activation="relu",
                            kernel_regularizer=l2(self.l2_const))(network)
        policy_net = Flatten()(policy_net)
        self.policy_net = Dense(self.board_width * self.board_height,
                                activation="softmax",
                                kernel_regularizer=l2(
                                    self.l2_const))(policy_net)

        self.model = Model(in_x, self.policy_net)

        def policy_value(state_input):
            state_input_union = np.array(state_input)
            results = self.model.predict_on_batch(state_input_union)
            return results

        self.policy_value = policy_value

    def policy_fn(self, board):
        """
        input: board
        output: a list of (action, probability) tuples for each available action and the score of the board state
        """
        legal_positions = board.availables
        current_state = board.current_state()
        act_probs = self.policy_value(
            current_state.reshape(
                (-1, 2, self.board_width, self.board_height)))
        act_probs = list(
            zip(legal_positions,
                act_probs.flatten()[legal_positions]))
        return act_probs

    def _loss_train_op(self, initial_learning_rate):
        """
        Three loss terms:
        loss = (z - v)^2 + pi^T * log(p) + c||theta||^2
        """

        # get the train op
        # opt = Adam()
        self.session = K.get_session()
        global_step = tf.Variable(0, trainable=False)
        lr = tf.train.exponential_decay(initial_learning_rate, global_step,
                                        10000, 0.95, True)
        opt = tf.train.AdamOptimizer(learning_rate=lr)
        one_hot_move_ph = tf.placeholder(
            tf.float32, (None, self.board_width * self.board_height), "moves")
        reward_ph = tf.placeholder(tf.float32, (None, ), "rewards")

        def self_entropy(probs):
            return -np.mean(np.sum(probs * np.log(probs + 1e-10), axis=1))

        def loss_op():

            objective = tf.log(tf.nn.softmax(self.model.output[0],
                                             axis=-1)) * one_hot_move_ph
            objective = tf.reduce_sum(objective, axis=-1, keepdims=False)
            objective = objective * reward_ph
            return -1 * objective

        self.loss_op = loss_op()
        self.minimize_op = opt.minimize(self.loss_op, global_step=global_step)

        def train_step(states, reward, moves):
            np_state_input = np.array(states)

            np_reward = np.array(reward)
            np_moves = np.eye(self.board_height *
                              self.board_width)[np.array(moves)]

            # K.set_value(self.model.optimizer.lr, learning_rate)

            # loss = self.model.train_on_batch(np_state_input, [np_winner])
            feed_dict = {
                self.model.input: np_state_input,
                one_hot_move_ph: np_moves,
                reward_ph: np_reward
            }
            _, loss, new_probs = self.session.run(
                [self.minimize_op, self.loss_op, self.model.output], feed_dict)
            entropy = self_entropy(new_probs)
            return loss, entropy

        self.train_step = train_step

    def get_policy_param(self):
        net_params = self.model.get_weights()
        return net_params

    def save_model(self, model_path):
        """ save model params to file """
        # net_params = self.get_policy_param()
        # pickle.dump(net_params, open(model_file, 'wb'), protocol=2)
        self.model.save_weights(model_path)

    def load_model(self, model_path):
        self.model.load_weights(model_path)
Пример #7
0
class CombinedAnalysisModel(object):
    model = None

    def __init__(self,
                 dim_input_x1,
                 time_step_x1,
                 dim_input_x2,
                 time_step_x2,
                 batch_size=1,
                 model_path=None,
                 fa_model_path=None,
                 ta_model_path=None):
        self.model_path = model_path
        self.fa_model_path = fa_model_path
        self.ta_model_path = ta_model_path
        self.batch_size = batch_size
        self.dim_input_x1 = dim_input_x1
        self.time_step_x1 = time_step_x1
        self.dim_input_x2 = dim_input_x2
        self.time_step_x2 = time_step_x2
        self.build()
        self.weight_loaded = False
        self.load_weights()

    def build(self):
        news_input = Input(shape=(self.time_step_x1, self.dim_input_x1),
                           name='x1')
        financial_time_series_input = Input(shape=(self.time_step_x2,
                                                   self.dim_input_x2),
                                            name='x2')
        lstm = LSTM(output_dim=nb_hidden_units,
                    dropout_U=dropout,
                    dropout_W=dropout,
                    W_regularizer=l2(l2_norm_alpha),
                    b_regularizer=l2(l2_norm_alpha),
                    activation='tanh',
                    name='h1',
                    trainable=False)
        bi_lstm = Bidirectional(lstm,
                                input_shape=(self.time_step_x1,
                                             self.dim_input_x1),
                                merge_mode='concat',
                                name='h1',
                                trainable=False)
        h1 = bi_lstm(news_input)

        lstm_layer_1 = LSTM(output_dim=nb_hidden_units,
                            dropout_U=dropout,
                            dropout_W=dropout,
                            W_regularizer=l2(l2_norm_alpha),
                            b_regularizer=l2(l2_norm_alpha),
                            activation='tanh',
                            return_sequences=True,
                            name='lstm_layer1',
                            trainable=False)
        lstm_layer_23 = LSTM(output_dim=nb_hidden_units,
                             dropout_U=dropout,
                             dropout_W=dropout,
                             W_regularizer=l2(l2_norm_alpha),
                             b_regularizer=l2(l2_norm_alpha),
                             activation='tanh',
                             return_sequences=False,
                             name='lstm_layer2_loss3',
                             trainable=False)
        h2_layer_1 = lstm_layer_1(financial_time_series_input)
        h2_layer_2 = lstm_layer_23(h2_layer_1)
        h_3 = Merge(mode='concat', name='h3')([h1, h2_layer_2])
        h_4 = Dense(nb_hidden_units, name='h4')(h_3)
        prediction = Dense(1, name='y3')(h_4)
        self.model = Model(input=[news_input, financial_time_series_input],
                           output=prediction,
                           name='combined model for financial analysis')
        plot(self.model, to_file='model.png')

    def reset(self):
        for l in self.model.layers:
            if type(l) is LSTM:
                l.reset_status()

    def compile_model(self, lr=0.0001, loss_weights=0.1):
        optimizer = Adam(lr=lr)
        loss = 'mse'
        # loss = custom_objective
        self.model.compile(optimizer=optimizer, loss=loss)

    def fit_model(self,
                  X1,
                  X2,
                  y,
                  X1_val=None,
                  X2_val=None,
                  y_val=None,
                  epoch=50):
        early_stopping = EarlyStopping(monitor='val_loss',
                                       patience=3,
                                       verbose=0)
        if X1_val is None:
            self.model.fit([X1, X2],
                           y,
                           batch_size=self.batch_size,
                           nb_epoch=epoch,
                           validation_split=0.2,
                           shuffle=True,
                           callbacks=[early_stopping])
        else:
            self.model.fit([X1, X2],
                           y,
                           batch_size=self.batch_size,
                           nb_epoch=epoch,
                           validation_data=([X1_val, X2_val], y_val),
                           shuffle=True,
                           callbacks=[early_stopping])

    def save(self):
        self.model.save_weights(self.model_path, overwrite=True)

    def load_weights(self):
        if self.model_path is not None and os.path.exists(self.model_path):
            self.model.load_weights(self.model_path)
            self.weight_loaded = True
        if self.ta_model_path is not None and os.path.exists(
                self.ta_model_path):
            self.model.load_weights(self.ta_model_path, by_name=True)
        if self.fa_model_path is not None and os.path.exists(
                self.fa_model_path):
            self.model.load_weights(self.fa_model_path, by_name=True)

    def print_weights(self, weights=None, detail=False):
        weights = weights or self.model.get_weights()
        for w in weights:
            print("w%s: sum(w)=%s, ave(w)=%s" %
                  (w.shape, np.sum(w), np.average(w)))
        if detail:
            for w in weights:
                print("%s: %s" % (w.shape, w))

    def model_eval(self, X1, X2, y):
        y_hat = self.model.predict([X1, X2], batch_size=1)
        count_true = 0
        count_all = y.shape[0]
        for i in range(y.shape[0]):
            count_true = count_true + 1 if y[i, 0] * y_hat[
                i, 0] > 0 else count_true
            print y[i, 0], y_hat[i, 0]
        print count_all, count_true
class FinancialTimeSeriesAnalysisModel(object):
    model = None

    def __init__(self, nb_time_step, dim_data, batch_size=1, model_path=None):
        self.model_path = model_path
        self.model_path = model_path
        self.batch_size = batch_size
        self.size_of_input_data_dim = dim_data
        self.size_of_input_timesteps = nb_time_step
        self.build()
        self.weight_loaded = False
        if model_path is not None:
            self.load_weights()

    def build(self):
        dim_data = self.size_of_input_data_dim
        nb_time_step = self.size_of_input_timesteps
        financial_time_series_input = Input(shape=(nb_time_step, dim_data))

        lstm_layer_1 = LSTM(output_dim=nb_hidden_units,
                            dropout_U=dropout,
                            dropout_W=dropout,
                            inner_activation='sigmoid',
                            W_regularizer=l2(l2_norm_alpha),
                            b_regularizer=l2(l2_norm_alpha),
                            activation='tanh',
                            return_sequences=True)
        lstm_layer_2 = LSTM(output_dim=nb_hidden_units,
                            dropout_U=dropout,
                            dropout_W=dropout,
                            inner_activation='sigmoid',
                            W_regularizer=l2(l2_norm_alpha),
                            b_regularizer=l2(l2_norm_alpha),
                            activation='tanh',
                            return_sequences=True)

        h1 = lstm_layer_1(financial_time_series_input)
        h2 = lstm_layer_2(h1)
        time_series_predictions = TimeDistributedDense(1)(h2)
        self.model = Model(
            financial_time_series_input,
            time_series_predictions,
            name="deep rnn for financial time series forecasting")

    def reset(self):
        for l in self.model.layers:
            if type(l) is LSTM:
                l.reset_status()

    def compile_model(self, lr=0.0001, arg_weight=1.):
        optimizer = Adam(lr=lr)
        loss = 'mse'
        self.model.compile(optimizer=optimizer, loss=loss)

    def fit_model(self, X, y, X_val=None, y_val=None, epoch=3):
        early_stopping = EarlyStopping(monitor='val_loss',
                                       patience=3,
                                       verbose=0)
        if X_val is None:
            self.model.fit(X,
                           y,
                           batch_size=self.batch_size,
                           nb_epoch=epoch,
                           validation_split=0.2,
                           shuffle=True,
                           callbacks=[early_stopping])
        else:
            self.model.fit(X,
                           y,
                           batch_size=self.batch_size,
                           nb_epoch=epoch,
                           validation_data=(X_val, y_val),
                           shuffle=True,
                           callbacks=[early_stopping])

    def save(self):
        self.model.save_weights(self.model_path, overwrite=True)

    def load_weights(self):
        if os.path.exists(self.model_path):
            self.model.load_weights(self.model_path)
            self.weight_loaded = True

    def print_weights(self, weights=None, detail=False):
        weights = weights or self.model.get_weights()
        for w in weights:
            print("w%s: sum(w)=%s, ave(w)=%s" %
                  (w.shape, np.sum(w), np.average(w)))
        if detail:
            for w in weights:
                print("%s: %s" % (w.shape, w))

    def model_eval(self, X, y):
        y_hat = self.model.predict(X, batch_size=1)
        count_true = 0
        count_all = y.shape[1]
        for i in range(y.shape[1]):
            count_true = count_true + 1 if y[0, i, 0] * y_hat[
                0, i, 0] > 0 else count_true
            print(y[0, i, 0], y_hat[0, i, 0])
        print(count_all, count_true)
Пример #9
0
class AdditionNPIModel(NPIStep):
    model = None
    f_enc = None

    def __init__(self, system: RuntimeSystem, model_path: str=None, program_set: AdditionProgramSet=None):
        self.system = system
        self.model_path = model_path
        self.program_set = program_set
        self.batch_size = 1
        self.build()
        self.weight_loaded = False
        self.load_weights()

    def build(self):
        enc_size = self.size_of_env_observation()
        argument_size = IntegerArguments.size_of_arguments
        input_enc = InputLayer(batch_input_shape=(self.batch_size, enc_size), name='input_enc')
        input_arg = InputLayer(batch_input_shape=(self.batch_size, argument_size), name='input_arg')
        input_prg = Embedding(input_dim=PROGRAM_VEC_SIZE, output_dim=PROGRAM_KEY_VEC_SIZE, input_length=1,
                              batch_input_shape=(self.batch_size, 1))

        f_enc = Sequential(name='f_enc')
        f_enc.add(Merge([input_enc, input_arg], mode='concat'))
        f_enc.add(Dense(256))
        f_enc.add(Dense(32))
        f_enc.add(Activation('relu', name='relu_enc'))
        self.f_enc = f_enc

        program_embedding = Sequential(name='program_embedding')
        program_embedding.add(input_prg)

        f_enc_convert = Sequential(name='f_enc_convert')
        f_enc_convert.add(f_enc)
        f_enc_convert.add(RepeatVector(1))

        f_lstm = Sequential(name='f_lstm')
        f_lstm.add(Merge([f_enc_convert, program_embedding], mode='concat'))
        # f_lstm.add(Activation('relu', name='relu_lstm_0'))
        f_lstm.add(LSTM(256, return_sequences=False, stateful=True))
        f_lstm.add(Activation('relu', name='relu_lstm_1'))
        f_lstm.add(RepeatVector(1))
        f_lstm.add(LSTM(256, return_sequences=False, stateful=True))
        f_lstm.add(Activation('relu', name='relu_lstm_2'))
        # plot(f_lstm, to_file='f_lstm.png', show_shapes=True)

        f_end = Sequential(name='f_end')
        f_end.add(f_lstm)
        f_end.add(Dense(10))
        f_end.add(Dense(1))
        f_end.add(Activation('hard_sigmoid', name='hard_sigmoid_end'))
        # plot(f_end, to_file='f_end.png', show_shapes=True)

        f_prog = Sequential(name='f_prog')
        f_prog.add(f_lstm)
        f_prog.add(Dense(PROGRAM_KEY_VEC_SIZE))
        f_prog.add(Dense(PROGRAM_VEC_SIZE))
        f_prog.add(Activation('softmax', name='softmax_prog'))
        # plot(f_prog, to_file='f_prog.png', show_shapes=True)

        f_args = []
        for ai in range(1, IntegerArguments.max_arg_num+1):
            f_arg = Sequential(name='f_arg%s' % ai)
            f_arg.add(f_lstm)
            f_arg.add(Dense(32))
            f_arg.add(Dense(IntegerArguments.depth))
            f_arg.add(Activation('softmax', name='softmax_arg%s' % ai))
            f_args.append(f_arg)
        # plot(f_arg, to_file='f_arg.png', show_shapes=True)

        self.model = Model([input_enc.input, input_arg.input, input_prg.input],
                           [f_end.output, f_prog.output] + [fa.output for fa in f_args],
                           name="npi")
        self.compile_model()
        plot(self.model, to_file='model.png', show_shapes=True)

    def reset(self):
        super(AdditionNPIModel, self).reset()
        for l in self.model.layers:
            if type(l) is LSTM:
                l.reset_states()

    def compile_model(self, lr=0.0001, arg_weight=1.):
        arg_num = IntegerArguments.max_arg_num
        optimizer = Adam(lr=lr)
        loss = ['binary_crossentropy', 'categorical_crossentropy'] + ['categorical_crossentropy'] * arg_num
        self.model.compile(optimizer=optimizer, loss=loss, loss_weights=[0.25, 0.25] + [arg_weight] * arg_num)

    def fit(self, steps_list, epoch=3000):
        """

        :param int epoch:
        :param typing.List[typing.Dict[q=dict, steps=typing.List[StepInOut]]] steps_list:
        :return:
        """

        def filter_question(condition_func):
            sub_steps_list = []
            for steps_dict in steps_list:
                question = steps_dict['q']
                if condition_func(question['in1'], question['in2']):
                    sub_steps_list.append(steps_dict)
            return sub_steps_list

        # self.print_weights()
        if not self.weight_loaded:
            self.train_f_enc(filter_question(lambda a, b: 10 <= a < 100 and 10 <= b < 100), epoch=100)
        self.f_enc.trainable = False

        q_type = "training questions of a+b < 10"
        print(q_type)
        pr = 0.8
        all_ok = self.fit_to_subset(filter_question(lambda a, b: a+b < 10), epoch=epoch, pass_rate=pr)
        print("%s is pass_rate >= %s: %s" % (q_type, pr, all_ok))

        q_type = "training questions of a<10 and b< 10 and 10 <= a+b"
        print(q_type)
        pr = 0.8
        all_ok = self.fit_to_subset(filter_question(lambda a, b: a<10 and b<10 and a + b >= 10), epoch=epoch, pass_rate=pr)
        print("%s is pass_rate >= %s: %s" % (q_type, pr, all_ok))

        q_type = "training questions of a<10 and b<10"
        print(q_type)
        pr = 0.8
        all_ok = self.fit_to_subset(filter_question(lambda a, b: a < 10 and b < 10), epoch=epoch, pass_rate=pr)
        print("%s is pass_rate >= %s: %s" % (q_type, pr, all_ok))

        q_type = "training questions of a<100 and b<100"
        print(q_type)
        pr = 0.8
        all_ok = self.fit_to_subset(filter_question(lambda a, b: a < 100 and b < 100), epoch=epoch, pass_rate=pr)
        print("%s is pass_rate >= %s: %s" % (q_type, pr, all_ok))

        while True:
            print("test all type of questions")
            cc, wc = self.test_to_subset(create_questions(1000))
            print("Accuracy %s(OK=%d, NG=%d)" % (cc/(cc+wc), cc, wc))
            if wc == 0:
                break

            q_type = "training questions of ALL"
            print(q_type)
            pr = 1.0
            self.fit_to_subset(filter_question(lambda a, b: True), epoch=epoch, pass_rate=pr)
            all_ok = self.fit_to_subset(filter_question(lambda a, b: True), epoch=epoch, pass_rate=pr, skip_correct=True)
            print("%s is pass_rate >= %s: %s" % (q_type, pr, all_ok))

    def fit_to_subset(self, steps_list, epoch=3000, pass_rate=1.0, skip_correct=False):
        learning_rate = 0.0001
        for i in range(30):
            all_ok = self.do_learn(steps_list, 30, learning_rate=learning_rate, pass_rate=pass_rate, arg_weight=1.,
                                   skip_correct=skip_correct)
            if all_ok:
                return True
            learning_rate *= 0.95
        return False

    def test_to_subset(self, questions):
        addition_env = AdditionEnv(FIELD_ROW, FIELD_WIDTH, FIELD_DEPTH)
        npi_runner = TerminalNPIRunner(None, self)
        correct_count = wrong_count = 0
        for idx, question in enumerate(questions):
            question = copy(question)
            if self.question_test(addition_env, npi_runner, question):
                correct_count += 1
            else:
                wrong_count += 1
        return correct_count, wrong_count

    @staticmethod
    def dict_to_str(d):
        return str(tuple([(k, d[k]) for k in sorted(d)]))

    def do_learn(self, steps_list, epoch, learning_rate=None, pass_rate=1.0, arg_weight=1., skip_correct=False):
        if learning_rate is not None:
            self.update_learning_rate(learning_rate, arg_weight)
        addition_env = AdditionEnv(FIELD_ROW, FIELD_WIDTH, FIELD_DEPTH)
        npi_runner = TerminalNPIRunner(None, self)
        last_weights = None
        correct_count = Counter()
        no_change_count = 0
        last_loss = 1000
        for ep in range(1, epoch+1):
            correct_new = wrong_new = 0
            losses = []
            ok_rate = []
            np.random.shuffle(steps_list)
            for idx, steps_dict in enumerate(steps_list):
                question = copy(steps_dict['q'])
                question_key = self.dict_to_str(question)
                if self.question_test(addition_env, npi_runner, question):
                    if correct_count[question_key] == 0:
                        correct_new += 1
                    correct_count[question_key] += 1
                    print("GOOD!: ep=%2d idx=%3d :%s CorrectCount=%s" % (ep, idx, self.dict_to_str(question), correct_count[question_key]))
                    ok_rate.append(1)
                    if skip_correct or int(math.sqrt(correct_count[question_key])) ** 2 != correct_count[question_key]:
                        continue
                else:
                    ok_rate.append(0)
                    if correct_count[question_key] > 0:
                        print("Degraded: ep=%2d idx=%3d :%s CorrectCount=%s -> 0" % (ep, idx, self.dict_to_str(question), correct_count[question_key]))
                        correct_count[question_key] = 0
                        wrong_new += 1

                steps = steps_dict['steps']
                xs = []
                ys = []
                ws = []
                for step in steps:
                    xs.append(self.convert_input(step.input))
                    y, w = self.convert_output(step.output)
                    ys.append(y)
                    ws.append(w)

                self.reset()

                for i, (x, y, w) in enumerate(zip(xs, ys, ws)):
                    loss = self.model.train_on_batch(x, y, sample_weight=w)
                    if not np.isfinite(loss):
                        print("Loss is not finite!, Last Input=%s" % ([i, (x, y, w)]))
                        self.print_weights(last_weights, detail=True)
                        raise RuntimeError("Loss is not finite!")
                    losses.append(loss)
                    last_weights = self.model.get_weights()
            if losses:
                cur_loss = np.average(losses)
                print("ep=%2d: ok_rate=%.2f%% (+%s -%s): ave loss %s (%s samples)" %
                      (ep, np.average(ok_rate)*100, correct_new, wrong_new, cur_loss, len(steps_list)))
                # self.print_weights()
                if correct_new + wrong_new == 0:
                    no_change_count += 1
                else:
                    no_change_count = 0

                if math.fabs(1 - cur_loss/last_loss) < 0.001 and no_change_count > 5:
                    print("math.fabs(1 - cur_loss/last_loss) < 0.001 and no_change_count > 5:")
                    return False
                last_loss = cur_loss
                print("=" * 80)
            self.save()
            if np.average(ok_rate) >= pass_rate:
                return True
        return False

    def update_learning_rate(self, learning_rate, arg_weight=1.):
        print("Re-Compile Model lr=%s aw=%s" % (learning_rate, arg_weight))
        self.compile_model(learning_rate, arg_weight=arg_weight)

    def train_f_enc(self, steps_list, epoch=50):
        print("training f_enc")
        f_add0 = Sequential(name='f_add0')
        f_add0.add(self.f_enc)
        f_add0.add(Dense(FIELD_DEPTH))
        f_add0.add(Activation('softmax', name='softmax_add0'))

        f_add1 = Sequential(name='f_add1')
        f_add1.add(self.f_enc)
        f_add1.add(Dense(FIELD_DEPTH))
        f_add1.add(Activation('softmax', name='softmax_add1'))

        env_model = Model(self.f_enc.inputs, [f_add0.output, f_add1.output], name="env_model")
        env_model.compile(optimizer='adam', loss=['categorical_crossentropy']*2)

        for ep in range(epoch):
            losses = []
            for idx, steps_dict in enumerate(steps_list):
                prev = None
                for step in steps_dict['steps']:
                    x = self.convert_input(step.input)[:2]
                    env_values = step.input.env.reshape((4, -1))
                    in1 = np.clip(env_values[0].argmax() - 1, 0, 9)
                    in2 = np.clip(env_values[1].argmax() - 1, 0, 9)
                    carry = np.clip(env_values[2].argmax() - 1, 0, 9)
                    y_num = in1 + in2 + carry
                    now = (in1, in2, carry)
                    if prev == now:
                        continue
                    prev = now
                    y0 = to_one_hot_array((y_num %  10)+1, FIELD_DEPTH)
                    y1 = to_one_hot_array((y_num // 10)+1, FIELD_DEPTH)
                    y = [yy.reshape((self.batch_size, -1)) for yy in [y0, y1]]
                    loss = env_model.train_on_batch(x, y)
                    losses.append(loss)
            print("ep %3d: loss=%s" % (ep, np.average(losses)))

    def question_test(self, addition_env, npi_runner, question):
        addition_env.reset()
        self.reset()
        try:
            run_npi(addition_env, npi_runner, self.program_set.ADD, question)
            if question['correct']:
                return True
        except StopIteration:
            pass
        return False

    def convert_input(self, p_in: StepInput):
        x_pg = np.array((p_in.program.program_id,))
        x = [xx.reshape((self.batch_size, -1)) for xx in (p_in.env, p_in.arguments.values, x_pg)]
        return x

    def convert_output(self, p_out: StepOutput):
        y = [np.array((p_out.r,))]
        weights = [[1.]]
        if p_out.program:
            arg_values = p_out.arguments.values
            arg_num = len(p_out.program.args or [])
            y += [p_out.program.to_one_hot(PROGRAM_VEC_SIZE)]
            weights += [[1.]]
        else:
            arg_values = IntegerArguments().values
            arg_num = 0
            y += [np.zeros((PROGRAM_VEC_SIZE, ))]
            weights += [[1e-10]]

        for v in arg_values:  # split by each args
            y += [v]
        weights += [[1.]] * arg_num + [[1e-10]] * (len(arg_values) - arg_num)
        weights = [np.array(w) for w in weights]
        return [yy.reshape((self.batch_size, -1)) for yy in y], weights

    def step(self, env_observation: np.ndarray, pg: Program, arguments: IntegerArguments) -> StepOutput:
        x = self.convert_input(StepInput(env_observation, pg, arguments))
        results = self.model.predict(x, batch_size=1)  # if batch_size==1, returns single row

        r, pg_one_hot, arg_values = results[0], results[1], results[2:]
        program = self.program_set.get(pg_one_hot.argmax())
        ret = StepOutput(r, program, IntegerArguments(values=np.stack(arg_values)))
        return ret

    def save(self):
        self.model.save_weights(self.model_path, overwrite=True)

    def load_weights(self):
        if os.path.exists(self.model_path):
            self.model.load_weights(self.model_path)
            self.weight_loaded = True

    def print_weights(self, weights=None, detail=False):
        weights = weights or self.model.get_weights()
        for w in weights:
            print("w%s: sum(w)=%s, ave(w)=%s" % (w.shape, np.sum(w), np.average(w)))
        if detail:
            for w in weights:
                print("%s: %s" % (w.shape, w))

    @staticmethod
    def size_of_env_observation():
        return FIELD_ROW * FIELD_DEPTH
class FinancialTimeSeriesAnalysisModel(object):
    model = None

    def __init__(self, nb_time_step, dim_data, batch_size=1, model_path=None):
        self.model_path = model_path
        self.model_path = model_path
        self.batch_size = batch_size
        self.size_of_input_data_dim = dim_data
        self.size_of_input_timesteps = nb_time_step
        self.build()
        self.weight_loaded = False
        if model_path is not None:
            self.load_weights()

    def build(self):
        dim_data = self.size_of_input_data_dim
        nb_time_step = self.size_of_input_timesteps
        financial_time_series_input = Input(shape=(nb_time_step, dim_data),
                                            name='x1')
        lstm_layer_1 = LSTM(output_dim=nb_hidden_units,
                            dropout_U=dropout,
                            dropout_W=dropout,
                            W_regularizer=l2(l2_norm_alpha),
                            b_regularizer=l2(l2_norm_alpha),
                            activation='tanh',
                            return_sequences=True,
                            name='lstm_layer1')
        lstm_layer_21 = LSTM(output_dim=nb_hidden_units,
                             dropout_U=dropout,
                             dropout_W=dropout,
                             W_regularizer=l2(l2_norm_alpha),
                             b_regularizer=l2(l2_norm_alpha),
                             activation='tanh',
                             return_sequences=True,
                             name='lstm_layer2_loss1')
        lstm_layer_22 = LSTM(output_dim=nb_hidden_units,
                             dropout_U=dropout,
                             dropout_W=dropout,
                             W_regularizer=l2(l2_norm_alpha),
                             b_regularizer=l2(l2_norm_alpha),
                             activation='tanh',
                             return_sequences=True,
                             name='lstm_layer2_loss2')
        lstm_layer_23 = LSTM(output_dim=nb_hidden_units,
                             dropout_U=dropout,
                             dropout_W=dropout,
                             W_regularizer=l2(l2_norm_alpha),
                             b_regularizer=l2(l2_norm_alpha),
                             activation='tanh',
                             return_sequences=True,
                             name='lstm_layer2_loss3')

        lstm_layer_24 = LSTM(output_dim=nb_hidden_units,
                             dropout_U=dropout,
                             dropout_W=dropout,
                             W_regularizer=l2(l2_norm_alpha),
                             b_regularizer=l2(l2_norm_alpha),
                             activation='tanh',
                             return_sequences=True,
                             name='lstm_layer2_loss4')

        lstm_layer_25 = LSTM(output_dim=nb_hidden_units,
                             dropout_U=dropout,
                             dropout_W=dropout,
                             W_regularizer=l2(l2_norm_alpha),
                             b_regularizer=l2(l2_norm_alpha),
                             activation='tanh',
                             return_sequences=True,
                             name='lstm_layer2_loss5')
        h1 = lstm_layer_1(financial_time_series_input)
        h21 = lstm_layer_21(h1)
        h22 = lstm_layer_22(h1)
        h23 = lstm_layer_23(h1)
        h24 = lstm_layer_24(h1)
        h25 = lstm_layer_25(h1)
        time_series_predictions1 = TimeDistributed(Dense(1),
                                                   name="p1")(h21)  # custom 1
        time_series_predictions2 = TimeDistributed(Dense(1),
                                                   name="p2")(h22)  # custom 2
        time_series_predictions3 = TimeDistributed(Dense(1),
                                                   name="p3")(h23)  # mse
        time_series_predictions4 = TimeDistributed(Dense(1,
                                                         activation='sigmoid'),
                                                   name="p4")(h24)  # logloss
        time_series_predictions5 = TimeDistributed(Dense(nb_labels,
                                                         activation='softmax'),
                                                   name="p5")(h25)  # cross
        self.model = Model(
            input=financial_time_series_input,
            output=[
                time_series_predictions1, time_series_predictions2,
                time_series_predictions3, time_series_predictions4,
                time_series_predictions5
            ],
            name="multi-task deep rnn for financial time series forecasting")
        plot(self.model, to_file='model.png')

    def reset(self):
        for l in self.model.layers:
            if type(l) is LSTM:
                l.reset_status()

    def compile_model(self, lr=0.0001, arg_weight=1.):
        optimizer = Adam(lr=lr)
        loss = [
            custom_objective1, custom_objective2, 'mse', 'binary_crossentropy',
            'categorical_crossentropy'
        ]
        self.model.compile(optimizer=optimizer, loss=loss)

    def fit_model(self, X, y, y_label, epoch=300):
        early_stopping = EarlyStopping(monitor='val_loss',
                                       patience=3,
                                       verbose=0)

        self.model.fit(X, [y] * 3 + [y > 0] + [y_label],
                       batch_size=self.batch_size,
                       nb_epoch=epoch,
                       validation_split=0.3,
                       shuffle=True,
                       callbacks=[early_stopping])

    def save(self):
        self.model.save_weights(self.model_path, overwrite=True)

    def load_weights(self):
        if os.path.exists(self.model_path):
            self.model.load_weights(self.model_path)
            self.weight_loaded = True

    def print_weights(self, weights=None, detail=False):
        weights = weights or self.model.get_weights()
        for w in weights:
            print("w%s: sum(w)=%s, ave(w)=%s" %
                  (w.shape, np.sum(w), np.average(w)))
        if detail:
            for w in weights:
                print("%s: %s" % (w.shape, w))

    def model_eval(self, X, y):
        y_hat = self.model.predict(X, batch_size=1)[0]
        count_true = 0
        count_all = y.shape[1]
        for i in range(y.shape[1]):
            count_true = count_true + 1 if y[0, i, 0] * y_hat[
                0, i, 0] > 0 else count_true
            print(y[0, i, 0], y_hat[0, i, 0])
        print(count_all, count_true)
Пример #11
0
def build_CNN_model(inputType,
                    do_training=False,
                    model_inputs=None,
                    loss_func='binary_crossentropy',
                    optimize_proc='adam',
                    is_IntermediateModel=False,
                    load_weight_path=None,
                    **kwargs):
    """

    :param inputType:
    :param do_training:
    :param model_inputs:
    :param loss_func:
    :param optimize_proc:
    :param is_IntermediateModel:
    :param load_weight_path:
    :param kwargs:
    :return:
    """

    # assert not do_training and model_inputs, "if do_training then must pass in model_inputs dictionary"

    EMBEDDING_TYPE = 'embeddingMatrix'
    ONEHOT_TYPE = '1hotVector'

    defined_input_types = {EMBEDDING_TYPE, ONEHOT_TYPE}

    assert inputType in defined_input_types, "unknown input type {0}".format(
        inputType)

    if inputType is ONEHOT_TYPE:

        review_input = Input(shape=(modelParameters.MaxLen_w, ),
                             dtype='float32',
                             name="ONEHOT_INPUT")

        layer = Embedding(modelParameters.VocabSize_w +
                          modelParameters.INDEX_FROM,
                          embedding_dims,
                          embeddings_initializer=embedding_init,
                          embeddings_regularizer=embedding_reg,
                          input_length=modelParameters.MaxLen_w,
                          name='1hot_embeddingLayer')(review_input)

        layer = SpatialDropout1D(0.50)(layer)

    elif inputType is EMBEDDING_TYPE:
        review_input = Input(shape=(modelParameters.MaxLen_w, embedding_dims),
                             dtype="float32",
                             name="EMBEDDING_INPUT")
        layer = review_input

    else:
        raise ValueError("Bad inputType arg to build_CNN_model")

    layer = Convolution1D(filters=num_filters1,
                          kernel_size=filter_length1,
                          padding=region,
                          strides=1,
                          activation=conv_activation1,
                          kernel_initializer='glorot_uniform',
                          bias_initializer='zeros',
                          kernel_regularizer=conv_reg1,
                          dilation_rate=1,
                          name='ConvLayer1')(layer)

    layer = SpatialDropout1D(0.50)(layer)

    layer = MaxPooling1D(pool_size=pool_len1)(layer)

    # layer = Convolution1D(filters=num_filters2,
    #                       kernel_size=filter_length2,
    #                       padding=region,
    #                       strides=1,
    #                       activation=conv_activation2,
    #                       kernel_initializer=conv_init2,
    #                       kernel_regularizer=conv_reg2,
    #                       dilation_rate=1,
    #                       name='ConvLayer2')(layer)
    #
    # layer = SpatialDropout1D(0.50)(layer)
    #
    # layer = MaxPooling1D(pool_size=pool_len2)(layer)

    # layer = Convolution1D(filters=num_filters3,
    #                       kernel_size=filter_length3,
    #                       padding=region,
    #                       activation=conv_activation3,
    #                       kernel_initializer=conv_init3,
    #                       kernel_regularizer=conv_reg3,
    #                       dilation_rate=1,
    #                       name='ConvLayer3')(layer)
    #
    # layer = SpatialDropout1D(0.50)(layer)
    #
    # layer = MaxPooling1D(pool_size=pool_len3)(layer)

    # #layer = GlobalMaxPool1D()(layer)
    #
    # layer = Convolution1D(filters=num_filters4,
    #                       kernel_size=filter_length4,
    #                       padding=region,
    #                       activation=conv_activation4,
    #                       kernel_initializer=conv_init4,
    #                       kernel_regularizer=conv_reg4,
    #                       dilation_rate=1,
    #                       name='ConvLayer4')(layer)
    #
    # #layer = leaky_relu(layer)
    #
    # layer = SpatialDropout1D(0.50)(layer)
    #
    # layer = MaxPooling1D(pool_size=pool_len4)(layer)
    # #layer = GlobalMaxPool1D()(layer)
    #
    # # layer = BatchNormalization()(layer)

    layer = Flatten()(layer)

    layer = Dense(dense_dims0,
                  activation=dense_activation0,
                  kernel_regularizer=dense_reg0,
                  kernel_initializer='glorot_normal',
                  bias_initializer='zeros',
                  name='dense0')(layer)

    layer = Dropout(0.50)(layer)

    layer = Dense(dense_dims1,
                  activation=dense_activation1,
                  kernel_regularizer=dense_reg1,
                  kernel_initializer='glorot_normal',
                  bias_initializer='zeros',
                  name='dense1')(layer)

    layer = Dropout(0.50)(layer)

    # layer = Dense(dense_dims2, activation=dense_activation2, kernel_regularizer=dense_reg2,
    #               kernel_initializer=dense_init2,
    #               name='dense2')(layer)
    #
    #
    # layer = Dropout(0.50)(layer)
    #
    # layer = Dense(dense_dims3, activation=dense_activation3, kernel_regularizer=dense_reg3,
    #               kernel_initializer=dense_init3,
    #               name='dense3_outA')(layer)
    # #layer = leaky_relu(layer)
    #
    if is_IntermediateModel:
        return Model(inputs=[review_input], outputs=[layer], name="CNN_model")

    #
    # layer = Dropout(0.5)(layer)

    layer = Dense(dense_dims_final,
                  activation=dense_activation_final,
                  kernel_initializer=dense_init_final,
                  kernel_regularizer=dense_reg0,
                  name='output_Full')(layer)

    CNN_model = Model(inputs=[review_input], outputs=[layer], name="CNN_model")

    CNN_model.compile(optimizer=Adam(lr=0.001, decay=0.0),
                      loss=loss_func,
                      metrics=[binary_accuracy])

    if load_weight_path is not None:
        CNN_model.load_weights(load_weight_path)

    hist = ""
    if do_training:
        weightPath = os.path.join(modelParameters.WEIGHT_PATH, filename)
        configPath = os.path.join(modelParameters.WEIGHT_PATH, filename_config)

        with open(configPath + ".json", 'wb') as f:
            f.write(CNN_model.to_json())

        checkpoint = ModelCheckpoint(weightPath +
                                     '_W.{epoch:02d}-{val_loss:.4f}.hdf5',
                                     verbose=1,
                                     save_best_only=True,
                                     save_weights_only=False,
                                     monitor='val_loss')

        earlyStop = EarlyStopping(patience=3, verbose=1, monitor='val_loss')

        LRadjuster = ReduceLROnPlateau(monitor='val_loss',
                                       factor=0.30,
                                       patience=0,
                                       verbose=1,
                                       cooldown=1,
                                       min_lr=0.00001,
                                       epsilon=1e-2)

        call_backs = [checkpoint, earlyStop, LRadjuster]

        CNN_model.summary()

        hist = CNN_model.fit(*model_inputs['training'],
                             batch_size=batch_size,
                             epochs=nb_epoch,
                             verbose=1,
                             validation_data=model_inputs['dev'],
                             callbacks=call_backs)

    return {"model": CNN_model, "hist": hist}
Пример #12
0
class ChessModel:
    def __init__(self, config: Config):
        self.config = config
        self.model = None  # type: Model
        self.graph = None
        self.digest = None
        self.api = None

    def get_pipes(self, num=1):
        if self.api is None:
            self.api = ChessModelAPI(self)
            self.api.start()
        return [self.api.get_pipe() for _ in range(num)]

    def build(self):
        mc = self.config.model
        in_x = x = Input((mc.input_stack_height, 8, 8))
        # (batch, channels, height, width)
        x = Conv2D(filters=mc.cnn_filter_num,
                   kernel_size=mc.cnn_filter_size,
                   padding="same",
                   data_format="channels_first",
                   use_bias=False,
                   kernel_initializer='glorot_normal',
                   bias_initializer='zeros',
                   kernel_regularizer=l2(mc.l2_reg),
                   input_shape=(mc.input_stack_height, 8, 8))(x)
        x = BatchNormalization(axis=1)(x)
        x = Activation("relu")(x)

        for _ in range(mc.res_layer_num):
            x = self._build_residual_block(x)

        res_out = x
        # for policy output
        x = Conv2D(filters=2,
                   kernel_size=1,
                   data_format="channels_first",
                   use_bias=False,
                   kernel_initializer='glorot_normal',
                   bias_initializer='zeros',
                   kernel_regularizer=l2(mc.l2_reg))(res_out)
        x = BatchNormalization(axis=1)(x)
        x = Activation("relu")(x)
        x = Flatten()(x)
        # no output for 'pass'
        policy_out = Dense(self.config.n_labels,
                           kernel_initializer='glorot_normal',
                           bias_initializer='zeros',
                           kernel_regularizer=l2(mc.l2_reg),
                           activation="softmax",
                           name="policy_out")(x)

        # for value output
        x = Conv2D(filters=1,
                   kernel_size=1,
                   data_format="channels_first",
                   use_bias=False,
                   kernel_initializer='glorot_normal',
                   bias_initializer='zeros',
                   kernel_regularizer=l2(mc.l2_reg))(res_out)
        x = BatchNormalization(axis=1)(x)
        x = Activation("relu")(x)
        x = Flatten()(x)
        x = Dense(mc.value_fc_size,
                  kernel_initializer='glorot_normal',
                  bias_initializer='zeros',
                  kernel_regularizer=l2(mc.l2_reg),
                  activation="relu")(x)
        value_out = Dense(1,
                          kernel_initializer='glorot_normal',
                          bias_initializer='zeros',
                          kernel_regularizer=l2(mc.l2_reg),
                          activation="tanh",
                          name="value_out")(x)

        self.model = Model(in_x, [policy_out, value_out], name="chess_model")
        self.graph = get_default_graph()

    def _build_residual_block(self, x):
        mc = self.config.model
        in_x = x
        x = Conv2D(filters=mc.cnn_filter_num,
                   kernel_size=mc.cnn_filter_size,
                   padding="same",
                   data_format="channels_first",
                   use_bias=False,
                   kernel_initializer='glorot_normal',
                   bias_initializer='zeros',
                   kernel_regularizer=l2(mc.l2_reg))(x)
        x = BatchNormalization(axis=1)(x)
        x = Activation("relu")(x)
        x = Conv2D(filters=mc.cnn_filter_num,
                   kernel_size=mc.cnn_filter_size,
                   padding="same",
                   data_format="channels_first",
                   use_bias=False,
                   kernel_initializer='glorot_normal',
                   bias_initializer='zeros',
                   kernel_regularizer=l2(mc.l2_reg))(x)
        x = BatchNormalization(axis=1)(x)
        x = Add()([in_x, x])
        x = Activation("relu")(x)
        return x

    @staticmethod
    def fetch_digest(weight_path):
        if os.path.exists(weight_path):
            m = hashlib.sha256()
            with open(weight_path, "rb") as f:
                m.update(f.read())
            return m.hexdigest()

    def load(self, config_path, weight_path):
        if os.path.exists(config_path) and os.path.exists(weight_path):
            logger.debug(f"loading model from {config_path}")
            with open(config_path, "rt") as f:
                self.model = Model.from_config(json.load(f))
            self.model.load_weights(weight_path)
            self.graph = get_default_graph()
            # self.model._make_predict_function()
            self.digest = self.fetch_digest(weight_path)
            logger.debug(f"loaded model digest = {self.digest}")
            return True
        else:
            logger.debug(
                f"model files do not exist at {config_path} and {weight_path}")
            return False

    def save(self, config_path, weight_path):
        logger.debug(f"save model to {config_path}")
        with open(config_path, "wt") as f:
            json.dump(self.model.get_config(), f)
            self.model.save_weights(weight_path)
        self.digest = self.fetch_digest(weight_path)
        logger.debug(f"saved model digest {self.digest}")
Пример #13
0
class GomokuModel:
    def __init__(self, config: Config):
        '''
        Manages the model saving and loading
        :param config: configuration settings
        '''
        self.config = config
        self.model = None  # type: Model
        self.digest = None

    def build(self, res_layers):
        '''
        Constructs the ResNet model based on number of layers
        :param res_layers: number of layers in the model
        '''
        mc = self.config.model
        in_x = x = Input((2, 8, 5))  # [own(8x8), enemy(8x8)]

        # (batch, channels, height, width)
        x = Conv2D(filters=mc.cnn_filter_num,
                   kernel_size=mc.cnn_filter_size,
                   padding="same",
                   data_format="channels_first",
                   kernel_regularizer=l2(mc.l2_reg))(x)
        x = BatchNormalization(axis=1)(x)
        x = Activation("relu")(x)

        logger.debug(f"Build Model with %d Res Blocks" % res_layers)

        #for _ in range(mc.res_layer_num):
        # build with number of res blocks
        for _ in range(res_layers):
            x = self._build_residual_block(x)

        res_out = x
        # for policy output
        x = Conv2D(filters=2,
                   kernel_size=1,
                   data_format="channels_first",
                   kernel_regularizer=l2(mc.l2_reg))(res_out)
        x = BatchNormalization(axis=1)(x)
        x = Activation("relu")(x)
        x = Flatten()(x)
        # no output for 'pass'
        policy_out = Dense(self.config.n_labels,
                           kernel_regularizer=l2(mc.l2_reg),
                           activation="softmax",
                           name="policy_out")(x)

        # for value output
        x = Conv2D(filters=1,
                   kernel_size=1,
                   data_format="channels_first",
                   kernel_regularizer=l2(mc.l2_reg))(res_out)
        x = BatchNormalization(axis=1)(x)
        x = Activation("relu")(x)
        x = Flatten()(x)
        x = Dense(mc.value_fc_size,
                  kernel_regularizer=l2(mc.l2_reg),
                  activation="relu")(x)
        value_out = Dense(1,
                          kernel_regularizer=l2(mc.l2_reg),
                          activation="tanh",
                          name="value_out")(x)

        self.model = Model(in_x, [policy_out, value_out],
                           name="connect4_model")

    def _build_residual_block(self, x):
        ''' Build a single residual block '''
        mc = self.config.model
        in_x = x
        x = Conv2D(filters=mc.cnn_filter_num,
                   kernel_size=mc.cnn_filter_size,
                   padding="same",
                   data_format="channels_first",
                   kernel_regularizer=l2(mc.l2_reg))(x)
        x = BatchNormalization(axis=1)(x)
        x = Activation("relu")(x)
        x = Conv2D(filters=mc.cnn_filter_num,
                   kernel_size=mc.cnn_filter_size,
                   padding="same",
                   data_format="channels_first",
                   kernel_regularizer=l2(mc.l2_reg))(x)
        x = BatchNormalization(axis=1)(x)
        x = Add()([in_x, x])
        x = Activation("relu")(x)
        return x

    @staticmethod
    def fetch_digest(weight_path):
        if os.path.exists(weight_path):
            m = hashlib.sha256()
            with open(weight_path, "rb") as f:
                m.update(f.read())
            return m.hexdigest()

    def load(self, config_path, weight_path):
        ''' Load model with existing weights '''

        if os.path.exists(config_path) and os.path.exists(weight_path):
            logger.debug(f"loading model from {weight_path}")
            with open(config_path, "rt") as f:
                self.model = Model.from_config(json.load(f))
            self.model.load_weights(weight_path)
            self.digest = self.fetch_digest(weight_path)
            logger.debug(f"loaded model digest = {self.digest}")
            return True
        else:
            logger.debug(
                f"model files does not exist at {config_path} and {weight_path}"
            )
            return False

    def save(self, config_path, weight_path):
        '''
        Save the model into specified path
        :param config_path: config path to save at
        :param weight_path: weight file path to save at
        '''

        logger.debug(f"save model to {weight_path}")
        with open(config_path, "wt") as f:
            json.dump(self.model.get_config(), f)
            self.model.save_weights(weight_path)
        #self.model.save(weight_path)
        self.digest = self.fetch_digest(weight_path)
        logger.debug(f"saved model digest {self.digest}")

    def update_model(self, target):
        '''
        Update the model with the target model weights
        :param target: the target model to copy from
        '''
        copy_layers = target.get_num_res_layers() * 7 + 4
        model_layers = len(self.model.layers)
        target_layers = len(target.model.layers)

        # set the weights of the previous layers
        for i in range(copy_layers):
            weight = target.model.layers[i].get_weights()
            self.model.layers[i].set_weights(weight)

        # set the weights of the layers after the res block
        for i in range(5 * 2 + 1):
            weight = target.model.layers[target_layers - i - 1].get_weights()
            self.model.layers[model_layers - i - 1].set_weights(weight)

    def get_num_res_layers(self):
        ''' Computes the number of layers in the architecture'''
        print('model layers %f' % len(self.model.layers))
        return int((len(self.model.layers) - 4 - 5 * 2 - 1) / 7)
Пример #14
0
class ChessModel:
    """
    The model which can be trained to take observations of a game of chess and return value and policy
    predictions.

    Attributes:
        :ivar Config config: configuration to use
        :ivar Model model: the Keras model to use for predictions
        :ivar digest: basically just a hash of the file containing the weights being used by this model
        :ivar ChessModelAPI api: the api to use to listen for and then return this models predictions (on a pipe).
    """
    def __init__(self, config: Config):
        self.config = config
        self.model = None  # type: Model
        self.digest = None
        self.api = None

    def get_pipes(self, num=1):
        """
        Creates a list of pipes on which observations of the game state will be listened for. Whenever
        an observation comes in, returns policy and value network predictions on that pipe.

        :param int num: number of pipes to create
        :return str(Connection): a list of all connections to the pipes that were created
        """
        if self.api is None:
            self.api = ChessModelAPI(self)
            self.api.start()
        return [self.api.create_pipe() for _ in range(num)]

    def build(self):
        """
        Builds the full Keras model and stores it in self.model.
        """
        mc = self.config.model
        in_x = x = Input((18, 8, 8))

        # (batch, channels, height, width)
        x = Conv2D(filters=mc.cnn_filter_num,
                   kernel_size=mc.cnn_first_filter_size,
                   padding="same",
                   data_format="channels_first",
                   use_bias=False,
                   kernel_regularizer=l2(mc.l2_reg),
                   name="input_conv-" + str(mc.cnn_first_filter_size) + "-" +
                   str(mc.cnn_filter_num))(x)
        x = BatchNormalization(axis=1, name="input_batchnorm")(x)
        x = Activation("relu", name="input_relu")(x)

        for i in range(mc.res_layer_num):
            x = self._build_residual_block(x, i + 1)

        res_out = x

        # for policy output
        x = Conv2D(filters=2,
                   kernel_size=1,
                   data_format="channels_first",
                   use_bias=False,
                   kernel_regularizer=l2(mc.l2_reg),
                   name="policy_conv-1-2")(res_out)
        x = BatchNormalization(axis=1, name="policy_batchnorm")(x)
        x = Activation("relu", name="policy_relu")(x)
        x = Flatten(name="policy_flatten")(x)
        # no output for 'pass'
        policy_out = Dense(self.config.n_labels,
                           kernel_regularizer=l2(mc.l2_reg),
                           activation="softmax",
                           name="policy_out")(x)

        # for value output
        x = Conv2D(filters=4,
                   kernel_size=1,
                   data_format="channels_first",
                   use_bias=False,
                   kernel_regularizer=l2(mc.l2_reg),
                   name="value_conv-1-4")(res_out)
        x = BatchNormalization(axis=1, name="value_batchnorm")(x)
        x = Activation("relu", name="value_relu")(x)
        x = Flatten(name="value_flatten")(x)
        x = Dense(mc.value_fc_size,
                  kernel_regularizer=l2(mc.l2_reg),
                  activation="relu",
                  name="value_dense")(x)
        value_out = Dense(1,
                          kernel_regularizer=l2(mc.l2_reg),
                          activation="tanh",
                          name="value_out")(x)

        self.model = Model(in_x, [policy_out, value_out], name="chess_model")

    def _build_residual_block(self, x, index):
        mc = self.config.model
        in_x = x
        res_name = "res" + str(index)
        x = Conv2D(filters=mc.cnn_filter_num,
                   kernel_size=mc.cnn_filter_size,
                   padding="same",
                   data_format="channels_first",
                   use_bias=False,
                   kernel_regularizer=l2(mc.l2_reg),
                   name=res_name + "_conv1-" + str(mc.cnn_filter_size) + "-" +
                   str(mc.cnn_filter_num))(x)
        x = BatchNormalization(axis=1, name=res_name + "_batchnorm1")(x)
        x = Activation("relu", name=res_name + "_relu1")(x)
        x = Conv2D(filters=mc.cnn_filter_num,
                   kernel_size=mc.cnn_filter_size,
                   padding="same",
                   data_format="channels_first",
                   use_bias=False,
                   kernel_regularizer=l2(mc.l2_reg),
                   name=res_name + "_conv2-" + str(mc.cnn_filter_size) + "-" +
                   str(mc.cnn_filter_num))(x)
        x = BatchNormalization(axis=1,
                               name="res" + str(index) + "_batchnorm2")(x)
        x = Add(name=res_name + "_add")([in_x, x])
        x = Activation("relu", name=res_name + "_relu2")(x)
        return x

    @staticmethod
    def fetch_digest(weight_path):
        if os.path.exists(weight_path):
            m = hashlib.sha256()
            with open(weight_path, "rb") as f:
                m.update(f.read())
            return m.hexdigest()

    def load(self, config_path, weight_path):
        """

        :param str config_path: path to the file containing the entire configuration
        :param str weight_path: path to the file containing the model weights
        :return: true iff successful in loading
        """
        mc = self.config.model
        resources = self.config.resource
        if mc.distributed and config_path == resources.model_best_config_path:
            try:
                logger.debug("loading model from server")
                ftp_connection = ftplib.FTP(
                    resources.model_best_distributed_ftp_server,
                    resources.model_best_distributed_ftp_user,
                    resources.model_best_distributed_ftp_password)
                ftp_connection.cwd(
                    resources.model_best_distributed_ftp_remote_path)
                ftp_connection.retrbinary("RETR model_best_config.json",
                                          open(config_path, 'wb').write)
                ftp_connection.retrbinary("RETR model_best_weight.h5",
                                          open(weight_path, 'wb').write)
                ftp_connection.quit()
            except:
                pass
        if os.path.exists(config_path) and os.path.exists(weight_path):
            logger.debug(f"loading model from {config_path}")
            with open(config_path, "rt") as f:
                self.model = Model.from_config(json.load(f))
            self.model.load_weights(weight_path)
            self.model._make_predict_function()
            self.digest = self.fetch_digest(weight_path)
            logger.debug(f"loaded model digest = {self.digest}")
            return True
        else:
            logger.debug(
                f"model files does not exist at {config_path} and {weight_path}"
            )
            return False

    def save(self, config_path, weight_path):
        """

        :param str config_path: path to save the entire configuration to
        :param str weight_path: path to save the model weights to
        """
        logger.debug(f"save model to {config_path}")
        with open(config_path, "wt") as f:
            json.dump(self.model.get_config(), f)
            self.model.save_weights(weight_path)
        self.digest = self.fetch_digest(weight_path)
        logger.debug(f"saved model digest {self.digest}")

        mc = self.config.model
        resources = self.config.resource
        if mc.distributed and config_path == resources.model_best_config_path:
            try:
                logger.debug("saving model to server")
                ftp_connection = ftplib.FTP(
                    resources.model_best_distributed_ftp_server,
                    resources.model_best_distributed_ftp_user,
                    resources.model_best_distributed_ftp_password)
                ftp_connection.cwd(
                    resources.model_best_distributed_ftp_remote_path)
                fh = open(config_path, 'rb')
                ftp_connection.storbinary('STOR model_best_config.json', fh)
                fh.close()

                fh = open(weight_path, 'rb')
                ftp_connection.storbinary('STOR model_best_weight.h5', fh)
                fh.close()
                ftp_connection.quit()
            except:
                pass
Пример #15
0
class CChessModel:

    def __init__(self, config: Config):
        self.config = config
        self.model = None  # type: Model
        self.digest = None
        self.n_labels = len(ActionLabelsRed)
        self.graph = None
        self.api = None

    def build(self):
        mc = self.config.model
        in_x = x = Input((14, 10, 9)) # 14 x 10 x 9

        # (batch, channels, height, width)
        x = Conv2D(filters=mc.cnn_filter_num, kernel_size=mc.cnn_first_filter_size, padding="same",
                   data_format="channels_first", use_bias=False, kernel_regularizer=l2(mc.l2_reg),
                   name="input_conv-"+str(mc.cnn_first_filter_size)+"-"+str(mc.cnn_filter_num))(x)
        x = BatchNormalization(axis=1, name="input_batchnorm")(x)
        x = Activation("relu", name="input_relu")(x)

        for i in range(mc.res_layer_num):
            x = self._build_residual_block(x, i + 1)

        res_out = x

        # for policy output
        x = Conv2D(filters=2, kernel_size=1, data_format="channels_first", use_bias=False, 
                    kernel_regularizer=l2(mc.l2_reg), name="policy_conv-1-2")(res_out)
        x = BatchNormalization(axis=1, name="policy_batchnorm")(x)
        x = Activation("relu", name="policy_relu")(x)
        x = Flatten(name="policy_flatten")(x)
        policy_out = Dense(self.n_labels, kernel_regularizer=l2(mc.l2_reg), activation="softmax", name="policy_out")(x)

        # for value output
        x = Conv2D(filters=4, kernel_size=1, data_format="channels_first", use_bias=False, 
                    kernel_regularizer=l2(mc.l2_reg), name="value_conv-1-4")(res_out)
        x = BatchNormalization(axis=1, name="value_batchnorm")(x)
        x = Activation("relu",name="value_relu")(x)
        x = Flatten(name="value_flatten")(x)
        x = Dense(mc.value_fc_size, kernel_regularizer=l2(mc.l2_reg), activation="relu", name="value_dense")(x)
        value_out = Dense(1, kernel_regularizer=l2(mc.l2_reg), activation="tanh", name="value_out")(x)

        self.model = Model(in_x, [policy_out, value_out], name="cchess_model")
        self.graph = tf.get_default_graph()

    def _build_residual_block(self, x, index):
        mc = self.config.model
        in_x = x
        res_name = "res" + str(index)
        x = Conv2D(filters=mc.cnn_filter_num, kernel_size=mc.cnn_filter_size, padding="same",
                   data_format="channels_first", use_bias=False, kernel_regularizer=l2(mc.l2_reg), 
                   name=res_name+"_conv1-"+str(mc.cnn_filter_size)+"-"+str(mc.cnn_filter_num))(x)
        x = BatchNormalization(axis=1, name=res_name+"_batchnorm1")(x)
        x = Activation("relu",name=res_name+"_relu1")(x)
        x = Conv2D(filters=mc.cnn_filter_num, kernel_size=mc.cnn_filter_size, padding="same",
                   data_format="channels_first", use_bias=False, kernel_regularizer=l2(mc.l2_reg), 
                   name=res_name+"_conv2-"+str(mc.cnn_filter_size)+"-"+str(mc.cnn_filter_num))(x)
        x = BatchNormalization(axis=1, name="res"+str(index)+"_batchnorm2")(x)
        x = Add(name=res_name+"_add")([in_x, x])
        x = Activation("relu", name=res_name+"_relu2")(x)
        return x

    @staticmethod
    def fetch_digest(weight_path):
        if os.path.exists(weight_path):
            m = hashlib.sha256()
            with open(weight_path, "rb") as f:
                m.update(f.read())
            return m.hexdigest()


    def load(self, config_path, weight_path):
        if os.path.exists(config_path) and os.path.exists(weight_path):
            logger.debug(f"loading model from {config_path}")
            with open(config_path, "rt") as f:
                self.model = Model.from_config(json.load(f))
            self.model.load_weights(weight_path)
            self.digest = self.fetch_digest(weight_path)
            self.graph = tf.get_default_graph()
            logger.debug(f"loaded model digest = {self.digest}")
            return True
        else:
            logger.debug(f"model files does not exist at {config_path} and {weight_path}")
            return False

    def save(self, config_path, weight_path):
        logger.debug(f"save model to {config_path}")
        with open(config_path, "wt") as f:
            json.dump(self.model.get_config(), f)
            self.model.save_weights(weight_path)
        self.digest = self.fetch_digest(weight_path)
        logger.debug(f"saved model digest {self.digest}")

    def get_pipes(self, num=1, api=None, need_reload=True):
        if self.api is None:
            self.api = CChessModelAPI(self.config, self)
            self.api.start()
        return self.api.get_pipe(need_reload)

    def close_pipes(self):
        if self.api is not None:
            self.api.close()
Пример #16
0
class ChessModel:
    def __init__(self, config: Config):
        self.config = config
        self.model = None  # type: Model
        self.digest = None
        self.policy_out = None
        self.value_out = None
        #self.net_params = get_policy_param()

    def build(self):
        mc = self.config.model
        in_x = x = Input((2, 8, 8))  # [own(8x8), enemy(8x8)]

        # (batch, channels, height, width)
        x = Conv2D(filters=mc.cnn_filter_num,
                   kernel_size=mc.cnn_filter_size,
                   padding='same',
                   kernel_regularizer=l2(mc.l2_reg))(x)
        x = BatchNormalization(momentum=.997, epsilon=1e-5)(x)
        x = Activation('relu')(x)

        for i in range(mc.res_layer_num):
            x = self._build_residual_block(x)

        res_out = x
        # for policy output
        x = Conv2D(filters=2, kernel_size=1,
                   kernel_regularizer=l2(mc.l2_reg))(res_out)
        x = BatchNormalization(momentum=.997, epsilon=1e-5)(x)
        x = Activation('relu')(x)
        x = Flatten()(x)
        policy_out = Dense(self.config.n_labels,
                           activation='softmax',
                           name='policy_out',
                           kernel_regularizer=l2(mc.l2_reg))(x)
        #self.value_out = Dense(1, activation='tanh', name='self.value_out')(x)

        # for value output
        x = Conv2D(filters=1, kernel_size=1,
                   kernel_regularizer=l2(mc.l2_reg))(res_out)
        x = BatchNormalization(momentum=.997, epsilon=1e-5)(x)
        x = Activation('relu')(x)
        x = Flatten()(x)
        x = Dense(mc.value_fc_size, kernel_regularizer=l2(mc.l2_reg))(x)
        x = Activation('relu')(x)
        value_out = Dense(1,
                          activation='tanh',
                          name='value_out',
                          kernel_regularizer=l2(mc.l2_reg))(x)

        self.model = Model(in_x, [policy_out, value_out], name="chess_model")

    def _build_residual_block(self, x):
        mc = self.config.model
        in_x = x

        x = Conv2D(filters=mc.cnn_filter_num,
                   kernel_size=mc.cnn_filter_size,
                   padding='same',
                   kernel_regularizer=l2(mc.l2_reg))(x)
        x = BatchNormalization(momentum=.997, epsilon=1e-5)(x)
        x = Activation('relu')(x)
        x = Conv2D(filters=mc.cnn_filter_num,
                   kernel_size=mc.cnn_filter_size,
                   padding='same',
                   kernel_regularizer=l2(mc.l2_reg))(x)
        x = BatchNormalization(momentum=.997, epsilon=1e-5)(x)
        x = Add()([x, in_x])
        x = Activation('relu')(x)
        return x

    @staticmethod
    def fetch_digest(weight_path):
        if os.path.exists(weight_path):
            m = hashlib.sha256()
            with open(weight_path, "rb") as f:
                m.update(f.read())
            return m.hexdigest()

    def load(self, config_path, weight_path):
        mc = self.config.model
        resources = self.config.resource
        if mc.distributed and config_path == resources.model_best_config_path:
            try:
                logger.debug(f"loading model from server")
                ftp_connection = ftplib.FTP(
                    resources.model_best_distributed_ftp_server,
                    resources.model_best_distributed_ftp_user,
                    resources.model_best_distributed_ftp_password)
                ftp_connection.cwd(
                    resources.model_best_distributed_ftp_remote_path)
                ftp_connection.retrbinary("RETR model_best_config.json",
                                          open(config_path, 'wb').write)
                ftp_connection.retrbinary("RETR model_best_weight.h5",
                                          open(weight_path, 'wb').write)
                ftp_connection.quit()
            except:
                pass

        if os.path.exists(config_path) and os.path.exists(weight_path):
            logger.debug(f"loading model from {config_path}")
            with open(config_path, "rt") as f:
                self.model = Model.from_config(json.load(f))
            self.model.load_weights(weight_path)
            self.digest = self.fetch_digest(weight_path)
            logger.debug(f"loaded model digest = {self.digest}")
            return True
        else:
            logger.debug(
                f"model files does not exist at {config_path} and {weight_path}"
            )
            return False

    def save(self, config_path, weight_path):
        logger.debug(f"save model to {config_path}")
        with open(config_path, "wt") as f:
            json.dump(self.model.get_config(), f)
            self.model.save_weights(weight_path)
        self.digest = self.fetch_digest(weight_path)
        logger.debug(f"saved model digest {self.digest}")

        mc = self.config.model
        resources = self.config.resource
        if mc.distributed and config_path == resources.model_best_config_path:
            try:
                logger.debug(f"saving model to server")
                ftp_connection = ftplib.FTP(
                    resources.model_best_distributed_ftp_server,
                    resources.model_best_distributed_ftp_user,
                    resources.model_best_distributed_ftp_password)
                ftp_connection.cwd(
                    resources.model_best_distributed_ftp_remote_path)
                fh = open(config_path, 'rb')
                ftp_connection.storbinary('STOR model_best_config.json', fh)
                fh.close()

                fh = open(weight_path, 'rb')
                ftp_connection.storbinary('STOR model_best_weight.h5', fh)
                fh.close()
                ftp_connection.quit()
            except:
                pass
Пример #17
0
class QNetwork:
    def __init__(self, config: Config) -> None:
        self.config = config
        self.digest = None

    def build(self) -> None:
        mc = self.config.model
        in_x = x = Input((4, 5, 5))

        x = Conv2D(filters=mc.cnn_filter_num,
                   kernel_size=mc.cnn_filter_size,
                   padding="same",
                   data_format="channels_first",
                   kernel_regularizer=l2(mc.l2_reg))(x)
        x = BatchNormalization(axis=1)(x)
        x = Activation("relu")(x)

        for _ in range(mc.res_layer_num):
            x = self._build_residual_block(x)

        res_out = x
        # for policy output
        x = Conv2D(filters=2,
                   kernel_size=1,
                   data_format="channels_first",
                   kernel_regularizer=l2(mc.l2_reg))(res_out)
        x = BatchNormalization(axis=1)(x)
        x = Activation("relu")(x)
        x = Flatten()(x)
        # no output for 'pass'
        out = Dense(100,
                    kernel_regularizer=l2(mc.l2_reg),
                    activation="softmax",
                    name="out")(x)

        # x = Dense(mc.value_fc_size, kernel_regularizer=l2(mc.l2_reg),
        #          activation="relu")(x)
        # value_out = Dense(1, kernel_regularizer=l2(mc.l2_reg),
        #                   activation="tanh", name="value_out")(x)

        self.model = Model(in_x, out, name="slipe_model")
        self.model.compile(loss='mse', optimizer=Adam(lr=mc.learning_rate))
        self.model.summary()

    def _build_residual_block(self, x):
        mc = self.config.model
        in_x = x
        x = Conv2D(filters=mc.cnn_filter_num,
                   kernel_size=mc.cnn_filter_size,
                   padding="same",
                   data_format="channels_first",
                   kernel_regularizer=l2(mc.l2_reg))(x)
        x = BatchNormalization(axis=1)(x)
        x = Activation("relu")(x)
        x = Conv2D(filters=mc.cnn_filter_num,
                   kernel_size=mc.cnn_filter_size,
                   padding="same",
                   data_format="channels_first",
                   kernel_regularizer=l2(mc.l2_reg))(x)
        x = BatchNormalization(axis=1)(x)
        x = Add()([in_x, x])
        x = Activation("relu")(x)
        return x

    # 重みの学習
    def replay(self, memory: Memory, batch_size: int, gamma: float,
               targetQN: 'QNetwork') -> None:
        inputs = np.zeros((batch_size, 4, 5, 5))
        targets = np.zeros((batch_size, 100))
        mini_batch = memory.sample(batch_size)

        for i, (state_b, action_b, reward_b,
                next_state_b) in enumerate(mini_batch):
            inputs[i] = state_b  # shape=(4, 5, 5)
            target = reward_b  # type: int

            # if not (next_state_b == 0).all():
            # 価値計算(DDQNにも対応できるように、行動決定のQネットワークと価値関数のQネットワークは分離)
            retmainQs = self.model.predict(next_state_b)
            next_action = np.argmax(retmainQs)  # 最大の報酬を返す行動を選択する
            target = reward_b + gamma * \
                targetQN.model.predict(next_state_b)[0][next_action]

            targets[i] = self.model.predict(state_b)[0][0]  # Qネットワークの出力
            # 教師信号 action_b: int <= 100
            targets[i, action_b] = target
        # epochsは訓練データの反復回数、verbose=0は表示なしの設定
        self.model.fit(inputs, targets, epochs=1, verbose=0)

    @staticmethod
    def fetch_digest(weight_path: str):
        if os.path.exists(weight_path):
            m = hashlib.sha256()
            with open(weight_path, "rb") as f:
                m.update(f.read())
            return m.hexdigest()

    def load(self, config_path: str, weight_path: str) -> bool:
        if os.path.exists(weight_path):  # os.path.exists(config_path) and
            logger.debug(f"loading model from {config_path}")
            with open(config_path, "rt") as f:
                self.model = Model.from_config(json.load(f))
            self.model.load_weights(weight_path)
            self.model.compile(
                loss='mse', optimizer=Adam(lr=self.config.model.learning_rate))
            self.model.summary()
            self.digest = self.fetch_digest(weight_path)
            logger.debug(f"loaded model digest = {self.digest}")
            return True
        else:
            logger.debug(
                f"model files does not exist at {config_path} and {weight_path}"
            )
            return False

    def save(self, config_path: str, weight_path: str) -> None:
        logger.debug(f"save model to {config_path}")
        with open(config_path, "wt") as f:
            json.dump(self.model.get_config(), f)
        self.model.save_weights(weight_path)
        self.digest = self.fetch_digest(weight_path)
        logger.debug(f"saved model digest {self.digest}")
Пример #18
0
class Connect4Model:
    def __init__(self, config: Config):
        self.config = config
        self.model = None  # type: Model
        self.digest = None

    def build(self):
        mc = self.config.model
        in_x = x = Input((2, 6, 7))  # [own(8x8), enemy(8x8)]
        activation = self.config.opts.activation
        print("activation selected is!!!!!!!!!!", activation)

        # (batch, channels, height, width)
        x = Conv2D(filters=mc.cnn_filter_num,
                   kernel_size=mc.cnn_filter_size,
                   padding="same",
                   data_format="channels_first",
                   kernel_regularizer=l2(mc.l2_reg))(x)
        x = BatchNormalization(axis=1)(x)
        #x = Activation("relu")(x)
        x = Activation(activation, name="input_" + activation)(x)
        print("activation selected is!!!!!!!!!!", activation)
        for i in range(mc.res_layer_num):
            x = self._build_residual_block(x, i + 1)

        res_out = x
        # for policy output
        x = Conv2D(filters=2,
                   kernel_size=1,
                   data_format="channels_first",
                   kernel_regularizer=l2(mc.l2_reg))(res_out)
        x = BatchNormalization(axis=1)(x)
        #x = Activation("relu")(x)
        x = Activation(activation, name="policy_" + activation)(x)
        x = Flatten()(x)
        # no output for 'pass'
        policy_out = Dense(self.config.n_labels,
                           kernel_regularizer=l2(mc.l2_reg),
                           activation="softmax",
                           name="policy_out")(x)

        # for value output
        x = Conv2D(filters=1,
                   kernel_size=1,
                   data_format="channels_first",
                   kernel_regularizer=l2(mc.l2_reg))(res_out)
        x = BatchNormalization(axis=1)(x)
        #x = Activation("relu")(x)
        x = Activation(activation, name="value_" + activation)(x)
        x = Flatten()(x)
        #x = Dense(mc.value_fc_size, kernel_regularizer=l2(mc.l2_reg), activation="relu")(x)
        x = Dense(mc.value_fc_size,
                  kernel_regularizer=l2(mc.l2_reg),
                  activation=activation,
                  name="value_dense")(x)
        value_out = Dense(1,
                          kernel_regularizer=l2(mc.l2_reg),
                          activation="tanh",
                          name="value_out")(x)

        self.model = Model(in_x, [policy_out, value_out],
                           name="connect4_model")

    def _build_residual_block(self, x, index):
        mc = self.config.model
        activation = self.config.opts.activation
        in_x = x
        res_name = "res" + str(index)
        x = Conv2D(filters=mc.cnn_filter_num,
                   kernel_size=mc.cnn_filter_size,
                   padding="same",
                   data_format="channels_first",
                   kernel_regularizer=l2(mc.l2_reg),
                   name=res_name + "_conv1-" + str(mc.cnn_filter_size) + "-" +
                   str(mc.cnn_filter_num))(x)
        x = BatchNormalization(axis=1, name=res_name + "_batchnorm1")(x)
        #x = Activation("relu")(x)
        x = Activation(activation, name=res_name + "_" + activation + "1")(x)
        x = Conv2D(filters=mc.cnn_filter_num,
                   kernel_size=mc.cnn_filter_size,
                   padding="same",
                   data_format="channels_first",
                   kernel_regularizer=l2(mc.l2_reg),
                   name=res_name + "_conv2-" + str(mc.cnn_filter_size) + "-" +
                   str(mc.cnn_filter_num))(x)
        x = BatchNormalization(axis=1)(x)
        x = Add(name=res_name + "_add")([in_x, x])
        #x = Activation("relu")(x)
        x = Activation(activation, name=res_name + "_2")(x)
        return x

    @staticmethod
    def fetch_digest(weight_path):
        if os.path.exists(weight_path):
            m = hashlib.sha256()
            with open(weight_path, "rb") as f:
                m.update(f.read())
            return m.hexdigest()

    def load(self, config_path, weight_path):
        mc = self.config.model
        resources = self.config.resource
        if mc.distributed and config_path == resources.model_best_config_path:
            logger.debug(f"loading model from server")
            ftp_connection = ftplib.FTP(
                resources.model_best_distributed_ftp_server,
                resources.model_best_distributed_ftp_user,
                resources.model_best_distributed_ftp_password)
            ftp_connection.cwd(
                resources.model_best_distributed_ftp_remote_path)
            ftp_connection.retrbinary("RETR model_best_config.json",
                                      open(config_path, 'wb').write)
            ftp_connection.retrbinary("RETR model_best_weight.h5",
                                      open(weight_path, 'wb').write)
            ftp_connection.quit()

        if os.path.exists(config_path) and os.path.exists(weight_path):
            logger.debug(f"loading model from {config_path}")
            with open(config_path, "rt") as f:
                self.model = Model.from_config(json.load(f))
            self.model.load_weights(weight_path)
            self.digest = self.fetch_digest(weight_path)
            logger.debug(f"loaded model digest = {self.digest}")
            return True
        else:
            logger.debug(
                f"model files does not exist at {config_path} and {weight_path}"
            )
            return False

    def save(self, config_path, weight_path):
        logger.debug(f"save model to {config_path}")
        with open(config_path, "wt") as f:
            json.dump(self.model.get_config(), f)
            self.model.save_weights(weight_path)
        self.digest = self.fetch_digest(weight_path)
        logger.debug(f"saved model digest {self.digest}")

        mc = self.config.model
        resources = self.config.resource
        if mc.distributed and config_path == resources.model_best_config_path:
            logger.debug(f"saving model to server")
            ftp_connection = ftplib.FTP(
                resources.model_best_distributed_ftp_server,
                resources.model_best_distributed_ftp_user,
                resources.model_best_distributed_ftp_password)
            ftp_connection.cwd(
                resources.model_best_distributed_ftp_remote_path)
            fh = open(config_path, 'rb')
            ftp_connection.storbinary('STOR model_best_config.json', fh)
            fh.close()

            fh = open(weight_path, 'rb')
            ftp_connection.storbinary('STOR model_best_weight.h5', fh)
            fh.close()
            ftp_connection.quit()
Пример #19
0
class ResiCNN:  # My JackNet with residual block
    cnn_filter_num = 64
    cnn_kernel_size = 3

    def __init__(self, channels=3):
        self.model = None
        self.optimizer = None
        self.channels = channels

    def bulid(self):  # build model
        image_in = Input((None, None, self.channels))

        conv = Conv2D(filters=self.cnn_filter_num,
                      kernel_size=self.cnn_kernel_size,
                      strides=(1, 1),
                      padding='same',
                      data_format='channels_last')(image_in)
        conv = Activation('relu')(conv)

        x = conv

        for layers in range(8):
            x = self._build_residual_block(x)

        conv_out = Conv2D(filters=self.channels,
                          kernel_size=self.cnn_kernel_size,
                          strides=(1, 1),
                          padding='same',
                          data_format='channels_last')(x)

        output = Add()([image_in, conv_out])

        self.model = Model(image_in, output, name='model')

    def _build_residual_block(self, x):  # build residual block
        x_in = x

        x = Conv2D(filters=self.cnn_filter_num,
                   kernel_size=self.cnn_kernel_size,
                   strides=(1, 1),
                   padding='same',
                   data_format='channels_last')(x)
        x = BatchNormalization(axis=-1)(x)
        x = Activation('relu')(x)
        x = Conv2D(filters=self.cnn_filter_num,
                   kernel_size=self.cnn_kernel_size,
                   strides=(1, 1),
                   padding='same',
                   data_format='channels_last')(x)
        x = BatchNormalization(axis=-1)(x)
        x = Add()([x_in, x])
        x = Activation("relu")(x)
        return x

    def predict(self, x):  # denoise on input x
        if x.ndim == 3:
            x = x.reshape(1, x.shape[0], x.shape[1], self.channels)
        return self.model.predict_on_batch(x)

    def load(self, config_path, model_path):  # load model
        print('restore model...')
        if os.path.exists(config_path) and os.path.exists(model_path):
            with open(config_path, 'r') as fp:
                self.model = Model.from_config(json.load(fp))
                self.model.load_weights(model_path)
            return True
        return False

    def save(self, config_path, model_path):  # save model
        with open(config_path, 'w') as fp:
            json.dump(self.model.get_config(), fp)
            self.model.save_weights(model_path)

    def compile(self):  # choose adam optimizer and set learning rate
        self.optimizer = Adam(lr=1e-2)
        self.model.compile(optimizer=self.optimizer, loss=self.loss)

    def train_generator(self,
                        data,
                        epochs=1,
                        steps_per_epochs=None,
                        callbacks=None):
        self.model.fit_generator(iter(data),
                                 epochs=epochs,
                                 steps_per_epoch=steps_per_epochs,
                                 callbacks=callbacks)

    def train(self, data, epochs=1, callbacks=None):
        self.model.fit(x=data[0],
                       y=data[1],
                       epochs=epochs,
                       batch_size=8,
                       callbacks=callbacks)

    @staticmethod
    def loss(y_true, y_pred):  # loss function, mean square error
        return 0.5 * K.sum(K.square(y_pred - y_true), axis=-1)
Пример #20
0
class ReversiModel:
    def __init__(self, config: Config):
        self.config = config
        self.model = None  # type: Model
        self.digest = None

    def build(self):
        mc = self.config.model
        in_x = x = Input(self.config.model.input_size)

        # (batch, channels, height, width)
        x = Conv2D(filters=mc.cnn_filter_num,
                   kernel_size=mc.cnn_filter_size,
                   padding="same",
                   data_format="channels_first",
                   kernel_regularizer=l2(mc.l2_reg))(x)
        x = BatchNormalization(axis=1)(x)
        x = Activation("relu")(x)

        for _ in range(mc.res_layer_num):
            x = self._build_residual_block(x)

        res_out = x
        # for policy output
        x = Conv2D(filters=2,
                   kernel_size=1,
                   data_format="channels_first",
                   kernel_regularizer=l2(mc.l2_reg))(res_out)
        x = BatchNormalization(axis=1)(x)
        x = Activation("relu")(x)
        x = Flatten()(x)
        policy_out = Dense(self.config.model.policy_size,
                           kernel_regularizer=l2(mc.l2_reg),
                           activation="softmax",
                           name="policy_out")(x)

        # for value output
        x = Conv2D(filters=1,
                   kernel_size=1,
                   data_format="channels_first",
                   kernel_regularizer=l2(mc.l2_reg))(res_out)
        x = BatchNormalization(axis=1)(x)
        x = Activation("relu")(x)
        x = Flatten()(x)
        x = Dense(mc.value_fc_size,
                  kernel_regularizer=l2(mc.l2_reg),
                  activation="relu")(x)
        value_out = Dense(1,
                          kernel_regularizer=l2(mc.l2_reg),
                          activation="tanh",
                          name="value_out")(x)

        self.model = Model(in_x, [policy_out, value_out], name="reversi_model")

    def _build_residual_block(self, x):
        mc = self.config.model
        in_x = x
        x = Conv2D(filters=mc.cnn_filter_num,
                   kernel_size=mc.cnn_filter_size,
                   padding="same",
                   data_format="channels_first",
                   kernel_regularizer=l2(mc.l2_reg))(x)
        x = BatchNormalization(axis=1)(x)
        x = Activation("relu")(x)
        x = Conv2D(filters=mc.cnn_filter_num,
                   kernel_size=mc.cnn_filter_size,
                   padding="same",
                   data_format="channels_first",
                   kernel_regularizer=l2(mc.l2_reg))(x)
        x = BatchNormalization(axis=1)(x)
        x = Add()([in_x, x])
        x = Activation("relu")(x)
        return x

    @staticmethod
    def fetch_digest(weight_path):
        if os.path.exists(weight_path):
            m = hashlib.sha256()
            with open(weight_path, "rb") as f:
                m.update(f.read())
            return m.hexdigest()

    @staticmethod
    def load_step_info(config_path):
        if os.path.exists(config_path):
            with open(config_path, "rt") as f:
                try:
                    config = json.load(f)
                    return int(config['steps'])
                except JSONDecodeError:
                    return None
                except ValueError:
                    return None
        else:
            return None

    def load(self, config_path, weight_path):
        if os.path.exists(config_path) and os.path.exists(weight_path):
            logger.debug(f"loading model from {config_path}")
            with open(config_path, "rt") as f:
                config = json.load(f)

                if 'weight_digest' in config:
                    exp_digest = config['weight_digest']
                    act_digest = self.fetch_digest(weight_path)
                    if exp_digest != act_digest:
                        logger.debug(
                            f"exp weight digest {exp_digest}, act {act_digest}"
                        )
                        return None

                try:
                    steps = int(config['steps'])
                except ValueError:
                    steps = None
                del config['steps']
                self.model = Model.from_config(config)
            self.model.load_weights(weight_path)
            self.digest = self.fetch_digest(weight_path)
            logger.debug(f"loaded model digest = {self.digest}")
            return steps
        else:
            logger.debug(
                f"model files does not exist at {config_path} and {weight_path}"
            )
            return None

    def save(self, config_path, weight_path, steps=0):
        logger.debug(f"save model to {config_path}")
        with open(config_path, "wt") as f:
            self.model.save_weights(weight_path)
            self.digest = self.fetch_digest(weight_path)
            config = self.model.get_config()
            config['steps'] = steps
            config['weight_digest'] = self.digest
            json.dump(config, f)
        logger.debug(f"saved model digest {self.digest}")
class ChessModel:
    """
    The model which can be trained to take observations of a game of chess and return value and policy
    predictions.

    Attributes:
        :ivar Config config: configuration to use
        :ivar Model model: the Keras model to use for predictions
        :ivar digest: basically just a hash of the file containing the weights being used by this model
        :ivar ChessModelAPI api: the api to use to listen for and then return this models predictions (on a pipe).
    """
    def __init__(self, config: Config):
        self.config = config
        self.model = None  # type: Model
        self.digest = None
        self.api = None

    def get_pipes(self, num=1):
        """
        Creates a list of pipes on which observations of the game state will be listened for. Whenever
        an observation comes in, returns policy and value network predictions on that pipe.

        :param int num: number of pipes to create
        :return str(Connection): a list of all connections to the pipes that were created
        """
        if self.api is None:
            self.api = ChessModelAPI(self)
            self.api.start()
        return [self.api.create_pipe() for _ in range(num)]

    def build(self):
        """
        Builds the full Keras model and stores it in self.model.
        Why biases are set to False : https://github.com/kuangliu/pytorch-cifar/issues/52
        """

        logger.debug(f"Building new model.")
        mc = self.config.model
        in_x = x = Input((18, 8, 8))

        # (batch, channels, height, width)
        x = Conv2D(filters=mc.cnn_filter_num,
                   kernel_size=mc.cnn_first_filter_size,
                   padding="same",
                   data_format="channels_first",
                   use_bias=False,
                   name="input_conv-" + str(mc.cnn_first_filter_size) + "-" +
                   str(mc.cnn_filter_num))(x)
        x = BatchNormalization(axis=1, name="input_batchnorm")(x)
        x = Activation("relu", name="input_relu")(x)

        for i in range(mc.common_res_layer_num):
            x = self._build_residual_block(x, i + 1)

        x_policy = x
        x_value = x

        # for policy output
        for i in range(mc.policy_res_layer_num):
            x_policy = self._build_residual_block(
                x_policy, mc.common_res_layer_num + i + 1)

        x = Conv2D(filters=32,
                   kernel_size=1,
                   data_format="channels_first",
                   use_bias=False,
                   name="policy_conv-1-2")(x_policy)
        x = BatchNormalization(axis=1, name="policy_batchnorm")(x)
        x = Activation("relu", name="policy_relu")(x)
        x = Flatten(name="policy_flatten")(x)
        # no output for 'pass'
        policy_out = Dense(self.config.n_labels,
                           activation="softmax",
                           name="policy_out")(x)

        for i in range(mc.value_res_layer_num):
            x_value = self._build_residual_block(
                x_value,
                mc.common_res_layer_num + mc.policy_res_layer_num + i + 1)

        # for value output
        x = Conv2D(filters=4,
                   kernel_size=1,
                   data_format="channels_first",
                   use_bias=False,
                   name="value_conv-1-4")(x_value)
        x = BatchNormalization(axis=1, name="value_batchnorm")(x)
        x = Activation("relu", name="value_relu")(x)
        x = Flatten(name="value_flatten")(x)
        x = Dense(mc.value_fc_size,
                  activation="relu",
                  name="value_dense",
                  use_bias=False)(x)
        x = BatchNormalization(name="value_batchnorm_2")(x)
        value_out = Dense(1, activation="tanh", name="value_out")(x)

        self.model = Model(in_x, [policy_out, value_out], name="chess_model")

    def _build_residual_block(self, x, index):
        mc = self.config.model
        in_x = x
        res_name = "res" + str(index)
        x = Conv2D(filters=mc.cnn_filter_num,
                   kernel_size=mc.cnn_filter_size,
                   padding="same",
                   data_format="channels_first",
                   use_bias=False,
                   name=res_name + "_conv1-" + str(mc.cnn_filter_size) + "-" +
                   str(mc.cnn_filter_num))(x)
        x = BatchNormalization(axis=1, name=res_name + "_batchnorm1")(x)
        x = Activation("relu", name=res_name + "_relu1")(x)
        x = Conv2D(filters=mc.cnn_filter_num,
                   kernel_size=mc.cnn_filter_size,
                   padding="same",
                   data_format="channels_first",
                   use_bias=False,
                   name=res_name + "_conv2-" + str(mc.cnn_filter_size) + "-" +
                   str(mc.cnn_filter_num))(x)
        x = BatchNormalization(axis=1,
                               name="res" + str(index) + "_batchnorm2")(x)
        x = Add(name=res_name + "_add")([in_x, x])
        x = Activation("relu", name=res_name + "_relu2")(x)
        return x

    @staticmethod
    def fetch_digest(weight_path):
        if os.path.exists(weight_path):
            m = hashlib.sha256()
            with open(weight_path, "rb") as f:
                m.update(f.read())
            return m.hexdigest()

    def load(self, config_path=None, weight_path=None):
        """

        :param str config_path: path to the file containing the entire configuration
        :param str weight_path: path to the file containing the model weights
        :return: true if successful in loading
        """

        if os.path.exists(config_path):
            logger.debug(f"loading model from {config_path}")
            with open(config_path, "rt") as f:
                self.model = Model.from_config(json.load(f))
            if os.path.exists(weight_path):
                self.model.load_weights(weight_path)
            self.model._make_predict_function()
            self.digest = self.fetch_digest(weight_path)
            logger.debug(f"loaded model digest = {self.digest}")
            return True
        else:
            logger.debug(
                f"model files does not exist at {config_path} and {weight_path}"
            )
            self.build()
            return True

    def save(self, config_path, weight_path):
        """

        :param str config_path: path to save the entire configuration to
        :param str weight_path: path to save the model weights to
        """
        logger.debug(f"save model to {config_path}")
        with open(config_path, "wt") as f:
            json.dump(self.model.get_config(), f)
            self.model.save_weights(weight_path)
        self.digest = self.fetch_digest(weight_path)
        logger.debug(f"saved model digest {self.digest}")
class ChessModel:
    def __init__(self, config: Config):
        self.config = config
        self.model = None  # type: Model
        self.digest = None
        self.api = None

    def get_pipes(self, num=1):
        if self.api is None:
            self.api = ChessModelAPI(self.config, self)
            self.api.start()
        return [self.api.get_pipe() for _ in range(num)]

    def build(self):
        mc = self.config.model
        # in_x = x = Input((18, 8, 8))
        in_x = x = Input((14, 10, 9))  # change to CC

        # (batch, channels, height, width)
        x = Conv2D(filters=mc.cnn_filter_num,
                   kernel_size=mc.cnn_first_filter_size,
                   padding="same",
                   data_format="channels_first",
                   use_bias=False,
                   kernel_regularizer=l2(mc.l2_reg),
                   name="input_conv-" + str(mc.cnn_first_filter_size) + "-" +
                   str(mc.cnn_filter_num))(x)
        x = BatchNormalization(axis=1, name="input_batchnorm")(x)
        x = Activation("relu", name="input_relu")(x)

        for i in range(mc.res_layer_num):
            x = self._build_residual_block(x, i + 1)

        res_out = x

        # for policy output
        x = Conv2D(filters=2,
                   kernel_size=1,
                   data_format="channels_first",
                   use_bias=False,
                   kernel_regularizer=l2(mc.l2_reg),
                   name="policy_conv-1-2")(res_out)
        x = BatchNormalization(axis=1, name="policy_batchnorm")(x)
        x = Activation("relu", name="policy_relu")(x)
        x = Flatten(name="policy_flatten")(x)
        # no output for 'pass'
        policy_out = Dense(self.config.n_labels,
                           kernel_regularizer=l2(mc.l2_reg),
                           activation="softmax",
                           name="policy_out")(x)

        # for value output
        x = Conv2D(filters=4,
                   kernel_size=1,
                   data_format="channels_first",
                   use_bias=False,
                   kernel_regularizer=l2(mc.l2_reg),
                   name="value_conv-1-4")(res_out)
        x = BatchNormalization(axis=1, name="value_batchnorm")(x)
        x = Activation("relu", name="value_relu")(x)
        x = Flatten(name="value_flatten")(x)
        x = Dense(mc.value_fc_size,
                  kernel_regularizer=l2(mc.l2_reg),
                  activation="relu",
                  name="value_dense")(x)
        value_out = Dense(1,
                          kernel_regularizer=l2(mc.l2_reg),
                          activation="tanh",
                          name="value_out")(x)

        self.model = Model(in_x, [policy_out, value_out], name="chess_model")

    def _build_residual_block(self, x, index):
        mc = self.config.model
        in_x = x
        res_name = "res" + str(index)
        x = Conv2D(filters=mc.cnn_filter_num,
                   kernel_size=mc.cnn_filter_size,
                   padding="same",
                   data_format="channels_first",
                   use_bias=False,
                   kernel_regularizer=l2(mc.l2_reg),
                   name=res_name + "_conv1-" + str(mc.cnn_filter_size) + "-" +
                   str(mc.cnn_filter_num))(x)
        x = BatchNormalization(axis=1, name=res_name + "_batchnorm1")(x)
        x = Activation("relu", name=res_name + "_relu1")(x)
        x = Conv2D(filters=mc.cnn_filter_num,
                   kernel_size=mc.cnn_filter_size,
                   padding="same",
                   data_format="channels_first",
                   use_bias=False,
                   kernel_regularizer=l2(mc.l2_reg),
                   name=res_name + "_conv2-" + str(mc.cnn_filter_size) + "-" +
                   str(mc.cnn_filter_num))(x)
        x = BatchNormalization(axis=1,
                               name="res" + str(index) + "_batchnorm2")(x)
        x = Add(name=res_name + "_add")([in_x, x])
        x = Activation("relu", name=res_name + "_relu2")(x)
        return x

    @staticmethod
    def fetch_digest(weight_path):
        if os.path.exists(weight_path):
            m = hashlib.sha256()
            with open(weight_path, "rb") as f:
                m.update(f.read())
            return m.hexdigest()

    def load(self, config_path, weight_path):
        mc = self.config.model
        resources = self.config.resource
        if mc.distributed and config_path == resources.model_best_config_path:
            try:
                logger.debug("loading model from server")
                ftp_connection = ftplib.FTP(
                    resources.model_best_distributed_ftp_server,
                    resources.model_best_distributed_ftp_user,
                    resources.model_best_distributed_ftp_password)
                ftp_connection.cwd(
                    resources.model_best_distributed_ftp_remote_path)
                ftp_connection.retrbinary("RETR model_best_config.json",
                                          open(config_path, 'wb').write)
                ftp_connection.retrbinary("RETR model_best_weight.h5",
                                          open(weight_path, 'wb').write)
                ftp_connection.quit()
            except:
                pass
        if os.path.exists(config_path) and os.path.exists(weight_path):
            logger.debug("loading model from %s" % (config_path))
            with open(config_path, "rt") as f:
                self.model = Model.from_config(json.load(f))
            self.model.load_weights(weight_path)
            self.model._make_predict_function()
            self.digest = self.fetch_digest(weight_path)
            logger.debug("loaded model digest = %s" % (self.digest))
            return True
        else:
            logger.debug("model files does not exist at %s and %s" %
                         (config_path, weight_path))
            return False

    def save(self, config_path, weight_path):
        logger.debug("saving model to %s" % (config_path))
        print('debug-3')
        with open(config_path, "wt") as f:
            print('debug-2')
            json.dump(self.model.get_config(), f)
            print('debug-1')
            self.model.save_weights(weight_path)
            print('debug-0')
        self.digest = self.fetch_digest(weight_path)
        logger.debug("saved model digest %s" % (self.digest))

        print('debug')

        mc = self.config.model
        resources = self.config.resource
        print('debug2')
        if mc.distributed and config_path == resources.model_best_config_path:
            try:
                print('debug3')
                logger.debug("saving model to server")
                ftp_connection = ftplib.FTP(
                    resources.model_best_distributed_ftp_server,
                    resources.model_best_distributed_ftp_user,
                    resources.model_best_distributed_ftp_password)
                ftp_connection.cwd(
                    resources.model_best_distributed_ftp_remote_path)
                fh = open(config_path, 'rb')
                ftp_connection.storbinary('STOR model_best_config.json', fh)
                fh.close()

                fh = open(weight_path, 'rb')
                ftp_connection.storbinary('STOR model_best_weight.h5', fh)
                fh.close()
                ftp_connection.quit()
            except:
                print('debug4')
                pass
Пример #23
0
class FinancialNewsAnalysisModel(object):
    model = None

    def __init__(self, nb_time_step, dim_data, batch_size=1, model_path=None):
        self.model_path = model_path
        self.model_path = model_path
        self.batch_size = batch_size
        self.size_of_input_data_dim = dim_data
        self.size_of_input_timesteps = nb_time_step
        self.build()
        self.weight_loaded = False
        if model_path is not None:
            self.load_weights()

    def build(self):
        dim_data = self.size_of_input_data_dim
        nb_time_step = self.size_of_input_timesteps
        news_input = Input(shape=(nb_time_step, dim_data))
        lstm = LSTM(output_dim=nb_hidden_units, dropout_U=dropout, dropout_W=dropout,
                    W_regularizer=l2(l2_norm_alpha), b_regularizer=l2(l2_norm_alpha), activation='tanh')
        bi_lstm = Bidirectional(lstm, input_shape=(nb_time_step, dim_data), merge_mode='concat')
        all_news_rep = bi_lstm(news_input)
        news_predictions = Dense(1, activation='linear')(all_news_rep)
        self.model = Model(news_input, news_predictions, name="deep rnn for financial news analysis")

    def reset(self):
        for l in self.model.layers:
            if type(l) is LSTM:
                l.reset_status()

    def compile_model(self, lr=0.0001, loss_weights=0.1):
        optimizer = Adam(lr=lr)
        loss = 'mse'
        # loss = custom_objective
        self.model.compile(optimizer=optimizer, loss=loss)
                           #metrics=['mse'])
        plot(self.model, to_file='model.png')

    def fit_model(self, X, y, X_val=None, y_val=None, epoch=500):
        early_stopping = EarlyStopping(monitor='val_loss', patience=100, verbose=0)
        if X_val is None:
            self.model.fit(X, y, batch_size=self.batch_size, nb_epoch=epoch, validation_split=0.2,
                           shuffle=True, callbacks=[early_stopping])
        else:
            self.model.fit(X, y, batch_size=self.batch_size, nb_epoch=epoch, validation_data=(X_val, y_val),
                           shuffle=True, callbacks=[early_stopping])

    def save(self):
        self.model.save_weights(self.model_path, overwrite=True)

    def load_weights(self):
        if os.path.exists(self.model_path):
            self.model.load_weights(self.model_path)
            self.weight_loaded = True

    def print_weights(self, weights=None, detail=False):
        weights = weights or self.model.get_weights()
        for w in weights:
            print("w%s: sum(w)=%s, ave(w)=%s" % (w.shape, np.sum(w), np.average(w)))
        if detail:
            for w in weights:
                print("%s: %s" % (w.shape, w))

    def model_eval(self, X, y):
        y_hat = self.model.predict(X, batch_size=1)
        count_true = 0
        count_all = y.shape[0]
        for i in range(y.shape[0]):
            count_true = count_true + 1 if y[i,0]*y_hat[i,0]>0 else count_true
            print y[i,0],y_hat[i,0]
        print count_all,count_true
Пример #24
0
from keras.callbacks import EarlyStopping, ModelCheckpoint, ReduceLROnPlateau

check_point = ModelCheckpoint('model.hdf5', verbose=True, save_best_only=True)
early_stop = EarlyStopping(patience=5, verbose=True)
model.fit(X_train,
          y_train.astype(int),
          validation_data=(X_valid, y_valid.astype(int)),
          epochs=5,
          verbose=True,
          callbacks=[early_stop, check_point])

# In[ ]:

from sklearn.metrics import accuracy_score
# distribution of confidence that will be used as submission
model.load_weights('model.hdf5')
confidence_valid = model.predict(X_valid)[:, 0] * 2 - 1
print(accuracy_score(confidence_valid > 0, y_valid))
plt.hist(confidence_valid, bins='auto')
plt.title("predicted confidence")
plt.show()

# In[ ]:

# calculation of actual metric that is used to calculate final score
r_valid = r_valid.clip(-1, 1)  # get rid of outliers. Where do they come from??
x_t_i = confidence_valid * r_valid * u_valid
data = {'day': d_valid, 'x_t_i': x_t_i}
df = pd.DataFrame(data)
x_t = df.groupby('day').sum().values.flatten()
mean = np.mean(x_t)
Пример #25
0
class Network:
    def __init__(self, conf):
        # All hyperparameters used in the model
        self._board_size = conf['board_size']  # the size of the playing board
        self._lr = conf['learning_rate']  # learning rate of SGD (2e-3)
        self._momentum = conf['momentum']  # nesterov momentum (1e-1)
        self._l2_coef = conf['l2']  # coefficient of L2 penalty (1e-4)
        self._mini_batch_size = conf['mini_batch_size']  # the size of batch when training the network
        self._fit_epochs = conf['fit_epochs']  # the number of iteration

        # Define Network
        self._build_network()

        # The location of the file which stores the parameters of the network
        self._net_para_file = conf['net_para_file']
        self._fit_history_file = conf['fit_history_file']

        # Whether we use previous model or not
        self._use_previous_model = conf['use_previous_model']
        if self._use_previous_model:
            if os.path.exists(self._net_para_file):
                self._model.load_weights(self._net_para_file)
            else:
                print('> error: [use_previous_model] = True, ' + self._net_para_file + ' not found')

    @log
    def _build_network(self):
        # Input_Layer
        init_x = Input((3, self._board_size, self._board_size))  # the input is a tensor with the shape 3*(15*15)
        x = init_x

        # First Convolutional Layer with 32 filters
        x = Conv2D(filters=32, kernel_size=(3, 3), strides=(1, 1), padding='same',
                   data_format='channels_first', kernel_regularizer=l2(self._l2_coef))(x)
        x = BatchNormalization()(x)
        x = Activation('relu')(x)

        # Two Residual Blocks
        x = self._residual_block(x)
        x = self._residual_block(x)
        x = self._residual_block(x)

        # Policy Head for generating prior probability vector for each action
        policy = Conv2D(filters=2, kernel_size=(1, 1), strides=(1, 1), padding='same',
                        data_format='channels_first', kernel_regularizer=l2(self._l2_coef))(x)
        policy = BatchNormalization()(policy)
        policy = Activation('relu')(policy)
        policy = Flatten()(policy)
        policy = Dense(self._board_size*self._board_size, kernel_regularizer=l2(self._l2_coef))(policy)
        self._policy = Activation('softmax')(policy)

        # Value Head for generating value of each action
        value = Conv2D(filters=1, kernel_size=(1, 1), strides=(1, 1), padding='same',
                       data_format="channels_first", kernel_regularizer=l2(self._l2_coef))(x)
        value = BatchNormalization()(value)
        value = Activation('relu')(value)
        value = Flatten()(value)
        value = Dense(32, kernel_regularizer=l2(self._l2_coef))(value)
        value = Activation('relu')(value)
        value = Dense(1, kernel_regularizer=l2(self._l2_coef))(value)
        self._value = Activation('tanh')(value)

        # Define Network
        self._model = Model(inputs=init_x, outputs=[self._policy, self._value])

        # Define the Loss Function
        opt = SGD(lr=self._lr, momentum=self._momentum, nesterov=True)  # stochastic gradient descend with momentum
        losses_type = ['categorical_crossentropy', 'mean_squared_error']  # cross-entrophy and MSE are weighted equally
        self._model.compile(optimizer=opt, loss=losses_type)

    def _residual_block(self, x):
        x_shortcut = x
        x = Conv2D(filters=32, kernel_size=(3, 3), strides=(1, 1), padding='same',
                   data_format="channels_first", kernel_regularizer=l2(self._l2_coef))(x)
        x = BatchNormalization()(x) 
        x = Activation('relu')(x)
        x = Conv2D(filters=32, kernel_size=(3, 3), strides=(1, 1), padding='same',
                   data_format="channels_first", kernel_regularizer=l2(self._l2_coef))(x)
        x = BatchNormalization()(x) 
        x = add([x, x_shortcut])  # Skip Connection
        x = Activation('relu')(x)
        return x
        
    def predict(self, board, color, last_move):
        if sum(sum(board)) == 0 and color == WHITE:
            print('error: network.predict')
        if sum(sum(board)) == 1 and color == BLACK:
            print('error: network.predict')
        tensor = board2tensor(board, color, last_move)
        policy, value_tensor = self._model.predict_on_batch(tensor)
        value = value_tensor[0][0]
        return policy, value

    def train(self, board_list, color_list, last_move_list, pi_list, z_list):
        size = len(color_list)
        for i in range(size):
            if sum(sum(board_list[i])) == 0 and color_list[i] == WHITE:
                print('error: network.train')
            if sum(sum(board_list[i])) == 1 and color_list[i] == BLACK:
                print('error: network.train')

        # Data Augmentation through symmetric and self-rotation transformation
        board_aug = []
        color_aug = []
        last_move_aug = []
        pi_aug = []
        z_aug = []
        for i in range(len(board_list)):
            new_board, new_color, new_last_move, new_pi, new_z = \
                data_augmentation(board_list[i], color_list[i], last_move_list[i], pi_list[i], z_list[i])
            board_aug.extend(new_board)
            color_aug.extend(new_color)
            last_move_aug.extend(new_last_move)
            pi_aug.extend(new_pi)
            z_aug.extend(new_z)
        board_list.extend(board_aug)
        color_list.extend(color_aug)
        last_move_list.extend(last_move_aug)
        pi_list.extend(pi_aug)
        z_list.extend(z_aug)

        # Regularize Data
        board_list = np.array([board2tensor(board_list[i], color_list[i], last_move_list[i], reshape_flag=False)
                               for i in range(len(board_list))])
        pi_list = np.array(pi_list)
        z_list = np.array(z_list)

        # Training
        hist = self._model.fit(board_list, [pi_list, z_list], epochs=self._fit_epochs, batch_size=self._mini_batch_size, verbose=1)
        hist_path = self._fit_history_file + '_' + str(self._fit_epochs) + '_' + str(self._mini_batch_size) + '.txt'
        with open(hist_path, 'a') as f:
            f.write(str(hist.history))
            return hist.history['loss'][0]  # only sample loss of first epoch
        
    def get_para(self):
        net_para = self._model.get_weights() 
        return net_para

    def save_model(self):
        """ save model para to file """
        self._model.save_weights(self._net_para_file)

    def load_model(self):
        if os.path.exists(self._net_para_file):
            self._model.load_weights(self._net_para_file)
        else:
            print('> error: ' + self._net_para_file + ' not found')
Пример #26
0
class FinancialTimeSeriesAnalysisModel(object):
    model = None

    def __init__(self, nb_time_step, dim_data, batch_size=1, model_path=None):
        self.model_path = model_path
        self.model_path = model_path
        self.batch_size = batch_size
        self.size_of_input_data_dim = dim_data
        self.size_of_input_timesteps = nb_time_step
        self.build()
        self.weight_loaded = False
        if model_path is not None:
            self.load_weights()

    def build(self):
        dim_data = self.size_of_input_data_dim
        nb_time_step = self.size_of_input_timesteps
        financial_time_series_input = Input(shape=(nb_time_step, dim_data), name='x1')
        lstm_layer_1 = LSTM(output_dim=nb_hidden_units, dropout_U=dropout, dropout_W=dropout,
                            W_regularizer=l2(l2_norm_alpha), b_regularizer=l2(l2_norm_alpha), activation='tanh',
                            return_sequences=True, name='lstm_layer1')
        lstm_layer_21 = LSTM(output_dim=nb_hidden_units, dropout_U=dropout, dropout_W=dropout,
                             W_regularizer=l2(l2_norm_alpha), b_regularizer=l2(l2_norm_alpha), activation='tanh',
                             return_sequences=True, name='lstm_layer2_loss1')
        lstm_layer_22 = LSTM(output_dim=nb_hidden_units, dropout_U=dropout, dropout_W=dropout,
                             W_regularizer=l2(l2_norm_alpha), b_regularizer=l2(l2_norm_alpha), activation='tanh',
                             return_sequences=True, name='lstm_layer2_loss2')
        lstm_layer_23 = LSTM(output_dim=nb_hidden_units, dropout_U=dropout, dropout_W=dropout,
                             W_regularizer=l2(l2_norm_alpha), b_regularizer=l2(l2_norm_alpha), activation='tanh',
                             return_sequences=True, name='lstm_layer2_loss3')

        lstm_layer_24 = LSTM(output_dim=nb_hidden_units, dropout_U=dropout, dropout_W=dropout,
                             W_regularizer=l2(l2_norm_alpha), b_regularizer=l2(l2_norm_alpha), activation='tanh',
                             return_sequences=True, name='lstm_layer2_loss4')

        lstm_layer_25 = LSTM(output_dim=nb_hidden_units, dropout_U=dropout, dropout_W=dropout,
                             W_regularizer=l2(l2_norm_alpha), b_regularizer=l2(l2_norm_alpha), activation='tanh',
                             return_sequences=True, name='lstm_layer2_loss5')
        h1 = lstm_layer_1(financial_time_series_input)
        h21 = lstm_layer_21(h1)
        h22 = lstm_layer_22(h1)
        h23 = lstm_layer_23(h1)
        h24 = lstm_layer_24(h1)
        h25 = lstm_layer_25(h1)
        time_series_predictions1 = TimeDistributed(Dense(1), name="p1")(h21)  # custom 1
        time_series_predictions2 = TimeDistributed(Dense(1), name="p2")(h22)  # custom 2
        time_series_predictions3 = TimeDistributed(Dense(1), name="p3")(h23)  # mse
        time_series_predictions4 = TimeDistributed(Dense(1, activation='sigmoid'), name="p4")(h24)  # logloss
        time_series_predictions5 = TimeDistributed(Dense(nb_labels, activation='softmax'), name="p5")(h25)  # cross
        self.model = Model(input=financial_time_series_input,
                           output=[time_series_predictions1, time_series_predictions2,
                                   time_series_predictions3, time_series_predictions4,
                                   time_series_predictions5],
                           name="multi-task deep rnn for financial time series forecasting")
        plot(self.model, to_file='model.png')

    def reset(self):
        for l in self.model.layers:
            if type(l) is LSTM:
                l.reset_status()

    def compile_model(self, lr=0.0001, arg_weight=1.):
        optimizer = Adam(lr=lr)
        loss = [custom_objective1, custom_objective2, 'mse', 'binary_crossentropy', 'categorical_crossentropy']
        self.model.compile(optimizer=optimizer, loss=loss)

    def fit_model(self, X, y, y_label, epoch=300):
        early_stopping = EarlyStopping(monitor='val_loss', patience=10, verbose=0)

        self.model.fit(X, [y]*3 + [y > 0] + [y_label], batch_size=self.batch_size, nb_epoch=epoch, validation_split=0.2,
                       shuffle=True, callbacks=[early_stopping])

    def save(self):
        self.model.save_weights(self.model_path, overwrite=True)

    def load_weights(self):
        if os.path.exists(self.model_path):
            self.model.load_weights(self.model_path)
            self.weight_loaded = True

    def print_weights(self, weights=None, detail=False):
        weights = weights or self.model.get_weights()
        for w in weights:
            print("w%s: sum(w)=%s, ave(w)=%s" % (w.shape, np.sum(w), np.average(w)))
        if detail:
            for w in weights:
                print("%s: %s" % (w.shape, w))

    def model_eval(self, X, y):
        y_hat = self.model.predict(X, batch_size=1)[0]
        count_true = 0
        count_all = y.shape[1]
        for i in range(y.shape[1]):
            count_true = count_true + 1 if y[0,i,0]*y_hat[0,i,0]>0 else count_true
            print(y[0,i,0],y_hat[0,i,0])
        print(count_all,count_true)
Пример #27
0
class Network():
    def __init__(self, conf):
        # Some Hyperparameters
        self._board_size = conf['board_size']  # the size of the playing board
        self._lr = conf['learning_rate']  # learning rate of SGD (2e-3)
        self._momentum = conf['momentum']  # nesterov momentum (1e-1)
        self._l2_coef = conf['l2']  # coefficient of L2 penalty (1e-4)
        # Define Network
        self._build_network()
        # File Location
        self._net_para_file = conf['net_para_file']
        # If we use previous model or not
        self._use_previous_model = conf['use_previous_model']
        if self._use_previous_model:
            net_para = self._model.load_weights(self._net_para_file)
            self._model.set_weights(net_para)

    def _build_network(self):
        # Input_Layer
        init_x = Input((3, self._board_size, self._board_size))
        x = init_x
        # Convolutional Layer
        x = Conv2D(filters=32,
                   kernel_size=(3, 3),
                   strides=(1, 1),
                   padding='same',
                   data_format='channels_first',
                   kernel_regularizer=l2(self._l2_coef))(x)
        x = BatchNormalization()(x)
        x = Activation('relu')(x)
        # Residual Layer
        x = self._residual_block(x)
        x = self._residual_block(x)
        x = self._residual_block(x)
        # Policy Head
        policy = Conv2D(filters=2,
                        kernel_size=(1, 1),
                        strides=(1, 1),
                        padding='same',
                        data_format='channels_first',
                        kernel_regularizer=l2(self._l2_coef))(x)
        policy = BatchNormalization()(policy)
        policy = Activation('relu')(policy)
        policy = Flatten()(policy)
        policy = Dense(self._board_size * self._board_size,
                       kernel_regularizer=l2(self._l2_coef))(policy)
        self._policy = Activation('softmax')(policy)
        # Value Head
        value = Conv2D(filters=1,
                       kernel_size=(1, 1),
                       strides=(1, 1),
                       padding='same',
                       data_format="channels_first",
                       kernel_regularizer=l2(self._l2_coef))(x)
        value = BatchNormalization()(value)
        value = Activation('relu')(value)
        value = Flatten()(value)
        value = Dense(32, kernel_regularizer=l2(self._l2_coef))(value)
        value = Activation('relu')(value)
        value = Dense(1, kernel_regularizer=l2(self._l2_coef))(value)
        self._value = Activation('tanh')(value)
        # Define Network
        self._model = Model(inputs=init_x, outputs=[self._policy, self._value])
        # Define the Loss Function
        opt = SGD(lr=self._lr, momentum=self._momentum, nesterov=True)
        losses_type = ['categorical_crossentropy', 'mean_squared_error']
        self._model.compile(optimizer=opt, loss=losses_type)

    def _residual_block(self, x):
        x_shortcut = x
        x = Conv2D(filters=32,
                   kernel_size=(3, 3),
                   strides=(1, 1),
                   padding='same',
                   data_format="channels_first",
                   kernel_regularizer=l2(self._l2_coef))(x)
        x = BatchNormalization()(x)
        x = Activation('relu')(x)
        x = Conv2D(filters=32,
                   kernel_size=(3, 3),
                   strides=(1, 1),
                   padding='same',
                   data_format="channels_first",
                   kernel_regularizer=l2(self._l2_coef))(x)
        x = BatchNormalization()(x)
        x = add([x, x_shortcut])  # Skip Connection
        x = Activation('relu')(x)
        return x

    def predict(self, board, color, random_flip=False):
        if random_flip:
            b_t, method_index = input_transform(board)
            tensor_t = board2tensor(b_t, color, reshape_flag=True)
            prob_tensor_t, value_tensor = self._model.predict_on_batch(
                tensor_t)
            policy = output_decode(prob_tensor_t, method_index, board.shape[0])
            value = value_tensor[0][0]
            return policy, value
        else:
            tensor = board2tensor(board, color)
            policy, value_tensor = self._model.predict_on_batch(tensor)
            value = value_tensor[0][0]
            return policy, value

    def train(self, board_list, color_list, pi_list, z_list):
        # Reguliza Data
        tensor_list = np.array([
            board2tensor(board_list[i], color_list[i], reshape_flag=False)
            for i in range(len(board_list))
        ])
        pi_list = np.array(pi_list)
        z_list = np.array(z_list)
        # Training
        self._model.fit(tensor_list, [pi_list, z_list],
                        epochs=20,
                        batch_size=len(color_list),
                        verbose=1)
        # Calculate Loss Explicitly
        loss = self._model.evaluate(tensor_list, [pi_list, z_list],
                                    batch_size=len(board_list),
                                    verbose=0)
        loss = loss[0]
        return loss

    def get_para(self):
        net_para = self._model.get_weights()
        return net_para

    def save_model(self):
        """ save model para to file """
        self._model.save_weights(self._net_para_file)

    def load_model(self):
        self._model.load_weights(self._net_para_file)
Пример #28
0
class ReversiModel:
    def __init__(self, config: Config):
        self.config = config
        self.model = None  # type: Model
        self.digest = None

    def build(self):
        mc = self.config.model
        in_x = x = Input((2, 8, 8))  # [own(8x8), enemy(8x8)]

        # (batch, channels, height, width)
        x = Conv2D(filters=mc.cnn_filter_num,
                   kernel_size=mc.cnn_filter_size,
                   padding="same",
                   data_format="channels_first",
                   kernel_regularizer=l2(mc.l2_reg))(x)
        x = BatchNormalization(axis=1)(x)
        x = Activation("relu")(x)

        for _ in range(mc.res_layer_num):
            x = self._build_residual_block(x)

        res_out = x
        # for policy output
        x = Conv2D(filters=2,
                   kernel_size=1,
                   data_format="channels_first",
                   kernel_regularizer=l2(mc.l2_reg))(res_out)
        x = BatchNormalization(axis=1)(x)
        x = Activation("relu")(x)
        x = Flatten()(x)
        # no output for 'pass'
        policy_out = Dense(8 * 8,
                           kernel_regularizer=l2(mc.l2_reg),
                           activation="softmax",
                           name="policy_out")(x)

        # for value output
        x = Conv2D(filters=1,
                   kernel_size=1,
                   data_format="channels_first",
                   kernel_regularizer=l2(mc.l2_reg))(res_out)
        x = BatchNormalization(axis=1)(x)
        x = Activation("relu")(x)
        x = Flatten()(x)
        x = Dense(mc.value_fc_size,
                  kernel_regularizer=l2(mc.l2_reg),
                  activation="relu")(x)
        value_out = Dense(1,
                          kernel_regularizer=l2(mc.l2_reg),
                          activation="tanh",
                          name="value_out")(x)

        self.model = Model(in_x, [policy_out, value_out], name="reversi_model")

    def _build_residual_block(self, x):
        mc = self.config.model
        in_x = x
        x = Conv2D(filters=mc.cnn_filter_num,
                   kernel_size=mc.cnn_filter_size,
                   padding="same",
                   data_format="channels_first",
                   kernel_regularizer=l2(mc.l2_reg))(x)
        x = BatchNormalization(axis=1)(x)
        x = Activation("relu")(x)
        x = Conv2D(filters=mc.cnn_filter_num,
                   kernel_size=mc.cnn_filter_size,
                   padding="same",
                   data_format="channels_first",
                   kernel_regularizer=l2(mc.l2_reg))(x)
        x = BatchNormalization(axis=1)(x)
        x = Add()([in_x, x])
        x = Activation("relu")(x)
        return x

    @staticmethod
    def fetch_digest(weight_path):
        if os.path.exists(weight_path):
            m = hashlib.sha256()
            with open(weight_path, "rb") as f:
                m.update(f.read())
            return m.hexdigest()

    def load(self, config_path, weight_path):
        if os.path.exists(config_path) and os.path.exists(weight_path):
            logger.debug(f"loading model from {config_path}")
            with open(config_path, "rt") as f:
                self.model = Model.from_config(json.load(f))
            self.model.load_weights(weight_path)
            self.digest = self.fetch_digest(weight_path)
            logger.debug(f"loaded model digest = {self.digest}")
            return True
        else:
            logger.debug(
                f"model files does not exist at {config_path} and {weight_path}"
            )
            return False

    def save(self, config_path, weight_path):
        logger.debug(f"save model to {config_path}")
        with open(config_path, "wt") as f:
            json.dump(self.model.get_config(), f)
            self.model.save_weights(weight_path)
        self.digest = self.fetch_digest(weight_path)
        logger.debug(f"saved model digest {self.digest}")
class FinancialNewsAnalysisModel(object):
    model = None

    def __init__(self, nb_time_step, dim_data, batch_size=1, model_path=None):
        self.model_path = model_path
        self.model_path = model_path
        self.batch_size = batch_size
        self.size_of_input_data_dim = dim_data
        self.size_of_input_timesteps = nb_time_step
        self.build()
        self.weight_loaded = False
        if model_path is not None:
            self.load_weights()

    def build(self):
        dim_data = self.size_of_input_data_dim
        nb_time_step = self.size_of_input_timesteps
        news_input = Input(shape=(nb_time_step, dim_data), name='x1')
        lstm = LSTM(output_dim=nb_hidden_units, dropout_U=dropout, dropout_W=dropout,
                    W_regularizer=l2(l2_norm_alpha), b_regularizer=l2(l2_norm_alpha),
                    activation='tanh', name='h1')
        bi_lstm = Bidirectional(lstm, input_shape=(nb_time_step, dim_data), merge_mode='concat', name='h1')
        all_news_rep = bi_lstm(news_input)
        news_predictions = Dense(1, activation='linear')(all_news_rep)
        self.model = Model(news_input, news_predictions, name="deep rnn for financial news analysis")

    def reset(self):
        for l in self.model.layers:
            if type(l) is LSTM:
                l.reset_status()

    def compile_model(self, lr=0.0001, loss_weights=0.1):
        optimizer = Adam(lr=lr)
        loss = 'mse'
        # loss = custom_objective
        self.model.compile(optimizer=optimizer, loss=loss)
                           #metrics=['mse'])
        plot(self.model, to_file='model.png')

    def fit_model(self, X, y, X_val=None, y_val=None, epoch=500):
        early_stopping = EarlyStopping(monitor='val_loss', patience=3, verbose=0)
        if X_val is None:
            self.model.fit(X, y, batch_size=self.batch_size, nb_epoch=epoch, validation_split=0.2,
                           shuffle=True, callbacks=[early_stopping])
        else:
            self.model.fit(X, y, batch_size=self.batch_size, nb_epoch=epoch, validation_data=(X_val, y_val),
                           shuffle=True, callbacks=[early_stopping])

    def save(self):
        self.model.save_weights(self.model_path, overwrite=True)

    def load_weights(self):
        if os.path.exists(self.model_path):
            self.model.load_weights(self.model_path)
            self.weight_loaded = True

    def print_weights(self, weights=None, detail=False):
        weights = weights or self.model.get_weights()
        for w in weights:
            print("w%s: sum(w)=%s, ave(w)=%s" % (w.shape, np.sum(w), np.average(w)))
        if detail:
            for w in weights:
                print("%s: %s" % (w.shape, w))

    def model_eval(self, X, y):
        y_hat = self.model.predict(X, batch_size=1)
        count_true = 0
        count_all = y.shape[0]
        for i in range(y.shape[0]):
            count_true = count_true + 1 if y[i,0]*y_hat[i,0]>0 else count_true
            print y[i,0],y_hat[i,0]
        print count_all,count_true
Пример #30
0
class CChessModel:

    def __init__(self, config: Config):
        self.config = config
        self.model = None  # type: Model
        self.digest = None
        self.n_labels = len(ActionLabelsRed)
        self.graph = None
        self.api = None

    def build(self):
        mc = self.config.model
        in_x = x = Input((28, 10, 9))
        x = Conv2D(filters=mc.cnn_filter_num,
                   kernel_size=mc.cnn_first_filter_size,
                   padding="same",
                   data_format="channels_first",
                   use_bias=False,
                   kernel_regularizer=l2(mc.l2_reg),
                   name="input_conv-" + str(mc.cnn_first_filter_size) + "-" + str(mc.cnn_filter_num))(x)
        x = BatchNormalization(axis=1, name="input_batchnorm")(x)
        x = Activation("relu", name="input_relu")(x)

        for i in range(mc.res_layer_num):
            x = self._build_residual_block(x, i + 1)

        res_out = x

        # for policy output
        x = Conv2D(filters=32, kernel_size=1, data_format="channels_first", use_bias=False,
                   kernel_regularizer=l2(mc.l2_reg), name="policy_conv-1-2")(res_out)
        x = BatchNormalization(axis=1, name="policy_batchnorm")(x)
        x = Activation("relu", name="policy_relu")(x)
        x = Flatten(name="policy_flatten")(x)
        policy_out = Dense(self.n_labels, kernel_regularizer=l2(mc.l2_reg), activation="softmax", name="policy_out")(x)

        # for value output
        x = Conv2D(filters=4, kernel_size=1, data_format="channels_first", use_bias=False,
                   kernel_regularizer=l2(mc.l2_reg), name="value_conv-1-4")(res_out)
        x = BatchNormalization(axis=1, name="value_batchnorm")(x)
        x = Activation("relu", name="value_relu")(x)
        x = Flatten(name="value_flatten")(x)
        x = Dense(mc.value_fc_size, kernel_regularizer=l2(mc.l2_reg), activation="relu", name="value_dense")(x)
        value_out = Dense(1, kernel_regularizer=l2(mc.l2_reg), activation="tanh", name="value_out")(x)

        self.model = Model(in_x, [policy_out, value_out], name="cchess_model")
        self.graph = tf.get_default_graph()

    def _build_residual_block(self, x, index):
        mc = self.config.model
        in_x = x
        res_name = "res" + str(index)
        x = Conv2D(filters=mc.cnn_filter_num, kernel_size=mc.cnn_filter_size, padding="same",
                   data_format="channels_first", use_bias=False, kernel_regularizer=l2(mc.l2_reg),
                   name=res_name + "_conv1-" + str(mc.cnn_filter_size) + "-" + str(mc.cnn_filter_num))(x)
        x = BatchNormalization(axis=1, name=res_name + "_batchnorm1")(x)
        x = Activation("relu", name=res_name + "_relu1")(x)
        x = Conv2D(filters=mc.cnn_filter_num, kernel_size=mc.cnn_filter_size, padding="same",
                   data_format="channels_first", use_bias=False, kernel_regularizer=l2(mc.l2_reg),
                   name=res_name + "_conv2-" + str(mc.cnn_filter_size) + "-" + str(mc.cnn_filter_num))(x)
        x = BatchNormalization(axis=1, name="res" + str(index) + "_batchnorm2")(x)
        x = Add(name=res_name + "_add")([in_x, x])
        x = Activation("relu", name=res_name + "_relu2")(x)
        return x

    @staticmethod
    def fetch_digest(weight_path):
        if os.path.exists(weight_path):
            m = hashlib.sha256()
            with open(weight_path, "rb") as f:
                m.update(f.read())
            return m.hexdigest()
        return None

    def load(self, config_path, weight_path):
        if os.path.exists(config_path) and os.path.exists(weight_path):
            logger.debug(f"loading model from {config_path}")
            with open(config_path, "rt") as f:
                self.model = Model.from_config(json.load(f))
            self.model.load_weights(weight_path)
            self.digest = self.fetch_digest(weight_path)
            self.graph = tf.get_default_graph()
            logger.debug(f"loaded model digest = {self.digest}")
            return True
        else:
            logger.debug(f"model files does not exist at {config_path} and {weight_path}")
            return False

    def save(self, config_path, weight_path):
        logger.debug(f"save model to {config_path}")
        with open(config_path, "wt") as f:
            json.dump(self.model.get_config(), f)
            self.model.save_weights(weight_path)
        self.digest = self.fetch_digest(weight_path)
        logger.debug(f"saved model digest {self.digest}")

    def get_pipes(self, need_reload=True):
        if self.api is None:
            self.api = CChessModelAPI(self.config, self)
            self.api.start(need_reload)
        return self.api.get_pipe(need_reload)

    def close_pipes(self):
        if self.api is not None:
            self.api.close()
            self.api = None
Пример #31
0
def model(weights_input=None):

    inputs = Input(IMAGE_SIZE)
    conv1 = Conv2D(64,
                   3,
                   activation="relu",
                   padding="same",
                   kernel_initializer="he_normal")(inputs)
    conv1 = Conv2D(64,
                   3,
                   activation="relu",
                   padding="same",
                   kernel_initializer="he_normal")(conv1)
    pool1 = MaxPooling2D(pool_size=(2, 2))(conv1)

    conv2 = Conv2D(128,
                   3,
                   activation="relu",
                   padding="same",
                   kernel_initializer="he_normal")(pool1)
    conv2 = Conv2D(128,
                   3,
                   activation="relu",
                   padding="same",
                   kernel_initializer="he_normal")(conv2)
    pool2 = MaxPooling2D(pool_size=(2, 2))(conv2)

    conv3 = Conv2D(256,
                   3,
                   activation="relu",
                   padding="same",
                   kernel_initializer="he_normal")(pool2)
    conv3 = Conv2D(256,
                   3,
                   activation="relu",
                   padding="same",
                   kernel_initializer="he_normal")(conv3)
    pool3 = MaxPooling2D(pool_size=(2, 2))(conv3)

    conv4 = Conv2D(512,
                   3,
                   activation="relu",
                   padding="same",
                   kernel_initializer="he_normal")(pool3)
    conv4 = Conv2D(512,
                   3,
                   activation="relu",
                   padding="same",
                   kernel_initializer="he_normal")(conv4)
    drop4 = Dropout(0.5)(conv4)
    pool4 = MaxPooling2D(pool_size=(2, 2))(drop4)

    conv5 = Conv2D(1024,
                   3,
                   activation="relu",
                   padding="same",
                   kernel_initializer="he_normal")(pool4)
    conv5 = Conv2D(1024,
                   3,
                   activation="relu",
                   padding="same",
                   kernel_initializer="he_normal")(conv5)
    drop5 = Dropout(0.5)(conv5)

    up6 = Conv2D(512,
                 2,
                 activation="relu",
                 padding="same",
                 kernel_initializer="he_normal")(UpSampling2D(size=(2,
                                                                    2))(drop5))
    merge6 = Concatenate(axis=3)([drop4, up6])
    conv6 = Conv2D(512,
                   3,
                   activation="relu",
                   padding="same",
                   kernel_initializer="he_normal")(merge6)
    conv6 = Conv2D(512,
                   3,
                   activation="relu",
                   padding="same",
                   kernel_initializer="he_normal")(conv6)

    up7 = Conv2D(256,
                 2,
                 activation="relu",
                 padding="same",
                 kernel_initializer="he_normal")(UpSampling2D(size=(2,
                                                                    2))(conv6))
    merge7 = Concatenate(axis=3)([conv3, up7])
    conv7 = Conv2D(256,
                   3,
                   activation="relu",
                   padding="same",
                   kernel_initializer="he_normal")(merge7)
    conv7 = Conv2D(256,
                   3,
                   activation="relu",
                   padding="same",
                   kernel_initializer="he_normal")(conv7)

    up8 = Conv2D(128,
                 2,
                 activation="relu",
                 padding="same",
                 kernel_initializer="he_normal")(UpSampling2D(size=(2,
                                                                    2))(conv7))
    merge8 = Concatenate(axis=3)([conv2, up8])
    conv8 = Conv2D(128,
                   3,
                   activation="relu",
                   padding="same",
                   kernel_initializer="he_normal")(merge8)
    conv8 = Conv2D(128,
                   3,
                   activation="relu",
                   padding="same",
                   kernel_initializer="he_normal")(conv8)

    up9 = Conv2D(64,
                 2,
                 activation="relu",
                 padding="same",
                 kernel_initializer="he_normal")(UpSampling2D(size=(2,
                                                                    2))(conv8))
    merge9 = Concatenate(axis=3)([conv1, up9])
    conv9 = Conv2D(64,
                   3,
                   activation="relu",
                   padding="same",
                   kernel_initializer="he_normal")(merge9)
    conv9 = Conv2D(64,
                   3,
                   activation="relu",
                   padding="same",
                   kernel_initializer="he_normal")(conv9)
    conv9 = Conv2D(2,
                   3,
                   activation="relu",
                   padding="same",
                   kernel_initializer="he_normal")(conv9)

    conv10 = Conv2D(1, 1, activation="sigmoid")(conv9)

    model = Model(inputs=inputs, outputs=conv10)
    model.compile(optimizer=Adam(lr=1e-4),
                  loss="binary_crossentropy",
                  metrics=["accuracy"])

    if weights_input:
        model.load_weights(weights_input)

    return model
Пример #32
0
class ChessModel:
    def __init__(self, config: Config):
        self.config = config
        self.model = None  # type: Model
        self.digest = None
        self.queue = None

    def get_api_queue(self):
        if self.queue is None:
            self.queue = ChessModelAPI(self.config, self).prediction_queue
        return self.queue

    def build(self):
        mc = self.config.model
        in_x = x = Input((101, 8, 8))

        # (batch, channels, height, width)
        x = Conv2D(filters=mc.cnn_filter_num,
                   kernel_size=mc.cnn_filter_size,
                   padding="same",
                   data_format="channels_first",
                   use_bias=False,
                   kernel_regularizer=l2(mc.l2_reg))(x)
        x = BatchNormalization(axis=1)(x)
        x = Activation("relu")(x)

        for _ in range(mc.res_layer_num):
            x = self._build_residual_block(x)

        res_out = x

        # for policy output
        x = Conv2D(filters=2,
                   kernel_size=1,
                   data_format="channels_first",
                   use_bias=False,
                   kernel_regularizer=l2(mc.l2_reg))(res_out)
        x = BatchNormalization(axis=1)(x)
        x = Activation("relu")(x)
        x = Flatten()(x)
        # no output for 'pass'
        policy_out = Dense(self.config.n_labels,
                           kernel_regularizer=l2(mc.l2_reg),
                           activation="softmax",
                           name="policy_out")(x)

        # for value output
        x = Conv2D(filters=1,
                   kernel_size=1,
                   data_format="channels_first",
                   use_bias=False,
                   kernel_regularizer=l2(mc.l2_reg))(res_out)
        x = BatchNormalization(axis=1)(x)
        x = Activation("relu")(x)
        x = Flatten()(x)
        x = Dense(mc.value_fc_size,
                  kernel_regularizer=l2(mc.l2_reg),
                  activation="relu")(x)
        value_out = Dense(1,
                          kernel_regularizer=l2(mc.l2_reg),
                          activation="tanh",
                          name="value_out")(x)

        self.model = Model(in_x, [policy_out, value_out], name="chess_model")

    def _build_residual_block(self, x):
        mc = self.config.model
        in_x = x
        x = Conv2D(filters=mc.cnn_filter_num,
                   kernel_size=mc.cnn_filter_size,
                   padding="same",
                   data_format="channels_first",
                   use_bias=False,
                   kernel_regularizer=l2(mc.l2_reg))(x)
        x = BatchNormalization(axis=1)(x)
        x = Activation("relu")(x)
        x = Conv2D(filters=mc.cnn_filter_num,
                   kernel_size=mc.cnn_filter_size,
                   padding="same",
                   data_format="channels_first",
                   use_bias=False,
                   kernel_regularizer=l2(mc.l2_reg))(x)
        x = BatchNormalization(axis=1)(x)
        x = Add()([in_x, x])
        x = Activation("relu")(x)
        return x

    @staticmethod
    def fetch_digest(weight_path):
        if os.path.exists(weight_path):
            m = hashlib.sha256()
            with open(weight_path, "rb") as f:
                m.update(f.read())
            return m.hexdigest()

    def load(self, config_path, weight_path):
        mc = self.config.model
        resources = self.config.resource
        if mc.distributed and config_path == resources.model_best_config_path:
            try:
                logger.debug("loading model from server")
                ftp_connection = ftplib.FTP(
                    resources.model_best_distributed_ftp_server,
                    resources.model_best_distributed_ftp_user,
                    resources.model_best_distributed_ftp_password)
                ftp_connection.cwd(
                    resources.model_best_distributed_ftp_remote_path)
                ftp_connection.retrbinary("RETR model_best_config.json",
                                          open(config_path, 'wb').write)
                ftp_connection.retrbinary("RETR model_best_weight.h5",
                                          open(weight_path, 'wb').write)
                ftp_connection.quit()
            except:
                pass
        from tensorflow import get_default_graph
        if os.path.exists(config_path) and os.path.exists(weight_path):
            logger.debug(f"loading model from {config_path}")
            with open(config_path, "rt") as f:
                self.model = Model.from_config(json.load(f))
            self.model.load_weights(weight_path)
            self.graph = get_default_graph()
            self.digest = self.fetch_digest(weight_path)
            logger.debug(f"loaded model digest = {self.digest}")
            #print(self.model.summary)
            return True
        else:
            logger.debug(
                f"model files does not exist at {config_path} and {weight_path}"
            )
            return False

    def save(self, config_path, weight_path):
        logger.debug(f"save model to {config_path}")
        with open(config_path, "wt") as f:
            json.dump(self.model.get_config(), f)
            self.model.save_weights(weight_path)
        self.digest = self.fetch_digest(weight_path)
        logger.debug(f"saved model digest {self.digest}")

        mc = self.config.model
        resources = self.config.resource
        if mc.distributed and config_path == resources.model_best_config_path:
            try:
                logger.debug("saving model to server")
                ftp_connection = ftplib.FTP(
                    resources.model_best_distributed_ftp_server,
                    resources.model_best_distributed_ftp_user,
                    resources.model_best_distributed_ftp_password)
                ftp_connection.cwd(
                    resources.model_best_distributed_ftp_remote_path)
                fh = open(config_path, 'rb')
                ftp_connection.storbinary('STOR model_best_config.json', fh)
                fh.close()

                fh = open(weight_path, 'rb')
                ftp_connection.storbinary('STOR model_best_weight.h5', fh)
                fh.close()
                ftp_connection.quit()
            except:
                pass
Пример #33
0
class ModelZero:
    def __init__(self, config: Config) -> None:
        self.config = config
        self.digest = None

    def build(self) -> None:
        mc = self.config.model
        in_x = x = Input(shape=(7, 5, 3))

        x = Conv2D(filters=mc.cnn_filter_num,
                   kernel_size=mc.cnn_filter_size,
                   padding="same",
                   data_format="channels_last",
                   kernel_regularizer=l2(mc.l2_reg))(x)
        x = Activation("relu")(x)

        for _ in range(mc.res_layer_num):
            x = self._build_residual_block(x)
        x = Activation("relu")(x)

        res_out = x
        # for policy output
        x = Conv2D(filters=mc.cnn_filter_num,
                   kernel_size=mc.cnn_filter_size,
                   data_format="channels_last",
                   kernel_regularizer=l2(mc.l2_reg))(res_out)
        x = BatchNormalization(axis=3)(x)
        x = Activation("relu")(x)
        x = Flatten()(x)
        # no output for 'pass'

        x = Dense(mc.value_fc_size,
                  kernel_regularizer=l2(mc.l2_reg),
                  activation="relu")(x)
        policy_out = Dense(mc.value_fc_size,
                           kernel_regularizer=l2(mc.l2_reg),
                           activation="relu")(x)
        policy_out = Dense(315,
                           kernel_regularizer=l2(mc.l2_reg),
                           activation="softmax",
                           name="policy_out")(policy_out)
        value_out = Dense(32,
                          kernel_regularizer=l2(mc.l2_reg),
                          activation="relu")(x)
        value_out = Dense(1,
                          kernel_regularizer=l2(mc.l2_reg),
                          activation="tanh",
                          name="value_out")(value_out)

        self.model = Model(in_x, [policy_out, value_out], name="slipe_model")
        self.compile_model()
        # self.model.summary()

    def compile_model(self):
        self.optimizer = SGD(lr=self.config.model.learning_rate, momentum=0.9)
        losses = [objective_function_for_policy, objective_function_for_value]
        self.model.compile(optimizer=self.optimizer, loss=losses)

    def _build_residual_block(self, x):
        mc = self.config.model
        in_x = x
        x = BatchNormalization(axis=3)(x)
        x = Activation("relu")(x)
        x = Conv2D(filters=mc.cnn_filter_num,
                   kernel_size=mc.cnn_filter_size,
                   padding="same",
                   data_format="channels_last",
                   kernel_regularizer=l2(mc.l2_reg))(x)
        x = BatchNormalization(axis=3)(x)
        x = Activation("relu")(x)
        x = Dropout(1. / 3)(x)
        x = Conv2D(filters=mc.cnn_filter_num,
                   kernel_size=mc.cnn_filter_size,
                   padding="same",
                   data_format="channels_last",
                   kernel_regularizer=l2(mc.l2_reg))(x)
        x = Add()([in_x, x])
        return x

    # 重みの学習
    def replay(self, wps, pi_mcts, board_logs, plus_turns, weights,
               batch_size: int, beta: float) -> None:
        inputs = np.zeros((batch_size, 7, 5, 3))
        policy_true = np.zeros((batch_size, 315))
        values_true = np.zeros((batch_size))
        input_weights = np.zeros((batch_size))
        indices = np.random.choice(np.arange(len(wps)),
                                   size=batch_size,
                                   replace=False)
        mini_batch = [(wps[i], pi_mcts[i], board_logs[i], plus_turns[i],
                       weights[i]) for i in indices]

        for i, (winner, pi, board, plus_turn, weight) in enumerate(mini_batch):
            gs = GameState()
            gs.board = board
            inputs[i] = gs.to_inputs(flip=not plus_turn)  # shape=(4, 5, 5)
            policy_true[i] = pi**beta
            values_true[i] = winner
            input_weights[i] = weight

        # epochsは訓練データの反復回数、verbose=0は表示なしの設定
        self.model.fit(inputs, [policy_true, values_true],
                       sample_weight=input_weights,
                       epochs=1,
                       verbose=0,
                       shuffle=True)

    @staticmethod
    def fetch_digest(weight_path: str):
        if os.path.exists(weight_path):
            m = hashlib.sha256()
            with open(weight_path, "rb") as f:
                m.update(f.read())
            return m.hexdigest()

    def load(self, config_path: str, weight_path: str) -> bool:
        if os.path.exists(weight_path):  # os.path.exists(config_path) and
            logger.debug(f"loading model from {config_path}")
            with open(config_path, "rt") as f:
                self.model = Model.from_config(json.load(f))
            self.model.load_weights(weight_path)
            self.compile_model()
            # self.model.summary()
            self.digest = self.fetch_digest(weight_path)
            logger.debug(f"loaded model digest = {self.digest}")
            return True
        else:
            logger.debug(
                f"model files does not exist at {config_path} and {weight_path}"
            )
            return False

    def save(self, config_path: str, weight_path: str) -> None:
        logger.debug(f"save model to {config_path}")
        with open(config_path, "wt") as f:
            json.dump(self.model.get_config(), f)
        self.model.save_weights(weight_path)
        self.digest = self.fetch_digest(weight_path)
        logger.debug(f"saved model digest {self.digest}")