动手学深度学习9.1. 门控循环单元(GRU)-笔记练习(PyTorch)

本节课程地址:门控循环单元(GRU)_哔哩哔哩_bilibili

本节教材地址:9.1. 门控循环单元(GRU) — 动手学深度学习 2.0.0 documentation (d2l.ai)

本节开源代码:...>d2l-zh>pytorch>chapter_multilayer-perceptrons>gru.ipynb


门控循环单元(GRU)

在 8.7节 中, 我们讨论了如何在循环神经网络中计算梯度, 以及矩阵连续乘积可以导致梯度消失或梯度爆炸的问题。 下面我们简单思考一下这种梯度异常在实践中的意义:

  • 我们可能会遇到这样的情况:早期观测值对预测所有未来观测值具有非常重要的意义。 考虑一个极端情况,其中第一个观测值包含一个校验和, 目标是在序列的末尾辨别校验和是否正确。 在这种情况下,第一个词元的影响至关重要。 我们希望有某些机制能够在一个记忆元里存储重要的早期信息。 如果没有这样的机制,我们将不得不给这个观测值指定一个非常大的梯度, 因为它会影响所有后续的观测值。
  • 我们可能会遇到这样的情况:一些词元没有相关的观测值。 例如,在对网页内容进行情感分析时, 可能有一些辅助HTML代码与网页传达的情绪无关。 我们希望有一些机制来跳过隐状态表示中的此类词元。
  • 我们可能会遇到这样的情况:序列的各个部分之间存在逻辑中断。 例如,书的章节之间可能会有过渡存在, 或者证券的熊市和牛市之间可能会有过渡存在。 在这种情况下,最好有一种方法来重置我们的内部状态表示。

在学术界已经提出了许多方法来解决这类问题。 其中最早的方法是"长短期记忆"(long-short-term memory,LSTM) (Hochreiter and Schmidhuber, 1997), 我们将在 9.2节 中讨论。 门控循环单元(gated recurrent unit,GRU) (href="https://zh.d2l.ai/chapter_references/zreferences.html#id23">Choet al., 2014) 是一个稍微简化的变体,通常能够提供同等的效果, 并且计算 (ef="https://zh.d2l.ai/chapter_references/zreferences.html#id26">Chunget al., 2014) 的速度明显更快。 由于门控循环单元更简单,我们从它开始解读。

门控隐状态

门控循环单元与普通的循环神经网络之间的关键区别在于: 前者支持隐状态的门控。 这意味着模型有专门的机制来确定应该何时更新隐状态, 以及应该何时重置隐状态。 这些机制是可学习的,并且能够解决了上面列出的问题。 例如,如果第一个词元非常重要, 模型将学会在第一次观测之后不更新隐状态。 同样,模型也可以学会跳过不相关的临时观测。 最后,模型还将学会在需要的时候重置隐状态。 下面我们将详细讨论各类门控。

重置门和更新门

我们首先介绍重置门(reset gate)和更新门(update gate)。 我们把它们设计成$(0, 1)$区间中的向量, 这样我们就可以进行凸组合。 重置门允许我们控制“可能还想记住”的过去状态的数量(能遗忘的机制); 更新门将允许我们控制新状态中有多少个是旧状态的副本(能关注的机制)。

我们从构造这些门控开始。 图9.1.1 描述了门控循环单元中的重置门和更新门的输入, 输入是由当前时间步的输入和前一时间步的隐状态给出。 两个门的输出是由使用sigmoid激活函数的两个全连接层给出。

我们来看一下门控循环单元的数学表达。 对于给定的时间步 t ,假设输入是一个小批量 \mathbf{X}_t \in \mathbb{R}^{n \times d}(样本个数 n ,输入个数 d ), 上一个时间步的隐状态是 \mathbf{X}_t \in \mathbb{R}^{n \times d} (隐藏单元个数 h )。 那么,重置门 \mathbf{R}_t \in \mathbb{R}^{n \times h} 和 更新门 \mathbf{Z}_t \in \mathbb{R}^{n \times h} 的计算如下所示:

