コード例 #1
0
ファイル: train.py プロジェクト: loicvz190/MMGCN
    def __init__(self, args):
        ##########################################################################################################################################
        seed = args.seed
        np.random.seed(seed)
        random.seed(seed)
        self.device = torch.device("cuda:0" if torch.cuda.is_available() and not args.no_cuda else "cpu")
        ##########################################################################################################################################
        self.model_name = args.model_name
        self.data_path = args.data_path
        self.learning_rate = args.l_r#l_r#
        self.weight_decay = args.weight_decay#weight_decay#
        self.batch_size = args.batch_size
        self.concat = args.concat
        self.num_workers = args.num_workers
        self.num_epoch = args.num_epoch
        self.num_user = args.num_user
        self.num_item = args.num_item
        self.dim_latent = args.dim_latent
        self.aggr_mode = args.aggr_mode#aggr_mode#
        self.num_layer = args.num_layer
        self.has_id = args.has_id
        self.dim_v = 2048
        self.dim_a = 128
        self.dim_t = 100
        ##########################################################################################################################################
        print('Data loading ...')
        self.train_dataset = MyDataset('./Data/', self.num_user, self.num_item)
        self.train_dataloader = DataLoader(self.train_dataset, batch_size=self.batch_size, shuffle=True, num_workers=self.num_workers)
        self.edge_index = np.load('./Data/train.npy')
        self.val_dataset = np.load('./Data/val.npy')
        self.test_dataset = np.load('./Data/test.npy')
        self.val_test_dataset = np.load('./Data/val_test.npy')
        self.v_feat = np.load('./Data/FeatureVideo_normal.npy')
        self.a_feat = np.load('./Data/FeatureAudio_avg_normal.npy')
        self.t_feat = np.load('./Data/FeatureText_stl_normal.npy')
        print('Data has been loaded.')
        ##########################################################################################################################################
        if self.model_name == 'MMGCN':
            self.features = [self.v_feat, self.a_feat, self.t_feat]
            self.model = MMGCN(self.features, self.edge_index, self.batch_size, self.num_user, self.num_item, self.aggr_mode, self.concat, self.num_layer, self.has_id, self.dim_latent).cuda()

        elif self.model_name == 'VBPR':
            self.dim_feat = self.dim_v+self.dim_a+self.dim_t
            self.features = torch.tensor(np.concatenate((self.v_feat, self.a_feat, self.t_feat), axis=1), dtype=torch.float)
            self.model = VBPR_model(self.num_user, self.num_item, self.dim_latent, self.dim_feat, self.features).to(self.device)

        elif self.model_name == 'GraphSAGE':
            self.dim_feat = self.dim_v+self.dim_a+self.dim_t
            self.features = torch.tensor(np.concatenate((self.v_feat, self.a_feat, self.t_feat), axis=1), dtype=torch.float)
            self.model = MMGraphSAGE(self.features, self.edge_index, self.batch_size, self.num_user, self.num_item, self.dim_latent, self.dim_feat).cuda()

        elif self.model_name == 'NGCF':
            self.model = NGCF(self.v_feat, self.a_feat, self.t_feat, self.edge_index, self.batch_size, self.num_user, self.num_item, self.dim_latent).cuda()

        if args.PATH_weight_load and os.path.exists(args.PATH_weight_load):
            self.model.load_state_dict(torch.load(args.PATH_weight_load))
            print('module weights loaded....')
        ##########################################################################################################################################
        self.optimizer = torch.optim.Adam([{'params': self.model.parameters(), 'lr': self.learning_rate}], weight_decay=self.weight_decay)
コード例 #2
0
 def __init__(self, args, n_user, n_item, norm_adj):
     super(Meta, self).__init__()
     self.update_lr = args.update_lr
     self.meta_lr = args.meta_lr
     self.task_num = args.batch_size
     self.update_step = args.update_step
     self.update_step_test = args.update_step_test
     self.net = NGCF(n_user, n_item, norm_adj, args)
     self.meta_optim = optim.Adam(self.net.parameters(), lr=self.meta_lr)
