【代码解析(5)】Secure Federated Matrix Factorization

Regular_MF.py

import time
import copy
import numpy as np

from shared_parameter import *
from load_data import train_data, test_data, item_id_list, user_id_list, predict_step


# 初始化用户矩阵和项目矩阵,每个元素都是0.01的初始值
user_vector = np.zeros([len(user_id_list), hidden_dim]) + 0.01

item_vector = np.zeros([len(item_id_list), hidden_dim]) + 0.01


def iterate():
    # 迭代更新用户和项目矩阵 User updates
    for i in range(len(user_id_list)):
        # 每一行
        for r in range(len(train_data[user_id_list[i]])):
            '''
                对于每个user,遍历他的所有交互item,每次计算都更新user的行和item的列
                print('我想看看上面这一句是什么:')
                print(user_id_list[i])
                1出现23次 4出现13次 5出现12次 6出现18次 7出现20次 8出现14次 10出现9次
                加在一起正好109个交互记录
                # print(train_data[user_id_list[i]])
                train_data[user_id_list[i]]表示用户user_id_list[i]的所有记录,list形式
            '''
            item_id, rate, _ = train_data[user_id_list[i]][r]
            '''
                train_data[user_id_list[i]][r]表示
                用户交互记录train_data[user_id_list[i]][r]第r条记录
                例:[15, 5.0, 964983815]
                item_id存储该item在item_id_list列表中的索引
                rate存储用户user_id_list[i]对该item的评分
            '''
            # 行向量与列向量相乘:user_vector[i],rate表示真值
            # 用户user_vector[i]和item_id(对应item_vector矩阵的第item_id行)有真实交互的
            error = rate - np.dot(user_vector[i], np.transpose(item_vector[item_id]))

            # print(user_vector[i])
            # 正好是100个数据对应100列 [0.02083091 0.02083091...]
            # 某个用户与某个item计算出来error然后就要更新用户行和item列了
            user_vector[i] = user_vector[i] - \
                            lr * (-2 * error * item_vector[item_id] + 2 * reg_u * user_vector[i])
            '''
                print('------------------')
                负数:print(lr * (-2 * error * item_vector[item_id] + 2 * reg_u * user_vector[i]))
                print(user_vector[i])
            '''
            item_vector[item_id] = item_vector[item_id] - \
                                   lr * (-2 * error * user_vector[i] + 2 * reg_v * item_vector[item_id])

# 遍历完所有的交互记录得到更新后的user_vector和item_vector


def loss():
    loss = []
    for i in range(len(user_id_list)):
        for r in range(len(train_data[user_id_list[i]])):
            item_id, rate, _ = train_data[user_id_list[i]][r]
            # 上面计算error需要np.transpose(item_vector[item_id])
            # 这里就不需要了吗
            # 矩阵相乘需要转置,向量相乘不需要,因为都是单个向量对应元素相乘相加
            error = (rate - np.dot(user_vector[i], np.transpose(item_vector[item_id]))) ** 2
            '''
                Time 0.0019617080688476562 s
                loss 0.7326558669374119
                Converged
                rmse 1.3969165
            '''
            # error = (rate - np.dot(user_vector[i], item_vector[item_id])) ** 2
            '''
                Time 0.0009965896606445312 s
                loss 0.7326558669374119
                Converged
                rmse 1.3969165
                上面两句好像结果一样
            '''
            loss.append(error)
    return np.mean(loss)


