如何使用Python+Opencv中的PCA给卷积神经网络特征降维

记录一个小实验,如何给卷积神经网络的特征值降维,在保证特征可判别性的同时减小特征值个数。

我们使用六组图片进行实验:

实验环境:

opencv-python 4.4.0.44

numpy 1.18.5

torch 1.0.1

1、首先,使用别人训练好的senet-101模型提取六张图片的特征值,得到6个2048维的特征向量。

2、用余弦相似度分别计算P1P2、D1D2、S1S2的相似度,分别是0.633、0.879、0.637。分别计算P1S1、D1P1、S1D1、P2S2、D2P2、S2D2的相似度,分别是0.136、0.105、0.138、0.224、0.163、0.178。可以看出,同类图片相似度大于0.5,异类图片相似度小于0.3。

3、使用opencv提供的pca接口实现降维算法,本次实验希望将2048维度的特征降到512。pca算法需要确保样本个数大于降维维度,所以我们额外从ImageNet数据集1000类图片中,每类随机选一张图片,共1000张组成训练数据。

4、使用opencv中的cv.PCACompute2函数,计算训练数据的特征值和特征向量。

5、使用六张图片的特征值 乘以 特征向量的转置([6*2048]x[2048*512]),得到降维后的六张图片特征([6*512])。

6、重复步骤2,P1P2、D1D2、S1S2的相似度分别为0.725、0.929、0.752。P1S1、D1P1、S1D1、P2S2、D2P2、S2D2的相似度分别是0.152、0.104、0.141、0.274、0.169、0.191。可以看出,同类图片相似度大于0.7,异类图片相似度小于0.3,特征依然保持可判别性。但是异类相似度的值都有不成程度的增长,说明特征判别性降低了。

def print_sim(data):
    print(pw.cosine_similarity(data[0].reshape(1, -1), data[2].reshape(1, -1)))
    print(pw.cosine_similarity(data[1].reshape(1, -1), data[3].reshape(1, -1)))
    print(pw.cosine_similarity(data[4].reshape(1, -1), data[5].reshape(1, -1)))

    print(pw.cosine_similarity(data[0].reshape(1, -1), data[1].reshape(1, -1)))
    print(pw.cosine_similarity(data[1].reshape(1, -1), data[4].reshape(1, -1)))
    print(pw.cosine_similarity(data[4].reshape(1, -1), data[0].reshape(1, -1)))
    print(pw.cosine_similarity(data[2].reshape(1, -1), data[3].reshape(1, -1)))
    print(pw.cosine_similarity(data[3].reshape(1, -1), data[5].reshape(1, -1)))
    print(pw.cosine_similarity(data[5].reshape(1, -1), data[2].reshape(1, -1)))

if __name__ == '__main__':

    #加载senet-101模型
    model = se_resnet101()
    param = torch.load('/home/dl/PycharmProjects/S2VT/extractor/se_resnet101-7e38fcc6.pth')
    model.load_state_dict(param)
    model.cuda()
    model.eval()

    #加载训练数据
    feats = None
    img_list = os.listdir('/home/dl/PycharmProjects/S2VT/Image')
    for image in img_list:
        img = cv.imread(os.path.join('/home/dl/PycharmProjects/S2VT/Image', image), 0)
        feat = get_img_resnet_feature(model, img).cpu().numpy()#这个特征提取函数自己写
        try:
            feats = np.vstack((feats, feat))
        except:
            feats = feat
        print(feats.shape[0])

    #调用pca函数,返回均值、特征向量、特征值(从大到小)
    mean, eigenvectors, eigenvalues  = cv.PCACompute2(feats, np.array([]), maxComponents=512)

    #加载6张测试图片
    feats = None
    img_list = os.listdir('/home/dl/PycharmProjects/S2VT/test_Image')
    for image in img_list:
        img = cv.imread(os.path.join('/home/dl/PycharmProjects/S2VT/test_Image', image), 0)
        feat = get_img_resnet_feature(model, img).cpu().numpy()
        try:
            feats = np.vstack((feats, feat))
        except:
            feats = feat

    #输出降维前和降维后的特征相似度
    print_sim(feats)
    pca_feats = np.matmul(feats, eigenvectors.T)#降维
    print_sim(pca_feats)

猜你喜欢

转载自blog.csdn.net/XLcaoyi/article/details/116103023