自然语言处理系列六十三》神经网络算法》LSTM长短期记忆神经网络算法

news2024/12/28 2:52:32

注:此文章内容均节选自充电了么创始人,CEO兼CTO陈敬雷老师的新书《自然语言处理原理与实战》(人工智能科学与技术丛书)【陈敬雷编著】【清华大学出版社】

文章目录

  • 自然语言处理系列六十三
    • 神经网络算法》LSTM长短期记忆神经网络算法
      • Seq2Seq端到端神经网络算法
  • 总结

自然语言处理系列六十三

神经网络算法》LSTM长短期记忆神经网络算法

长短期记忆网络(LSTM,Long Short-Term Memory)是一种时间循环神经网络,是为了解决一般的RNN(循环神经网络)存在的长期依赖问题而专门设计出来的,所有的RNN都具有一种重复神经网络模块的链式形式。在标准RNN中,这个重复的结构模块只有一个非常简单的结构,例如一个tanh层。
1. LSTM介绍
长短期记忆网络(long short term memory, LSTM)的设计正是为了解决上述RNN的依赖问题,即为了解决RNN有时依赖的间隔短,有时依赖的间隔长的问题。其中循环神经网络被成功应用的关键就是LSTM。在很多的任务上,采用LSTM结构的循环神经网络比标准的循环神经网络的表现更好。LSTM结构是由Sepp hochreiter和Jurgen Schemidhuber于1997年提出的,它是一种特殊的循环神经网络结构。
2. LSTM结构
长LSTM的设计就是为了精确解决RNN的长短记忆问题,其中默认情况下LSTM是记住长时间依赖的信息,而不是让LSTM努力去学习记住长时间的依赖,如图7.30所示。
在这里插入图片描述

图7.30LSTM结构
所有循环神经网络都有一个重复结构的模型形式,在标准的RNN中,重复的结构是一个简单的循环体,如图7.28 所示的A循环体。然而LSTM的循环体是一个拥有四个相互关联的全连接前馈神经网络的复制结构,如图7.30所示。
目前可以先不必了解LSTM细节,只需先明白如下图7.31所示的符号语义:
在这里插入图片描述

图7.31 符号语义
Neural NetWork Layer:该图表示一个神经网络层;
Pointwise Operation:该图表示一种操作,如加号表示矩阵或向量的求和、乘号表示向量的乘法操作;
Vector Tansfer:每一条线表示一个向量,从一个节点输出到另一个节点;
Concatenate:该图表示两个向量的合并,即由两个向量合并为一个向量,如有X1和X2两向量合并后为[X1,X2]向量;
Copy:该图表示一个向量复制了两个向量,其中两个向量值相同。

3. LSTM分析
LSTM设计的关键是神经元的状态,如下图7.32所示顶部的水平线。神经元的状态类似传送带一样,按照传送方向从左端被传送到右端,在传送过程中基本不会改变,只是进行一些简单的线性运算:加或减操作。神经元的通过线性操作能够小心地管理神经元的状态信息,将这种管理方式称为门操作(gate)。
在这里插入图片描述

图7.32 C-line
门操作能够随意的控制神经元状态信息的流动,如下图7.33所示,它由一个sigmoid激活函数的神经网络层和一个点乘运算组成。Sigmoid层输出要么是1要么是0,若是0则不能让任何数据通过;若是1则意味着任何数据都能通过。
在这里插入图片描述

图7.33 gate
LSTM有三个门来管理和控制神经元的状态信息
1)遗忘门
  LSTM的第一步是决定要从上一个时刻的状态中丢弃什么信息,其是由一个sigmoid全连接的前馈神经网络的输出阿里管理,将这种操作称为遗忘门(forget get layer)。如图7.34所示。这个全连接的前馈神经网络的输入是和组成的向量,输出是向量。向量是由1和0组成,1表示能够通过,0表示不能通过。
在这里插入图片描述

图7.34 focus-f
2)输入门
第二步决定哪些输入信息要保存到神经元的状态中。这又两队前馈神经网络,如图7.35所示。首先是一个sigmoid层的全连接前馈神经网络,称为输入门(input gate layer),其决定了哪些值将被更新;然后是一个tanh层的全连接前馈神经网络,其输出是一个向量,向量可以被添加到当前时刻的神经元状态中;最后根据两个神经网络的结果创建一个新的神经元状态。
在这里插入图片描述

