我有一个包含60k个句子的样本数据集,正在尝试创建一个序列模型。在清理之后,预处理'y‘的长度是573,806行。唯一令牌的长度为16207。
为了在嵌入层中使用它,我尝试将这个'y‘转换成一个二进制类。我尝试过一种方式--热编码、to_categorical和哈希。所有这些方法都需要大量的内存分配(37 my ),我的google Colab Pro崩溃了。
似乎没有办法避免由于内存分配过多而导致的崩溃。Here is my related SO thread
鉴于此,我正在为这个问题寻找一些指导。有没有其他内存高效的方法可以用来解决这个问题,可以与顺序模型一起工作?
提前谢谢。
发布于 2020-12-24 11:04:19
而不是将数据表示为一个热编码的向量,因为您发现您可以做的是利用embedding columns,它能够将高维数据嵌入到较低维向量空间中,从而减少所需的总列数。
使用one-hot编码表示一周中的几天

使用嵌入表示一周中的某几天

Tensorflow为此提供了tf.feature_column.embedding_column(),您可以在Tensorflow上找到更多信息。
但是,请注意,参数categorical_column需要由tf.feature_column.categorical_column()函数创建。
embedding_column = tf.feature_column.embedding_column(
categorical_column=categorical_column,
dimension=dimension_of_embedding_vector)dimension_of_embedding_vector公式更多的是一个经验法则,它基于这个公式,并且从这个Google BlogPost中有更多的信息,他们使用类别数量的第四个根。:
embedding_dimensions = number_of_categories**0.25另一个公式是由杰里米·霍华德(fast.ai的创始人)提出的,他建议使用:
embedding size = min(50, number of categories/2).发布于 2020-12-24 16:34:13
下面是我推荐你处理句子的方法。为方便起见,让我们将数据集中的列称为‘语句’,并假设您已经读入了数据帧,因为变量数据代码如下
from tensorflow.keras.preprocessing.text import Tokenizer
from tensorflow.keras.preprocessing.sequence import pad_sequences
from sklearn.model_selection import train_test_split
def get_sequences(texts):
tokenizer = Tokenizer()
tokenizer.fit_on_texts(texts)
vocab_length = len(tokenizer.word_index) + 1
print("Vocab length:", vocab_length)
sequences = tokenizer.texts_to_sequences(texts)
max_seq_length = np.max([len(sequence) for sequence in sequences])
print("Max sequence length:", max_seq_length)
sequences = pad_sequences(sequences, maxlen=max_seq_length, padding='post')
return sequences
sentence_sequences = get_sequences(data['sentence'])
df = data.drop('sentence', axis=1)现在,您可以将sentence_sequences提供给模型中的keras嵌入层
emb_dim =64 # user defined dimension I find 64 usually works well
sentence_embedding = tf.keras.layers.Embedding(
input_dim=max_seq_length,output_dim=emb_dim,
input_length=sentence_sequences.shape[1],
name='sentence_embedding')(sentence_sequences)如果您除了句子之外还有其他功能,那么您可以将它们创建为模型的单独输入。处理它们,扁平化结果,然后用句子嵌入将它们连接起来。将结果放入一个密集层,其中神经元的数量与类的数量相同,并使用softmax激活。关于如何处理文本的好视频教程,我推荐去here.
发布于 2021-01-02 12:22:06
我想在这里留下一个答案可能会对将来的某人有所帮助。
下面尝试的所有不同方法的模型架构都是相同的。
使用to_categrical对y进行单热编码时的
纪元10/10 30/30 ============================== - 7s 245ms/步长损失: 0.0116 -精度: 0.6046
从categorical_column_with_vocabulary_list构建y时的 --> embedding_column,它产生向量
纪元10/10 30/30 ============================== - 8s 266ms/步长损失:-0.0012 -精度: 0.0084
当y是从feature_column.bucketized_column构建时的 --> indicator_column,它产生单热编码
纪元10/10 30/30 ============================== - 7s 248ms/步长损失: 0.0113 -精度: 0.6160
当y是从categorical_column_with_hash_bucket (最大特征)构建时的--> embedding_column (最大特征),它产生向量
纪元10/10 30/30 ============================== - 7s 229ms/步长损失:-0.0365 -精度: 0.0398
当y从产生向量的crossed_column,embedding_column构建时,性能几乎与hash_bucket方法相同。
考虑到这些实验,我重新设计了逻辑以使用DataGenerator方法,并使用one-hot编码迭代地训练整个数据集。这种方法适合可用内存,需要更长的训练时间,但这会产生更好的准确性。
https://stackoverflow.com/questions/65433177
复制相似问题