Autoencoder的一些應用(pytorch版)

  • 預備知識-數據裝載(pytorch)

     數據的加載,一般面對的數據是numpy array的格式,如何轉變爲支持batch_size,shuffle等功能的數據集呢,pytorch 採用 DataLoader類來實現,參考源碼

# DataLoader 類的構造函數

def __init__(self, dataset, batch_size=1, shuffle=False, sampler=None,
                 batch_sampler=None, num_workers=0, collate_fn=None,
                 pin_memory=False, drop_last=False, timeout=0,
                 worker_init_fn=None, multiprocessing_context=None):
    torch._C._log_api_usage_once("python.data_loader")
    
# TensorDataset 類,繼承了Dataset
class TensorDataset(Dataset)

    我們採用如下步驟:1. numpy array -> tensor    2.tensor -> dataset  3.通過dataloader加載dataset;具體實現demo如下:

import torch
from torch.utils.data import DataLoader,Dataset,TensorDataset
from sklearn.datasets import load_iris

iris=load_iris()
data=iris.data

tensor_x=torch.from_numpy(data)
my_dataset=TensorDataset(tensor_x)
my_dataset_loader=DataLoader(my_dataset,batch_size=10,shuffle=False)
print(isinstance(my_dataset,Dataset))  # 返回是true

 

     一些基本概念

  1. batch,一般來說會採用梯度下降的方法進行迭代,估計參數;深度學習中一般採用sgd,batch就是每次迭代參數用到的樣本量
  2. epoch,輪訓的次數;1個epoch等於使用訓練集中全部樣本訓練一次
  • autoencoder原理和作用

1582253294892-e26c53cc-fbc4-4134-91c0-77cd38b614e9.png

  • 如何判斷encoder是好還是壞的?
    • GAN裏面的discriminator可以進行判斷,目標是使得 encoder 與 原始的輸入x 的loss越小越好,與其他輸入x越大越好。
  • 如何判斷embedding好還是壞呢?
    • 一個句子 與 下一個句子的embedding的相似度越大越好,與隨機拿來的句子相似度越小越好;或者構建一個分類器,如果分類器,如果能正確識別上下句子的pair 與上句與隨機句子的pair,那麼這個embbeding是不錯的
  • 如果encoded 向量能夠離散化,那麼解釋性會比較好,比如用one-hot 或者 sigmoid 二分類也可以。會有微分的問題。語音中VQVAE
  • 文章摘要!
class autoencode(nn.Module):                    
    def __init__(self):                         
        super(autoencode,self).__init__()       
        self.encoder=nn.Sequential(             
            nn.Linear(4, 3),                    
            nn.Tanh(),                          
            nn.Linear(3, 2),                    
        )                                       
        self.decoder=nn.Sequential(             
            nn.Linear(2, 3),                    
            nn.Tanh(),                          
            nn.Linear(3, 4),                    
            nn.Sigmoid()                        
        )                                       
                                                
    def forward(self, x):                       
        encoder=self.encoder(x)                 
        decoder=self.decoder(encoder)           
        return encoder,decoder                                                        

       上面Encoded Data 就是降維後的向量,針對sklearn裏面的iris數據集,訓練一個autoencoder模型,進行降維,最終壓縮到2維

import matplotlib.pyplot as plt           
                                          
x_=[]                                     
y_=[]                                     
for i, (x, y) in enumerate(my_dataset):   
    _, pred = model(V(x))            # 這裏的model爲訓練好的autoencoder模型               
    #loss = criterion(pred, x)            
    dimension=_.data.numpy()              
    x_.append(dimension[0])               
    y_.append(dimension[1])               
                                          
plt.scatter(numpy.array(x_),numpy.array(y_),c=Y)        
                                          
for i in range(len(numpy.array(x_))):     
    plt.annotate(i,(x_[i],y_[i]))         
                                          
plt.show()                                
                                          

image.png

  • autoencoder用於異常檢測
  1. 實際上就是decoder之後向量的與input向量之間的差距大小的比較,設定一個閾值,如果距離大於該閾值,那麼定義爲異常,前提要對input做標準化
  2. 下面利用訓練好的autoencoder模型,得到decoder,並計算input 和 decoder之間的
    ###### 與isolation forest 比較
    auto_outlier=[]
    for i in range(15):
        auto_outlier.append(losses[i][0])
    print(auto_outlier)#  定義損失前15的樣本作爲autoencoder模型識別的異常
    #[118, 100, 122, 136, 148, 114, 62, 87, 129, 76, 107, 131, 130, 106, 144]
    
    ## 定義iforest
    clf = IsolationForest()
    clf.fit(iforestX)
    res=clf.predict(iforestX)
    iforest_outlier=[]
    for i,data in enumerate(res):
        if data==-1:             # 識別結果中-1的爲異常點
            iforest_outlier.append(i)
    
    print(iforest_outlier)
    #[13, 14, 15, 41, 60, 98, 105, 106, 107, 109, 117, 118, 122, 131, 135]
    
    # 兩者都交集
    print([ele for ele in auto_outlier if ele in iforest_outlier])
    
    # 根據可可視化的結果觀察,isolation 表現更好
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章