范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

使用TensorFlow进行文本分类

  1 前言
  在自然语言处理中,文本分类是非常普遍的应用,本文将介绍使用TensorFlow开发基于嵌入(Embedding)的文本分类模型,由于TensorFlow的API变化迅速且兼容性感人,因此本文均使用的截至2022年4月16日最新版的TensorFlow(tf)及相关库,主要包括: TensorFlow(v2.8.0) ,TensorFlow Datasets(tfds v4.0.1) 和TensorFlow Text(tf_text v2.8.1) ,如遇bug,请首先检查TensorFlow相关库的版本。此工作流主要使用的API有:tf.strings tfds tf_text tf.data.Dataset tf.keras (Sequential & Functional API) 2 获取数据
  TensorFlow Datasets(tfds)里含有非常多的 示例数据 [1] 用于研究试验,本文使用经典的电影评论数据,进行情感二分类任务的研究。首先使用tfds的API直接加载数据,结果将存在一个tf.data.Dataset [2] 对象中。import collections import pathlib  import tensorflow as tf from tensorflow.keras import layers from tensorflow.keras import losses from tensorflow.keras import utils from tensorflow.keras.layers import TextVectorization  import tensorflow_datasets as tfds import tensorflow_text as tf_text  import plotly.express as px import matplotlib.pyplot as plt  BATCH_SIZE = 32  # Training set. train_ds = tfds.load(     "imdb_reviews",     split="train[:80%]",     shuffle_files=True,     as_supervised=True)  # Validation set - a tf.data.Dataset object val_ds = tfds.load(     "imdb_reviews",     split="train[80%:]",     shuffle_files=True,     as_supervised=True)   # Check the count of records print(train_ds.cardinality().numpy()) print(val_ds.cardinality().numpy())
  返回值为: 20000 5000
  使用如下方法查看一条示例数据: for data, label in  train_ds.take(1):   print(type(data))   print("Text:", data.numpy())   print("Label:", label.numpy())
  返回值为:  Text: b"This was an absolutely terrible movie. Don"t be lured in by Christopher Walken or Michael Ironside. Both are great actors, but this must simply be their worst role in history. Even their great acting could not redeem this movie"s ridiculous storyline. This movie is an early nineties US propaganda piece. The most pathetic scenes were those when the Columbian rebels were making their cases for revolutions. Maria Conchita Alonso appeared phony, and her pseudo-love affair with Walken was nothing but a pathetic emotional plug in a movie that was devoid of any real meaning. I am disappointed that there are movies like this, ruining actor"s like Christopher Walken"s good name. I could barely sit through it." Label: 0 3 文本预处理
  该小节使用tf_text和tf.stings的处理文本的API对数据进行处理,tf.data.Dataset能够很方便地将对应的函数映射到数据中,推荐学习和使用。 3.1 转换文字大小写
  分类任务中字符大小写对模型预测没有贡献,因此对dataset使用 map 操作把所有字符转为小写,务必注意tf.data.Dataset里的数据格式。train_ds = train_ds.map(lambda text, label: (tf_text.case_fold_utf8(text), label)) val_ds = val_ds.map(lambda text, label: (tf_text.case_fold_utf8(text), label)) 3.2 文本格式化
  该步骤对文本使用正则表达式进行格式化处理,如标点前后加上空格,利于后续步骤使用空格分词。 str_regex_pattern = [("[^A-Za-z0-9(),!?"`]", " "),(""s", " "s",) ,(""ve", " "ve"),("n"t", " n"t"),(""re", " "re"),(""d", " "d") ,(""ll", " "ll"),(",", " , "),("!", " ! "),("(", " ( "),(")", " ) "),("?", " ? "),("s{2,}", " ")]  for pattern, rewrite in str_regex_pattern:   train_ds = train_ds.map(lambda text, label: (tf.strings.regex_replace(text, pattern=pattern, rewrite=rewrite), label))   val_ds = val_ds.map(lambda text, label: (tf.strings.regex_replace(text, pattern=pattern, rewrite=rewrite), label))  3.3 构建词表
  使用训练集构造词表(注意不要使用验证集或者测试集,会导致信息泄露),该步骤将字符映射到相应的索引,利于将数据转化为模型能够进行训练和预测的格式。 # Do not use validation set as that will lead to data leak train_text = train_ds.map(lambda text, label: text)  tokenizer = tf_text.WhitespaceTokenizer()  unique_tokens = collections.defaultdict(lambda: 0) sentence_length =  [] for text in train_text.as_numpy_iterator():   tokens = tokenizer.tokenize(text).numpy()   sentence_length.append(len(tokens))   for token in tokens:     unique_tokens[token] += 1  # check out the average sentence length -> ~250 tokens print(sum(sentence_length)/len(sentence_length))  # print 10 most used tokens - token, frequency d_view = [ (v,k) for k,v in unique_tokens.items()] d_view.sort(reverse=True)   for v,k in d_view[:10]:     print("%s: %d" % (k,v))
  返回值显示,高频使用的词都是英语中常见的字符: b"the": 269406 b",": 221098 b"and": 131502 b"a": 130309 b"of": 116695 b"to": 108605 b"is": 88351 b"br": 81558 b"it": 77094 b"in": 75177
  也可以使用图表直观地展示每个词的使用频率,这一步有利于帮助选择词表的大小。 fig = px.scatter(x=range(len(d_view)), y=[cnt for cnt, word in d_view]) fig.show()
  字符的使用频率分布
  由图可见,在七万多个字符中,许多字符出现的频率极低,因此选择词表大小为两万。 3.4 构建词表映射
  使用TensorFlow的 tf.lookup.StaticVocabularyTable 对字符进行映射,其能将字符映射到对应的索引上,并使用一个简单的样本进行测试。keys = [token for cnt, token in d_view][:vocab_size] values = range(2, len(keys) + 2)  # Reserve `0` for padding, `1` for OOV tokens.  num_oov_buckets =1  # Note: must assign the key_dtype and value_dtype when the keys and values are Python arrays init = tf.lookup.KeyValueTensorInitializer(     keys= keys,     values= values,     key_dtype=tf.string, value_dtype=tf.int64)  table = tf.lookup.StaticVocabularyTable(    init,    num_oov_buckets=num_oov_buckets)  # Test the look up table with sample input input_tensor = tf.constant(["emerson", "lake", "palmer", "king"]) print(table[input_tensor].numpy())
  输出为: array([20000,  2065, 14207,   618])
  接下来就可以将文本映射到索引上了,构造一个函数用于转化,并将它作用到数据集上: def text_index_lookup(text, label):   tokenized = tokenizer.tokenize(text)   vectorized = table.lookup(tokenized)   return vectorized, label  train_ds = train_ds.map(text_index_lookup) val_ds = val_ds.map(text_index_lookup) 3.5 配置数据集
  借助tf.data.Dataset的 cache 和prefetch API,能够有效提高性能,cache 方法将数据加载在内存中用于快速读写,而prefetch 则能够在模型预测时同步处理数据,提高时间利用率。AUTOTUNE = tf.data.AUTOTUNE  def configure_dataset(dataset):   return dataset.cache().prefetch(buffer_size=AUTOTUNE)  train_ds = configure_dataset(train_ds) val_ds = configure_dataset(val_ds)
  文本长短不一,但神经网络需要输入数据具有固定的维度,因此对数据进行padding确保长度一致,并分批次。 BATCH_SIZE = 32 train_ds = train_ds.padded_batch(BATCH_SIZE  ) val_ds = val_ds.padded_batch(BATCH_SIZE  ) 3.6 处理测试集
  用于验证模型性能的测试集也可以使用同样的方式处理,确保模型可以正常预测: # Test set. test_ds = tfds.load(     "imdb_reviews",     split="test",     # batch_size=BATCH_SIZE,     shuffle_files=True,     as_supervised=True)  test_ds = test_ds.map(lambda text, label: (tf_text.case_fold_utf8(text), label))  for pattern, rewrite in str_regex_pattern:   test_ds = test_ds.map(lambda text, label: (tf.strings.regex_replace(text, pattern=pattern, rewrite=rewrite), label))  test_ds = test_ds.map(text_index_lookup) test_ds = configure_dataset(test_ds) test_ds = test_ds.padded_batch(BATCH_SIZE  ) 4 建立模型4.1 使用Sequential API构建卷积神经网络vocab_size += 2 # 0 for padding and 1 for oov token  def create_model(vocab_size, num_labels, dropout_rate):   model = tf.keras.Sequential([       tf.keras.layers.Embedding(vocab_size, 128, mask_zero=True),        tf.keras.layers.Conv1D(32, 3, padding="valid", activation="relu", strides=1),       tf.keras.layers.MaxPooling1D(pool_size=2),        tf.keras.layers.Conv1D(64, 4, padding="valid", activation="relu", strides=1),       tf.keras.layers.MaxPooling1D(pool_size=2),        tf.keras.layers.Conv1D(128, 5, padding="valid", activation="relu", strides=1),       tf.keras.layers.GlobalMaxPooling1D( ),        tf.keras.layers.Dropout(dropout_rate),        tf.keras.layers.Dense(num_labels)   ])   return model  tf.keras.backend.clear_session() model = create_model(vocab_size=vocab_size, num_labels=2, dropout_rate=0.5)  # 在SGD中使用momentum将显著提高收敛速度 loss = losses.SparseCategoricalCrossentropy(from_logits=True) optimizer = tf.keras.optimizers.SGD(learning_rate=0.01, momentum=0.9)  model.compile(loss=loss, optimizer=optimizer, metrics="accuracy")  print(model.summary())
  输出为: Model: "sequential" _________________________________________________________________  Layer (type)                Output Shape              Param #    =================================================================  embedding (Embedding)       (None, None, 128)         2560256      conv1d (Conv1D)             (None, None, 32)          12320        max_pooling1d (MaxPooling1D  (None, None, 32)         0           )                                                                  conv1d_1 (Conv1D)           (None, None, 64)          8256         max_pooling1d_1 (MaxPooling  (None, None, 64)         0           1D)                                                                conv1d_2 (Conv1D)           (None, None, 128)         41088        global_max_pooling1d (Globa  (None, 128)              0           lMaxPooling1D)                                                     dropout (Dropout)           (None, 128)               0            dense (Dense)               (None, 2)                 258         ================================================================= Total params: 2,622,178 Trainable params: 2,622,178 Non-trainable params: 0 _________________________________________________________________
  接下来即可训练、评估模型: # early stopping reduces the risk of overfitting early_stopping = tf.keras.callbacks.EarlyStopping(patience=10) epochs = 100 history = model.fit(x=train_ds, validation_data=val_ds,epochs=epochs, callbacks=[early_stopping])  loss, accuracy = model.evaluate(test_ds)  print("Loss: ", loss) print("Accuracy: {:2.2%}".format(accuracy))
  考虑到模型结构简单,效果还可以接受: 782/782 [==============================] - 57s 72ms/step - loss: 0.4583 - accuracy: 0.8678 Loss:  0.45827823877334595 Accuracy: 86.78% 4.2 使用Functional API构建双向LSTM
  步骤与使用Sequential API类似,但Functional API更为灵活。 input = tf.keras.layers.Input([None] ) x = tf.keras.layers.Embedding(         input_dim=vocab_size,         output_dim=128,         # Use masking to handle the variable sequence lengths         mask_zero=True)(input)  x = tf.keras.layers.Bidirectional(tf.keras.layers.LSTM(64))(x) x = tf.keras.layers.Dense(64, activation="relu")(x) x = tf.keras.layers.Dropout(dropout_rate)(x) output = tf.keras.layers.Dense(num_labels)(x)  lstm_model = tf.keras.Model(inputs=input, outputs=output, name="text_lstm_model")  loss = losses.SparseCategoricalCrossentropy(from_logits=True) optimizer = tf.keras.optimizers.SGD(learning_rate=0.01, momentum=0.9)  lstm_model.compile(loss=loss, optimizer=optimizer, metrics="accuracy")  lstm_model.summary()
  输出为: Model: "text_lstm_model" _________________________________________________________________  Layer (type)                Output Shape              Param #    =================================================================  input_5 (InputLayer)        [(None, None)]            0            embedding_5 (Embedding)     (None, None, 128)         2560256      bidirectional_4 (Bidirectio  (None, 128)              98816       nal)                                                               dense_4 (Dense)             (None, 64)                8256         dropout_2 (Dropout)         (None, 64)                0            dense_5 (Dense)             (None, 2)                 130         ================================================================= Total params: 2,667,458 Trainable params: 2,667,458 Non-trainable params: 0 _________________________________________________________________
  同样地,对模型进行训练与预测: history_2 = lstm_model.fit(x=train_ds, validation_data=val_ds, epochs=epochs, callbacks=[early_stopping])  loss, accuracy = lstm_model.evaluate(test_ds)  print("Loss: ", loss) print("Accuracy: {:2.2%}".format(accuracy))
  考虑到模型结构简单,效果还可以接受: 782/782 [==============================] - 84s 106ms/step - loss: 0.4105 - accuracy: 0.8160 Loss:  0.4105057716369629 Accuracy: 81.60% 5 总结
  关于文本分类,还有许多新的技术可以尝试,上述工作流中也还有许多决策可以做试验(炼丹),本文旨在使用最新的TensorFlow API过一遍文本分类任务中的重要知识点和常用API,实际工作中仍有许多地方可以优化。希望这次的分享对你有帮助,欢迎在评论区留言讨论! 参考资料
  [1] TensorFlow Datasets数据集:  https://www.tensorflow.org/datasets
  [2] tf.data.Dataset:  https://www.tensorflow.org/api_docs/python/tf/data/Dataset

2。5亿变7000万!欧文续约合同曝光,篮网不签就没了关于欧文的去留问题,一直是NBA关注的焦点。根据纽约时报记者刘易斯的报道,欧文已经联系了多支球队商讨签约的可能性,如果无法和篮网达成5年2。5亿顶薪续约合同,他想要的是其他球队一份即日起,雁栖岛旅游参观恢复对外接待游客朋友们雁栖岛旅游参观APEC展示中心和一带一路国际合作高峰论坛展示中心公众参观,即日起恢复对外接待游客。请有意前来参观游览的游客提前预约。特此通知!新华社资料图温馨提示一预约电有哪些高质量的朋友圈文案?旅行篇1。日子很滚烫,又热又明朗。2。背包,生活,目的地。下一站,我不告诉你。3。保持热爱,奔赴山海。4。即将要去的地方,都是素未谋面的故乡。5。愿我们在旅行的路上马不停蹄。6。趁咖啡故事清迈稻田人生咖啡厅,四季尽享价值百万的风景清迈素有咖啡之城,泰北玫瑰之城之称,除了蓝天白云,清迈最不缺的就是如诗如画般的稻田风景。本期咖啡故事的主角是清迈桑甘烹雨树集市附近的稻田人生咖啡厅,一年四季可以享受不同的价值百万的贝林厄姆否认在对阵德国的比赛中呕吐那只是果汁直播吧6月8日讯北京时间今天凌晨的欧国联第二轮,英格兰在客场11战平德国。在伤停补时阶段,英格兰中场贝林厄姆被摄像机拍到在场上吐了一些液体。贝林厄姆在比赛接近结束时明显出现身体上的巴啦啦小魔仙15年后重聚,黑魔仙们没变化,小魔仙却难聚全前段时间,在某档综艺中,巴啦啦小魔仙里的扮演者们出现在了镜头前,他们穿上了当年的服饰,造型装扮上也都是接近15年前的模样,这让众多观众直呼爷青回,但在看清台上的人之后,也有不少观众孟庭丽现实版樊胜美,被家人吸血到死,器官捐献救了8条人命她是现实版樊胜美,被家人疯狂吸血,五十岁便过劳而死,女演员孟庭丽的一生,究竟有着怎样的苦楚?孟庭丽追悼会演员孟庭丽孟庭丽出生于中国台湾一个不富裕的家庭,作为家中的老大,她很早的时候唏嘘!娇娇直播卖茶叶,让2岁女儿喝银针茶,专家儿童不宜喝茶01。hr一个妈妈带着两个女儿在外地漂泊,本来挺让人同情的一件事,可看了妈妈对女儿的所作所为后,我真的想感慨一句娇娇,你不是个称职的好妈妈!02。hr众所周知,娇娇原名张玉娇,曾经新剧上线,女主杨超越却平均一集只有五分钟,真的是演技问题?新剧上线,女主杨超越却平均一集只有五分钟,演技真的这么差?网友吐槽谁是英雄谁是英雄女主杨超越饰演的温柔戏份过少,导致女主人设立不起来。这部剧是大男主剧,杨超越作为女主戏份少点可以理歌王谭咏麟将上亿资产全部留给妻子,只为让私生子认祖归宗文白面书誏编辑白面书誏当年,谭咏麟突然抱回了一个男孩,对着发妻杨洁薇说道我在外边有个儿子,我要让他回来认祖归宗,你们一定要和平相处,家里的钱全都由你来管。对杨洁薇来说,曾经爱得多炙张亮小女儿7岁生日照,头戴花环穿公主裙好像爸爸,夫妻离婚4年仍同住6月9日,张亮工作室晒出一组二女儿Zoe的近照,庆祝她7周岁快乐。照片中,小小的Zoe身穿淡粉色的娃娃裙,头上戴着花环,身后蓝天白云风景秀丽,大朵白色雏菊和气球点缀其中,看起来非常
无线电波的发现当电磁波的概念在1864年左右首次提出时,它遭到了极大的怀疑。结果,这个想法搁置了很长时间。这是可以理解的,因为该理论的基础很复杂,而且概念上的想法与物理思维不一致。少数敬业的人花为什么网球运动自带时尚基因?在7月10日发生于英国伦敦的2022温布尔登网球公开赛男单决赛上,塞尔维亚网球名将诺瓦克德约科维奇(NovakDjokovic)以31逆转击败澳大利亚选手尼克克耶高斯(NickKy我妥协了,回县城了成年人的妥协,一半是理解,一半是算了。我理解不了那么多,那就算了吧,我承认我是个俗人,不适合太多压力,我回县城了,赚着5000的工资,我很满足。没必要纠结后悔,人生如棋,落子无悔。燃油车每公里超过块,新能源车才毛,可它为何不受宠呢?油价一直上涨,95号汽油一直在10元上下徘徊,虽然说国际油价在下跌,但是国内油价也只是做了象征性的调整,高油价一直让所有车主头疼啊,路况差一点的地区,每公里的油费超过元甚至元了,开投影仪好用吗?产品体验官推荐目前最好的家用投影仪在投影仪领域,新手小白们最常见的问题就是投影仪好用吗?,作为产品体验官,谭星这几年接触过的投影仪之多,基本涵盖了各个档次的产品,对这个问题最有发言权。家用投影仪凭借其百寸大屏以及移新能源汽车车辆购置税优惠是否延续?工信部加紧研究中国青年报客户端北京7月19日电(中青报中青网记者王林)新能源汽车车辆购置税优惠政策是否将会延续?工业和信息化部新闻发言人总工程师田玉龙今天在国新办新闻发布会上表示,这个问题国务院两大游戏品牌同台竞技,红魔7S和ROG6谁才是性能颜值双优手机?最近,搭载第一代骁龙8的新品游戏手机扎堆发布,在市场上引起了不小的风波。诚然,得益于第一代骁龙8处理器的加持,新发布的各款手机在性能功耗和发热等方面都得到了不同程度的优化提升,在手我是一个喜欢等待黎明的人作者周步朗诵隋源我是一个喜欢等待黎明的人周步我是一个喜欢等待黎明的人我喜欢漫天的霞光,更喜欢微露的晨曦喜欢红彤彤的太阳徐徐上升那火一样的色泽照亮每一双告别黑夜的瞳孔我们必须承认,这个世界上最奢侈的华为Mate50渲染图曝光,华为影像XMAGE加持,搭载鸿蒙OS3。0近日知名爆料人特米曝光了Mate50系列机型背部概念渲染图,将直接搭载鸿蒙OS3。0,从左到右依次分别为Mate50,Mate50Pro和Mate50X,据悉Mate50将会有4个下一个离队者?西班牙人前锋或被租借到西乙弱旅LandryDimata(24)notienesitioenelEspanyoldeDiegoMartnezypuedequeprontoabandoneladisciplinab晚上18点!巴萨做出争议决定拉波尔塔成众矢之的,球迷骂声一片北京时间7月18日晚上18点,针对巴萨最新的计划,西班牙媒体每日体育报进行了跟踪报道,他们表示巴萨准备激活第三个经济杠杆,俱乐部正筹划出售巴萨工作室49的股份,而这样的决定也引发了