基于pytorch的CNN、LSTM神经网络模型调参小结

(Demo)

  • 这是最近两个月来的一个小总结,实现的demo已经上传github,里面包含了CNN、LSTM、BiLSTM、GRU以及CNN与LSTM、BiLSTM的结合还有多层多通道CNN、LSTM、BiLSTM等多个神经网络模型的的实现。这篇文章总结一下最近一段时间遇到的问题、处理方法和相关策略,以及经验(其实并没有什么经验)等,白菜一枚。
  • Demo Site:  https://github.com/bamtercelboo/cnn-lstm-bilstm-deepcnn-clstm-in-pytorch

(一) Pytorch简述

  • Pytorch是一个较新的深度学习框架,是一个 Python 优先的深度学习框架,能够在强大的 GPU 加速基础上实现张量和动态神经网络。

(二) CNN、LSTM

(三)数据预处理

  1、我现在使用的语料是基本规范的数据(例如下),但是加载语料数据的过程中仍然存在着一些需要预处理的地方,像一些数据的大小写、数字的处理以及“\n \t”等一些字符,现在使用torchtext第三方库进行加载数据预处理。

  • You Should Pay Nine Bucks for This : Because you can hear about suffering Afghan refugees on the news and still be unaffected . ||| 2
    Dramas like this make it human . ||| 4

  2、torch建立词表、处理语料数据的大小写:

  • import torchtext.data as data
    # lower word
    text_field = data.Field(lower=True)

  3、处理语料数据数字等特殊字符:

  •  1 from torchtext import data
     2       def clean_str(string):
     3             string = re.sub(r"[^A-Za-z0-9(),!?\‘\`]", " ", string)
     4             string = re.sub(r"\‘s", " \‘s", string)
     5             string = re.sub(r"\‘ve", " \‘ve", string)
     6             string = re.sub(r"n\‘t", " n\‘t", string)
     7             string = re.sub(r"\‘re", " \‘re", string)
     8             string = re.sub(r"\‘d", " \‘d", string)
     9             string = re.sub(r"\‘ll", " \‘ll", string)
    10             string = re.sub(r",", " , ", string)
    11             string = re.sub(r"!", " ! ", string)
    12             string = re.sub(r"\(", " \( ", string)
    13             string = re.sub(r"\)", " \) ", string)
    14             string = re.sub(r"\?", " \? ", string)
    15             string = re.sub(r"\s{2,}", " ", string)
    16             return string.strip()
    17
    18         text_field.preprocessing = data.Pipeline(clean_str)

  4、需要注意的地方:

  • 加载数据集的时候可以使用random打乱数据
  • 1 if shuffle:
    2     random.shuffle(examples_train)
    3     random.shuffle(examples_dev)
    4     random.shuffle(examples_test)

  • torchtext建立训练集、开发集、测试集迭代器的时候,可以选择在每次迭代的时候是否去打乱数据
  •  1 class Iterator(object):
     2     """Defines an iterator that loads batches of data from a Dataset.
     3
     4     Attributes:
     5         dataset: The Dataset object to load Examples from.
     6         batch_size: Batch size.
     7         sort_key: A key to use for sorting examples in order to batch together
     8             examples with similar lengths and minimize padding. The sort_key
     9             provided to the Iterator constructor overrides the sort_key
    10             attribute of the Dataset, or defers to it if None.
    11         train: Whether the iterator represents a train set.
    12         repeat: Whether to repeat the iterator for multiple epochs.
    13         shuffle: Whether to shuffle examples between epochs.
    14         sort: Whether to sort examples according to self.sort_key.
    15             Note that repeat, shuffle, and sort default to train, train, and
    16             (not train).
    17         device: Device to create batches on. Use -1 for CPU and None for the
    18             currently active GPU device.
    19     """

