我想提取1d CNN图层的权重,并了解预测值的精确计算方式。我无法使用get_weights()
函数的权重重新生成预测值。
为了解释我的理解,这里有一个小数据集。
n_filter = 64
kernel_size = 10
len_timeseries = 123
n_feature = 3
X = np.random.random(sample_size*len_timeseries*n_feature).reshape(sample_size,len_timeseries,n_feature)
y = np.random.random(sample_size*(len_timeseries-kernel_size+1)*n_filter).reshape(sample_size,
(len_timeseries-kernel_size+1),
n_filter)
现在,创建一个简单的1d CNN模型:
model = Sequential()
model.add(Conv1D(n_filter,kernel_size,
input_shape=(len_timeseries,n_feature)))
model.compile(loss="mse",optimizer="adam")
调整模型并将X
的值预测为:
model.fit(X,y,nb_epoch=1)
y_pred = model.predict(X)
y_pred
的维度应该是(1000, 114, 64)
。
现在,我想使用存储在y_pred[irow,0,ilayer]]
中的权重来重现model.layer
的值。因为只有单层len(model.layer)=1
。所以我从第一层和唯一层中提取权重:
weight = model.layers[0].get_weights()
print(len(weight))
> 2
weight0 = np.array(weight[0])
print(weight0.shape)
> (10, 1, 3, 64)
weight1 = np.array(weight[1])
print(weight1.shape)
> (64,)
权重的长度为2,我假设第0个位置包含要素的权重,第1个位置包含偏差。
作为weight0.shape=(kernel_size,1,n_feature,n_filter)
,我认为我可以通过以下方式获取y_pred[irow,0,ilayer]
的值:
ifilter = 0
irow = 0
y_pred_by_hand = weight1[ifilter] + np.sum( weight0[:,0,:,ifilter] * X[irow,:kernel_size,:])
y_pred_by_hand
> 0.5124888777
但是,此值与y_pred[irow,0,ifilter]
完全不同,因为:
y_pred[irow,0,ifilter]
>0.408206
请让我知道我哪里出错了。
答案 0 :(得分:3)
您在此处误解了weights
属性。您要查找的是图层的output
属性,该属性是model.predict
给出的结果。这可以通过layer.output
获得。通常,Layer
被输入张量,并由weights
矩阵作用,这取决于所使用的层的类型。此计算给出了输出张量,这是您正在寻找的。
例如,考虑具有形状(1,3)的输入张量A的简单密集层,发出张量B(1,1)的输出sigmoid层和权重矩阵W.W的形状基于输入和输出形状。因此,在这种情况下,Dense层会A matmul W
,其结果将是预测B.W的形状将被确定为(3,1),这可能导致输出形状为(1,1) )。所以你要找的是B,但是你试图访问W。