前言

矩阵运算在深度学习中多用于多特征运算

下图中每一列为一个特征,每一行的多个特征组成 Y 的一行结果。将多个特征归结为一个举证,然后按照举证进行计算。

常用公式

\[A·B=C\] \[G=\frac{\partial L}{\partial C}\] \[\bigtriangledown A=G·B^T\] \[\bigtriangledown B=A^T·G\]

复现

上图可知,这里 A 就是 X,B 就是 K,C 就是 pre。我们已知的是 X 和 pre,未知的是 K。求得 K 后,只要通过各个特征就能算出对应的 pre。

\(delta\_k=\frac{\partial Loss}{\partial k}\) 起始就是 \(\bigtriangledown K\),即可以用 \(\bigtriangledown K=X^T·G\) 算得。这个式子中的 X 已知,G 可以用 \(G=\frac{\partial Loss}{\partial pre}\) 求得。

G = 2 * (pre - y) 中的常数 2 我们一般不要,因为最后它与 lr 进行相乘时,常数可能会导致梯度爆炸。因此可以用 G = 2 * (pre - y) ,但是为了更好地防止梯度爆炸,可以在后面除以 len (X),计算出平均的梯度,因为 len (X) 是常数,所以对最后的结果准确性并没有影响。最后变成 G= (pre - y)/len(X)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
import numpy as np  
import pandas as pd


def get_data(file):
# skiprows=1表示删除表头,names表示重新加上表头
data = pd.read_csv(file,names=["y","x1","x2","x3","x4","x5","x6"],skiprows=1)
# print(data)

y = data["y"].values.reshape(-1,1) # reshape(行数,列表),-1表示不知道,1表示确定为1列。所以reshape(-1,1)表示变成1列数据
mean_y = np.mean(y) # 求和取平均值
std_y = np.std(y) # 求标准差,即方差开根。列表求方差,需要将每个数与平均值相减再平方,这些平方相加的结果就是方差。
y = (y - mean_y) / std_y
# print(y)

x = data[[f"x{i}" for i in range(1,7)]].values # values是直接将数据转化为numpy矩阵形式
mean_x = np.mean(x,axis=0,keepdims = True) # axis=0为纵向,axis=1为横向;keepidms=True表示保持其二维或者三维的特性(结果保持其原来维数)
std_x = np.std(x,axis=0,keepdims=True)
x = (x - mean_x) / std_x
# print(x)

return x,y,mean_y,std_y,mean_x,std_x


if __name__ == "__main__":
X,y,mean_y,std_y,mean_x,std_x = get_data("上海二手房价.csv")

K = np.random.random((6,1)) # 生成6行1列的浮点数,浮点数都是从0-1中随机,维度为2

epoch = 10000
lr = 0.001
b = 1 # 偏置项

for e in range(epoch):
pre = X @ K # 270*6 @ 6*1 = 270*1
# print(pre) loss = np.sum((pre-y)**2)/len(X) # y是270*1
print(loss)

G = (pre - y)/len(X)
delta_k = X.T @ G
delta_b = np.mean(G) # 偏置项求导就是G的求平均

K = K - lr * delta_k
b = b - lr * delta_b

while True:
bedroom = (int(input("请输入卧室数量:")))
ting = (int(input("请输入客厅数量:")))
wei = (int(input("请输入卫生间数量:")))
area = (int(input("请输入面积:")))
floor = (int(input("请输入楼层:")))
year = (int(input("请输入建成年份:")))

test_x = (np.array([bedroom, ting, wei, area, floor, year]).reshape(1, -1) - mean_x) / std_x

p = test_x @ K + b
print("房价为: ", p * std_y + mean_y)

输出:
……
0.9240587745570578
0.9240567410064711
0.9240547079709156
0.9240526754502584
0.9240506434443663
0.9240486119531061
0.9240465809763451
0.9240445505139503
请输入卧室数量: 2
请输入客厅数量: 1
请输入卫生间数量: 1
请输入面积: 80
请输入楼层: 4
请输入建成年份: 2010
房价为: [[76331.47770039]]

相关链接

bilibili
GitHub