TextCNN代码解读及实战,Python通用流行框架大全

“”"读取语料

:param file_path:

:param type:

:return:

“”"

src_data = []

labels = []

seg = pkuseg.pkuseg() #使用默认分词方式。

with codecs.open(file_path,‘r’,encoding=‘utf-8’) as fout:

for line in tqdm(fout.readlines(),desc=‘reading corpus’):

if line is not None:

line.strip()的意思是去掉每句话句首句尾的空格

.split(‘\t’)的意思是根据’\t’把label和文章内容分开,label和内容是通过‘\t’隔开的。

\t表示空四个字符,也称缩进,相当于按一下Tab键

pair = line.strip().split(‘\t’)

if len(pair) != 2:

print(pair)

continue

src_data.append(seg.cut(pair[1]))# 对文章内容分词。

labels.append(pair[0])

return (src_data, labels) #返回文章内容的分词结果和labels

  • 经过这个步骤得到了labels和分词后的文章。如下代码:

src_sents, labels = read_corpus(‘cnews/cnews.train.txt’)

对labels做映射:

labels = {label: idx for idx, label in enumerate(labels)}

得到labels对应的idx的字典,idx的值是最后一次插入label的值。

第二步 构建词向量

这一步主要用到vocab.py的from_corpus方法

思路:

1、创建vocab_entry对象。

2、对分词后的文章统计词频,生成一个词和词频构成的字典。

3、从字典中取出Top size - 2个元素。

4、获取元素的词。

5、执行add方法将词放入vocab_entry,生成词和id,id就是词对应的向量值。

代码如下:

@staticmethod

def from_corpus(corpus, size, min_feq=3):

“”“从给定语料中创建VocabEntry”“”

vocab_entry = VocabEntry()

chain函数来自于itertools库,itertools库提供了非常有用的基于迭代对象的函数,而chain函数则是可以串联多个迭代对象来形成一个更大的迭代对象

*的作用:返回单个迭代器。

word_freq是个字典,key=词,value=词频

word_freq = Counter(chain(*corpus)) # Counter 是实现的 dict 的一个子类,可以用来方便地计数,统计词频

valid_words = word_freq.most_common(size - 2) # most_common()函数用来实现Top n 功能,在这里选出Top size-2个词

valid_words = [word for word, value in valid_words if value >= min_feq] # 把符合要求的词找出来放到list里面。

print(‘number of word types: {}, number of word types w/ frequency >= {}: {}’

.format(len(word_freq), min_feq, len(valid_words)))

for word in valid_words: # 将词放进VocabEntry里面。

vocab_entry.add(word)

return vocab_entry

创建完成后将词向量保存到json文件中

vocab = Vocab.build(src_sents, labels, 50000, 3)

print(‘generated vocabulary, source %d words’ % (len(vocab.vocab)))

vocab.save(‘./vocab.json’)

训练

=============================================================

训练使用Train_CNN.py,先看分析main方法的参数。

参数


parse = argparse.ArgumentParser()

parse.add_argument(“–train_data_dir”, default=‘./cnews/cnews.train.txt’, type=str, required=False)

parse.add_argument(“–dev_data_dir”, default=‘./cnews/cnews.val.txt’, type=str, required=False)

parse.add_argument(“–test_data_dir”, default=‘./cnews/cnews.test.txt’, type=str, required=False)

parse.add_argument(“–output_file”, default=‘deep_model.log’, type=str, required=False)

parse.add_argument(“–batch_size”, default=8, type=int)

parse.add_argument(“–do_train”, default=True, action=“store_true”, help=“Whether to run training.”)

parse.add_argument(“–do_test”, default=True, action=“store_true”, help=“Whether to run training.”)

parse.add_argument(“–learnning_rate”, default=5e-4, type=float)

parse.add_argument(“–num_epoch”, default=50, type=int)

parse.add_argument(“–max_vocab_size”, default=50000, type=int)

parse.add_argument(“–min_freq”, default=2, type=int)

parse.add_argument(“–embed_size”, default=300, type=int)

parse.add_argument(“–dropout_rate”, default=0.2, type=float)

