校园春色亚洲色图_亚洲视频分类_中文字幕精品一区二区精品_麻豆一区区三区四区产品精品蜜桃

主頁 > 知識庫 > pytorch實現textCNN的具體操作

pytorch實現textCNN的具體操作

熱門標簽:激戰2地圖標注 白銀外呼系統 騰訊外呼線路 唐山智能外呼系統一般多少錢 廣告地圖標注app 哈爾濱ai外呼系統定制 海南400電話如何申請 陜西金融外呼系統 公司電話機器人

1. 原理

2014年的一篇文章,開創cnn用到文本分類的先河。

Convolutional Neural Networks for Sentence Classification

原理說簡單也簡單,其實就是單層CNN加個全連接層:

不過與圖像中的cnn相比,改動為將卷積核的寬固定為一個詞向量的維度,而長度一般取2,3,4,5這樣。

上圖中第一幅圖的每個詞對應的一行為一個詞向量,可以使用word2vec或者glove預訓練得到。本例中使用隨機初始化的向量。

2. 數據預處理

手中有三個文件,分別為train.txt,valid.txt,test.txt。其中每一行是一個字符串化的字典,格式為{‘type': ‘xx', ‘text':‘xxxxx'}。

2.1 轉換為csv格式

首先將每個文件轉換為csv文件,分為text和label兩列。一共有4種label,可以轉換為數字表示。代碼如下:

# 獲取文件內容
def getData(file):
    f = open(file,'r')
    raw_data = f.readlines()
    return raw_data
# 轉換文件格式
def d2csv(raw_data,label_map,name):
    texts = []
    labels = []
    i = 0
    for line in raw_data:
        d = eval(line) #將每行字符串轉換為字典
        if len(d['type']) = 1 or len(d['text']) = 1: #篩掉無效數據
            continue
        y = label_map[d['type']] #根據label_map將label轉換為數字表示
        x = d['text']
        texts.append(x)
        labels.append(y)
        i+=1
        if i%1000 == 0:
            print(i)
    df = pd.DataFrame({'text':texts,'label':labels})
    df.to_csv('data/'+name+'.csv',index=False,sep='\t') # 保存文件
label_map = {'執行':0,'刑事':1,'民事':2,'行政':3}
train_data = getData('data/train.txt') #22000+行
d2csv(train_data,label_map,'train')
valid_data = getData('data/valid.txt') # 2000+行
d2csv(valid_data,label_map,'valid')
test_data = getData('data/test.txt') # 2000+行
d2csv(test_data,label_map,'test')

2.2 觀察數據分布

對于本任務來說,需要觀察每個文本分詞之后的長度。因為每個句子是不一樣長的,所以需要設定一個固定的長度給模型,數據中不夠長的部分填充,超出部分舍去。

訓練的時候只有訓練數據,因此觀察訓練數據的文本長度分布即可。分詞可以使用jieba分詞等工具。

train_text = []
for line in train_data:
    d = eval(line)
    t = jieba.cut(d['text'])
    train_text.append(t)
sentence_length = [len(x) for x in train_text] #train_text是train.csv中每一行分詞之后的數據
%matplotlib notebook
import matplotlib.pyplot as plt
plt.hist(sentence_length,1000,normed=1,cumulative=True)
plt.xlim(0,1000)
plt.show()

得到長度的分布圖:

可以看到長度小于1000的文本占據所有訓練數據的80%左右,因此訓練時每個文本固定長度為1000個詞。

2.3 由文本得到訓練用的mini-batch數據

目前我們手里的數據為csv形式的兩列數據,一列字符串text,一列數字label。label部分不需要再處理了,不過text部分跟可訓練的數據還差得遠。

假設每個詞對應的詞向量維度為 D i m Dim Dim,每一個樣本的分詞后的長度已知設為 W = 1000 W=1000 W=1000,每個mini-batch的大小為 N N N。那么我們希望得到的是一個個維度為 N ∗ W ∗ D i m N*W*Dim N∗W∗Dim的浮點數數據作為mini-batch輸入到模型。

于是還需要以下幾個步驟:

