为什么当我删除过滤器及其相关权重时 CNN 的准确性会下降?
Why does accruacy of the CNN drop when I remove a filter and its associated weights?
model
架构是 Conv2D with 32 filters
-> Flatten
-> Dense
-> Compile
-> Fit
我使用
删除了第一层的最后一个过滤器和该模型中相应的全连接层
w,b = model.layers[0].get_weights()
w = np.delete(w, [32], -1)
b = np.delete(b, [32], 0)
w_2,b_2 = model.layers[2].get_weights()
w_2 = w_2[:20956,:]
我使用 20956 因为第一层的输出是 26 x 26 x 31,这是一个二维图像尺寸乘以通道数。
我使用以下方法创建了一个名为 model_1
的新模型:
# Input stays the same
model_1 = Sequential()
# New modified conv layer
model_1.add(Conv2D(31, kernel_size=(3, 3),
activation='relu',
input_shape=input_shape,
kernel_initializer='he_normal'))
model_1.add(Flatten())
model_1.add(Dense(10, activation='softmax'))
model_1.layers[0].set_weights([w,b])
model_1.layers[2].set_weights([w_2,b_2])
model_1.compile(loss="categorical_crossentropy",
optimizer="Adam",
metrics=['accuracy'])
我可以通过 model_1.layers[0].get_weights()[0] == model.layers[0].get_weights()[0][:,:,:,:31]
和 model_1.layers[2].get_weights()[0] == model.layers[2].get_weights()[0][:20956,:]
来确认权重相同,returns 正确。
当我做
score = model_1.evaluate(x_test_reshape, y_test)
print('Test loss:', score[0])
print('Test accuracy:', score[1])
score = model.evaluate(x_test_reshape, y_test)
print('Test loss:', score[0])
print('Test accuracy:', score[1])
准确率从 98% 下降到 10%,知道为什么吗?
你实际上是在从最后一个卷积层中删除一个通道。直觉上这听起来没什么大不了的,剩下的 31 个通道仍然可以使网络表现良好。实际上,所有卷积通道都在随后的密集层中相互交互,但由于这种交互缺少其中一个信息通道,因此对其进行了优化,其准确性会下降。
另一种思考方式是将您的网络视为连续步骤的函数,这些步骤以图像作为输入并以 98% 的准确度作为输出标签。删除此函数中的一小部分 (1/32) 计算将改变结果,并且可能会产生更糟糕的结果,因为该函数在这些计算仍然存在的情况下进行了优化。您正在删除显然对达到高精度至关重要的功能的一部分。
您可以通过使用 31 个通道短时间训练您的新模型来测试这一点。由于新模型只需要重新学习删除通道的功能,应该很快就能再次达到高性能。
model
架构是 Conv2D with 32 filters
-> Flatten
-> Dense
-> Compile
-> Fit
我使用
删除了第一层的最后一个过滤器和该模型中相应的全连接层w,b = model.layers[0].get_weights()
w = np.delete(w, [32], -1)
b = np.delete(b, [32], 0)
w_2,b_2 = model.layers[2].get_weights()
w_2 = w_2[:20956,:]
我使用 20956 因为第一层的输出是 26 x 26 x 31,这是一个二维图像尺寸乘以通道数。
我使用以下方法创建了一个名为 model_1
的新模型:
# Input stays the same
model_1 = Sequential()
# New modified conv layer
model_1.add(Conv2D(31, kernel_size=(3, 3),
activation='relu',
input_shape=input_shape,
kernel_initializer='he_normal'))
model_1.add(Flatten())
model_1.add(Dense(10, activation='softmax'))
model_1.layers[0].set_weights([w,b])
model_1.layers[2].set_weights([w_2,b_2])
model_1.compile(loss="categorical_crossentropy",
optimizer="Adam",
metrics=['accuracy'])
我可以通过 model_1.layers[0].get_weights()[0] == model.layers[0].get_weights()[0][:,:,:,:31]
和 model_1.layers[2].get_weights()[0] == model.layers[2].get_weights()[0][:20956,:]
来确认权重相同,returns 正确。
当我做
score = model_1.evaluate(x_test_reshape, y_test)
print('Test loss:', score[0])
print('Test accuracy:', score[1])
score = model.evaluate(x_test_reshape, y_test)
print('Test loss:', score[0])
print('Test accuracy:', score[1])
准确率从 98% 下降到 10%,知道为什么吗?
你实际上是在从最后一个卷积层中删除一个通道。直觉上这听起来没什么大不了的,剩下的 31 个通道仍然可以使网络表现良好。实际上,所有卷积通道都在随后的密集层中相互交互,但由于这种交互缺少其中一个信息通道,因此对其进行了优化,其准确性会下降。
另一种思考方式是将您的网络视为连续步骤的函数,这些步骤以图像作为输入并以 98% 的准确度作为输出标签。删除此函数中的一小部分 (1/32) 计算将改变结果,并且可能会产生更糟糕的结果,因为该函数在这些计算仍然存在的情况下进行了优化。您正在删除显然对达到高精度至关重要的功能的一部分。
您可以通过使用 31 个通道短时间训练您的新模型来测试这一点。由于新模型只需要重新学习删除通道的功能,应该很快就能再次达到高性能。