parse.add_argument(“–warmup_steps”, default=0, type=int, help=“Linear warmup over warmup_steps.”)

parse.add_argument(“–GRAD_CLIP”, default=1, type=float)

parse.add_argument(“–vocab_path”, default=‘vocab.json’, type=str)

parse.add_argument(“–num_filter”, default=100, type=int, help=“CNN模型一个filter的输出channels”)

参数说明:

train_data_dir:训练集路径。

dev_data_dir:验证集路径

test_data_dir:测试集路径

output_file:输出的log路径

batch_size:batchsize的大小。

do_train:是否训练,默认True、

do_test:是否测试,默认True

learnning_rate:学习率

num_epoch:epoch的数量

max_vocab_size:词向量的个数

min_freq:词频,过滤低于这个数值的词

embed_size:Embedding的长度。

dropout_rate:dropout的值。

warmup_steps:设置预热的值。

vocab_path:词向量保存的路径

num_filter:卷积输出的数量。

构建词向量


vocab = build_vocab(args)

label_map = vocab.labels

print(label_map)

build_vocab的方法:

def build_vocab(args):

if not os.path.exists(args.vocab_path):

src_sents, labels = read_corpus(args.train_data_dir)

labels = {label: idx for idx, label in enumerate(labels)}

vocab = Vocab.build(src_sents, labels, args.max_vocab_size, args.min_freq)

vocab.save(args.vocab_path)

else:

vocab = Vocab.load(args.vocab_path)

return vocab

创建模型

创建CNN模型,将模型放到GPU上,调用train方法,训练。

cnn_model = CNN(len(vocab.vocab), args.embed_size, args.num_filter, [2, 3, 4], len(label_map),

dropout=args.dropout_rate)

cnn_model.to(device)

print(cnn_model.parameters)

train(args, cnn_model, train_data, dev_data, vocab, dtype=‘CNN’)

对train方法做了一些注解,如下:

def train(args, model, train_data, dev_data, vocab, dtype=‘CNN’):

LOG_FILE = args.output_file

#记录训练log

with open(LOG_FILE, “a”) as fout:

fout.write(‘\n’)

fout.write(‘==========’ * 6)

fout.write(‘start trainning: {}’.format(dtype))

fout.write(‘\n’)

time_start = time.time()

if not os.path.exists(os.path.join(‘./runs’, dtype)):

os.makedirs(os.path.join(‘./runs’, dtype))

tb_writer = SummaryWriter(os.path.join(‘./runs’, dtype))

计算总的迭代次数

t_total = args.num_epoch * (math.ceil(len(train_data) / args.batch_size))

optimizer = AdamW(model.parameters(), lr=args.learnning_rate, eps=1e-8)#设置优化器

scheduler = get_linear_schedule_with_warmup(optimizer=optimizer, num_warmup_steps=args.warmup_steps,

num_training_steps=t_total) #设置预热。

criterion = nn.CrossEntropyLoss()# 设置loss为交叉熵

global_step = 0

total_loss = 0.

logg_loss = 0.

val_acces = []

train_epoch = trange(args.num_epoch, desc=‘train_epoch’)

for epoch in train_epoch:#训练epoch

model.train()

for src_sents, labels in batch_iter(train_data, args.batch_size, shuffle=True):

src_sents = vocab.vocab.to_input_tensor(src_sents, args.device)

global_step += 1

optimizer.zero_grad()

logits = model(src_sents)

y_labels = torch.tensor(labels, device=args.device)

example_losses = criterion(logits, y_labels)

example_losses.backward()

torch.nn.utils.clip_grad_norm_(model.parameters(), args.GRAD_CLIP)

optimizer.step()

scheduler.step()

total_loss += example_losses.item()

if global_step % 100 == 0:

loss_scalar = (total_loss - logg_loss) / 100

logg_loss = total_loss

with open(LOG_FILE, “a”) as fout:

fout.write(“epoch: {}, iter: {}, loss: {},learn_rate: {}\n”.format(epoch, global_step, loss_scalar,

scheduler.get_lr()[0]))

