ALBERT:替换自己的数据实现分类算法

前言

网上有很多关于BERT代码运行的文章,但是关于ALBERT的却很少,好在是先试着用过了BERT的代码,因为种种问题才决定换ALBERT。写下这篇博客记录一下遇到的各种问题。
相比于BERT,ALBERT有多方面的提升。应用层面来看,主要是由于参数的共享,使得在模型体积明显的减小了。以base版的模型为例,BERT的模型接近ALBERT的10倍,虽然没有理论上的28倍那么夸张,运行的时候对资源的占用确实小了不少。之前用titan才能跑的BERT,现在用1080ti就能跑ALBERT了。

模型大小对比


一、代码下载

谷歌官方代码(TF版):google-research/albert
Pytorch版:albert_pytorch
brightmart版albert:albert_zh

二、运行过程

笔者使用的是官方的TensorFlow版的代码,代码从github下载即可。

1.下载模型文件和数据集

官方提供的模型分为Base、Large、Xlarge、Xxlarge四种大小:
Base
Large
Xlarge
Xxlarge

下载好合适的版本解压出来即可,笔者用的是albert_base。
数据集用的是一个英文的文本数据,分为两句话有关联则为1,无关则为0,这样的一个二分类。和代码一起上传到网盘了(数据集、base模型和改好的代码打包在一起)。
链接: https://pan.baidu.com/s/1ZqbcwP205-LFTjAfETPiDw
提取码: 6bde

2.修改代码

本文以分类任务为例,主要是看run_classifier.py。

引用
打开就能看到,from albert import ***,一看三行红线,赶紧去pip了albert包,还真下载到了。其实这里的albert并不是指能够在pip或者conda上下载到的albert包。这里就是指这些代码本身,看到网上有个方法是把这些代码放到一个文件夹里,我也没太明白,直接暴力删除from albert,直接从根目录import所需的文件。

在这里插入图片描述
然后直接运行run_classifier.py,把相同的报错的地方的from albert全部删除。

解决了这个问题,就可以开始写自己的类了。这和BERT里基本一样,都是定义了多个Processor,在main函数里声明。在run_classifier.py的main函数里找到processors,在最后加一个

"selfsort": classifier_utils.SelfProcessor,

在这里插入图片描述

接下来就是要写自己的processor类了,相比于BERT的源码,ALBERT将这部分的内容写在了classifier_utils.py文件里。在此,我们仿着源码里的Porcessor,加入自己的类SelfProcessor。代码如下:

class SelfProcessor(DataProcessor):   #英文数据集
  def get_train_examples(self, data_dir):
    index = 0
    examples = []
    file_path = os.path.join(data_dir + "/train.csv")
    f = csv.reader(open(file_path, 'r'))
    for i in f:
      guid = 'train-%d' % index
      text = i[0].split("\t")
      text_a = self.process_text(text[3])
      text_b = self.process_text(text[4].replace("\n",""))
      label = self.process_text(text[0])
      examples.append(InputExample(guid=guid, text_a=text_a,
                                   text_b=text_b, label=label))
      index += 1
    return examples

  def get_dev_examples(self, data_dir):
    index = 0
    examples = []
    file_path = os.path.join(data_dir + "/val.csv")
    f = csv.reader(open(file_path, 'r'))
    for i in f:
      guid = 'val-%d' % index
      text = i[0].split("\t")
      text_a = self.process_text(text[3])
      text_b = self.process_text(text[4].replace("\n",""))
      label = self.process_text(text[0])
      examples.append(InputExample(guid=guid, text_a=text_a,
                                   text_b=text_b, label=label))
      index += 1
    return examples

  def get_test_examples(self, data_dir):
    """See base class."""
    index = 0
    examples = []
    file_path = os.path.join(data_dir + "/test.csv")
    f = csv.reader(open(file_path, 'r', encoding='utf-8'))
    for i in f:
      guid = 'test-%d' % index
      text = i[0].split("\t")
      text_a = self.process_text(text[3])
      text_b = self.process_text(text[4].replace("\n", ""))
      label = self.process_text(text[0])
      examples.append(InputExample(guid=guid, text_a=text_a,
                                   text_b=text_b, label=label))
      index += 1
    return examples

  def get_labels(self):
    """See base class."""
    return ["0", "1"]

因为是判断两句话之间关系的分类任务,所以text_a和text_b都有值。

想用GPU跑的话,可以在run_classifier.py里加这么一句

os.environ["CUDA_VISIBLE_DEVICES"] = "0"

就可以调用单卡训练了,否则是使用CPU训练。

3.运行代码

按照官方给出的方法,在文件所在路径运行下面指令即可:

python albert.run_classifier \
  --data_dir='./data'\
  --output_dir='./output' \
  --init_checkpoint=None \
  --albert_config_file='./albert_base/albert_config.json' \
  --task_name = 'selfsort' \
  --vocab_file = './albert_base/30k-clean.vocab' \
  --spm_model_file='./albert_base/30k-clean.model'\
  --do_train = True\
  --do_eval = True\
  --do_predict = False\
  --do_lower_case = True\
  --max_seq_length=128 \
  --optimizer=adamw \
  --task_name= 'selfsort'\
  --warmup_step=1000 \
  --learning_rate=3e-5 \
  --train_step=1000 \
  --save_checkpoints_steps=100 \
  --train_batch_size=128

而本人比较懒,不想每次运行代码都用这么长的指令,这些超参数我都写到了代码里,想偷懒的也可以这么做,因为文件的位置总是不变的。
超参数

4.运行结果

在这里插入图片描述
训练了1000步,正确率66%,也不是特别高,训练100次的时候就达到差不多的水平。

遇到的问题

1.各种库的安装

按照官方的说法,代码推荐的tensorflow版本是1.15,笔者最后也是下载的这个,还有类似tensorflow_hub和sentencepiece,pip install装不上就用conda install,总有一款适合你。

2.显存不足

改小超参数就好了,max_seq_length、train_batch_size、eval_batch_size这些改小点。

3.改了代码和数据集但预测结果一直不变

这个问题坑了我一下午,最后发现是缓存在cached文件夹下的tfrecord文件导致的。第一次运行的时候读取出来的数据会缓存到cached_dir路径下,便于训练的时候读取。但是这个第一次写入后,再次运行的时候并不会覆写掉,而是直接调用。所以在测试的过程中,运行一次代码清空一下output和cached文件夹。

如需转载请标记出处。

  • 3
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JL__Liu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值