TextCNN_pytorch实现
发布日期:2022-02-17 04:52:20
浏览次数:14
分类:技术文章
本文共 5089 字,大约阅读时间需要 16 分钟。
import numpy as npimport torchfrom torch.functional import splitimport torch.nn as nnimport torch.optim as optimimport torch.nn.functional as F"""filter_list:Conv2d(1, 3, kernel_size=(2, 4), stride=(1, 1)) 1:表示输入channel为1; 3:表示输出channel为3; kernel_size: 卷积核大小为[2x4]; stride=(1, 1): 步长为1进行滑动filter_list: '0':Conv2d(1, 3, kernel_size=(2, 4), stride=(1, 1)) '1':Conv2d(1, 3, kernel_size=(2, 4), stride=(1, 1)) '2':Conv2d(1, 3, kernel_size=(2, 4), stride=(1, 1)) len():3a.permute(2, 0, 1): 若a维度为 [6, 1, 3], 将a的维度转化为 [3, 6, 1]"""class TextCNN(nn.Module): def __init__(self): super(TextCNN, self).__init__() self.num_filters_total = num_filters * len(filter_sizes) # 3 * 3 = 9 self.W = nn.Embedding(vocab_size, embedding_size) # (16, 4)的词表,根据索引得到 self.Weight = nn.Linear(self.num_filters_total, num_classes, bias=False) # Weight:[9, 2] 输入9个特征,输出2个特征,二分类 self.Bias = nn.Parameter(torch.ones( [num_classes])) # 加个偏置,一维长度为2的向量 data:tensor([1., 1.]) self.filter_list = nn.ModuleList([ nn.Conv2d(1, num_filters, (size, embedding_size)) for size in filter_sizes ]) # nn.Conv2d(1, 3, (2, 4)) def forward(self, x): embedded_chars = self.W( x) # embedded_chars:[6, 3, 4] 词向量维度为4,输入x为[6, 3] # print('embedded_chars_size:{}'.format(embedded_chars.size())) embedded_chars = embedded_chars.unsqueeze( 1) # 在索引为1的地方扩充一个维度,变为[6, 1, 3, 4] pooled_outputs = [] # 就相当于进行了三个滤波器,均由输入数据进过Conv2d(1, 3, kernel_size=(2, 4), stride=(1, 1))卷积 # 得到了三个卷积后的结果,也就是输入1,输出3的含义, 输入维度:[6, 3] 输出维度:[6, 1, 1, 3] for i, conv in enumerate(self.filter_list): # print(i, conv) h = F.relu(conv(embedded_chars)) # h: torch.Size([6, 3, 2, 1]) # print("h_size:{}".format(h.size())) mp = nn.MaxPool2d( (sequence_length - filter_sizes[i] + 1, 1)) #构建一个维度为 2x1的最大池化 pooled = mp(h).permute(0, 3, 2, 1) # mp(h): [6, 3, 1, 1] # print("pooled_size:{}".format( # pooled.size())) #pooled_size:torch.Size([6, 1, 1, 3]) pooled_outputs.append( pooled) # 最终三个卷积后的结果append到pooled_outputs,将三个滤波器卷积后的结果拼接到list中 # print("pooledn_outputs.size:{}, pooled_outputs:{}".format( # len(pooled_outputs), pooled_outputs)) h_pool = torch.cat( pooled_outputs, len(filter_sizes)) # shape: [6, 1, 1 ,9],将三个6113cat成6119 # print("h_pool_size:{}".format(h_pool.size())) h_pool_flat = torch.reshape( h_pool, [-1, self.num_filters_total]) # reshape为:[6, 9]维度 # print("h_pool_flat_size:{}".format(h_pool_flat.size())) model = self.Weight( h_pool_flat) + self.Bias # 变为 [6, 2] + 长度为2的向量,得到模型的输出 # print('model:{}'.format(model)) return model"""x.view(a,b,c) 将维度变为 [a, b, c]"""if __name__ == '__main__': embedding_size = 4 sequence_length = 3 num_classes = 2 filter_sizes = [2, 2, 2] # ****啥作用? num_filters = 3 # 不是很懂啊 sentences = [ "i love you", "he loves me", "she likes baseball", "i hate you", "sorry for that", "this is awful" ] labels = [1, 1, 1, 0, 0, 0] # word_list = " ".join(sentences).split() # print('word_list:{}'.format(word_list)) # word_list = list(set(word_list)) # print('word_list_len:{}, word_list:{}'.format(len(word_list), word_list)) # word_dict = {w: i for i, w in enumerate(word_list)} word_dict = { w: i for i, w in enumerate(list(set(' '.join(sentences).split()))) } vocab_size = len(word_dict) model = TextCNN() # 先允许TextCNN的__init__()函数 criterion = nn.CrossEntropyLoss() optimizer = optim.Adam(model.parameters(), lr=0.001) inputs = torch.LongTensor([[word_dict[i] for i in sen.split()] for sen in sentences]) targets = torch.LongTensor([out for out in labels]) # input_ = ([[word_dict[n] for n in sen.split()] # for sen in sentences]) # input_ :[batch_size, 3] 3为每条数据的长度 # print('input_size:{}, input:{}'.format( # torch.Tensor(input_).size(), input_)) # inputs = torch.LongTensor(np.asarray(input_)) # print('inputs_size:{}, inputs:{}'.format( # inputs.size(), inputs)) # inputs: [6, 3] 一批数据6条,每条数据三个单词 # 训练 for epoch in range(5001): optimizer.zero_grad() outputs = model(inputs) loss = criterion(outputs, targets) if epoch % 1000 == 0: print("Epoch:", "%04d" % (epoch), 'cost=', '{:.6f}'.format(loss)) loss.backward() optimizer.step() # Test test_text = 'he likes you' test = [[word_dict[t] for t in test_text.split()]] test = torch.LongTensor(test) # tests = [np.asarray([word_dict[n] for n in test_text.split()])] # test_batch = torch.LongTensor(tests) predict = model(test).data.max(1, keepdim=True)[1] print("predict:{}".format(predict)) # 保存模型 # torch.save(model, './model/TextCNN.pkl')
转载地址:https://blog.csdn.net/qq_41427834/article/details/116352345 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!
发表评论
最新留言
留言是一种美德,欢迎回访!
[***.207.175.100]2024年04月07日 01时25分01秒
关于作者
喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
Arduino串口显示文字
2019-04-27
Emacs-001_设置字体
2019-04-27
Emacs-002-Windows下的Emacs安装与运行
2019-04-27
Emacs-004-修改字体显示大小
2019-04-27
Emacs-005-关闭自动备份
2019-04-27
Emacs-006-行号模式的开启与关闭
2019-04-27
Emacs-007-日历查看
2019-04-27
Emacs-009-让Tab键不被空格替换
2019-04-27
Emacs-010-C语言缩进使用Tab且显示为4字符宽度
2019-04-27
Emacs-011-设置load-path
2019-04-27
Emacs-012-查询按键的功能
2019-04-27
Emacs-013-查询Emacs函数功能说明
2019-04-27
Emacs-014-已输入单词自动补全功能
2019-04-27
Emacs-017-company插件的配置
2019-04-27
Emacs-018-实现光标跳转到指定行
2019-04-27
Emacs-021-shell模式
2019-04-27
Emacs-022-光标以字符或者单词为单位跳转
2019-04-27
Emacs-023-光标跳转到行首或者行尾
2019-04-27
Web001-Win7中安装IIS7
2019-04-27
Web002-IIS安装是否成功测试.docx
2019-04-27