print(“epoch: {}, iter: {}, loss: {}, learning_rate: {}”.format(epoch, global_step, loss_scalar,

scheduler.get_lr()[0]))

tb_writer.add_scalar(“lr”, scheduler.get_lr()[0], global_step)

tb_writer.add_scalar(“loss”, loss_scalar, global_step)

print(“Epoch”, epoch, “Training loss”, total_loss / global_step)

eval_loss, eval_result = evaluate(args, criterion, model, dev_data, vocab) # 评估模型

with open(LOG_FILE, “a”) as fout:

fout.write(“EVALUATE: epoch: {}, loss: {},eval_result: {}\n”.format(epoch, eval_loss, eval_result))

eval_acc = eval_result[‘acc’]

if len(val_acces) == 0 or eval_acc > max(val_acces):

如果比之前的acc要高,就保存模型

print(“best model on epoch: {}, eval_acc: {}”.format(epoch, eval_acc))

torch.save(model.state_dict(), “classifa-best-{}.th”.format(dtype))

val_acces.append(eval_acc)

time_end = time.time()

print(“run model of {},taking total {} m”.format(dtype, (time_end - time_start) / 60))

做了那么多年开发,自学了很多门编程语言,我很明白学习资源对于学一门新语言的重要性,这些年也收藏了不少的Python干货,对我来说这些东西确实已经用不到了,但对于准备自学Python的人来说,或许它就是一个宝藏,可以给你省去很多的时间和精力。

别在网上瞎学了,我最近也做了一些资源的更新,只要你是我的粉丝,这期福利你都可拿走。

我先来介绍一下这些东西怎么用,文末抱走。


(1)Python所有方向的学习路线(新版)

这是我花了几天的时间去把Python所有方向的技术点做的整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。

最近我才对这些路线做了一下新的更新,知识体系更全面了。

在这里插入图片描述

(2)Python学习视频

包含了Python入门、爬虫、数据分析和web开发的学习视频,总共100多个,虽然没有那么全面,但是对于入门来说是没问题的,学完这些之后,你可以按照我上面的学习路线去网上找其他的知识资源进行进阶。

在这里插入图片描述

(3)100多个练手项目

我们在看视频学习的时候,不能光动眼动脑不动手,比较科学的学习方法是在理解之后运用它们,这时候练手项目就很适合了,只是里面的项目比较多,水平也是参差不齐,大家可以挑自己能做的项目去练练。

在这里插入图片描述

(4)200多本电子书

这些年我也收藏了很多电子书,大概200多本,有时候带实体书不方便的话,我就会去打开电子书看看,书籍可不一定比视频教程差,尤其是权威的技术书籍。

基本上主流的和经典的都有,这里我就不放图了,版权问题,个人看看是没有问题的。

(5)Python知识点汇总

知识点汇总有点像学习路线,但与学习路线不同的点就在于,知识点汇总更为细致,里面包含了对具体知识点的简单说明,而我们的学习路线则更为抽象和简单,只是为了方便大家只是某个领域你应该学习哪些技术栈。

在这里插入图片描述

(6)其他资料

还有其他的一些东西,比如说我自己出的Python入门图文类教程,没有电脑的时候用手机也可以学习知识,学会了理论之后再去敲代码实践验证,还有Python中文版的库资料、MySQL和HTML标签大全等等,这些都是可以送给粉丝们的东西。

在这里插入图片描述

这些都不是什么非常值钱的东西,但对于没有资源或者资源不是很好的学习者来说确实很不错,你要是用得到的话都可以直接抱走,关注过我的人都知道,这些都是可以拿到的。

小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Python工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Python爬虫全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频

如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注:python)
img

TML标签大全等等,这些都是可以送给粉丝们的东西。

在这里插入图片描述

这些都不是什么非常值钱的东西,但对于没有资源或者资源不是很好的学习者来说确实很不错,你要是用得到的话都可以直接抱走,关注过我的人都知道,这些都是可以拿到的。

小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Python工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Python爬虫全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频

如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注:python)
[外链图片转存中…(img-nh3nid7I-1710881032646)]

  • 18
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值