コード例 #3
0
class Meta(nn.Module):
    def __init__(self, args, n_user, n_item, norm_adj):
        super(Meta, self).__init__()
        self.update_lr = args.update_lr
        self.meta_lr = args.meta_lr
        self.task_num = args.batch_size
        self.update_step = args.update_step
        self.update_step_test = args.update_step_test
        self.net = NGCF(n_user, n_item, norm_adj, args)
        self.meta_optim = optim.Adam(self.net.parameters(), lr=self.meta_lr)

    def forward(self, users, pos_items, neg_items, test_pos_items,
                test_neg_items):

        losses_q = [0 for _ in range(self.update_step + 1)
                    ]  # losses_q[i] is the loss on step i

        # 1. run the i-th task and compute loss for k=0
        u_g_embedding, pos_i_g_embedding, neg_i_g_embedding = self.net(
            users, pos_items, neg_items, vars=None)
        loss, _, _ = self.net.create_bpr_loss(u_g_embedding, pos_i_g_embedding,
                                              neg_i_g_embedding)
        grad = torch.autograd.grad(loss, self.net.parameters())
        fast_weights = list(
            map(lambda p: p[1] - self.update_lr * p[0],
                zip(grad, self.net.parameters())))

        # this is the loss and accuracy before first update
        with torch.no_grad():
            u_g_embedding_q, pos_i_g_embedding_q, neg_i_g_embedding_q = self.net(
                users, test_pos_items, test_neg_items, self.net.parameters())
            loss_q, _, _ = self.net.create_bpr_loss(u_g_embedding_q,
                                                    pos_i_g_embedding_q,
                                                    neg_i_g_embedding_q)
            losses_q[0] += loss_q

        # this is the loss and accuracy after the first update
        with torch.no_grad():
            u_g_embedding_q, pos_i_g_embedding_q, neg_i_g_embedding_q = self.net(
                users, test_pos_items, test_neg_items, fast_weights)
            loss_q, _, _ = self.net.create_bpr_loss(u_g_embedding_q,
                                                    pos_i_g_embedding_q,
                                                    neg_i_g_embedding_q)
            losses_q[1] += loss_q

        for k in range(1, self.update_step):
            # 1. run the i-th task and compute loss for k=1~K-1
            u_g_embedding, pos_i_g_embedding, neg_i_g_embedding = self.net(
                users, pos_items, neg_items, fast_weights)
            loss, _, _ = self.net.create_bpr_loss(u_g_embedding,
                                                  pos_i_g_embedding,
                                                  neg_i_g_embedding)
            # 2. compute grad on theta_pi
            grad = torch.autograd.grad(loss, self.net.parameters())
            # 3. theta_pi = theta_pi - train_lr * grad
            fast_weights = list(
                map(lambda p: p[1] - self.update_lr * p[0],
                    zip(grad, fast_weights)))

            u_g_embedding_q, pos_i_g_embedding_q, neg_i_g_embedding_q = self.net(
                users, test_pos_items, test_neg_items, fast_weights)
            # loss_q will be overwritten and just keep the loss_q on last update step.
            loss_q, _, _ = self.net.create_bpr_loss(u_g_embedding_q,
                                                    pos_i_g_embedding_q,
                                                    neg_i_g_embedding_q)
            losses_q[k + 1] += loss_q

        # end of all tasks
        loss_q = losses_q[-1]

        # optimize theta parameters
        self.meta_optim.zero_grad()
        loss_q.backward()
        self.meta_optim.step()
        # average testing acc on batch tasks for different uodate step
        return [one.tolist() for one in losses_q]

    def finetunning(self, users, pos_items, neg_items, test_pos_items,
                    test_neg_items):

        losses_q = [0 for _ in range(self.update_step_test + 1)
                    ]  # losses_q[i] is the loss on step i

        # 1. run the i-th task and compute loss for k=0
        u_g_embedding, pos_i_g_embedding, neg_i_g_embedding = self.net(
            users, pos_items, neg_items, vars=None)
        loss, _, _ = self.net.create_bpr_loss(u_g_embedding, pos_i_g_embedding,
                                              neg_i_g_embedding)
        grad = torch.autograd.grad(loss, self.net.parameters())
        fast_weights = list(
            map(lambda p: p[1] - self.update_lr * p[0],
                zip(grad, self.net.parameters())))

        # this is the loss and accuracy before first update
        with torch.no_grad():
            u_g_embedding_q, pos_i_g_embedding_q, neg_i_g_embedding_q = self.net(
                users, test_pos_items, test_neg_items, self.net.parameters())
            loss_q, _, _ = self.net.create_bpr_loss(u_g_embedding_q,
                                                    pos_i_g_embedding_q,
                                                    neg_i_g_embedding_q)
            losses_q[0] += loss_q

        # this is the loss and accuracy after the first update
        with torch.no_grad():
            # [setsz, nway]
            u_g_embedding_q, pos_i_g_embedding_q, neg_i_g_embedding_q = self.net(
                users, test_pos_items, test_neg_items, fast_weights)
            loss_q, _, _ = self.net.create_bpr_loss(u_g_embedding_q,
                                                    pos_i_g_embedding_q,
                                                    neg_i_g_embedding_q)
            losses_q[1] += loss_q

        for k in range(1, self.update_step_test):
            # 1. run the i-th task and compute loss for k=1~K-1
            u_g_embedding, pos_i_g_embedding, neg_i_g_embedding = self.net(
                users, pos_items, neg_items, fast_weights)
            loss, _, _ = self.net.create_bpr_loss(u_g_embedding,
                                                  pos_i_g_embedding,
                                                  neg_i_g_embedding)
            # 2. compute grad on theta_pi
            grad = torch.autograd.grad(loss, self.net.parameters())
            # 3. theta_pi = theta_pi - train_lr * grad
            fast_weights = list(
                map(lambda p: p[1] - self.update_lr * p[0],
                    zip(grad, fast_weights)))

            u_g_embedding_q, pos_i_g_embedding_q, neg_i_g_embedding_q = self.net(
                users, test_pos_items, test_neg_items, fast_weights)
            # loss_q will be overwritten and just keep the loss_q on last update step.
            loss_q, _, _ = self.net.create_bpr_loss(u_g_embedding_q,
                                                    pos_i_g_embedding_q,
                                                    neg_i_g_embedding_q)
            losses_q[k + 1] += loss_q

        return [one.tolist() for one in losses_q]
