当前位置:   article > 正文

人工智能代码实战:AI李白如何创作诗词_神经网络创作李白的诗

神经网络创作李白的诗

下面给大家讲解AI生成式模型的主流解决方案,通过一个机器人写诗词的案例,带大家掌握GRU模型, char-to-char策略, GPT2, T5等技术使用。

第一部分:人工智能概述【主要分支】

通讯、感知与行动是现代人工智能的三个关键能力

  • 计算机视觉(CV)
  • 自然语言处理(NLP)
  • 语音识别

语音识别

语音识别:指识别语音(说出的语言)并将其转换成对应文本的技术。相反的任务(文本转语音/TTS)也是这一领域内一个类似的研究主题。

当前阶段:进展颇丰,已经处于应用阶段很长时间

面临难题:声纹识别和 「鸡尾酒会效应」等一些特殊情况的难题。

自然语言处理

自然语言处理是指用计算机对自然语言的信息在单词级别,语义级别,篇章级别等进行处理。

最早的NLP任务 VS 最终的NLP任务

测试者与被测试者(一个人和一台机器)隔开的情况下,通过一些装置(如键盘)向被测试者随意提问。

测试准则(经过一段时间的聊天,比如15-30分钟),如果测试者不能确定被测试者是人还是机器,那么这台机器就通过了测试,并被认为具有人类智能。

深度学习定义

深度学习,利用人脑仿生的方式,一层一层的神经元,去自动模拟事物特征,进行预测对图片、声音的研究,大部分是使用深度学习技术。

NLP的几大基本任务

序列标注任务:

--- 分词

--- 词性标注

--- 命名实体识别

分类任务 :

--- 文本类型的分类

--- 情感分析

--- 舆情监控

句子关系任务:

--- 问答系统

--- 对话系统 (聊天机器人)

生成式任务 :

--- 机器翻译

--- 文章摘要

第二部分:看图说话任务 (背景分析)

首先对比一下传统的机器翻译任务架构图(seq2seq)

任务: 利用模型生成一段针对图片的描述文本, 这段文本和图片直接相关, 并抽取核心的语义, 比如下图所示。

如何找到和机器翻译任务的共同点?

数据预处理

训练数据集: MS-COCO

数据下载地址: Common Objects in Context

整个数据集分成两个部分:

1: 标注文件: annotations/captions_train2014.json

2: 图片文件: train2014/xxxx.jpg

  1. # 使用InceptionV3预训练模型处理图片训练集数据
  2. def load_image(image_path):
  3. # 以原生图片路径image_path为参数, 返回处理后的图片和图片路径
  4. # 读取原生图片路径
  5. img = tf.io.read_file(image_path)
  6. # 对图片进行图片格式的解码, 颜色通道为3
  7. img = tf.image.decode_jpeg(img, channels=3)
  8. # 统一图片尺寸为299x299
  9. img = tf.image.resize(img, (299, 299))
  10. # 调用keras.applications.inception_v3中的preprocess_input方法对统一尺寸后的图片进行处理
  11. img = tf.keras.applications.inception_v3.preprocess_input(img)
  12. # 返回处理后的图片和对应的图片地址
  13. return img, image_path

经过刚才的函数预处理后的返回图片, 就是这个样子

  1. top_k = 5000
  2. # 使用tf.keras.preprocessing.text.Tokenizer方法实例化数值映射器
  3. tokenizer = tf.keras.preprocessing.text.Tokenizer(num_words=top_k,
  4. oov_token="<unk>",
  5. filters='!"#$%&()*+.,-/:;=?@[\]^_`{|}~ ')
  6. # 使用数值映射器拟合train_captions(用于训练的描述文本)
  7. tokenizer.fit_on_texts(train_captions)
  8. tokenizer.word_index['<pad>'] = 0
  9. tokenizer.index_word[0] = '<pad>'
  10. # 最后作用于描述文本得到对应的数值映射结果
  11. train_seqs = tokenizer.texts_to_sequences(train_captions)
  12. print("train_seqs:", train_seqs)

经过上面代码对文本描述进行预处理后, 所有的文本已经完成了数字化映射:

模型构建与训练

# 第一步是编码器, 基于seq2seq架构, 我们选择CNN为主体的编码器, 负责提取图片特征:

  1. class CNN_Encoder(tf.keras.Model):
  2. def __init__(self, embedding_dim):
  3. super(CNN_Encoder, self).__init__()
  4. # 实例化一个全连接层
  5. self.fc = tf.keras.layers.Dense(embedding_dim)
  6. def call(self, x):
  7. # 使用全连接层
  8. x = self.fc(x)
  9. # 激活函数使用relu函数
  10. x = tf.nn.relu(x)
  11. return x