\begin{aligned} \mathbf{R}_t = \sigma(\mathbf{X}_t \mathbf{W}_{xr} + \mathbf{H}_{t-1} \mathbf{W}_{hr} + \mathbf{b}_r),\\ \mathbf{Z}_t = \sigma(\mathbf{X}_t \mathbf{W}_{xz} + \mathbf{H}_{t-1} \mathbf{W}_{hz} + \mathbf{b}_z), \end{aligned}

其中 \mathbf{W}_{xr}, \mathbf{W}_{xz} \in \mathbb{R}^{d \times h} 和 \mathbf{W}_{hr}, \mathbf{W}_{hz} \in \mathbb{R}^{h \times h} 是权重参数, \mathbf{b}_r, \mathbf{b}_z \in \mathbb{R}^{1 \times h} 是偏置参数。 请注意,在求和过程中会触发广播机制 (请参阅 2.1.3节)。 我们使用sigmoid函数(如 4.1节 中介绍的) 将输入值转换到区间 (0, 1) 。

候选隐状态

接下来,让我们将重置门 \mathbf{R}_t 与 (8.4.5) 中的常规隐状态更新机制集成, 得到在时间步 t 的候选隐状态(candidate hidden state) \tilde{\mathbf{H}}_t \in \mathbb{R}^{n \times h} 。

\tilde{\mathbf{H}}_t = \tanh(\mathbf{X}_t \mathbf{W}_{xh} + \left(\mathbf{R}_t \odot \mathbf{H}_{t-1}\right) \mathbf{W}_{hh} + \mathbf{b}_h),(9.1.2)

其中 \mathbf{W}_{xh} \in \mathbb{R}^{d \times h}  \mathbf{W}_{hh} \in \mathbb{R}^{h \times h} 是权重参数, \mathbf{b}_h \in \mathbb{R}^{1 \times h} 是偏置项, 符号 \odot 是Hadamard积(按元素乘积)运算符。 在这里,我们使用tanh非线性激活函数来确保候选隐状态中的值保持在区间 (-1, 1) 中。

与 (8.4.5) 相比, (9.1.2)中的 \mathbf{R}_t  \mathbf{H}_{t-1} 的元素相乘可以减少以往状态的影响。 每当重置门 \mathbf{R}_t 中的项接近 1 时, 我们恢复一个如 (8.4.5)中的普通的循环神经网络。 对于重置门 \mathbf{R}_t 中所有接近 0 的项, 候选隐状态是以 \mathbf{X}_t 作为输入的多层感知机的结果。 因此,任何预先存在的隐状态都会被重置为默认值。

图9.1.2 说明了应用重置门之后的计算流程。

隐状态

上述的计算结果只是候选隐状态,我们仍然需要结合更新门 \mathbf{Z}_t 的效果。 这一步确定新的隐状态 \mathbf{H}_t \in \mathbb{R}^{n \times h} 在多大程度上来自旧的状态 \mathbf{H}_{t-1} 和 新的候选状态 \tilde{\mathbf{H}}_t 。 更新门 \mathbf{Z}_t 仅需要在 \mathbf{H}_{t-1} 和 \tilde{\mathbf{H}}_t 之间进行按元素的凸组合就可以实现这个目标。 这就得出了门控循环单元的最终更新公式:

\mathbf{H}_t = \mathbf{Z}_t \odot \mathbf{H}_{t-1} + (1 - \mathbf{Z}_t) \odot \tilde{\mathbf{H}}_t. (9.1.3)

每当更新门 \mathbf{Z}_t 接近 1 时,模型就倾向只保留旧状态。 此时,来自 \mathbf{X}_t 的信息基本上被忽略, 从而有效地跳过了依赖链条中的时间步 t 。 相反,当 \mathbf{Z}_t 接近 0 时, 新的隐状态 Ht 就会接近候选隐状态 \tilde{\mathbf{H}}_t 。 这些设计可以帮助我们处理循环神经网络中的梯度消失问题, 并更好地捕获时间步距离很长的序列的依赖关系。 例如,如果整个子序列的所有时间步的更新门都接近于 1 , 则无论序列的长度如何,在序列起始时间步的旧隐状态都将很容易保留并传递到序列结束。

