# 前向传播函数
# - x:包含输入数据的numpy数组,形状为(N,d_1,...,d_k)
# - w:形状为(D,M)的一系列权重
# - b:偏置,形状为(M,)
def affine_forward(x, w, b):
out = None # 初始化返回值为None
N = x.shape[0] # 重置输入参数X的形状
x_row = x.reshape(N, -1) # (N,D)
out = np.dot(x_row, w) + b # (N,M)
cache = (x, w, b) # 缓存值,反向传播时使用
return out,cache
在某些应用场景中,x的维度可能更高。比如对于一个2020像素的4张灰度图,x的形状将是(4,20,20),对应的参数就是N=4,d_1=20,d_2=20。(这里边第一个参数用N表示,它代表的是同时用于计算前向传播的数据有几组,后边的参数d_1~d_k代表的是数据本身的形状。)
对于这种维度大于2的x来说,需要对其进行重新塑形,也就是将(4,20,20)的高维数组变化为(4,2020)这样的二位数组。为什么要这么做呢?是为了方便计算。这样变换之后高维的向量被“拍扁”成一维向量(长度为20*20的一维向量),对应的W和b也都是一维的,既统一了参数形式,又不会影响数据的正常使用。
我的理解是N就是数据的数量,不同的数据有不同的规格,每个数据的具体样式则是d_1,d_2,d_k决定的。如果有四个数据,数据本身就是20行20列的,那么x的形状应该写作(4,20,20)。照这样说,如果有四个数据,每个数据是一行两列的,x的形状为什么不是(4,1,2)而是(4,2)呢?1可以省略不写吗?