分詞去除停用詞建立詞匯表(詞匯表是詞語到index的映射,index從0到M,M為已知詞匯的個數,形如{'可愛‘:0, ‘美好':1,…})將分詞且去除停用詞之后的數據轉換為下標數據,維度應該為 N a l l ∗ W N_{all}*W Nall​∗W, N a l l N_{all} Nall​是所有樣本的數量。其中長度不足W的樣本在后面補特定字符,長度超過W的樣本截斷。將數據分割為一個個 N ∗ W N*W N∗W大小的mini-batch作為模型的輸入。根據mini-batch數據向詞向量中映射得到 N ∗ W ∗ D i m N*W*Dim N∗W∗Dim大小的最終輸入。(這步在模型中)

看起來復雜哭了,手動處理起來確實有些麻煩。不過后來發現跟pytorch很相關的有個包torchtext能夠很方便的做到這幾步,所以直接來介紹用這個包的做法。

在貼代碼之前先貼兩個torchtext的教程。torchtext入門教程 還是不懂的話看torchtext文檔。 還還是不懂請直接看源碼。對照教程看以下代碼。

首先是分詞函數,寫為有一個參數的函數:

def tokenizer(x):
    res = [w for w in jieba.cut(x)]
    return res

接著是停用詞表,在網上找的一個停用詞資源(也可以跳過這步):

stop_words = []
print('build stop words set')
with open('data/stopwords.dat') as f:
    for l in f.readlines():
        stop_words.append(l.strip())

然后設定TEXT和LABEL兩個field。定義以及參數含義看上面的文檔或教程。

TEXT = data.Field(sequential=True, tokenize=tokenizer,fix_length=1000,stop_words=stop_words)
LABEL = data.Field(sequential=False,use_vocab=False)

讀取文件,分詞,去掉停用詞等等。直接一波帶走:

train,valid,test = data.TabularDataset.splits(path='data',train='train.csv',
                                              validation='valid.csv',test='test.csv',
                                              format='csv',
                                              skip_header=True,csv_reader_params={'delimiter':'\t'},
                                              fields=[('text',TEXT),('label',LABEL)])

建立詞匯表:

TEXT.build_vocab(train)

生成iterator形式的mini-batch數據:

train_iter, val_iter, test_iter = data.Iterator.splits((train,valid,test),
                                                             batch_sizes=(args.batch_size,args.batch_size,args.batch_size),
                                                             device=args.device,
                                                             sort_key=lambda x:len(x.text),
                                                             sort_within_batch=False,
                                                             repeat=False)

That's all! 簡單得令人發指!雖然為了搞懂這幾個函數整了大半天。最終的這幾個xxx_iter就會生成我們需要的維度為N ∗ W N*WN∗W的數據。

3. 模型

模型其實相對很簡單,只有一個embedding映射,加一層cnn加一個激活函數以及一個全連接。

不過需要注意使用不同大小的卷積核的寫法。

可以選擇使用多個nn.Conv2d然后手動拼起來,這里使用nn.ModuleList模塊。其實本質上還是使用多個Conv2d然后拼起來。

import torch
import torch.nn as nn
import torch.nn.functional as F
class textCNN(nn.Module):
    def __init__(self, args):
        super(textCNN, self).__init__()
        self.args = args
        
        Vocab = args.embed_num ## 已知詞的數量
        Dim = args.embed_dim ##每個詞向量長度
        Cla = args.class_num ##類別數
        Ci = 1 ##輸入的channel數
        Knum = args.kernel_num ## 每種卷積核的數量
        Ks = args.kernel_sizes ## 卷積核list,形如[2,3,4]
        
        self.embed = nn.Embedding(Vocab,Dim) ## 詞向量,這里直接隨機
        
        self.convs = nn.ModuleList([nn.Conv2d(Ci,Knum,(K,Dim)) for K in Ks]) ## 卷積層
        self.dropout = nn.Dropout(args.dropout) 
        self.fc = nn.Linear(len(Ks)*Knum,Cla) ##全連接層
        
    def forward(self,x):
        x = self.embed(x) #(N,W,D)
        
        x = x.unsqueeze(1) #(N,Ci,W,D)
        x = [F.relu(conv(x)).squeeze(3) for conv in self.convs] # len(Ks)*(N,Knum,W)
        x = [F.max_pool1d(line,line.size(2)).squeeze(2) for line in x]  # len(Ks)*(N,Knum)
        
        x = torch.cat(x,1) #(N,Knum*len(Ks))
        
        x = self.dropout(x)
        logit = self.fc(x)
        return logit