图9.1.3 说明了更新门起作用后的计算流。

总之,门控循环单元具有以下两个显著特征:

  • 重置门有助于捕获序列中的短期依赖关系;
  • 更新门有助于捕获序列中的长期依赖关系。

极端情况,当 \mathbf{R}_t 为 1 且 \mathbf{Z}_t 为 0 时,GRU相当于RNN。

从零开始实现

为了更好地理解门控循环单元模型,我们从零开始实现它。 首先,我们读取 8.5节 中使用的时间机器数据集:

import torch
from torch import nn
from d2l import torch as d2lbatch_size, num_steps = 32, 35
train_iter, vocab = d2l.load_data_time_machine(batch_size, num_steps)

[初始化模型参数]

下一步是初始化模型参数。 我们从标准差为0.01的高斯分布中提取权重, 并将偏置项设为0,超参数num_hiddens定义隐藏单元的数量, 实例化与更新门、重置门、候选隐状态和输出层相关的所有权重和偏置。

def get_params(vocab_size, num_hiddens, device):num_inputs = num_outputs = vocab_sizedef normal(shape):return torch.randn(size=shape, device=device)*0.01def three():return (normal((num_inputs, num_hiddens)),normal((num_hiddens, num_hiddens)),torch.zeros(num_hiddens, device=device))W_xz, W_hz, b_z = three()  # 更新门参数W_xr, W_hr, b_r = three()  # 重置门参数W_xh, W_hh, b_h = three()  # 候选隐状态参数# 输出层参数W_hq = normal((num_hiddens, num_outputs))b_q = torch.zeros(num_outputs, device=device)# 附加梯度params = [W_xz, W_hz, b_z, W_xr, W_hr, b_r, W_xh, W_hh, b_h, W_hq, b_q]for param in params:param.requires_grad_(True)return params

定义模型

现在我们将[定义隐状态的初始化函数]init_gru_state。 与 8.5节 中定义的init_rnn_state函数一样, 此函数返回一个形状为(批量大小,隐藏单元个数)的张量,张量的值全部为零。

def init_gru_state(batch_size, num_hiddens, device):return (torch.zeros((batch_size, num_hiddens), device=device), )

现在我们准备[定义门控循环单元模型], 模型的架构与基本的循环神经网络单元是相同的, 只是权重更新公式更为复杂。

def gru(inputs, state, params):W_xz, W_hz, b_z, W_xr, W_hr, b_r, W_xh, W_hh, b_h, W_hq, b_q = paramsH, = stateoutputs = []for X in inputs:Z = torch.sigmoid((X @ W_xz) + (H @ W_hz) + b_z)R = torch.sigmoid((X @ W_xr) + (H @ W_hr) + b_r)H_tilda = torch.tanh((X @ W_xh) + ((R * H) @ W_hh) + b_h)H = Z * H + (1 - Z) * H_tildaY = H @ W_hq + b_qoutputs.append(Y)return torch.cat(outputs, dim=0), (H,)

[训练]与预测

训练和预测的工作方式与 8.5节 完全相同。 训练结束后,我们分别打印输出训练集的困惑度, 以及前缀“time traveler”和“traveler”的预测序列上的困惑度。

vocab_size, num_hiddens, device = len(vocab), 256, d2l.try_gpu()
num_epochs, lr = 500, 1
model = d2l.RNNModelScratch(len(vocab), num_hiddens, device, get_params,init_gru_state, gru)
d2l.train_ch8(model, train_iter, vocab, lr, num_epochs, device)

输出结果:
perplexity 1.1, 23537.9 tokens/sec on cpu
time traveller for so it will be convenient to speak of himwas e
travelleryou can show black is white by argument said filby