コード例 #4
0
import warnings
warnings.filterwarnings('ignore')
from time import time


if __name__ == '__main__':

    args.device = torch.device('cuda:' + str(args.gpu_id))

    plain_adj, norm_adj, mean_adj = data_generator.get_adj_mat()

    args.node_dropout = eval(args.node_dropout)
    args.mess_dropout = eval(args.mess_dropout)

    model = NGCF(data_generator.n_users,
                 data_generator.n_items,
                 norm_adj,
                 args).to(args.device)

    t0 = time()
    """
    *********************************************************
    Train.
    """
    cur_best_pre_0, stopping_step = 0, 0
    optimizer = optim.Adam(model.parameters(), lr=args.lr)

    loss_loger, pre_loger, rec_loger, ndcg_loger, hit_loger = [], [], [], [], []
    for epoch in range(args.epoch):
        t1 = time()
        loss, mf_loss, emb_loss = 0., 0., 0.
        n_batch = data_generator.n_train // args.batch_size + 1
コード例 #5
0
    pretrain_data = np.load(pretrain_path)
    print('load the pretrained embeddings.')
    return pretrain_data


pretrain_data = None
if args.pretrain == -1:
    try:
        pretrain_data = load_pretrained_data()
    except Exception:
        raise RuntimeError("pretrain embedding not found.")

