def load_model(self, modelpath): self.base_rbm = RBM(self.num_visible, self.num_hidden, self.k, self.learning_rate, self.momentum_coefficient, self.weight_decay) self.base_rbm.load(os.path.join(modelpath, "base_rbm.pt")) self.cluster_rbms = [] for i in range(self.num_cluster): self.cluster_rbms.append(RBM(self.num_visible, self.num_hidden, self.k, self.learning_rate, self.momentum_coefficient, self.weight_decay)) for i in range(self.num_cluster): self.cluster_rbms[i].load(os.path.join(modelpath, "cluster_rbm{}.pt".format(i+1))) with open(os.path.join(modelpath, "kmeans"), "rb") as fp: self.kmeans = pickle.load(fp) self.ensemble_model = load_model(os.path.join(modelpath, "ensemble_model"))
# open data with open(os.path.join(datapath, "train_matrix"), "rb") as fp: train_matrix = pickle.load(fp) train_matrix = train_matrix.astype(float) / 5 with open(os.path.join(datapath, "valid_interaction"), "rb") as fp: valid_interaction = pickle.load(fp) with open(os.path.join(datapath, "train_interaction"), "rb") as fp: train_interaction = pickle.load(fp) # train RBM num_visible = train_matrix.shape[1] num_hidden = 128 k = 5 epochs = 100 batch_size = 20 rbm = RBM(num_visible, num_hidden, k) rbm.train(train_matrix, epochs, batch_size) # train policy network epochs = 5 batch_size = 20 k = 5 learning_rate = 0.0001 neg_reward = -0.05 policy_net = PolicyNetwork(rbm, learning_rate) policy_net.train_epoch_first(train_interaction, epochs, batch_size, k, neg_reward) # validate valid_input = np.array([i[0] for i in valid_interaction]).astype(float) valid_tensor = torch.FloatTensor(valid_input) / 5
dhrbm_HR10 = test.hit_rate(dhrbm_prediction, last_item, 10) dhrbm_HR25 = test.hit_rate(dhrbm_prediction, last_item, 25) dhrbm_arhr = test.arhr(dhrbm_prediction, last_item) dhrbm_time = end_time - start_time # control: rbm with num_hidden = 256 train_data = np.concatenate( [data.rating_train_with_last, data.meta_train_with_last], axis=1) valid_data = np.concatenate([data.rating_valid, data.meta_valid], axis=1) entire_data = np.concatenate([train_data, valid_data], axis=0) num_hidden = 256 epochs = 100 batch_size = 20 control_256_rbm = RBM(num_visible, num_hidden, k) control_256_rbm.train(entire_data, epochs, batch_size) start_time = time.time() control_256_prediction = control_256_rbm.predict(test_tensor).numpy() end_time = time.time() control_256_HR10 = test.hit_rate(control_256_prediction, last_item, 10) control_256_HR25 = test.hit_rate(control_256_prediction, last_item, 25) control_256_arhr = test.arhr(control_256_prediction, last_item) control_256_time = end_time - start_time # control: rbm with num_hidden = 512 num_hidden = 512 epochs = 100 batch_size = 20
end_time = time.time() ensemble_HR10 = test.hit_rate(ensemble_prediction, last_item, 10) ensemble_HR25 = test.hit_rate(ensemble_prediction, last_item, 25) ensemble_arhr = test.arhr(ensemble_prediction, last_item) ensemble_time = end_time - start_time # train rbms for selection and weighted output methods epochs = 100 bootstrap_epochs = 50 batch_size = 20 # train base rbm train_data = np.concatenate( [data.rating_train_with_last, data.meta_train_with_last], axis=1) base_rbm = RBM(num_visible, num_hidden, k) base_rbm.train(train_data, epochs, batch_size) # get cluster rbm train input train_set = torch.FloatTensor(train_data) base_hidden = base_rbm.sample_hidden(train_set).numpy() kmeans = KMeans(n_clusters=num_cluster).fit(base_hidden) labels = kmeans.labels_ cluster_data = [] for i in range(num_cluster): data_inds = np.where(labels == i)[0] data = train_data[data_inds] cluster_data.append(data) # train cluster rbms cluster_rbms = []
if __name__ == "__main__": datapath = "../data" modelpath = "../model" # open data with open(os.path.join(datapath, "train_matrix"), "rb") as fp: train_matrix = pickle.load(fp) train_matrix = train_matrix.astype(float) / 5 with open(os.path.join(datapath, "test_interaction"), "rb") as fp: test_interaction = pickle.load(fp) # load model num_visible = train_matrix.shape[1] num_hidden = 128 k = 5 rbm = RBM(num_visible, num_hidden, k) policy_net = PolicyNetwork(rbm) policy_net.load_model(modelpath, "policy_net.pt") # validate test_input = np.array([i[0] for i in test_interaction]).astype(float) test_tensor = torch.FloatTensor(test_input) / 5 test_next_books = [i[1] for i in test_interaction] rlrbm_prediction = policy_net.forward(test_tensor, np.sign(test_tensor)).detach().numpy() rlrbm_prediction = rlrbm_prediction * np.where(test_tensor==0, 1, 0) rlrbm_HR10 = hit_rate(rlrbm_prediction, test_next_books, 10) rlrbm_HR25 = hit_rate(rlrbm_prediction, test_next_books, 25) rlrbm_arhr = arhr(rlrbm_prediction, test_next_books)
def train_base_rbm(self, train_data, epochs, batch_size): self.base_rbm = RBM(self.num_visible, self.num_hidden, self.k, self.learning_rate, self.momentum_coefficient, self.weight_decay) self.base_rbm.train(train_data, epochs, batch_size)
class DHRBM: def __init__(self, num_visible, num_hidden, k, num_cluster, learning_rate=1e-2, momentum_coefficient=0.5, weight_decay=1e-4): self.num_visible = num_visible self.num_hidden = num_hidden self.k = k self.num_cluster = num_cluster self.learning_rate = learning_rate self.momentum_coefficient = momentum_coefficient self.weight_decay = weight_decay def train_base_rbm(self, train_data, epochs, batch_size): self.base_rbm = RBM(self.num_visible, self.num_hidden, self.k, self.learning_rate, self.momentum_coefficient, self.weight_decay) self.base_rbm.train(train_data, epochs, batch_size) def cluster_data(self, train_data): train_set = torch.FloatTensor(train_data) base_hidden = self.base_rbm.sample_hidden(train_set).numpy() self.kmeans = KMeans(n_clusters=self.num_cluster).fit(base_hidden) labels = self.kmeans.labels_ self.cluster_data = [] for i in range(self.num_cluster): data_inds = np.where(labels == i)[0] data = train_data[data_inds] self.cluster_data.append(data) def train_cluster_rbm(self, train_data, epochs, bootstrap_epochs, batch_size): self.train_base_rbm(train_data, epochs, batch_size) self.cluster_data(train_data) self.cluster_rbms = [] for i in range(self.num_cluster): cluster_rbm = copy.deepcopy(self.base_rbm) cluster_rbm.weights_momentum = torch.zeros(self.num_visible, self.num_hidden) cluster_rbm.visible_bias_momentum = torch.zeros(self.num_visible) cluster_rbm.hidden_bias_momentum = torch.zeros(self.num_hidden) cluster_rbm.train(self.cluster_data[i], bootstrap_epochs, batch_size) self.cluster_rbms.append(cluster_rbm) def make_ensemble_model(self, input_dim, hidden_dim, output_dim): input_layer = Input(shape=(input_dim,)) hidden_layer = Dense(hidden_dim, activation='relu')(input_layer) output = Dense(output_dim, activation='sigmoid')(hidden_layer) self.ensemble_model = Model(inputs=input_layer, outputs=output) temp_weight = np.mean(np.array([self.cluster_rbms[i].weights.numpy().T for i in range(self.num_cluster)]), axis=0) temp_bias = np.mean(np.array([self.cluster_rbms[i].visible_bias.numpy().T for i in range(self.num_cluster)]), axis=0) self.ensemble_model.layers[2].set_weights([temp_weight, temp_bias]) self.ensemble_model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy']) def make_ensemble_input(self, train_data, num_train): train_set = torch.FloatTensor(train_data) hiddens = [] for i in range(self.num_cluster): hidden = self.cluster_rbms[i].sample_hidden(train_set).numpy()[:num_train] hiddens.append(hidden) base_hidden = self.base_rbm.sample_hidden(train_set).numpy()[:num_train] kmeans_dist = self.kmeans.transform(base_hidden) ensemble_input_data = np.concatenate(hiddens+[kmeans_dist], axis=1) return ensemble_input_data def train_ensemble_model(self, train_data, output_data, num_train, epochs, batch_size): ensemble_input = self.make_ensemble_input(train_data, num_train) input_dim = ensemble_input.shape[1] output_dim = output_data.shape[1] hidden_dim = int((input_dim-3)/3) self.make_ensemble_model(input_dim, hidden_dim, output_dim) history = self.ensemble_model.fit(ensemble_input, output_data, batch_size=batch_size, epochs=epochs, verbose=1) return history def predict(self, test_data): ensemble_input = self.make_ensemble_input(test_data, test_data.shape[0]) return self.ensemble_model.predict(ensemble_input) def save_model(self, modelpath): self.base_rbm.save(os.path.join(modelpath, "base_rbm.pt")) for i in range(self.num_cluster): self.cluster_rbms[i].save(os.path.join(modelpath, "cluster_rbm{}.pt".format(i+1))) with open(os.path.join(modelpath, "kmeans"), "wb") as fp: pickle.dump(self.kmeans, fp) self.ensemble_model.save(os.path.join(modelpath, "ensemble_model")) def load_model(self, modelpath): self.base_rbm = RBM(self.num_visible, self.num_hidden, self.k, self.learning_rate, self.momentum_coefficient, self.weight_decay) self.base_rbm.load(os.path.join(modelpath, "base_rbm.pt")) self.cluster_rbms = [] for i in range(self.num_cluster): self.cluster_rbms.append(RBM(self.num_visible, self.num_hidden, self.k, self.learning_rate, self.momentum_coefficient, self.weight_decay)) for i in range(self.num_cluster): self.cluster_rbms[i].load(os.path.join(modelpath, "cluster_rbm{}.pt".format(i+1))) with open(os.path.join(modelpath, "kmeans"), "rb") as fp: self.kmeans = pickle.load(fp) self.ensemble_model = load_model(os.path.join(modelpath, "ensemble_model"))