[简洁实现]

高级API包含了前文介绍的所有配置细节, 所以我们可以直接实例化门控循环单元模型。 这段代码的运行速度要快得多, 因为它使用的是编译好的运算符而不是Python来处理之前阐述的许多细节。

num_inputs = vocab_size
gru_layer = nn.GRU(num_inputs, num_hiddens)
model = d2l.RNNModel(gru_layer, len(vocab))
model = model.to(device)
d2l.train_ch8(model, train_iter, vocab, lr, num_epochs, device)

输出结果:
perplexity 1.0, 39868.2 tokens/sec on cpu
time traveller for so it will be convenient to speak of himwas e
travelleryou can show black is white by argument said filby

小结

  • 门控循环神经网络可以更好地捕获时间步距离很长的序列上的依赖关系。
  • 重置门有助于捕获序列中的短期依赖关系。
  • 更新门有助于捕获序列中的长期依赖关系。
  • 重置门打开(R=1)时,门控循环单元包含基本循环神经网络;更新门打开(Z=1)时,门控循环单元可以跳过子序列。

练习

  1. 假设我们只想使用时间步 t' 的输入来预测时间步 t > t' 的输出。对于每个时间步,重置门和更新门的最佳值是什么?
    解:
    对于重置门 
    \mathbf{R}_t 中所有接近0的项,候选隐状态是以 \mathbf{X}_t 作为输入的多层感知机的结果。
    当 
    \mathbf{Z}_t 接近0时,新的隐状态 \mathbf{H}_t 就会接近候选隐状态 \tilde{\mathbf{H}}_t
    因此,当只想使用时间步
    t′的输入来预测时间步 t > t' 的输出时,\mathbf{R}_t 和 \mathbf{Z}_t 的最佳值均为0。
  2. 调整和分析超参数对运行时间、困惑度和输出顺序的影响。
    解:
    超参数包括:
  • 批量大小 batch_size,由下面代码试验结果0和1比较可以看出:batch_size增加会增加运行时间,并大大增加困惑度。
  • 批量步长 num_steps,由下面代码试验结果0和2比较可以看出:num_steps降低会略增加运行时间,但困惑度降为最低。
  • 隐藏层数 num_hiddens,由下面代码试验结果0和3比较可以看出:num_hiddens增加会大大增加运行时间,但困惑度同样能将为最低。
  • 迭代次数 num_epochs,这个可以从运行结果图中直接看出:epochs越大,运行时间越长;如果epochs过低,则模型无法完成收敛,困惑度不能有效降低,因此,需要保证足够的epochs。下面代码不做epochs的调整。
  • 学习率 lr,由下面代码试验结果0和4比较可以看出:learning rate降低会导致模型无法完成收敛,困惑度很高。

代码如下:

import time# 单一变量依次调整 batch_size, num_steps, num_hiddens, lr
hyper_0 = [32, 35, 256, 1] # 初始值
hyper_1 = [64, 35, 256, 1]
hyper_2 = [32, 10, 256, 1]
hyper_3 = [32, 35, 512, 1]
hyper_4 = [32, 35, 256, 0.1]
hyper_params = [hyper_0, hyper_1, hyper_2, hyper_3, hyper_4]def train_ch9_1(net, train_iter, vocab, lr, num_epochs, device,use_random_iter=False):loss = nn.CrossEntropyLoss()# 初始化if isinstance(net, nn.Module):updater = torch.optim.SGD(net.parameters(), lr)else:updater = lambda batch_size: d2l.sgd(net.params, lr, batch_size)predict = lambda prefix: d2l.predict_ch8(prefix, 50, net, vocab, device)# 训练和预测for epoch in range(num_epochs):ppl, _ = d2l.train_epoch_ch8(net, train_iter, loss, updater, device, use_random_iter)print(predict('time traveller'))print(predict('traveller'))return ppl ppls = []
run_times = []for i, hyper in enumerate(hyper_params):num_epochs = 500batch_size, num_steps, num_hiddens, lr = hypertrain_iter, vocab = d2l.load_data_time_machine(batch_size, num_steps)vocab_size, device = len(vocab), d2l.try_gpu()model = d2l.RNNModelScratch(len(vocab), num_hiddens, device, get_params,init_gru_state, gru)print(f'hyper_{i}:')print(f'When batch_size = {hyper[0]}, num_steps = {hyper[1]}, num_hiddens = {hyper[2]}, lr = {hyper[3]}:')start = time.time()ppl = train_ch9_1(model, train_iter, vocab, lr, num_epochs, device)end = time.time()run_time = end - startprint(f'困惑度 {ppl:.1f}, {run_time:.1f} 秒')ppls.append(ppl)run_times.append(run_time)

