理论分析
分布式编码算法:
原理图:
重要参数分析:
代码实现
# 因为比较复杂,所以在这里只实现矩阵和向量的乘法运算, 先不考虑分布式运算.
# 因为X.T需要列分块进行矩阵乘法, 而X需要行分块进行矩阵向量乘法. 所以说如果只实现softmax, 那么只需要实现矩阵乘法即可.
# 但是如果考虑一般的矩阵向量乘法运算
"""
1. 解决import的问题, 通过把coded_elastic_computing写到sys.path中来解决(见import.py)
2. Xw=np.concatenate(Xw, axis=0), 可以实现在不同行组之间进行拼接
3. 如果你需要将多维数组展开成一个向量,并且这个向量需要是列向量(即二维数组,形状为(N, 1)),可以使用reshape方法:
column_vector = arr..reshape(-1, 1)
4. 哭死, 误差好大, 不知道哪里出了问题, 总之是很奇怪的样子. 最离谱的是最后的四行都有数, 按理来说应该全为0. 因为是paddling的, 所以最后四行应该是0.
随便挑了一下, 结果出来了, 哈哈哈, 确实这个东西有点运气的成分在里面的: 其实是忘记了加转置. (应该是那个论文上写错了, 忘记了加转置)
H_for_j=np.linalg.inv(G_for_j).T
"""
import numpy as np
from coded_elastic_computing_docu import *
def elastic_coded_X(X, G):
"""
矩阵向量乘法
:param X: 矩阵
:param v: 向量
:return: 矩阵向量乘法结果
"""
# G矩阵的分解, 模仿coded_elastic_computing.py中的函数
P=G.shape[0]
L=G.shape[1]
gap=int(X.shape[0]/L)
gap2=int(X.shape[0]/P/L)
X_i=[] # 也就是分成的三个原始数据矩阵A 0,B 1,C 2
for i in range(L):
X_i.append(X[i*gap:i*gap+gap,:])
X_s_i=[[] for i in range(P)] # 按照机器进行编码的结果, 对应的函数的情况是, 对原始矩阵按照G进行编码, 然后在分成不同的行组(group)
for s in range(P): # s indicate different machines
result=[]
for i in range(L):
result.append(X_i[i]*G[s][i])
result=np.sum(result, axis=0)
for j in range(P): # j indicate different row group
X_s_i[s].append(result[j*gap2:j*gap2+gap2,:])
return X_s_i # 从C举着来看,应该是正确的, 基本上认为没有问题 "C:/Users/user/OneDrive/图片/屏幕快照/proof1.png"
#备注一下 X_s_i[s][j] 对应的是第s个机器, 第j个行组的编码结果, 也就是说, 第s个机器, 第j个行组的编码结果, 就是X_s_i[s][j]
def matrix_vector_multiplication(X_s_i, w, S_i, G):
# notice of the G, because there is no cancelling happen
P=G.shape[0]
L=G.shape[1]
Xw=[[] for i in range(L)]
for j in range(P):# different row group
index=S_i[j]
u=[]
for i in range(L):
u.append(X_s_i[index[i]][j]@w)
G_for_j=G[index,:]
H_for_j=np.linalg.inv(G_for_j).T # 这里的T表示转置, 因为G是对称矩阵, 所以G^{-1}就是G的转置
# culculate u_{t,j}*G^{-1}
for m in range(L): # m indicate different result for diff machines
result=[]
for n in range(L): # n indicate different indics, or for sum
result.append(u[n]*H_for_j[n][m])
result=np.array(result)
result=np.sum(result, axis=0)
Xw[m].append(result)
Xw=np.array(Xw)
Xw=Xw.reshape(-1,1) # 转化为列向量
return Xw
if __name__ == '__main__':
# test
G_coded = MDS(P_max=P_max, L=L)[0:P]
A_raw, B_raw = create_matrix(A_row, A_column, B_row, B_column)
A_pad = padding_column(A_raw, L, P)
X=A_pad.T
S_i = generate_S_i(P, L)
X_s_i = elastic_coded_X(X, G_coded)
np.random.seed(0)
w=np.random.rand(X.shape[1],1)
result_coded = matrix_vector_multiplication(X_s_i, w, S_i, G_coded)
result = X@w
result_err = result_coded - result
# result_coded = result_coded.astype(int)
print(result_err)
结果:
E:\anaconda\pythonw.exe E:\pycharm\python_doc\大床\coded_elastic_computing\task_two_softmax_part\coded_elastic_computing_vector_matrix.py
[[ 1.42108547e-14]
[-1.42108547e-14]
[-2.84217094e-14]
[-4.26325641e-14]
[-1.42108547e-14]
[-1.42108547e-14]
[ 1.42108547e-14]
[ 2.84217094e-14]
[ 1.42108547e-14]
[ 0.00000000e+00]
[ 2.84217094e-14]
[-1.42108547e-14]
[ 1.98951966e-13]
[ 1.70530257e-13]
[ 2.84217094e-14]
[ 5.68434189e-14]
[ 2.84217094e-14]
[ 0.00000000e+00]
[ 0.00000000e+00]
[-1.42108547e-14]
[-5.68434189e-14]
[ 5.68434189e-14]
[ 0.00000000e+00]
[ 2.84217094e-14]
[-4.26325641e-14]
[-4.26325641e-14]
[ 0.00000000e+00]
[ 0.00000000e+00]
[ 2.84217094e-14]
[ 2.84217094e-14]
[ 0.00000000e+00]
[ 0.00000000e+00]
[ 0.00000000e+00]
[ 0.00000000e+00]
[ 0.00000000e+00]
[-1.13686838e-13]]
进程已结束,退出代码为 0
可见精度很高.
参考文献
Yaoqing Yang, Pulkit Grover, Soummya Kar--Coded Elastic Computing
持续分享分布式计算