(四)Word Embedding

  1、word embedding简单来说就是语料中每一个单词对应的其相应的词向量,目前训练词向量的方式最使用的应该是word2vec(参考 http://www.cnblogs.com/bamtercelboo/p/7181899.html

  2、上文中已经通过torchtext建立了相关的词汇表,加载词向量有两种方式,一个是加载外部根据语料训练好的预训练词向量,另一个方式是随机初始化词向量,两种方式相互比较的话当时是使用预训练好的词向量效果会好很多,但是自己训练的词向量并不见得会有很好的效果,因为语料数据可能不足,像已经训练好的词向量,像Google News那个词向量,是业界公认的词向量,但是由于数量巨大,如果硬件设施(GPU)不行的话,还是不要去尝试这个了。

  3、提供几个下载预训练词向量的地址

  4、加载外部词向量方式

  • 加载词汇表中在词向量里面能够找到的词向量
  •  1 # load word embedding
     2 def load_my_vecs(path, vocab, freqs):
     3     word_vecs = {}
     4     with open(path, encoding="utf-8") as f:
     5         count  = 0
     6         lines = f.readlines()[1:]
     7         for line in lines:
     8             values = line.split(" ")
     9             word = values[0]
    10             # word = word.lower()
    11             count += 1
    12             if word in vocab:  # whether to judge if in vocab
    13                 vector = []
    14                 for count, val in enumerate(values):
    15                     if count == 0:
    16                         continue
    17                     vector.append(float(val))
    18                 word_vecs[word] = vector
    19     return word_vecs

  • 处理词汇表中在词向量里面找不到的word,俗称OOV(out of vocabulary),OOV越多,可能对加过的影响也就越大,所以对OOV词的处理就显得尤为关键,现在有几种策略可以参考:
  • 对已经找到的词向量平均化
  •  1 # solve unknown by avg word embedding
     2 def add_unknown_words_by_avg(word_vecs, vocab, k=100):
     3     # solve unknown words inplaced by zero list
     4     word_vecs_numpy = []
     5     for word in vocab:
     6         if word in word_vecs:
     7             word_vecs_numpy.append(word_vecs[word])
     8     print(len(word_vecs_numpy))
     9     col = []
    10     for i in range(k):
    11         sum = 0.0
    12         # for j in range(int(len(word_vecs_numpy) / 4)):
    13         for j in range(int(len(word_vecs_numpy))):
    14             sum += word_vecs_numpy[j][i]
    15             sum = round(sum, 6)
    16         col.append(sum)
    17     zero = []
    18     for m in range(k):
    19         # avg = col[m] / (len(col) * 5)
    20         avg = col[m] / (len(word_vecs_numpy))
    21         avg = round(avg, 6)
    22         zero.append(float(avg))
    23
    24     list_word2vec = []
    25     oov = 0
    26     iov = 0
    27     for word in vocab:
    28         if word not in word_vecs:
    29             # word_vecs[word] = np.random.uniform(-0.25, 0.25, k).tolist()
    30             # word_vecs[word] = [0.0] * k
    31             oov += 1
    32             word_vecs[word] = zero
    33             list_word2vec.append(word_vecs[word])
    34         else:
    35             iov += 1
    36             list_word2vec.append(word_vecs[word])
    37     print("oov count", oov)
    38     print("iov count", iov)
    39     return list_word2vec

  • 随机初始化或者全部取zero,随机初始化或者是取zero,可以是所有的OOV都使用一个随机值,也可以每一个OOV word都是随机的,具体效果看自己效果
  • 随机初始化的值看过几篇论文,有的随机初始化是在(-0.25,0.25)或者是(-0.1,0.1)之间,具体的效果可以自己去测试一下,不同的数据集,不同的外部词向量估计效果不一样,我测试的结果是0.25要好于0.1
  •  1 # solve unknown word by uniform(-0.25,0.25)
     2 def add_unknown_words_by_uniform(word_vecs, vocab, k=100):
     3     list_word2vec = []
     4     oov = 0
     5     iov = 0
     6     # uniform = np.random.uniform(-0.25, 0.25, k).round(6).tolist()
     7     for word in vocab:
     8         if word not in word_vecs:
     9             oov += 1
    10             word_vecs[word] = np.random.uniform(-0.25, 0.25, k).round(6).tolist()
    11             # word_vecs[word] = np.random.uniform(-0.1, 0.1, k).round(6).tolist()
    12             # word_vecs[word] = uniform
    13             list_word2vec.append(word_vecs[word])
    14         else:
    15             iov += 1
    16             list_word2vec.append(word_vecs[word])
    17     print("oov count", oov)
    18     print("iov count", iov)
    19     return list_word2vec

  • 特别需要注意处理后的OOV词向量是否在一定的范围之内,这个一定要在处理之后手动或者是demo查看一下,想处理出来的词向量大于15,30的这种,可能就是你自己处理方式的问题,也可以是说是你自己demo可能存在bug,对结果的影响很大。

1 if shuffle:
2     random.shuffle(examples_train)
3     random.shuffle(examples_dev)
4     random.shuffle(examples,
时间: 2024-10-13 21:23:26

基于pytorch的CNN、LSTM神经网络模型调参小结的相关文章

转载:scikit-learn随机森林调参小结

在Bagging与随机森林算法原理小结中,我们对随机森林(Random Forest, 以下简称RF)的原理做了总结.本文就从实践的角度对RF做一个总结.重点讲述scikit-learn中RF的调参注意事项,以及和GBDT调参的异同点. 1. scikit-learn随机森林类库概述 在scikit-learn中,RF的分类类是RandomForestClassifier,回归类是RandomForestRegressor.当然RF的变种Extra Trees也有, 分类类ExtraTreesC

scikit-learn随机森林调参小结

1. scikit-learn随机森林类库概述 在scikit-learn中,RF的分类类是RandomForestClassifier,回归类是RandomForestRegressor.当然RF的变种Extra Trees也有, 分类类ExtraTreesClassifier,回归类ExtraTreesRegressor.由于RF和Extra Trees的区别较小,调参方法基本相同,本文只关注于RF的调参. 和GBDT的调参类似,RF需要调参的参数也包括两部分,第一部分是Bagging框架的

scikit-learn 梯度提升树(GBDT)调参小结

在梯度提升树(GBDT)原理小结中,我们对GBDT的原理做了总结,本文我们就从scikit-learn里GBDT的类库使用方法作一个总结,主要会关注调参中的一些要点. 1. scikit-learn GBDT类库概述 在sacikit-learn中,GradientBoostingClassifier为GBDT的分类类, 而GradientBoostingRegressor为GBDT的回归类.两者的参数类型完全相同,当然有些参数比如损失函数loss的可选择项并不相同.这些参数中,类似于Adabo

支持向量机高斯核调参小结

在支持向量机(以下简称SVM)的核函数中,高斯核(以下简称RBF)是最常用的,从理论上讲, RBF一定不比线性核函数差,但是在实际应用中,却面临着几个重要的超参数的调优问题.如果调的不好,可能比线性核函数还要差.所以我们实际应用中,能用线性核函数得到较好效果的都会选择线性核函数.如果线性核不好,我们就需要使用RBF,在享受RBF对非线性数据的良好分类效果前,我们需要对主要的超参数进行选取.本文我们就对scikit-learn中 SVM RBF的调参做一个小结. 1. SVM RBF 主要超参数概

GBDT调参总结

GBDT类库弱学习器参数 GBDT类库boosting框架参数 n_estimators 弱学习器的最大迭代次数,或者说最大的弱学习器的个数.一般来说n_estimators太小,容易欠拟合,n_estimators太大,又容易过拟合,一般选择一个适中的数值.默认是100.在实际调参的过程中,我们常常将n_estimators和下面介绍的参数learning_rate一起考虑. learning_rate 每个弱学习器的权重缩减系数νν,也称作步长,在原理篇的正则化章节我们也讲到了,加上了正则化

基于tensorflow的MNIST手写字识别(一)--白话卷积神经网络模型

一.卷积神经网络模型知识要点卷积卷积 1.卷积 2.池化 3.全连接 4.梯度下降法 5.softmax 本次就是用最简单的方法给大家讲解这些概念,因为具体的各种论文网上都有,连推导都有,所以本文主要就是给大家做个铺垫,如有错误请指正,相互学习共同进步. 二.卷积神经网络讲解 2.1卷积神经网络作用 大家应该知道大名鼎鼎的傅里叶变换,即一个波形,可以有不同的正弦函数和余弦函数进行叠加完成,卷积神经网络也是一样,可以认为一张图片是由各种不同特征的图片叠加而成的,所以它的作用是用来提取特定的特征,举

自然语言处理的神经网络模型初探

欢迎大家前往云+社区,获取更多腾讯海量技术实践干货哦~ 深度学习(Deep Learning)技术对自然语言处理(NLP,Natural Language Processing)领域有着巨大的影响. 但作为初学者,您要从何处开始学习呢? 深度学习和自然语言处理都是较为广阔的领域,但每个领域重点研究些什么?在自然语言处理领域中,又是哪一方面最受深度学习的影响呢? 通过阅读本文,您会对自然语言处理中的深度学习有一个初步的认识. 阅读这篇文章后,您可以知道: 对自然语言处理领域影响最为深远的神经网络结

从图(Graph)到图卷积(Graph Convolution):漫谈图神经网络模型 (一)

本文属于图神经网络的系列文章,文章目录如下: 从图(Graph)到图卷积(Graph Convolution):漫谈图神经网络模型 (一) 从图(Graph)到图卷积(Graph Convolution):漫谈图神经网络模型 (二) 从图(Graph)到图卷积(Graph Convolution):漫谈图神经网络模型 (三) 笔者最近看了一些图与图卷积神经网络的论文,深感其强大,但一些Survey或教程默认了读者对图神经网络背景知识的了解,对未学过信号处理的读者不太友好.同时,很多教程只讲是什么

神经网络模型种类

神经网络模型种类 一般地,CNN的基本结构包括两层,其一为特征提取层,每个神经元的输入与前一层的局部接受域相连,并提取该局部的特征.一旦该局部特征被提取后,它与其它特征间的位置关系也随之确定下来:其二是特征映射层,网络的每个计算层由多个特征映射组成,每个特征映射是一个平面,平面上所有神经元的权值相等.特征映射结构采用影响函数核小的sigmoid函数作为卷积网络的激活函数,使得特征映射具有位移不变性.此外,由于一个映射面上的神经元共享权值,因而减少了网络自由参数的个数.卷积神经网络中的每一个卷积层