输出结果:
hyper_0:
When batch_size = 32, num_steps = 35, num_hiddens = 256, lr = 1:
time travelleryou can show black is white by argument said filby
traveller with a slight accession ofcheerfulness really thi
困惑度 1.1, 206.8 秒
hyper_1:
When batch_size = 64, num_steps = 35, num_hiddens = 256, lr = 1:
time traveller that is and the pald the per and and the pald the
traveller that is and the pald the per and and the pald the
困惑度 4.8, 336.2 秒
hyper_2:
When batch_size = 32, num_steps = 10, num_hiddens = 256, lr = 1:
time travelleryou can show black is white by argument said filby
travelleryou can show black is white by argument said filby
困惑度 1.0, 242.9 秒
hyper_3:
When batch_size = 32, num_steps = 35, num_hiddens = 512, lr = 1:
time traveller for so it will be convenient to speak of himwas e
travelleryou can show black is white by argument said filby
困惑度 1.0, 749.2 秒
hyper_4:
When batch_size = 32, num_steps = 35, num_hiddens = 256, lr = 0.1:
time travellere the the the the the the the the the the the the
travellere the the the the the the the the the the the the
困惑度 10.3, 208.9 秒

import matplotlib.pyplot as pltfig, ax1 = plt.subplots(figsize=(8, 6))
ax2 = ax1.twinx()
ax1.bar([0, 1, 2, 3, 4], ppls, alpha=0.8)
ax1.set_ylim()
ax1.set_xlabel('No. hyper_params')
ax1.set_ylabel('Perplexity')
ax2.plot([0, 1, 2, 3, 4], run_times, linewidth='2', color = 'darkred')
ax2.set_ylabel('Run_time')
ax2.set_ylim()
plt.plot(0, 0, linewidth='2', color = 'darkred', label="Run_time")
plt.bar(0, 0, alpha=0.8, label="Perplexity")
plt.legend(loc='upper left', frameon=False)
plt.show()

3. 比较rnn.RNNrnn.GRU的不同实现对运行时间、困惑度和输出字符串的影响。
解:
8.6节应用RNN的运行结果为:
perplexity 1.3, 79579.9 tokens/sec
time traveller after the pauserequired for the prathere for anou
traveller bat no sime soc ans have a dimentab incane round ;
本节应用GRU的运行结果为:
perplexity 1.0, 39699.2 tokens/sec
time travelleryou can show black is white by argument said filby
traveller with a slight accession ofcheerfulness really thi;
由上可见,GRU由于增加了权重更新的参数和计算量,运行时间变慢,但同时GRU的网络结构优化也降低了困惑度(从1.3降到最佳的1.0),输出的字符串也更加准确合理。

4. 如果仅仅实现门控循环单元的一部分,例如,只有一个重置门或一个更新门会怎样?
解:
重置门赋予了GRU的遗忘机制,其作用是确定当前输入对单元状态的影响程度,允许网络忽略与当前任务无关的过去信息,也即重置前一时刻的隐状态H_{t-1}。只有重置门,网络会无法有效地处理长期依赖关系,因为单元状态可能会在不适当的时间被重置,或者无法适应新的输入。
更新门赋予了GRU的关注机制,其作用是控制单元状态的更新程度,决定了网络如何结合新的输入信息和保留的旧信息。只有更新门,网络会无法有效地处理短期依赖关系,因为更新门无法决定忽略哪些过去信息。
比较代码如下:

# 只有一个重置门
def get_params_reset(vocab_size, num_hiddens, device):num_inputs = num_outputs = vocab_sizedef normal(shape):return torch.randn(size=shape, device=device)*0.01def two():return (normal((num_inputs, num_hiddens)),normal((num_hiddens, num_hiddens)),torch.zeros(num_hiddens, device=device))W_xr, W_hr, b_r = two()  # 重置门参数W_xh, W_hh, b_h = two()  # 候选隐状态参数# 输出层参数W_hq = normal((num_hiddens, num_outputs))b_q = torch.zeros(num_outputs, device=device)# 附加梯度params = [W_xr, W_hr, b_r, W_xh, W_hh, b_h, W_hq, b_q]for param in params:param.requires_grad_(True)return paramsdef gru_only_reset(inputs, state, params):W_xr, W_hr, b_r, W_xh, W_hh, b_h, W_hq, b_q = paramsH, = stateoutputs = []for X in inputs:R = torch.sigmoid((X @ W_xr) + (H @ W_hr) + b_r)H = torch.tanh((X @ W_xh) + ((R * H) @ W_hh) + b_h)Y = H @ W_hq + b_qoutputs.append(Y)return torch.cat(outputs, dim=0), (H,)vocab_size, num_hiddens, device = len(vocab), 256, d2l.try_gpu()
num_epochs, lr = 500, 1
model = d2l.RNNModelScratch(len(vocab), num_hiddens, device, get_params_reset,init_gru_state, gru_only_reset)
d2l.train_ch8(model, train_iter, vocab, lr, num_epochs, device)

输出结果:
perplexity 1.0, 28502.0 tokens/sec on cpu
time travelleryou can show black is white by argument said filby
travelleryou can show black is white by argument said filby

# 只有一个更新门
def get_params_Z(vocab_size, num_hiddens, device):num_inputs = num_outputs = vocab_sizedef normal(shape):return torch.randn(size=shape, device=device)*0.01def two():return (normal((num_inputs, num_hiddens)),normal((num_hiddens, num_hiddens)),torch.zeros(num_hiddens, device=device))W_xz, W_hz, b_z = two()  # 更新门参数W_xh, W_hh, b_h = two()  # 候选隐状态参数# 输出层参数W_hq = normal((num_hiddens, num_outputs))b_q = torch.zeros(num_outputs, device=device)# 附加梯度params = [W_xz, W_hz, b_z, W_xh, W_hh, b_h, W_hq, b_q]for param in params:param.requires_grad_(True)return paramsdef gru_only_Z(inputs, state, params):W_xz, W_hz, b_z, W_xh, W_hh, b_h, W_hq, b_q = paramsH, = stateoutputs = []for X in inputs:Z = torch.sigmoid((X @ W_xz) + (H @ W_hz) + b_z)H_tilda = torch.tanh((X @ W_xh) + (H @ W_hh) + b_h)H = Z * H + (1 - Z) * H_tildaY = H @ W_hq + b_qoutputs.append(Y)return torch.cat(outputs, dim=0), (H,)vocab_size, num_hiddens, device = len(vocab), 256, d2l.try_gpu()
num_epochs, lr = 500, 1
model = d2l.RNNModelScratch(len(vocab), num_hiddens, device, get_params_Z,init_gru_state, gru_only_Z)
d2l.train_ch8(model, train_iter, vocab, lr, num_epochs, device)

输出结果:

perplexity 1.0, 32176.4 tokens/sec on cpu
time traveller for so it will be convenient to speak of himwas e
traveller with a slight accession ofcheerfulness really thi

 

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

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

相关文章