adj_list = dataset.get_adj_mat()
model = NGCF(adj_list,
             dataset.user_attr,
             dataset.item_attr,
             data_config=data_config,
             args=args,
             pretrain_data=pretrain_data)
"""
*********************************************************
Save the model parameters.
"""
weight_list = [
    model.weights[key] for key in model.weights
    if key not in ('user_embedding', 'item_embedding')
]
saver = tf.train.Saver(var_list=list(model.weights.values()))

config = tf.ConfigProto()
config.gpu_options.allow_growth = True
sess = tf.Session(config=config)
コード例 #6
0
import torch

from NGCF import NGCF
from utility.batch_test import *
from utility.helper import *

if __name__ == '__main__':
    args.device = torch.device('cuda:' + str(args.gpu_id))
    adj_mat, norm_adj_mat, mean_adj_mat = data_generator.get_adj_mat()

    model = NGCF(data_generator.n_users, data_generator.n_items, norm_adj_mat,
                 args).to(args.device)

    t0 = time()
    """
    *********************************************************
    Train.
    """
    cur_best_pre_0, stopping_step = 0, 0
    optimizer = torch.optim.Adam(model.parameters(), lr=args.lr)

    loss_loger, pre_loger, rec_loger, ndcg_loger, hit_loger = [], [], [], [], []
    for epoch in range(args.epoch):
        model.train()

        t1 = time()
        loss, mf_loss, emb_loss = 0., 0., 0.
        n_batch = data_generator.n_train // args.batch_size + 1

        for idx in range(n_batch):
            users, pos_items, neg_items = data_generator.sample()