图7.35 focus-i
3)状态控制
第三步就可以更新上一时刻的状态为当前时刻的状态了。上述的第一步的遗忘门计算了一个控制向量,此时可通过这个向量过滤了一部分状态,如图7.36所示的乘法操作;上述第二步的输入门根据输入向量计算了新状态,此时可以通过这个新状态和状态根据一个新的状态,如图 27所示的加法操作。
在这里插入图片描述

图7.36focus-C
4)输出门
最后一步就是决定神经元的输出向量是什么,此时的输出是根据上述第三步的状态进行计算的,即根据一个sigmoid层的全连接前馈神经网络过滤到一部分状态作为当前时刻神经元的输出,如图7.37所示。这个计算过程是:首先通过sigmoid层生成一个过滤向量;然后通过一个tanh函数计算当前时刻的状态向量(即将向量每个值的范围变换到[-1,1]之间);接着通过sigmoid层的输出向量过滤tanh函数结果,即为当前时刻神经元的输出。
在这里插入图片描述

图7.37focus-o
4.LSTM实现语言模型代码实战
下面实现一个语言模型,它是NLP中比较重要的一部分,给上文的语境后,可以预测下一个单词出现的概率。如果是中文的话,需要做中文分词。什么是语言模型?统计语言模型是一个单词序列上的概率分布,对于一个给定长度为m的序列,它可以为整个序列产生一个概率 P(w_1,w_2,…,w_m)。其实就是想办法找到一个概率分布,它可以表示任意一个句子或序列出现的概率。
目前在自然语言处理相关应用非常广泛,如语音识别(speech recognition) , 机器翻译(machine translation), 词性标注(part-of-speech tagging), 句法分析(parsing)等。传统方法主要是基于统计学模型,最近几年基于神经网络的语言模型也越来越成熟。
下面就是基于LSTM神经网络的语言模型代码实现,先准备下数据和代码环境:
#首先下载PTB数据集并解压放到工作路径下
wget http://www.fit.vutbr.cz/~imikolov/rnnlm/simple-examples.tgz
tar xvf simple-examples.tgz
#然后下载tensorflow models库,进入目录models/tutorials/rnn/ptb。然后载入常用的库,#和tensorflow models中的PTB reader,通过它读取数据
git clone https://github.com/tensorflow/models.git
cd models/tutorials/rnn/ptb
LSTM核心如代码7.2所示
【代码7.2】 lstm.py

#-*- coding: utf-8 -*-
import time
import numpy as np
import tensorflow as tf
import ptb.reader as reader


flags = tf.app.flags
FLAGS = flags.FLAGS

logging = tf.logging

flags.DEFINE_string("save_path", './Out',
                   "Model output directory.")
flags.DEFINE_bool("use_fp16", False,
                 "Train using 16-bit floats instead of 32bit floats")

def data_type():
 return tf.float16 if FLAGS.use_fp16 else tf.float32