信息学奥赛复赛复习01-CSP-J2019-01-字符、字符数组、字符串、string、字符串读取

PDF文档回复:20240923 1 2019 CSP-J 题目1 数字游戏 [题目描述] 小 K 同学向小 P 同学发送了一个长度为 8 的 01 字符串来玩数字游戏,小 P 同学想要知道字符串中究竟有多少个 1。 注意:01 字符串为每一个字符是 0 或者 1 的字符串,如 101 …

文心智能体搭建步骤

通过使用文心智能体平台来创建智能体的过程。这种方法可以让没有编程经验的人也能快速构建智能体,降低了技 术门槛。以下是一些建议和心得: 1.选择合适的平台:文心智能体平台是一个优秀的选择,它提供了零代码和低代码的开发环境,极大地降低了…

vue中高德地图使用 Marker 标点 - 标点数据快到 1000 时页面卡顿问题解决(已解决 - 多方面原因)+ 海量点功能实现解决

目录 1.业务需求2.最初实现及出现的问题3.解决 - 1000 个标点时页面就出现 卡顿 问题4.使用海量点、聚合标点后还有卡顿,排查其他原因5.最终解决5.1页面中list数据渲染问题解决5.2地图相关实例不要放在 vue 的可响应数据中 页面展示 1.业务需求 需要在 高德地图 中标…

【linux驱动】什么是驱动

内核简介 在谈驱动之前,我们需要先谈内核。 内核,是一个操作系统的核心。是基于硬件的第一层软件扩充,提供操作系统的最基本的功能,是操作系统工作的基础,决定着整个操作系统的性能和稳定性。 下面是微内核和宏内核…

oracle avg、count、max、min、sum、having、any、all、nvl的用法

组函数 having的使用 any的使用 all的使用 nvl 从执行结果来看,nvl(列名,默认值),nvl的作用就是如果列名所在的这一行出现空则用默认值替换

Offer60:n个骰子的点数

题目:把n个骰子扔在地上,所有骰子朝上一面的点数之和为s。输入n,打印出s的所有可能的值出现的概率。 分析:要解决这个问题,我们需要先统计出每个点数出现的次数,然后把每个点数出现的次数除以,就能求出每个点数出现的概率了。我们…

day-58 最接近的三数之和

思路 双指针&#xff1a;首先利用Arrays.sort()函数对数组进行排序&#xff0c;通过枚举中间位置的那个数&#xff0c;题目就变为了双指针 解题过程 指针边界&#xff08;right>i&&left<i&#xff09;&#xff0c;当三数之和小于等于target时&#xff0c;left,反…

电力系统中有哪些好的运维的平台?

摘要&#xff1a;介绍台商大厦&#xff0c;采用综合保护装置、多功能仪表、变压器温控仪、直流屏、烟雾传感器、门磁开关、网络摄像头等设备&#xff0c;采集配电现场的各种电参量和状态信号。系统采用现场就地组网的方式&#xff0c;组网后通过现场网关远传至阿里云平台&#…

精神分裂症、抑郁症和异常衰老的脑电信号特征:一项监督式机器学习研究

摘要 背景&#xff1a;EEG是一种非侵入性、成本效益高且稳健的工具&#xff0c;能够以高时间分辨率直接测量体内神经元的整体活动。结合先进的机器学习(ML)技术&#xff0c;EEG记录可以提供有关精神疾病的计算机模拟生物标志物。 假设&#xff1a;病理性和生理性衰老过程会影…

CMake 构建Qt程序弹出黑色控制台

CMake 构建Qt程序弹出黑色控制台

OpenBayes 一周速览|IC-Light 图片打光神器一键启动!Tecnalia 电子设备废物高光谱数据集上线,提高电子废物回收准确性

公共资源速递 This Weekly Snapshots &#xff01; 5 个数据集&#xff1a; * BTAD 工业异常数据集 * WebVid 大型短视频数据集 * bAbi 问答和文本理解的数据集 * OpenMIR 音乐收听脑电图数据集 * Tecnalia 电子设备废物高光谱数据集 2 个教程&#xff1a; * ComfyUl …