if __name__ == '__main__':
    # max_iteration=175
    for iteration in range(max_iteration):

        print('#################################')
        print('Iteration', iteration)
        '''
            deepcopy一旦复制出来了,就独立了
            copy.copy()
            copy.deepcopy()
        '''
        tmp_user_vector = copy.deepcopy(user_vector)
        tmp_item_vector = copy.deepcopy(item_vector)

        t = time.time()
        iterate()
        '''
        tmp_user_vector = copy.deepcopy(user_vector)
        tmp_item_vector = copy.deepcopy(item_vector)
        记录上一个值
        经过iterate(),user_vector和item_vector都更新了
        
        '''
        print('Time', time.time() - t, 's')

        print('loss', loss())
        '''
        每一次迭代iterate()得到的user_vector和item_vector都不一样
        因为每次作为初始矩阵都不一样了error也就不一样了
        
        '''
        '''
            print(np.abs(user_vector - tmp_user_vector)) 输出矩阵 7×100矩阵每一行值一样
            print(np.mean(np.abs(user_vector - tmp_user_vector))) 矩阵所有元素相减除以总数
            1e-4=0.0001
        '''
        # print(np.abs(user_vector - tmp_user_vector))
        if np.mean(np.abs(user_vector - tmp_user_vector)) < 1e-4 and\
           np.mean(np.abs(item_vector - tmp_item_vector)) < 1e-4:
            print('Converged')
            break

    np.save('user-%s' % len(user_id_list), user_vector)
    np.save('item-%s' % len(item_id_list), item_vector)

    prediction = []
    real_label = []

    # testing
    # print('..................')
    # print(user_vector[0:1])
    # print(item_vector)
    # print(np.dot(user_vector[0:1], np.transpose(item_vector)))
    # print(np.dot(user_vector[0:1], np.transpose(item_vector))[0])
    # 这两句一样的表述  print(np.dot(user_vector[0:1], np.transpose(item_vector)))
    '''这样相乘的话,与user_i无关的item也参与了'''
    for i in range(len(user_id_list)):
        '''
        # i从0开始到6,有7个user
        每个user有3个交互记录
        一共可得21个评分预测
        '''

        p = np.dot(user_vector[i:i+1], np.transpose(item_vector))[0]
        # p为1×40的矩阵,预测评分矩阵
        r = test_data[user_id_list[i]]
        # 列表r中的每个列表为与用户user_id_list[i]有关的item信息
        real_label.append([e[1] for e in r])
        # real_label记录每个评分
        prediction.append([p[e[0]] for e in r])
        '''p[e[0]]表示p矩阵的第几个记录,这个记录是与用户真实交互的,无关的item直接忽略不要'''

    prediction = np.array(prediction, dtype=np.float32)
    real_label = np.array(real_label, dtype=np.float32)
    # print(prediction)
    # RMSE
    print('rmse', np.sqrt(np.mean(np.square(real_label - prediction))))
    # MAE
    print('mae', np.mean(np.abs(real_label - prediction)))


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Federated learning是一种分布式机器学习方法,它允许在不共享数据的情况下训练模型。以下是一个简单的Python代码示例,用于实现基本的federated learning: 1. 客户端代码: ```python import tensorflow as tf import numpy as np # 加载本地数据 def load_data(): # 加载本地数据 return x_train, y_train # 定义客户端模型 def create_model(): model = tf.keras.models.Sequential([ tf.keras.layers.Dense(10, activation='relu', input_shape=(784,)), tf.keras.layers.Dense(10, activation='softmax') ]) model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy']) return model # 客户端训练 def train_client(model, x_train, y_train): model.fit(x_train, y_train, epochs=5, batch_size=32) return model # 客户端评估 def evaluate_client(model, x_test, y_test): loss, acc = model.evaluate(x_test, y_test) return acc # 加载本地数据 x_train, y_train = load_data() # 创建客户端模型 model = create_model() # 客户端训练 model = train_client(model, x_train, y_train) # 客户端评估 acc = evaluate_client(model, x_test, y_test) # 将模型上传到服务器 model_weights = model.get_weights() ``` 2. 服务器代码: ```python import tensorflow as tf import numpy as np # 加载本地数据 def load_data(): # 加载本地数据 return x_test, y_test # 定义全局模型 def create_global_model(): model = tf.keras.models.Sequential([ tf.keras.layers.Dense(10, activation='relu', input_shape=(784,)), tf.keras.layers.Dense(10, activation='softmax') ]) model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy']) return model # 更新全局模型 def update_global_model(global_model, client_models): # 计算客户端模型的平均权重 client_weights = [model.get_weights() for model in client_models] avg_weights = np.mean(client_weights, axis=) # 更新全局模型的权重 global_model.set_weights(avg_weights) return global_model # 评估全局模型 def evaluate_global_model(global_model, x_test, y_test): loss, acc = global_model.evaluate(x_test, y_test) return acc # 加载本地数据 x_test, y_test = load_data() # 创建全局模型 global_model = create_global_model() # 更新全局模型 global_model = update_global_model(global_model, client_models) # 评估全局模型 acc = evaluate_global_model(global_model, x_test, y_test) ``` 这是一个非常简单的federated learning实现,它只涉及一个客户端和一个服务器。在实际应用中,可能会涉及多个客户端和多个服务器,以及更复杂的模型和训练过程。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值