4. 訓練腳本

import os
import sys
import torch
import torch.autograd as autograd
import torch.nn.functional as F
def train(train_iter, dev_iter, model, args):
    if args.cuda:
        model.cuda(args.device)    
    optimizer = torch.optim.Adam(model.parameters(), lr=args.lr)
    
    steps = 0
    best_acc = 0
    last_step = 0
    model.train()
    print('training...')
    for epoch in range(1, args.epochs+1):
        for batch in train_iter:
            feature, target = batch.text, batch.label #(W,N) (N)
            feature.data.t_()
            
            if args.cuda:
                feature, target = feature.cuda(), target.cuda()
            
            optimizer.zero_grad()
            logit = model(feature)
            loss = F.cross_entropy(logit, target)
            loss.backward()
            optimizer.step()
            
            steps += 1
            if steps % args.log_interval == 0:
                result = torch.max(logit,1)[1].view(target.size())
                corrects = (result.data == target.data).sum()
                accuracy = corrects*100.0/batch.batch_size
                sys.stdout.write('\rBatch[{}] - loss: {:.6f} acc: {:.4f}$({}/{})'.format(steps,
                                                                                        loss.data.item(),
                                                                                        accuracy,
                                                                                        corrects,
                                                                                        batch.batch_size))
            if steps % args.dev_interval == 0:
                dev_acc = eval(dev_iter, model, args)
                if dev_acc > best_acc:
                    best_acc = dev_acc
                    last_step = steps
                    if args.save_best:
                        save(model,args.save_dir,'best',steps)
                else:
                    if steps - last_step >= args.early_stop:
                        print('early stop by {} steps.'.format(args.early_stop))
            elif steps % args.save_interval == 0:
                save(model,args.save_dir,'snapshot',steps)

訓練腳本中還有設置optimizer以及loss的部分。其余部分比較trivial。

模型的保存:

def save(model, save_dir, save_prefix, steps):
    if not os.path.isdir(save_dir):
        os.makedirs(save_dir)
    save_prefix = os.path.join(save_dir,save_prefix)
    save_path = '{}_steps_{}.pt'.format(save_prefix,steps)
    torch.save(model.state_dict(),save_path)

eval函數,用來評估驗證集與測試集合上的準確率acc。

def eval(data_iter, model, args):
    model.eval()
    corrects, avg_loss = 0,0
    for batch in data_iter:
        feature, target = batch.text, batch.label
        feature.data.t_()
        
        if args.cuda:
            feature, target = feature.cuda(), target.cuda()
        
        logit = model(feature)
        loss = F.cross_entropy(logit,target)
        
        avg_loss += loss.data[0]
        result = torch.max(logit,1)[1]
        corrects += (result.view(target.size()).data == target.data).sum()
    
    size = len(data_iter.dataset)
    avg_loss /= size 
    accuracy = 100.0 * corrects/size
    print('\nEvaluation - loss: {:.6f} acc: {:.4f}%({}/{}) \n'.format(avg_loss,accuracy,corrects,size))
    return accuracy

5. main函數

這暫時就不貼了。可以參考下一部分給出的github。

最終在測試集合上accuracy為97%(畢竟只是四分類)。

但是遇到個問題就是隨著accuracy上升,loss也在迅速增大。

在一番探究之后大致得出結論就是,這樣是沒問題的。比如在本例中是個四分類,加入全連接層輸出的結果是[-10000,0,0,10000],而正確分類是0。

那么這就是個錯誤的結果。計算一下這個單個樣例的loss。先算softmax,約等于[ e − 20000 , e − 10000 , e − 10000 , 1 e^{-20000},e^{-10000},e^{-10000},1 e−20000,e−10000,e−10000,1]。真實的label為[1,0,0,0],因此交叉熵為20000。

所以我們發現這一個錯誤樣例的loss就會這么大。最終的loss大一些也是正常的。

