Semi-supervised Discriminant Learning

先看看SSKDA 的formulations,后面附代码

 

 

'''
Semi-supervised Kernel Discriminant Analysis
Deniu He
2023-04-04
'''
import numpy as np
from sklearn.datasets import load_iris
from sklearn import datasets
from sklearn.metrics.pairwise import rbf_kernel
from sklearn.metrics.pairwise import pairwise_kernels
import matplotlib.pyplot as plt
from numpy import linalg as LA
from sklearn.neighbors import kneighbors_graph

class SSKDA():
    def __init__(self, n_components=None, kernel=None, gamma=None):
        self.n_components = n_components
        self.Beta = None
        self.X = None
        self.labeled = None
        self.gamma = gamma
        if kernel is not None:
            self.kernel = None
        else:
            self.kernel = 'linear'



    def fit(self, X, y, labeled_index, unlabeled_index, miu = 1e-3):
        self.nSample = X.shape[0]
        self.y = y
        self.X = X
        self.labels = np.unique(y)
        self.nClass = len(self.labels)
        self.labeled = labeled_index
        self.unlabeled = unlabeled_index
        self.miu = miu
        self.index_total = np.arange(X.shape[0])

        self.nLabeled = len(labeled_index)
        self.Kernel_total = rbf_kernel(X=X, gamma=self.gamma)
        self.Kernel_L_T = self.Kernel_total[np.ix_(self.labeled, self.index_total)]
        graph = kneighbors_graph(X=X, n_neighbors=4, mode='connectivity', include_self=True)
        S = graph.toarray()
        D = np.diag(S)
        self.L = D - S
        self.N = self.get_N()
        self.H = self.get_H()
        # print("N::",self.N.shape)
        # print("H::",self.H.shape)
        # print(self.miu)
        # print("self.Kernel_L_U ::",self.Kernel_L_T.shape )
        # print("self.L",self.L.shape)
        self.N_KLK = self.N + self.miu * self.Kernel_L_T @ self.L @ self.Kernel_L_T.T
        epsilon = 1e-08
        eig_val, eig_vec = LA.eigh(LA.inv(self.N_KLK + epsilon * np.eye(self.nLabeled))@self.H)
        ord_idx = eig_val.argsort()[::-1]  # sort eigenvalues in descending order (largest eigenvalue first)
        eig_val = eig_val[ord_idx]
        eig_vec = eig_vec[:,ord_idx]
        if self.n_components is not None:
            self.Beta = eig_vec[:,:self.n_components]
        else:
            self.Beta = eig_vec[:,:self.nClass-1]

    def transform(self, X):
        # print(self.labeled.shape)
        # print(X.shape)
        # print(self.X.shape)
        Kernel_train_input = rbf_kernel(X=self.X[self.labeled], Y=X, gamma=self.gamma)
        X_transform = self.Beta.T @ Kernel_train_input
        return X_transform.T

    def get_H(self):
        H = np.zeros((self.nLabeled, self.nLabeled))
        M_star = self.Kernel_total[np.ix_(self.labeled, self.labeled)]
        M_star = M_star.sum(axis=1)
        M_star = M_star.reshape((-1,1))
        M_star = (1 / self.nSample) * M_star

        for i, lab in enumerate(self.labels):
            idx_list = np.where(self.y[self.labeled] == lab)[0]
            idx_list = self.labeled[idx_list]  # 真实索引
            Ki = self.Kernel_total[np.ix_(self.labeled, idx_list)]
            M_c = Ki.sum(axis=1)
            M_c = M_c.reshape((-1,1))
            M_c = (1 / len(idx_list)) * M_c
            H += len(idx_list) * (M_c - M_star) @ (M_c - M_star).T
        return H

    def get_N(self):
        N = np.zeros((self.nLabeled, self.nLabeled))
        for i, lab in enumerate(self.labels):
            idx_list = np.where(self.y[self.labeled] == lab)[0]
            Ki = self.Kernel_total[np.ix_(self.labeled, idx_list)]
            N += Ki @ (np.eye(len(idx_list)) - np.ones(len(idx_list)) * (1/ len(idx_list))) @ Ki.T
        N += np.eye(self.nLabeled) * 1e-8
        return N


