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)
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')
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}
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
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
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)
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)
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)
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}
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}")
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)
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
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()
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
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}")
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()
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)
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
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
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)
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')
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)
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)
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
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
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
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
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}")