不過為什么隨著accuracy接近100%而導致loss迅速增加這個問題還需要進一步研究。大概是因為隨著accuracy升高導致結果接近訓練集的分布,這樣與驗證集或測試集的分布產生比較極端差別的個例會增加。

6.引用

代碼部分參考了很多這位老哥的github,在此感謝。跟他不一樣的地方主要是數據處理部分。

以上為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

您可能感興趣的文章:
  • 基于PyTorch實現一個簡單的CNN圖像分類器
  • Pytorch mask-rcnn 實現細節分享
  • Pytorch 使用CNN圖像分類的實現
  • pytorch實現CNN卷積神經網絡
  • 用Pytorch訓練CNN(數據集MNIST,使用GPU的方法)
  • PyTorch CNN實戰之MNIST手寫數字識別示例
  • PyTorch上實現卷積神經網絡CNN的方法
  • CNN的Pytorch實現(LeNet)

標簽:常德 惠州 四川 鷹潭 黑龍江 黔西 上海 益陽

巨人網絡通訊聲明:本文標題《pytorch實現textCNN的具體操作》,本文關鍵詞  pytorch,實現,textCNN,的,具體,;如發現本文內容存在版權問題,煩請提供相關信息告之我們,我們將及時溝通與處理。本站內容系統采集于網絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《pytorch實現textCNN的具體操作》相關的同類信息!
  • 本頁收集關于pytorch實現textCNN的具體操作的相關信息資訊供網民參考!
  • 推薦文章
    校园春色亚洲色图_亚洲视频分类_中文字幕精品一区二区精品_麻豆一区区三区四区产品精品蜜桃
    91免费视频网| 91原创在线视频| 天天综合色天天| 日韩电影一区二区三区四区| 性久久久久久久| 91日韩一区二区三区| 成人一区二区三区在线观看| 欧美日本一区二区在线观看| 6080yy午夜一二三区久久| 日韩精品一区二区三区视频| 久久久99久久| 五月综合激情日本mⅴ| 色婷婷av一区二区三区软件| 亚洲午夜在线视频| 欧美成人猛片aaaaaaa| 美脚の诱脚舐め脚责91| 精品国产91久久久久久久妲己| 久久亚洲精品国产精品紫薇| 亚洲精品网站在线观看| 国产综合久久久久久久久久久久| 成人av片在线观看| 国产精品国产三级国产普通话三级 | 2019国产精品| 国产精品亚洲专一区二区三区| 久久天天做天天爱综合色| 亚洲欧洲精品一区二区三区| 亚洲自拍另类综合| 成人午夜av电影| 日韩一区二区三区电影在线观看| 欧美成人乱码一区二区三区| 亚洲自拍偷拍网站| 欧洲视频一区二区| 国产精品动漫网站| 大陆成人av片| 国产网站一区二区| 国产精品夜夜嗨| 久久久久国产精品人| 国产一区在线观看视频| 91精品国产综合久久久久久| 五月天丁香久久| 欧美卡1卡2卡| 热久久免费视频| 日韩一级免费观看| 婷婷中文字幕综合| 成人国产精品免费观看视频| 国产欧美日韩在线视频| 国产成人免费av在线| 欧美国产1区2区| aaa欧美日韩| 午夜精品久久久| 久久久精品国产免大香伊| 成人av在线资源| 一区二区三区四区av| 精品日韩在线观看| 国产经典欧美精品| 一区二区三区资源| 91精品欧美久久久久久动漫 | 亚洲高清三级视频| 91日韩在线专区| 韩国一区二区三区| 中文字幕一区av| 欧美一区二区三区在| 成人免费毛片aaaaa**| 亚洲国产欧美日韩另类综合| 日本一区二区电影| 日韩三级伦理片妻子的秘密按摩| 成人高清视频免费观看| 国产自产2019最新不卡| 日韩精品三区四区| 五月激情丁香一区二区三区| 亚洲美女淫视频| 亚洲男人的天堂网| 亚洲色图欧洲色图| 中文字幕第一区综合| 日本一区二区在线不卡| 久久奇米777| 国产精品每日更新| 国产精品久久夜| 26uuu久久综合| 欧美一级精品在线| 精品国产区一区| 26uuu另类欧美亚洲曰本| 精品国产伦一区二区三区免费| 制服丝袜在线91| 欧美一区二区在线免费播放| 日韩欧美中文一区| 久久精品视频一区二区| 亚洲精品精品亚洲| 五月天亚洲精品| 国内成人精品2018免费看| 韩国成人在线视频| 91小视频免费看| 欧美日韩中字一区| 精品久久久久久久久久久久久久久久久 | 亚洲激情av在线| 日本伊人色综合网| 99视频精品免费视频| 51精品久久久久久久蜜臀| 国产精品女人毛片| 强制捆绑调教一区二区| 成人av资源在线观看| 在线观看成人小视频| 精品理论电影在线观看| 亚洲女同ⅹxx女同tv| 成人午夜视频在线| 日韩一区二区三区视频在线| 国产午夜精品一区二区 | 亚洲地区一二三色| 日韩电影免费在线看| 成人三级在线视频| 日韩一级二级三级精品视频| 综合欧美亚洲日本| 97国产一区二区| 国产欧美日本一区视频| 国产一区二区三区四区五区美女| 91精品国产欧美一区二区成人 | 在线视频你懂得一区二区三区| 亚洲色欲色欲www| 波多野结衣在线aⅴ中文字幕不卡| 精品免费国产二区三区| 国产在线国偷精品产拍免费yy| 日韩欧美中文一区二区| 国产iv一区二区三区| 久久综合九色综合欧美就去吻 | 亚洲一线二线三线视频| 欧美亚洲综合另类| 免费成人av在线| 欧美一区二区三区啪啪| 国内精品嫩模私拍在线| 亚洲国产精品成人综合| 一道本成人在线| 狠狠色综合播放一区二区| 亚洲欧美一区二区在线观看| 99国产精品久| 美洲天堂一区二卡三卡四卡视频 | 国内精品久久久久影院薰衣草 | 欧美日韩国产123区| 激情综合网av| 亚洲精品福利视频网站| 国产日韩高清在线| 91精品国产色综合久久不卡电影 | 欧美偷拍一区二区| 国产一区999| 日本在线不卡一区| 亚洲午夜免费视频| 亚洲欧洲一区二区三区| 日韩欧美在线影院| 欧美在线观看一区| aaa欧美日韩| 成人免费高清视频在线观看| 久久成人综合网| 婷婷综合久久一区二区三区| 亚洲一区二区三区四区五区中文| 国产欧美一区二区精品性色超碰| 欧美日韩国产免费一区二区| 日本大香伊一区二区三区| 99精品视频在线播放观看| 91在线视频播放| 91一区二区在线| 欧美日韩免费一区二区三区| 欧美日韩精品欧美日韩精品| 色婷婷综合久色| 91精品国产综合久久婷婷香蕉| 欧美性色aⅴ视频一区日韩精品| 欧美在线三级电影| 欧美三级在线视频| 欧美大胆一级视频| 欧美国产欧美综合| 午夜久久久影院| 久久精品国产一区二区三| 国产精品2024| 欧美日韩不卡视频| 国产婷婷色一区二区三区四区| 国产欧美一区二区精品仙草咪| 亚洲综合在线免费观看| 国模冰冰炮一区二区| 在线视频亚洲一区| 久久久久久久久蜜桃| 奇米综合一区二区三区精品视频| 精品一区二区成人精品| 欧美亚洲国产一区二区三区| 久久免费精品国产久精品久久久久| 综合电影一区二区三区 | 久久精品免费在线观看| 亚洲第一搞黄网站| 欧美午夜精品免费| 亚洲摸摸操操av| 成人性生交大合| 欧美成人精品二区三区99精品| 亚洲一区二区高清| 一道本成人在线| 亚洲欧美日韩国产手机在线| 成年人午夜久久久| 中文字幕+乱码+中文字幕一区| 美女网站在线免费欧美精品| 91精品国产色综合久久ai换脸| 亚洲国产欧美一区二区三区丁香婷| 色妞www精品视频| 亚洲摸摸操操av| 欧美日韩高清一区二区不卡|