第二步是注意力机制:

  1. class BahdanauAttention(tf.keras.Model):
  2. def __init__(self, units):
  3. super(BahdanauAttention, self).__init__()
  4. self.W1 = tf.keras.layers.Dense(units)
  5. self.W2 = tf.keras.layers.Dense(units)
  6. self.V = tf.keras.layers.Dense(1)
  7. def call(self, features, hidden):
  8. hidden_with_time_axis = tf.expand_dims(hidden, 1)
  9. score = tf.nn.tanh(self.W1(features) + self.W2(hidden_with_time_axis))
  10. attention_weights = tf.nn.softmax(self.V(score), axis=1)
  11. context_vector = attention_weights * features
  12. context_vector = tf.reduce_sum(context_vector, axis=1)
  13. return context_vector, attention_weights

# 第三步是解码器, 基于seq2seq架构, 我们选取GRU作为解码器:

  1. class RNN_Decoder(tf.keras.Model):
  2. def __init__(self, embedding_dim, units, vocab_size):
  3. super(RNN_Decoder, self).__init__()
  4. self.units = units
  5. self.embedding = tf.keras.layers.Embedding(vocab_size, embedding_dim)
  6. self.gru = tf.keras.layers.GRU(self.units, return_sequences=True,
  7. return_state=True, recurrent_initializer=‘glorot_uniform')
  8. # 实例化两个全连接层
  9. self.fc1 = tf.keras.layers.Dense(self.units)
  10. self.fc2 = tf.keras.layers.Dense(vocab_size)
  11. # 实例化注意力机制
  12. self.attention = BahdanauAttention(self.units)
  13. def call(self, x, features, hidden):
  14. # 首先使用注意力计算规则获得features和hidden的注意力结果
  15. context_vector, attention_weights = self.attention(features, hidden)
  16. x = self.embedding(x)
  17. x = tf.concat([tf.expand_dims(context_vector, 1), x], axis=-1)
  18. output, state = self.gru(x)
  19. x = self.fc1(output)
  20. x = tf.reshape(x, (-1, x.shape[2]))
  21. x = self.fc2(x)
  22. # 返回解码结果, gru隐层状态, 和注意力权重
  23. return x, state, attention_weights
  24. # 开启一个用于梯度记录的上下文管理器
  25. with tf.GradientTape() as tape:
  26. # 使用编码器处理输入的图片张量
  27. features = encoder(img_tensor)
  28. # 开始使用解码器循环解码,解码长度为target.shape[1]即文本描述张量的最大长度
  29. for i in range(1, target.shape[1]):
  30. # 使用解码器获得第一个预测值和隐含张量
  31. predictions, hidden, _ = decoder(dec_input, features, hidden)
  32. # 计算该解码过程的损失
  33. loss += loss_function(target[:, i], predictions)
  34. # 接下来这里使用了teacher_forcing来定义下一次解码的输入
  35. # 关于teacher_forcing请查看下方定义和作用
  36. dec_input = tf.expand_dims(target[:, i], 1)
  37. # 全部循环解码完成后, 计算句子粒度的平均损失
  38. average_loss = (loss / int(target.shape[1]))
  39. # 获得整个模型训练的参数变量
  40. trainable_variables = encoder.trainable_variables + decoder.trainable_variables
  41. # 使用梯度管理器对象对参数变量求解梯度
  42. gradients = tape.gradient(loss, trainable_variables)
  43. # 根据梯度更新参数
  44. optimizer.apply_gradients(zip(gradients, trainable_variables))
  45. # 返回句子粒度的平均损失
  46. return average_loss
  47. # 使用编码器对图片进行编码
  48. features = encoder(img_tensor_val)
  49. dec_input = tf.expand_dims([tokenizer.word_index['<start>']], 0)
  50. result = []
  51. # 根据解码器结果生成最终的文本结果
  52. for i in range(max_length):
  53. predictions, hidden, attention_weights = decoder(dec_input, features, hidden)
  54. predicted_id = tf.random.categorical(predictions, 1)[0][0].numpy()
  55. # 根据数值映射器和predicted_id获得对应单词(文本)并装入结果列表中
  56. result.append(tokenizer.index_word[predicted_id])
  57. if tokenizer.index_word[predicted_id] == '<end>':
  58. return result, attention_plot
  59. # 如果不是终止符, 则将本次的结果扩展维度作为下次解码器的输出
  60. dec_input = tf.expand_dims([predicted_id], 0)

Prediction Caption: a person is sitting down to surfboard in no to their surf <end>

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/黑客灵魂/article/detail/773894
推荐阅读
相关标签
  

闽ICP备14008679号