#定义语言模型处理的输入数据的class
class PTBInput(object):
  """The input data."""
  #初始化方法
  #读取config中的batch_size,num_steps到本地变量。
  def __init__(self, config, data, name=None):
    self.batch_size = batch_size = config.batch_size
    self.num_steps = num_steps = config.num_steps #num_steps是LSTM的展开步数
    #计算每个epoch内需要多好轮训练的迭代
    self.epoch_size = ((len(data) // batch_size) - 1) // num_steps
    #通过ptb_reader获取特征数据input_data和label数据targets
    self.input_data, self.targets = reader.ptb_producer(
        data, batch_size, num_steps, name=name)

#定义语言模型的class
class PTBModel(object):
  """PTB模型"""
  #训练标记,配置参数,ptb类的实例input_
  def __init__(self, is_training, config, input_):
    self._input = input_

    batch_size = input_.batch_size
    num_steps = input_.num_steps
    size = config.hidden_size #hidden_size是LSTM的节点数
    vocab_size = config.vocab_size #vocab_size是词汇表

    #使用遗忘门的偏置可以获得稍好的结果
    def lstm_cell():
      #使用tf.contrib.rnn.BasicLSTMCell设置默认的LSTM单元
      return tf.contrib.rnn.BasicLSTMCell(
          size, forget_bias=0.0, state_is_tuple=True)
          #state_is_tuple表示接受和返回的state将是2-tuple的形式

    attn_cell = lstm_cell
#如果训练状态且Dropout的keep_prob小于1,则在前面的lstm_cell之后接一个DropOut层,
#这里的做法是调用tf.contrib.rnn.DropoutWrapper函数
    if is_training and config.keep_prob < 1:
      def attn_cell():
        return tf.contrib.rnn.DropoutWrapper(
            lstm_cell(), output_keep_prob=config.keep_prob)
#最后使用rnn堆叠函数tf.contrib.rnn.MultiRNNCell将前面构造的lstm_cell
#多层堆叠得到cell
           #堆叠次数,为config中的num_layers.
    cell = tf.contrib.rnn.MultiRNNCell(
        [attn_cell() for _ in range(config.num_layers)], state_is_tuple=True)
    #这里同样将state_is_tuple设置为True

    #并掉用cell.zero_state设置LSTM单元的初始化状态为0
    self._initial_state = cell.zero_state(batch_size, tf.float32)
    #这里需要注意,LSTM单元可以读入一个单词并结合之前存储的状态state计算下一个单词
#出现的概率,
    #并且每次读取一个单词后它的状态state会被更新

    #创建网络的词embedding部分,embedding即为将one-hot的编码格式的单词转化为向量
#的表达形式
    #这部分操作在GPU中实现
    with tf.device("/cpu:0"):
      #初始哈embedding矩阵,其行数设置词汇表数vocab_size,列数(每个单词的向量表达
#的维数)设为hidden_size
      #hidden_size和LSTM单元中的隐含节点数一致#在训练过程中,embedding的参数可以
#被优化和更新。
      embedding = tf.get_variable(
          "embedding", [vocab_size, size], dtype=tf.float32)

      #接下来是使用tf.nn.embedding_lookup查询单词对应的向量表达获得inputs
      inputs = tf.nn.embedding_lookup(embedding, input_.input_data)

    #如果为训练状态,则添加一层Dropout
    if is_training and config.keep_prob < 1:
      inputs = tf.nn.dropout(inputs, config.keep_prob)

    #Simplified version of models/tutorials/rnn/rnn.py's rnn().
    #This builds an unrolled LSTM for tutorial purposes only.
    #In general, use the rnn() or state_saving_rnn() from rnn.py.
    #
    #The alternative version of the code below is:
    #
    #inputs = tf.unstack(inputs, num=num_steps, axis=1)
    #outputs, state = tf.nn.rnn(cell, inputs,
    #initial_state=self._initial_state)

    #定义输出outputs
    outputs = []
    state = self._initial_state
    #首先使用tf.variable_scope将接下来的名称设为RNN
    with tf.variable_scope("RNN"):
      #为了控制训练过程,我们会限制梯度在反向传播时可以展开的步数为一个固定的值,而这个步#数也是num_steps
      #这里设置一个循环,长度为num_steps,来控制梯度的传播
      for time_step in range(num_steps):
        #并且从第二次循环开始,我们使用tf.get_variable_scope().reuse_variables()
#设置复用变量
        if time_step > 0: tf.get_variable_scope().reuse_variables()
        #每次循环内,我们传入inputs和state到堆叠的LSTM单元即(cell)中
        #注意,inputs有三个维度,第一个维度是batch中的低级个样本,
        #第二个维度代表是样本中的第几个单词,第三个维度是单词的向量表达的维度。
        #inputs[:, time_step, :]代表所有样板的第time_step个单词
        (cell_output, state) = cell(inputs[:, time_step, :], state)
        #这里我们得到输出cell_output和更新后的state

        outputs.append(cell_output)
            #最后我们将结果cell_output添加到输出列表ouputs中

    #将output的内容用tf.contact串联到一起,并使用tf.reshape将其转为一个很长的一维
#向量
    output = tf.reshape(tf.concat(outputs, 1), [-1, size])
    #接下来是softmax层,先定义权重softmax_w和偏置softmax_b
    softmax_w = tf.get_variable(
        "softmax_w", [size, vocab_size], dtype=tf.float32)
    softmax_b = tf.get_variable("softmax_b", [vocab_size], dtype=tf.float32)
    #然后使用tf.matmul将输出output乘上权重并加上偏置得到logits
    logits = tf.matmul(output, softmax_w) + softmax_b
    #这里直接使用tf.contrib.legacy_seq2seq.sequence_loss_by_example计算输出
#logits
    #和targets的偏差

    loss = tf.contrib.legacy_seq2seq.sequence_loss_by_example(
        [logits],
        [tf.reshape(input_.targets, [-1])],
        [tf.ones([batch_size * num_steps], dtype=tf.float32)])
    #这里的sequence_loss即target words的averge negative log probability,

    self._cost = cost = tf.reduce_sum(loss) / batch_size
    #然后再使用tf.reduce_sum汇总batch的误差。
    self._final_state = state

    if not is_training:
      return
      #如果此时不是训练状态,直接返回。

    #定义学习速率的变量lr,并将其设为不可训练
    self._lr = tf.Variable(0.0, trainable=False)

    #再使用tf.trainable_variables获取所有可训练的参数tvars
    tvars = tf.trainable_variables()
    #针对前面得到的cost,计算tvars的梯度,并用tf.clip_by_global_norm设置梯度的最
#大范数max_grad_norm
    grads, _ = tf.clip_by_global_norm(tf.gradients(cost, tvars),
                                      config.max_grad_norm)
    #这即是Gradient Clipping的方法,控制梯度的最大范数,某种程度上起到正则化的效果。
    #Gradient Clipping可防止Gradient Explosion梯度爆炸的问题,如果对梯度不加限制,
    #则可能会因为迭代中梯度过大导致训练难以收敛

    #然后定义GradientDescent优化器
    optimizer = tf.train.GradientDescentOptimizer(self._lr)

    #再创建训练操作_train_op,用optimizer.apply_gradients将前面clip过的梯度应用
#到所有可训练的参数tvars上,
    #然后使用tf.contrib.framework.get_or_create_global_step()生成全局统一的训练
#步数
    self._train_op = optimizer.apply_gradients(
        zip(grads, tvars),
        global_step=tf.contrib.framework.get_or_create_global_step())

    #设置一个_new_lr的placeholder用以控制学习速率。
    self._new_lr = tf.placeholder(
        tf.float32, shape=[], name="new_learning_rate")
    #同时定义个assign_lr的函数,用以在外部控制模型的学习速率
    self._lr_update = tf.assign(self._lr, self._new_lr)

  #同时定义个assign_lr的函数,用以在外部控制模型的学习速率
  #方式是将学习速率值传入_new_lr这个place_holder,并执行_update_lr操作完成对学习速
#率的修改
  def assign_lr(self, session, lr_value):
    session.run(self._lr_update, feed_dict={self._new_lr: lr_value})

  #模型定义完毕,再定义定义这个PTBModel class的一些property
  #Python中的@property装饰器可以将返回变量设为只读,防止修改变量引发的问题

  #这里定义input,initial_state,cost,lr,final_state,train_op为property,方便外
#部访问
  @property
  def input(self):
    return self._input

  @property
  def initial_state(self):
    return self._initial_state

  @property
  def cost(self):
    return self._cost

  @property
  def final_state(self):
    return self._final_state

  @property
  def lr(self):
    return self._lr

  @property
  def train_op(self):
    return self._train_op


#接下来定义几种不同大小的模型的参数
#首先是小模型的设置
class SmallConfig(object):
  """Small config."""
  init_scale = 0.1 #网络中权重值的初始Scale
  learning_rate = 1.0 #学习速率的初始值
  max_grad_norm = 5 #前面提到的梯度的最大范数
  num_layers = 2 #num_layers是LSTM可以堆叠的层数
  num_steps = 20 #是LSTM梯度反向传播的展开步数
  hidden_size = 200 #LSTM的隐含节点数
  max_epoch = 4 #是初始学习速率的可训练的epoch数,在此之后需要调整学习速率
  max_max_epoch = 13 #总共可以训练的epoch数
  keep_prob = 1.0 #keep_prob是dorpout层的保留节点的比例
  lr_decay = 0.5 #学习速率的衰减速率
  batch_size = 20 #每个batch中样板的数量
  vocab_size = 10000

#具体每个参数的值,在不同的配置中对比才有意义

#在中等模型中,我们减小了init_state,即希望权重初值不要过大,小一些有利于温和的训练
#学习速率和最大梯度范数不变,LSTM层数不变。
#这里将梯度反向传播的展开步数从20增大到35.
#hidden_size和max_max_epoch也相应地增大约3倍;同时,这里开始设置dropout的
#keep_prob到0.5
#而之前设置1,即没有dropout;
#因为学习迭代次数的增大,因此将学习速率的衰减速率lr_decay也减小了。
#batch_size和词汇表vocab_size的大小保持不变
class MediumConfig(object):
  """Medium config."""
  init_scale = 0.05
  learning_rate = 1.0
  max_grad_norm = 5
  num_layers = 2
  num_steps = 35
  hidden_size = 650
  max_epoch = 6
  max_max_epoch = 39
  keep_prob = 0.5
  lr_decay = 0.8
  batch_size = 20
  vocab_size = 10000

#大型模型,进一步缩小了init_scale并大大放宽了最大梯度范数max_grad_norm到10
#同时将hidden_size提升到了1500,并且max_epoch,max_max_epoch也相应增大了;
#而keep_drop也因为模型复杂度的上升继续下降,学习速率的衰减速率lr_decay也进一步减小
class LargeConfig(object):
  """Large config."""
  init_scale = 0.04
  learning_rate = 1.0
  max_grad_norm = 10
  num_layers = 2
  num_steps = 35
  hidden_size = 1500
  max_epoch = 14
  max_max_epoch = 55
  keep_prob = 0.35
  lr_decay = 1 / 1.15
  batch_size = 20
  vocab_size = 10000


#TstConfig只是测试用,参数都尽量使用最小值,只是为了测试可以完整允许模型
class TstConfig(object):
  """Tiny config, for testing."""
  init_scale = 0.1
  learning_rate = 1.0
  max_grad_norm = 1
  num_layers = 1
  num_steps = 2
  hidden_size = 2
  max_epoch = 1
  max_max_epoch = 1
  keep_prob = 1.0
  lr_decay = 0.5
  batch_size = 20
  vocab_size = 10000

#定义训练一个epoch数据的函数run_epoch。
def run_epoch(session, model, eval_op=None, verbose=False):
  """Runs the model on the given data."""
  #记录当前时间,初始化损失costs和迭代数iters。
  start_time = time.time()
  costs = 0.0
  iters = 0
  state = session.run(model.initial_state)
  #并执行model.initial_state来初始化状态并获得初始状态

  #接着创建输出结果的字典表fetches
  #其中包括cost和final_state
  fetches = {
      "cost": model.cost,
      "final_state": model.final_state,
  }
  #如果有评测操作eval_op,也一并加入fetches
  if eval_op is not None:
    fetches["eval_op"] = eval_op

  #接着进行循环训练中,次数为epoch_size
  for step in range(model.input.epoch_size):
    feed_dict = {}
    #在每次循环中,我们生成训练用的feed_dict

    for i, (c, h) in enumerate(model.initial_state):
      feed_dict[c] = state[i].c
      feed_dict[h] = state[i].h

    #将全部的LSTM单元的state加入feed_dict,然后传入feed_dict并执行
    #fetchees对网络进行一次训练,并且拿到cost和state
    vals = session.run(fetches, feed_dict)
    cost = vals["cost"]
    state = vals["final_state"]

    #我们累加cost到costs,并且累加num_steps到iters。
    costs += cost
    iters += model.input.num_steps

    #我们每完成约10%的epoch,就进行一次结果的展示,依次展示当前epoch的进度,
    #perplexity(即平均cost的自然常数指数,语言模型性能的重要指标,越低代表模型输出的
#概率分布在预测样本上越好)
 #和训练速度(单词/s)

    if verbose and step % (model.input.epoch_size // 10) == 10:
      print("%.3f perplexity: %.3f speed: %.0f wps" %
            (step * 1.0 / model.input.epoch_size, np.exp(costs / iters),
             iters * model.input.batch_size / (time.time() - start_time)))
  #最后返回perplexity作为函数的结果
  return np.exp(costs / iters)


#使用reader.ptb_raw_data直接读取解压后的数据,得到训练数据,验证数据和测试数据
raw_data = reader.ptb_raw_data('./simple-examples/data/')
train_data, valid_data, test_data, _ = raw_data


#这里定义训练模型的配置为小型配置
config = SmallConfig()
eval_config = SmallConfig()
eval_config.batch_size = 1
eval_config.num_steps = 1
#需要注意的是测试配置eval_config需和训练配置一致
#这里将测试配置的batch_size和num_steps修改为1


#创建默认的Graph,并使用tf.random_uniform_initializer设置参数的初始化器
with tf.Graph().as_default():
  initializer = tf.random_uniform_initializer(-config.init_scale,
                                              config.init_scale)

  with tf.name_scope("Train"):
    #使用PTBInput和PTBModel创建一个用来训练的模型m
    train_input = PTBInput(config=config, data=train_data, name="TrainInput")
    with tf.variable_scope("Model", reuse=None, initializer=initializer):
      m = PTBModel(is_training=True, config=config, input_=train_input)
      #tf.scalar_summary("Training Loss", m.cost)
      #tf.scalar_summary("Learning Rate", m.lr)

  with tf.name_scope("Valid"):
    #使用PTBInput和PTBModel创建一个用来验证的模型mvalid
    valid_input = PTBInput(config=config, data=valid_data, name="ValidInput")
    with tf.variable_scope("Model", reuse=True, initializer=initializer):
      mvalid = PTBModel(is_training=False, config=config, input_=valid_input)
      #tf.scalar_summary("Validation Loss", mvalid.cost)

  with tf.name_scope("Tst"):
    #使用PTBInput和PTBModel创建一个用来验证的模型Tst
    test_input = PTBInput(config=eval_config, data=test_data, name="TstInput")
    with tf.variable_scope("Model", reuse=True, initializer=initializer):
      mtst = PTBModel(is_training=False, config=eval_config,
                       input_=test_input)

  #其中训练和验证模型直接使用前面的cofig,测试模型则使用前面的测试配置eval_config


  sv = tf.train.Supervisor()
  #使用tf.train.Supervisor创建训练的管理器sv

  #并使用sv.managed_session()创建默认的session
  with sv.managed_session() as session:
    #再执行训练多个epoch数据的循环
    for i in range(config.max_max_epoch):
      #在每个epoch循环内,我们先计算累计的学习速率衰减值,
      #这里只需要计算超过max_epoch的轮数,再求lr_decay的超出轮数次幂即可
      #然后将初始学习速率乘以累计的衰减,并更新学习速率。
      lr_decay = config.lr_decay ** max(i + 1 - config.max_epoch, 0.0)
      m.assign_lr(session, config.learning_rate * lr_decay)

      #在循环内执行一个epoch的训练和验证,并输出当前的学习速率,训练和验证即的
#perplexity
      print("Epoch: %d Learning rate: %.3f" % (i + 1, session.run(m.lr)))
      train_perplexity = run_epoch(session, m, eval_op=m.train_op,
                                   verbose=True)
      print("Epoch: %d Train Perplexity: %.3f" % (i + 1, train_perplexity))
      valid_perplexity = run_epoch(session, mvalid)
      print("Epoch: %d Valid Perplexity: %.3f" % (i + 1, valid_perplexity))

    #在完成全部训练之后,计算并输出模型在测试集上的perplexity
    tst_perplexity = run_epoch(session, mtst)
    print("Test Perplexity: %.3f" % tst_perplexity)
     #
     #if FLAGS.save_path:
     #  print("Saving model to %s." % FLAGS.save_path)
     #  sv.saver.save(session, FLAGS.save_path, global_step=sv.global_step)

if __name__ == "__main__":
 tf.app.run()

LSTM经常用来解决处理和预测序列化问题,下面要讲的Seq2Seq端到端神经网络就是基于LSTM的,当然Seq2Seq也不是必须基于LSTM,它也可以是基于CNN的。下面我们来看下Seq2Seq。

Seq2Seq端到端神经网络算法

下一篇文章分享Seq2Seq端到端神经网络算法,更多内容可参见
《自然语言处理原理与实战》(人工智能科学与技术丛书)【陈敬雷编著】【清华大学出版社】书籍。
更多的技术交流和探讨也欢迎加我个人微信chenjinglei66。

总结

此文章有对应的配套新书教材和视频:

【配套新书教材】
《自然语言处理原理与实战》(人工智能科学与技术丛书)【陈敬雷编著】【清华大学出版社】
新书特色:本书从自然语言处理基础开始,逐步深入各种NLP热点前沿技术,使用了Java和Python两门语言精心编排了大量代码实例,契合公司实际工作场景技能,侧重实战。
全书共分为19章,详细讲解中文分词、词性标注、命名实体识别、依存句法分析、语义角色标注、文本相似度算法、语义相似度计算、词频-逆文档频率(TF-IDF)、条件随机场、新词发现与短语提取、搜索引擎Solr Cloud和Elasticsearch、Word2vec词向量模型、文本分类、文本聚类、关键词提取和文本摘要、自然语言模型(Language Model)、分布式深度学习实战等内容,同时配套完整实战项目,例如对话机器人实战、搜索引擎项目实战、推荐算法系统实战。
本书理论联系实践,深入浅出,知识点全面,通过阅读本书,读者不仅可以理解自然语言处理的知识,还能通过实战项目案例更好地将理论融入实际工作中。
《分布式机器学习实战》(人工智能科学与技术丛书)【陈敬雷编著】【清华大学出版社】
新书特色:深入浅出,逐步讲解分布式机器学习的框架及应用配套个性化推荐算法系统、人脸识别、对话机器人等实战项目。

【配套视频】

推荐系统/智能问答/人脸识别实战 视频教程【陈敬雷】
视频特色:把目前互联网热门、前沿的项目实战汇聚一堂,通过真实的项目实战课程,让你快速成为算法总监、架构师、技术负责人!包含了推荐系统、智能问答、人脸识别等前沿的精品课程,下面分别介绍各个实战项目:
1、推荐算法系统实战
听完此课,可以实现一个完整的推荐系统!下面我们就从推荐系统的整体架构以及各个子系统的实现给大家深度解密来自一线大型互联网公司重量级的实战产品项目!
2、智能问答/对话机器人实战
由浅入深的给大家详细讲解对话机器人项目的原理以及代码实现、并在公司服务器上演示如何实际操作和部署的全过程!
3、人脸识别实战
从人脸识别原理、人脸识别应用场景、人脸检测与对齐、人脸识别比对、人脸年龄识别、人脸性别识别几个方向,从理论到源码实战、再到服务器操作给大家深度讲解!

自然语言处理NLP原理与实战 视频教程【陈敬雷】
视频特色:《自然语言处理NLP原理与实战》包含了互联网公司前沿的热门算法的核心原理,以及源码级别的应用操作实战,直接讲解自然语言处理的核心精髓部分,自然语言处理从业者或者转行自然语言处理者必听视频!

人工智能《分布式机器学习实战》 视频教程【陈敬雷】
视频特色:视频核心内容有互联网公司大数据和人工智能、大数据算法系统架构、大数据基础、Python编程、Java编程、Scala编程、Docker容器、Mahout分布式机器学习平台、Spark分布式机器学习平台、分布式深度学习框架和神经网络算法、自然语言处理算法、工业级完整系统实战(推荐算法系统实战、人脸识别实战、对话机器人实战)。

上一篇:自然语言处理系列六十二》神经网络算法》MLP多层感知机算法
下一篇:自然语言处理系列六十三》神经网络算法》Seq2Seq端到端神经网络算法

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2114105.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【C++多线程编程】 线程安全与对象生命周期管理

目录 类的线程安全 实现线程安全 构造函数在多线程中的安全性 析构函数多线程环境的安全 智能指针实现多线程安全 shared_ptr 非完全线程安全 shared_ptr可能导致对象生命周期延长 const引用可以减少传递shared_ptr开销 shared_ptr 智能指针块模块的优点 析构所在线程…

前端核心基础知识总结

目录 前言 一、HTML模块 1. 标签结构 2. 语义化标签 3. 表单元素 二、CSS模块 1. 选择器 2. 盒模型 示例一&#xff1a;为一个div标签设置了宽度为 200 像素&#xff0c;高度为 100 像素的内容区。 示例二&#xff1a;内边距的存在可以使内容与边框之间有一定的间隔&…

数字化转型专家讲师培训师唐兴通中欧国际工商学院数字化转型战略与实现路径AIGC人工智能数字化战略数字商业模式创新

《数字化转型战略与实现路径》 课程内容与收益 本课程的目标是通过深入的学习来帮助学员全面地了解数字化转型的概念和实现路径&#xff0c;掌握数字化转型的各种方法和技巧&#xff0c;进而提升数字化转型的能力和水平&#xff0c;从而使企业更具有竞争力。在这个课程中&…

《黑神话悟空》永冻流出装如何装备!!

整体玩法是通过法宝芭蕉扇打出控制后&#xff0c;再用化身技打出冰冻&#xff0c;冰冻期间用棍花持续输出&#xff0c;同时积攒元气和棍势&#xff0c;在利用三或四棍势打出一波爆发输出&#xff0c;基本上一套打完元气又满了&#xff0c;可以再放下一次控制&#xff0c;如此循…

【AI大模型应用开发】1.3 Prompt攻防(安全) 和 Prompt逆向工程

AI大模型应用开发教程 随着GPT和Prompt工程的大火&#xff0c;随之而来的是隐私问题和安全问题。尤其是最近GPTs刚刚开放&#xff0c;藏在GPTs后面的提示词就被网友们扒了出来&#xff0c;甚至直接被人作为开源项目发布&#xff0c;一点安全和隐私都没有&#xff0c;原作者的收…

C语言程序与设计第四版课后习题 - 1~8章大合集

前言 本文章是一个大合集&#xff0c;按照课后习题的命名方式命名&#xff0c;方便寻找&#xff0c;只需要在目录上点相对应的题号即可在这里插入图片描述 第一章课后习题 1.1 编写一个C程序 题目概述&#xff1a; 请参照本章例题&#xff0c;编写一个C程序&#xff0c;输…

CMU 10423 Generative AI:lec3(阅读材料:GPT1论文解读)

推荐参考&#xff1a;李沐的B站视频《GPT&#xff0c;GPT-2&#xff0c;GPT-3 论文精读》https://www.bilibili.com/video/BV1AF411b7xQ 一点记忆&#xff1a; GPT1参数量&#xff1a;大概1亿参数 12层decoder&#xff08;维度768&#xff0c;12个注意力头&#xff09; 训练集…

1-3 微信小程序协同工作和发布

协同工作和发布 &#x1f95f;&#x1f95e;以权限管理需求为例 一个项目组&#xff0c;一般有不同的岗位&#xff0c;不同角色的员工同时参与项目成员 流程 成员管理的两个方面 不同项目成员对应的权限 版本

热烈庆祝中国科学技术大学建校六六周年

卡西莫多的诗文集2022-2024.9月6-校庆国庆专版 欢迎分享 通过网盘分享的文件&#xff1a;卡西莫多的诗文集2022-2024.9月6-A5-校庆国庆专版.pdf 链接: 百度网盘 请输入提取码 提取码: umpm

请解释JSP中的九大内置对象及其作用。什么是Java Web中的请求转发和重定向?它们有什么区别?

请解释JSP中的九大内置对象及其作用。 JSP&#xff08;JavaServer Pages&#xff09;中的九大内置对象&#xff08;也称为隐式对象或自动对象&#xff09;是JSP容器为每个页面提供的Java对象&#xff0c;这些对象在JSP页面被转换成Servlet时自动可用&#xff0c;无需显式声明。…

多线程 | join方法

文章目录 1. 作用2. 用法3. 异常4. 源码为什么使用wait方法 5. 如何实现按照指定顺序执行线程6. 线程运行状态 1. 作用 在 Java 多线程中&#xff0c;join方法用于等待一个线程执行完毕。当一个线程调用另一个线程的join方法时&#xff0c;当前线程会进入等待状态&#xff0c;…

Ai+若依(智能售货机运营管理系统---帝可得)-人员管理-点位管理-区域管理-合作商管理----【08篇---0001:上】

项目介绍 售货机简介 帝可得是一个基于物联网概念下的智能售货机运营管理系统 物联网 物联网(IoT:Internet of Things)简单来说,就是让各种物品通过互联网连接起来,实现信息的交换和通信。 这个概念听起来可能有点抽象,但我们可以把它想象成一个超级大的社交网络。不过…

Spring Cloud 微服务注册

1&#xff1a;Intellij 新建服务 user-service 2&#xff1a;pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"…

【HTML】可展开的顶层菜单栏

效果&#xff1a; 代码&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>导航栏下拉&l…

LabVIEW环境中等待FPGA模块初始化完成

这个程序使用的是LabVIEW环境中的FPGA模块和I/O模块初始化功能&#xff0c;主要实现等待FAM&#xff08;Field-Programmable Gate Array Module&#xff0c;FPGA模块&#xff09;的初始化完成&#xff0c;并处理初始化过程中的错误。让我们逐步分析各部分的功能&#xff1a; 1.…

C++常见异常汇总(四): No package ‘casadi‘ found

文章目录 1、No package adolc found2、Could not find a package configuration file provided by "grid_map_msgs"3、 No package casadi found4、No package absl found 1、No package ‘adolc’ found git clone https://github.com/coin-or/ADOL-C.gitcd ADOL-…

好代码源码网整站数据打包代码

最新数据库版本的好代码资源网整站数据打包代码&#xff0c;最新资源数据&#xff0c;所有数据都有效可用。数据都是更新到最新的2024年6月份的数据。完全明文无加密后门版本定制开发的wordpres主题&#xff0c;无需独立服务器&#xff0c;虚拟主机也可以完美运营&#xff0c;只…

Redis 管道的神奇力量

今天我们要来探索一个 Redis 中非常强大且实用的特性——管道&#xff08;Pipeline&#xff09;。如果你想让你的 Redis 操作更加高效&#xff0c;那么这篇文章绝对值得一读。 一、Redis 管道是什么 Redis 管道是一种在客户端和服务器之间批量执行命令的技术。它允许客户端将…

Python中的单下划线和双下划线使用规则

引言 Python 遵循一些关键的命名规则&#xff0c;这些规则涉及到使用单个或双下划线。通过这些规则&#xff0c;你可以在应用程序接口&#xff08;API&#xff09;中区分可访问的和不可访问的标识符&#xff0c;编写适用于继承的稳健类&#xff0c;以及防止命名冲突等。 遵守这…

Sysbench性能测试工具的安装与使用

目录 前言1. Sysbench介绍2. 下载与安装2.1 系统准备2.2 安装Sysbench 3. Sysbench命令参数详解3.1 CPU测试3.2 内存测试3.3 磁盘I/O测试3.4 数据库测试 4. 实例演示&#xff1a;多维度性能测试4.1 CPU性能测试示例4.2 数据库性能测试示例4.3 内存网络性能测试4.4 磁盘I/O网络性…