コード例 #7
0
ファイル: train.py プロジェクト: loicvz190/MMGCN
class Net:
    def __init__(self, args):
        ##########################################################################################################################################
        seed = args.seed
        np.random.seed(seed)
        random.seed(seed)
        self.device = torch.device("cuda:0" if torch.cuda.is_available() and not args.no_cuda else "cpu")
        ##########################################################################################################################################
        self.model_name = args.model_name
        self.data_path = args.data_path
        self.learning_rate = args.l_r#l_r#
        self.weight_decay = args.weight_decay#weight_decay#
        self.batch_size = args.batch_size
        self.concat = args.concat
        self.num_workers = args.num_workers
        self.num_epoch = args.num_epoch
        self.num_user = args.num_user
        self.num_item = args.num_item
        self.dim_latent = args.dim_latent
        self.aggr_mode = args.aggr_mode#aggr_mode#
        self.num_layer = args.num_layer
        self.has_id = args.has_id
        self.dim_v = 2048
        self.dim_a = 128
        self.dim_t = 100
        ##########################################################################################################################################
        print('Data loading ...')
        self.train_dataset = MyDataset('./Data/', self.num_user, self.num_item)
        self.train_dataloader = DataLoader(self.train_dataset, batch_size=self.batch_size, shuffle=True, num_workers=self.num_workers)
        self.edge_index = np.load('./Data/train.npy')
        self.val_dataset = np.load('./Data/val.npy')
        self.test_dataset = np.load('./Data/test.npy')
        self.val_test_dataset = np.load('./Data/val_test.npy')
        self.v_feat = np.load('./Data/FeatureVideo_normal.npy')
        self.a_feat = np.load('./Data/FeatureAudio_avg_normal.npy')
        self.t_feat = np.load('./Data/FeatureText_stl_normal.npy')
        print('Data has been loaded.')
        ##########################################################################################################################################
        if self.model_name == 'MMGCN':
            self.features = [self.v_feat, self.a_feat, self.t_feat]
            self.model = MMGCN(self.features, self.edge_index, self.batch_size, self.num_user, self.num_item, self.aggr_mode, self.concat, self.num_layer, self.has_id, self.dim_latent).cuda()

        elif self.model_name == 'VBPR':
            self.dim_feat = self.dim_v+self.dim_a+self.dim_t
            self.features = torch.tensor(np.concatenate((self.v_feat, self.a_feat, self.t_feat), axis=1), dtype=torch.float)
            self.model = VBPR_model(self.num_user, self.num_item, self.dim_latent, self.dim_feat, self.features).to(self.device)

        elif self.model_name == 'GraphSAGE':
            self.dim_feat = self.dim_v+self.dim_a+self.dim_t
            self.features = torch.tensor(np.concatenate((self.v_feat, self.a_feat, self.t_feat), axis=1), dtype=torch.float)
            self.model = MMGraphSAGE(self.features, self.edge_index, self.batch_size, self.num_user, self.num_item, self.dim_latent, self.dim_feat).cuda()

        elif self.model_name == 'NGCF':
            self.model = NGCF(self.v_feat, self.a_feat, self.t_feat, self.edge_index, self.batch_size, self.num_user, self.num_item, self.dim_latent).cuda()

        if args.PATH_weight_load and os.path.exists(args.PATH_weight_load):
            self.model.load_state_dict(torch.load(args.PATH_weight_load))
            print('module weights loaded....')
        ##########################################################################################################################################
        self.optimizer = torch.optim.Adam([{'params': self.model.parameters(), 'lr': self.learning_rate}], weight_decay=self.weight_decay)
        ##########################################################################################################################################

    def run(self):
        max_recall = 0.0
        max_pre = 0.0
        max_ndcg = 0.0
        step = 0
        for epoch in range(self.num_epoch):
            self.model.train()
            print('Now, training start ...')
            pbar = tqdm(total=len(self.train_dataset))
            sum_loss = 0.0
            for data in self.train_dataloader:
                self.optimizer.zero_grad()
                self.loss = self.model.loss(data)
                self.loss.backward()
                self.optimizer.step()
                pbar.update(self.batch_size)
                sum_loss += self.loss
            print(sum_loss/self.batch_size)
            pbar.close()

            if epoch % 5 == 0:
                print('Validation start...')
                self.model.eval()
                with torch.no_grad():
                    precision, recall, ndcg_score = self.model.accuracy(self.val_dataset, topk=10)
                    print('---------------------------------Val: {0}-th epoch {1}-th top Precition:{2:.4f} Recall:{3:.4f} NDCG:{4:.4f}---------------------------------'.format(
                        epoch, 10, precision, recall, ndcg_score))

            if epoch % 10 == 0:
                self.model.eval()
                with torch.no_grad():
                    precision, recall, ndcg_score = self.model.accuracy(self.test_dataset, topk=10)
                    print('---------------------------------Test: {0}-th epoch {1}-th top Precition:{2:.4f} Recall:{3:.4f} NDCG:{4:.4f}---------------------------------'.format(
                        epoch, 10, precision, recall, ndcg_score))

        return max_recall, max_pre, max_ndcg
コード例 #8
0
from NGCF import NGCF
# data will be loaded in batch_test
from utility.batch_test import *
from time import time
from tqdm import tqdm 


if __name__ == '__main__':
    args.device = torch.device('cuda:' + str(args.gpu_id))
    norm_adj = data_generator.get_adj_mat()

    args.node_dropout = eval(args.node_dropout)
    args.mess_dropout = eval(args.mess_dropout)

    model = NGCF(data_generator.n_users,
                 data_generator.n_items,
                 norm_adj,
                 args).to(args.device)

    t0 = time()
    """
    *********************************************************
    Train.
    """
    cur_best_pre_0, stopping_step = 0, 0
    optimizer = optim.Adam(model.parameters(), lr=args.lr)

    for epoch in range(args.epoch):
        t1 = time()
        loss, mf_loss, emb_loss = 0., 0., 0.
        n_batch = data_generator.n_train // args.batch_size + 1