if __name__ == '__main__':
    X, y = datasets.make_circles(n_samples=400, shuffle=True, noise=0.01, random_state=42)
    plt.scatter(X[:,0], X[:,1], c=y)
    plt.show()

    labeled_idx = np.random.choice(np.arange(400), size=20, replace=False)
    unlabeled_idx = list(np.arange(400))
    for idx in labeled_idx:
        unlabeled_idx.remove(idx)
    unlabeled_idx = np.asarray(unlabeled_idx)



    sskda = SSKDA(n_components=2, kernel='rbf', gamma=0.01)
    sskda.fit(X=X,y=y,labeled_index=labeled_idx, unlabeled_index=unlabeled_idx)

    X_transformed = sskda.transform(X=X)
    plt.scatter(X_transformed[:,0], X_transformed[:,1], c=y)
    plt.show()






 总共有400个点(样本)

使用20个标记样本的半监督的结果:

使用100个标记样本的半监督结果:

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: Temporal Ensembling是一种半监督学习方法,它使用了时间上的一致性来提高模型的性能。该方法通过对未标记数据进行预测,并将预测结果与之前的预测结果进行平均,从而获得更加稳定和准确的预测结果。同时,该方法还使用了一个噪声注入技术来增加模型的鲁棒性。该方法已经在图像分类、语音识别等领域取得了很好的效果。 ### 回答2: Temporal Ensembling是一种半监督学习方法。它主要通过使用同一批数据的多个副本,在单批数据上进行迭代学习来提高预测模型的准确性。这种方法能够很好地利用已有数据中的潜在信息,同时也能避免因缺乏大量标注数据而损失准确性的问题。 Temporal Ensembling的核心思想是使用模型的历史预测结果来生成新的虚拟标签。在训练期间,模型不断地更新,同时不断生成新的“标注”,并将这些新的“标注”与原始标注数据一起训练。这样,模型可以从大量带有“标注”的数据中学习并逐渐提高其准确性。 Temporal Ensembling方法在许多学习任务中都展现出优良的性能,比如图像分类、物体识别、图像分割、语音识别等。其中,与其他半监督学习方法相比,Temporal Ensembling在半监督图像分类中的性能最为出色。 尽管Temporal Ensembling的性能非常出色,但是其中的一些问题仍需要解决。 首先,这种方法需要大量的GPU计算力和存储空间,并且需要复杂的算法设计。其次,由于该方法是基于生成虚拟标签的,因此,如果模型在未来预测错误而不正确地生成了虚拟标签,那么可能会产生负面影响。 总之,Temporal Ensembling是一种有效的半监督学习方法,其取得的结果显示出高水平的准确性。与其他方法相比,Temporal Ensembling具有更好的稳健性及效能。也因此,它在深度学习领域中被广泛应用。 ### 回答3: Temporal Ensembling是一种半监督学习技术,可以用于训练深度神经网络。该技术旨在利用未标记的数据来改善模型的泛化能力。在传统的监督学习中,我们需要分类器预测每个样本的标签,并将其与真实标签进行比较以计算损失函数。然而,在许多现实世界的场景中,标记数据的数量通常是有限的,这使得监督学习变得更加困难和昂贵。相反,在半监督学习中,我们将未标记的数据与标记数据结合在一起进行训练。 Temporal Ensembling的实现是基于一个假设,即相似的输入应该具有相似的潜在表示形式。具体来说,该技术通过在连续训练周期中收集了单次训练中的模型预测,通过将这些预测结果整合成一个移动平均版本来构建模型共识。这可以看作是把模型的预测提供给下一个周期的训练,让模型逐渐整合起来,在连续的训练周期中收集了对训练数据更准确的表示。在训练过程中,我们不仅使用真实标签来计算损失函数,还将平均预测意味着的交叉熵添加到损失函数中。这使得模型学习时能够尽可能地匹配模型共识中的数据。 虽然在许多情况下,半监督学习可以增加模型学习任务的效果,但它依赖于许多因素,包括未标记样本的数量、分布和标记样本之间的相似性。使用Temporal Ensembling时,需要做好降噪处理,适当选择数据能够真正提高该技术效果。此外,需要注意的是,Temporal Ensembling只能在没有过度拟合数据集时才能有效,因为此技术基于模型共识构建。在实际应用中,可以将Temporal Ensembling与其他半监督学习技术结合使用,以提高模型性能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

DeniuHe

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值