随机掉落的项目足迹:Vue3 + wangEditor5富文本编辑器——toolbar.getConfig() 查看工具栏的默认配置

问题引入 小提示&#xff1a;问题引入是一个讲故事的废话环节&#xff0c;各位小伙伴可以直接跳到第二大点&#xff1a;问题解决 我的项目不需要在富文本编辑器中引入添加代码块的功能&#xff0c;于是我寻思在工具栏上把操作代码的菜单删一删 于是我来到官网文档工具栏配置 …

vue-baidu-map的基本使用

前言 公司项目需求引入百度地图&#xff0c;由于给的时间比较短&#xff0c;所以就用了已经封装好了的vue-baidu-map 一、vue-baidu-map是什么&#xff1f; vue-baidu-map是基于vue.js封装的百度地图组件(官方文档) 二、使用步骤 1.下载插件 //我下载的版本 npm install …

CTO来分享:创业公司,如何提升MVP新产品开发速度?

创业公司的MVP新产品开发之路 对于创业公司&#xff0c;资源有限、早期项目概念模糊&#xff0c;加上人员不足&#xff08;甚至是只有创始人自己一人&#xff09;&#xff0c;如何能在短时间内、低成本、快速上线自己的MVP产品&#xff0c;验证产品和市场的匹配度&#xff0c;…

淘宝商品评论数据获取API接口响应参数列表展示(可测key)

item_review-获得淘宝商品评论 在电商领域&#xff0c;商品评论数据是商家和消费者都极为关注的重要信息。通过这些数据&#xff0c;商家可以了解产品的市场反馈&#xff0c;优化产品和服务&#xff1b;而消费者则可以参考其他用户的评价&#xff0c;做出更明智的购买决策。然…

辛普森积分公式

辛普森公式是用于数值积分的一种方法&#xff0c;其基本思想是将积分区间等分成若干小段&#xff0c;并在每一小段内用一个二次函数来近似代替被积函数&#xff0c;从而计算积分值。它是一种比较精确的数值积分方法&#xff0c;比其他常见的数值积分方法&#xff08;如梯形法和…

Nature Genetics|三代测序微量建库技术:媲美WGBS的直接甲基化检测

DNA修饰和甲基化是理解基因调控机制的关键。以往&#xff0c;我们的经验表明&#xff0c;使用三代测序从未经扩增的长DNA模板中同时读取序列信息和碱基修饰&#xff0c;需要投入大量的DNA样本来构建文库。 今天&#xff0c;小编带大家看一篇2024年发表于《Nature Genetics》的…

Web端云剪辑解决方案,素材商城提供近万种各类的特效素材

在数字内容爆炸式增长的今天&#xff0c;高质量、高效率的视频制作已成为企业传播品牌、吸引用户不可或缺的关键。美摄科技&#xff0c;作为业界领先的视频云处理与创意解决方案提供商&#xff0c;正式推出其革命性的Web端云剪辑解决方案&#xff0c;以云端之力&#xff0c;赋能…

PS教程,从零开始学PS

A01 进入PS的世界 广告设计\平面设计产品包装设计摄影后期图像美化\照片美化网页网店UI界面设计游戏美术动漫图形创意恶意创意\动态表情效果图后期调整 了解基本规律掌握操作规律开发扩展思维 A02 PS软件安装 获得PS安装程序安装PS启动PS A03 认识界面 1. PS主界面构成 …

使用 MobaXterm 远程连接 Linux 虚拟机并实现文件传输

文章目录 前言一、什么是 MobaXterm二 、MobaXterm 安装三、使用 MobaXterm 远程连接 Linux 虚拟机1. 准备工作2. 创建 SSH 连接3. 登录虚拟机 四、使用 MobaXterm 进行文件传输总结 前言 在日常开发和运维中&#xff0c;Windows 用户经常需要通过远程连接到 Linux 服务器进行…