推理时的单幅图像特征缩减

Single image feature reduction at inference time

我正在尝试使用 scikit-learn 训练 SVM 分类器。在训练时我想减少特征向量维度。 我用PCA降维了

pp = PCA(n_components=400).fit(features)
features = pp.transform(features)

PCA 需要 m x n 数据集来确定方差。但在推理时我只有单个图像和相应的一维特征向量。我想知道如何在推理时减少特征向量以匹配训练维度。

作为现在 scikit-learn 中的所有预处理模块,PCA 包括一个 transform 方法,它可以根据已经拟合的 PCA 转换转换新样本;来自 docs:

transform(self, X)

Apply dimensionality reduction to X.

X is projected on the first principal components previously extracted from a training set.

这是一个带有虚拟数据的简短演示,改编自文档中的示例:

import numpy as np
from sklearn.decomposition import PCA

X = np.array([[-1, -1], [-2, -1], [-3, -2], [1, 1], [2, 1], [3, 2]])
pca = PCA(n_components=2)
pca.fit(X)

X_new = ([[1, -1]]) # new data, notice the double array brackets

X_new_pca = pca.transform(X_new)
X_new_pca
# array([[-0.2935787 ,  1.38340578]])

如果你想避免单个新样本的双括号,你应该把它做成一个 numpy 数组并按如下方式重新整形:

X_new = np.array([1, -1])
X_new_pca = pca.transform(X_new.reshape(1, -1))
X_new_pca
# array([[-0.2935787 ,  1.38340578]]) # same result

在“训练”PCA 之后(或者从数学上讲,在计算降维矩阵之后),您可以在任何大小合适的矩阵或向量上使用 transform 函数,而不管原始数据是什么。

from sklearn.decomposition import PCA
import numpy as np

m = 100
n = 200

features = np.random.randn(m,n)
print(features.shape)
>> (100, 200)

# Learn the PCA
pp = PCA(n_components=50).fit(features)
low_dim_features = pp.transform(features)
print(low_dim_features.shape)
>> (100, 50)

# Perform dimensionality reduction to a new sample
new_sample = np.random.randn(1, n)
low_dim_sample = pp.transform(new_sample)
print(low_dim_sample.shape)
>> (1, 50)

PCA 在这种情况下可以很好地工作。测试时是否有单个图像并不重要。假设您的训练集是 100 个样本乘以 1000 个特征。在训练集上拟合 PCA 将为您提供 1000 x N 个特征向量,因为您将拥有 1000 x 1000 的协方差矩阵。通过 eignedecomposition,您将只需要 select 一小部分特征向量。假设你 select 只有 25,你将有 1000 x 25 个特征向量。在测试时,对于 1 x 1000 个特征的单个示例,您只需将特征投影到 1000 x 25 的特征空间,最终得到 1 x 25 个减少的特征(您的特征现在将是 25 个特征的维度)。因此,您的训练集将具有 100 x 25 个特征,而您的单个测试样本将具有 1 x 25 个特征。您可以用它训练和测试任何机器学习分类器。