“”"读取语料
: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)
TML标签大全等等,这些都是可以送给粉丝们的东西。
这些都不是什么非常值钱的东西,但对于没有资源或者资源不是很好的学习者来说确实很不错,你要是用得到的话都可以直接抱走,关注过我的人都知道,这些都是可以拿到的。
小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级Python工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Python爬虫全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注:python)
[外链图片转存中…(img-nh3nid7I-1710881032646)]