d2l从零与简洁实现RNN

李沐《动手学深度学习》d2l——安装和使用 今天想要跟着沐神学习一下循环神经网络,在跑代码的时候,d2l出现了问题,这里记录一下解决的过程,方便以后查阅。 阅读详情

详解一下该章的代码

目录

1.从零实现RNN

1.1加载数据

1.2One-hot独热向量

1.3初始化参数

1.4.1tuple补充

1.5封装一下上面的函数

1.6预测

1.6.1函数里面lambada的探索

1.7梯度剪裁

1.8训练

2.简洁版RNN

2.1同样的数据载入

2.2模型定义

2.3训练

3.rnn总结一下输入输出维度


1.从零实现RNN

1.1加载数据

batch_size, num_steps = 32, 35
train_iter, vocab = d2l.load_data_time_machine(batch_size, num_steps)

  既然是从0实现我就一块都讲了,看一看这个load_data函数长什么样:

def load_data_time_machine(batch_size, num_steps, #@save
    use_random_iter=False, max_tokens=10000):
    """返回时光机器数据集的迭代器和词表"""
    data_iter = SeqDataLoader(
        batch_size, num_steps, use_random_iter, max_tokens)
    return data_iter, data_iter.vocab

看看套的这个类是什么:

class SeqDataLoader: #@save
    """加载序列数据的迭代器"""
    def __init__(self, batch_size, num_steps, use_random_iter, max_tokens):
        if use_random_iter:
            self.data_iter_fn = d2l.seq_data_iter_random
        else:
            self.data_iter_fn = d2l.seq_data_iter_sequential
        self.corpus, self.vocab = d2l.load_corpus_time_machine(max_tokens)
        self.batch_size, self.num_steps = batch_size, num_steps
    def __iter__(self):
        return self.data_iter_fn(self.corpus, self.batch_size, self.num_steps)

   其中,d2l.load_corpus_time_machine(max_tokens)是获得corpus和vocab,这两个参数是为了调用data_corpus_fn用的。
   进入data_iter_fn是顺序或随机获得每个iter的X和Y,均为(bs,T)--详情见上一节: 语言模型

  总结一下得到了什么:train_iter为原txt的X,Y,尺寸均为(bs,T);vocab为该txt对应的vocab(char)

1.2One-hot独热向量

  每次采样的小批量数据的形状是(bs,时间步数T)
  经过one_hot转变成(T,bs,len),将X转置实现的,为了方便后续通过外层维度更新小批量数据的隐状态。

举个例子:这个例子中,bs=2;T=5

X = torch.arange(10).reshape((2, 5))
F.one_hot(X.T, 28).shape

'''
torch.Size([5, 2, 28])
'''

1.3初始化参数

  输入输出都是从Vocab里面来的(label就是features的后一个),所以要保证输入输出尺寸相同
  这里面num_hiddens隐藏单元数是超参数。

def get_params(vocab_size, num_hiddens, device):
    num_inputs = num_outputs = vocab_size
    
    def normal(shape):
        return torch.randn(size=shape, device=device) * 0.01
    
    # 隐藏层参数
    W_xh = normal((num_inputs, num_hiddens))
    W_hh = normal((num_hiddens, num_hiddens))
    b_h = torch.zeros(num_hiddens, device=device)
    # 输出层参数
    W_hq = normal((num_hiddens, num_outputs))
    b_q = torch.zeros(num_outputs, device=device)
    # 附加梯度
    params = [W_xh, W_hh, b_h, W_hq, b_q]
    for param in params:
        param.requires_grad_(True)
    return params

初始化H0

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

1.4定义RNN计算块fn

  更新为(T,bs,len)后,看成3维矩阵,T为行,bs为列,len为厚度,通过最外层T提取的每一行,为第一个时间部对应的bs个单词,其中每个单词为len长的独热向量表示。通过计算的H
  X这里为(bs,len),每次迭代通过T迭代出的是每一个时间步对应的单词位置,比如T=5,则共迭代5次,每一次迭代一个位置,每个位置X吐出bs个单词(前面可得),每个单词用len(vocab)长度的one-hot表示。
  计算得到的Y尺寸为(bs,v),与X一致,后续有进行了cat操作,所以最终返回的为(bs*T,len);另一个是当前的隐藏状态H

def rnn(inputs, state, params):
    # inputs的形状:(时间步数量,批量⼤⼩,词表⼤⼩)
    W_xh, W_hh, b_h, W_hq, b_q = params
    H, = state
    outputs = []
    # X的形状:(批量⼤⼩,词表⼤⼩)
    for X in inputs:
        H = torch.tanh(torch.mm(X, W_xh) + torch.mm(H, W_hh) + b_h)
        Y = torch.mm(H, W_hq) + b_q
        outputs.append(Y)
    return torch.cat(outputs, dim=0), (H,)

1.4.1tuple补充

  补充以下关于tuple的取值,如果把tuple里面的值取出来,则后面加‘,’,如果想把单一值存tuple,括号里面也要加',',否则就是int了

a = (5,)
b, = a
b

'''
5
'''

1.5封装一下上面的函数

class RNNModelScratch: #@save
    """从零开始实现的循环神经⽹络模型"""
    def __init__(self, vocab_size, num_hiddens, device,
                get_params, init_state, forward_fn):
        
        self.vocab_size, self.num_hiddens = vocab_size, num_hiddens
        self.params = get_params(vocab_size, num_hiddens, device)
        self.init_state, self.forward_fn = init_state, forward_fn
        
    def __call__(self, X, state):
        X = F.one_hot(X.T, self.vocab_size).type(torch.float32)
        return self.forward_fn(X, state, self.params)
    
    def begin_state(self, batch_size, device):
        return self.init_state(batch_size, self.num_hiddens, device)

  检查以下输出维度
  这里设定的X中,bs为2,T为5
  可看出Y为(T*bs,len);隐藏状态不变(bs,hiddens)
  隐藏状态尺寸:Xt×Wxh (bs,v)(v,h)--(bs,h)

num_hiddens = 512
net = RNNModelScratch(len(vocab), num_hiddens, d2l.try_gpu(),
                      get_params,
                      init_rnn_state, rnn)

state = net.begin_state(X.shape[0], d2l.try_gpu())
Y, new_state = net(X.to(d2l.try_gpu()), state) # 此时送进去的X是(bs,T)
Y.shape, len(new_state), new_state[0].shape

'''
(torch.Size([10, 28]), 1, torch.Size([2, 512]))
'''

1.6预测

  perfix是提供的包含多个字符的字符串。
  output是每个字符串在vocab里面的下标,将prefix的第一个char放进vocab拿到该char对应下标,output一开始就是一个idx
  不要开始的net输出,因为有label,只更新H。训练完label后,再输出预测
  再使用idx转成token

def predict_ch8(prefix, num_preds, net, vocab, device): #@save
    """在prefix后⾯⽣成新字符"""
    state = net.begin_state(batch_size=1, device=device)
    outputs = [vocab[prefix[0]]]
    get_input = lambda: torch.tensor([outputs[-1]], device=device).reshape((1, 1))
    for y in prefix[1:]: # 预热期
        _, state = net(get_input(), state)
        outputs.append(vocab[y])
    for _ in range(num_preds): # 预测num_preds步
        y, state = net(get_input(), state)
        outputs.append(int(y.argmax(dim=1).reshape(1)))
    return ''.join([vocab.idx_to_token[i] for i in outputs])

predict_ch8('time traveller ', 10, net, vocab, d2l.try_gpu())

'''
'time traveller waqdsaqdsa'
'''

1.6.1函数里面lambada的探索

  lambda的作用:将outputs动态的带入循环中,如下代码所示更明晰,这里get_inputs传入out的参数为outputs,然后将传入参数的最后一个拿出来变成(1,1)的tensor再送入net中进行输出。
  原函数中没有设置传入参数,是因为直接将需要迭代的参数写到里面去了,这样函数再for loop迭代过程中自动更新outputs。
  但是如果不写lambda的话,则outputs不会产生变化,迭代过程中input都是一样的,进而产生的输出也都是一样的了。

  outputs在for loop中有append当前y的操作,vocab[i]=5,prefix[1:]取到的第一个char也是i,故经过第一轮后outputs为[3,5]。

  前向预测的时候,state是经过prefix计算后的H,这里y得到的是(1,len),表示的是每个可能的char的各个类别的预测分数,再取argmax得到最大可能char的idx,然后再并到outputs中,前面的vocab[y]中y为char,通过getitem得到idx,这里直接返回的也是idx。
  第一个字母返回idx是20,idx_to_token一下是p,在最后的输出中验证了这一点(见下图):

去掉lambda与补全lambda形式:

def predict_ch81(prefix, num_preds, net, vocab, device): #@save
    """在prefix后⾯⽣成新字符"""
    state = net.begin_state(batch_size=1, device=device)
    outputs = [vocab[prefix[0]]]
    get_input = lambda out: torch.tensor([out[-1]], device=device).reshape((1, 1))
    for y in prefix[1:]: # 预热期
        _, state = net(get_input(outputs), state)
        outputs.append(vocab[y])
    for _ in range(num_preds): # 预测num_preds步
        y, state = net(get_input(outputs), state)
        outputs.append(int(y.argmax(dim=1).reshape(1)))
    return ''.join([vocab.idx_to_token[i] for i in outputs])
def predict_ch82(prefix, num_preds, net, vocab, device): #@save
    """在prefix后⾯⽣成新字符"""
    state = net.begin_state(batch_size=1, device=device)
    outputs = [vocab[prefix[0]]]
    get_input = torch.tensor([outputs[-1]], device=device).reshape((1, 1))
#     get_input2 = lambda: torch.tensor([outputs[-1]], device=device).reshape((1, 1))
    for y in prefix[1:]: # 预热期
        _, state = net(get_input, state)
        outputs.append(vocab[y])
    for _ in range(num_preds): # 预测num_preds步
        y, state = net(get_input, state)
        outputs.append(int(y.argmax(dim=1).reshape(1)))
    return ''.join([vocab.idx_to_token[i] for i in outputs])

补全:(添加了自变量定义,并在后续传入)

predict_ch81('time traveller ', 10, net, vocab, d2l.try_gpu())

'''
'time traveller waqdsaqdsa'
'''

去掉lambda:input不会变,导致输出的都是一个东西。

predict_ch82('time traveller ', 10, net, vocab, d2l.try_gpu())

'''
'time traveller llllllllll'
'''

1.7梯度剪裁

  实现目标:若para的L2norm之和大于theta,则每个para* theta/norm
  sum是py自带函数;torch.sum仅能对tensor进行操作,可以实现在不同维度上求和,可部署GPU

def grad_clipping(net, theta): #@save
    """裁剪梯度"""
    if isinstance(net, nn.Module):
        params = [p for p in net.parameters() if p.requires_grad]
    else:
        params = net.params
    norm = torch.sqrt(sum(torch.sum((p.grad ** 2)) for p in params))
    if norm > theta:
        for param in params:
            param.grad[:] *= theta / norm

1.8训练

  iter=total/bs..也就是bs的总个数
  如果是random的iter,则每个bs之间的X不再上下关联,是随机的(前面有Sequential是前后顺序的)。所以前面一个iter的state对于后面的不再适用,要清零。
  backward只在一个iteraion里面做,所以对前面的state要进行.detach_()分离梯度操作,使得隐状态的梯度计算总是限制在一个小批量数据的时间步内。
  y为什么转置再reshape(-1)见下面
  注意使用了梯度裁剪后,在算完backward后加一个clipping
  别忘了最后要用困惑度,加exp

#@save
def train_epoch_ch8(net, train_iter, loss, updater, device, use_random_iter):
    """训练⽹络⼀个迭代周期(定义⻅第8章)"""
    state, timer = None, d2l.Timer()
    metric = d2l.Accumulator(2) # 训练损失之和,词元数量
    for X, Y in train_iter:
        if state is None or use_random_iter:
            # 在第⼀次迭代或使⽤随机抽样时初始化state
            state = net.begin_state(batch_size=X.shape[0], device=device)
    else:
        if isinstance(net, nn.Module) and not isinstance(state, tuple):
            # state对于nn.GRU是个张量
            state.detach_()
        else:
            # state对于nn.LSTM或对于我们从零开始实现的模型是个张量
            for s in state:
                s.detach_()
    y = Y.T.reshape(-1)
    X, y = X.to(device), y.to(device)
    y_hat, state = net(X, state)
    l = loss(y_hat, y.long()).mean()
    if isinstance(updater, torch.optim.Optimizer):
        updater.zero_grad()
        l.backward()
        grad_clipping(net, 1)
        updater.step()
    else:
        l.backward()
        grad_clipping(net, 1)
        # 因为已经调⽤了mean函数
        updater(batch_size=1)
        metric.add(l * y.numel(), y.numel())
    return math.exp(metric[0] / metric[1]), metric[1] / timer.stop()

对于y为什么也要使Y进行转置,原因:

  省事版:因为X再送进net中进行了转置操作,所以y也要。
  详细版: 1.虽然reshape(-1)后维度一样,但是内容可不一样,原y_hat是(bs* T,len),是由T个bs按dim=0螺起来的,每个bs为T对应位置的bs个预测。(第一个bs即为对T[0]的bs个预测,不同bs的T[0]对应的char不一样,这里T[0]只表示位置)
### 2.对于reshape(-1),会先将第一行展开,后再将第二行展开放到第一行后面...从而降成一维。Y本来是(bs,T),如果不转置则展开为按T展开,则第一行中的元素为各个T[i]对应的编号,而转置后wei(T,bs),每一行都对应着同一个T[i],与y_hat是对应一致的!!

for X, Y in train_iter:
    print(X.shape, Y.shape)
y = Y.T.reshape(-1)
y2 = Y.reshape(-1)
print(y)
print(y2)


'''
torch.Size([32, 35]) torch.Size([32, 35])
torch.Size([32, 35]) torch.Size([32, 35])
...
tensor([ 6,  1,  9,  ...,  7, 10, 21])
tensor([ 6,  3, 12,  ...,  8,  1, 21])
'''

  本质还是多分类,所以loss为交叉熵;每个bs中由T个单词,所以单bs送入net中其本质使进行了bs*T次的分类cls任务。bs是一个批量,里面有T个char。
  没有val,直接用predict预测后面50个char看看长什么样子

#@save
def train_ch8(net, train_iter, vocab, lr, num_epochs, device,
                use_random_iter=False):
    """训练模型(定义⻅第8章)"""
    loss = nn.CrossEntropyLoss()
    animator = d2l.Animator(xlabel='epoch', ylabel='perplexity',
                            legend=['train'], xlim=[10, num_epochs])
    # 初始化
    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: predict_ch8(prefix, 50, net, vocab, device)
    # 训练和预测
    for epoch in range(num_epochs):
        ppl, speed = train_epoch_ch8(
                    net, train_iter, loss, updater, device, use_random_iter)
        if (epoch + 1) % 10 == 0:
            print(predict('time traveller'))
            animator.add(epoch + 1, [ppl])
    print(f'困惑度 {ppl:.1f}, {speed:.1f} 词元/秒 {str(device)}')
    print(predict('time traveller'))
    print(predict('traveller'))
num_epochs, lr = 500, 1
train_ch8(net, train_iter, vocab, lr, num_epochs, d2l.try_gpu())

'''
困惑度 1.2, 63602.5 词元/秒 cuda:0
time travellerit s against reason said filbywhat thas se sho ls 
travellerit s against reason said filbywhat thas se sho ls 
'''

2.简洁版RNN

2.1同样的数据载入

batch_size, num_steps = 32, 35
train_iter, vocab = d2l.load_data_time_machine(batch_size, num_steps)

2.2模型定义

一层循环神经网络的输出被用作下一层循环神经网络的输入

num_hiddens = 256
rnn_layer = nn.RNN(len(vocab), num_hiddens)
state = torch.zeros((1, batch_size, num_hiddens))
state.shape

'''
torch.Size([1, 32, 256])
'''

  这里的X经过rnn得到的Y,输出的是(T,bs,hiddens),不涉及层的运算,指每个时间步的隐状态。
  state尺寸为(隐藏层数,bs,hidden),是最后一个时间步的隐状态Ht。

X = torch.rand(size=(num_steps, batch_size, len(vocab)))
Y, state_new = rnn_layer(X, state)
Y.shape, state_new.shape

'''
(torch.Size([35, 32, 256]), torch.Size([1, 32, 256]))
'''

  Y是所有每一个时间步的隐状态H,类似于从0实现里面rnn中的全部的H!!!

  state是最后一个时间步的。

  时间步T,在图中表现为输入的X有几个。

  torch里面的rnnlayer只包括隐藏层,不包括输出层。所以调用rnn_layer的时候,要构造一个输出层Linear.

#@save
class RNNModel(nn.Module):
    """循环神经⽹络模型"""
    def __init__(self, rnn_layer, vocab_size, **kwargs):
        super(RNNModel, self).__init__(**kwargs)
        self.rnn = rnn_layer
        self.vocab_size = vocab_size
        self.num_hiddens = self.rnn.hidden_size
        # 如果RNN是双向的(之后将介绍),num_directions应该是2,否则应该是1
        if not self.rnn.bidirectional:
            self.num_directions = 1
            self.linear = nn.Linear(self.num_hiddens, self.vocab_size)
        else:
            self.num_directions = 2
            self.linear = nn.Linear(self.num_hiddens * 2, self.vocab_size)
            
    def forward(self, inputs, state):
        X = F.one_hot(inputs.T.long(), self.vocab_size)
        X = X.to(torch.float32)
        Y, state = self.rnn(X, state)
        # 全连接层⾸先将Y的形状改为(时间步数*批量⼤⼩,隐藏单元数)
        # 它的输出形状是(时间步数*批量⼤⼩,词表⼤⼩)。即(bs*T,len(v))
        output = self.linear(Y.reshape((-1, Y.shape[-1])))
        return output, state
    
    def begin_state(self, device, batch_size=1):
        if not isinstance(self.rnn, nn.LSTM):
            # nn.GRU以张量作为隐状态
            return torch.zeros((self.num_directions * self.rnn.num_layers,
                                batch_size, self.num_hiddens),
                                device=device)
        else:
            # nn.LSTM以元组作为隐状态
            return (torch.zeros((
                self.num_directions * self.rnn.num_layers,
                batch_size, self.num_hiddens), device=device),
                torch.zeros((
                    self.num_directions * self.rnn.num_layers,
                    batch_size, self.num_hiddens), device=device))

2.3训练

device = d2l.try_gpu()
net = RNNModel(rnn_layer, vocab_size=len(vocab))
net = net.to(device)
num_epochs, lr = 500, 1
d2l.train_ch8(net, train_iter, vocab, lr, num_epochs, device)

'''
perplexity 1.3, 259910.4 tokens/sec on cuda:0
time travellerisus aits a berthat this is so extensivel is suld 
traveller came back andfilby s anecdote cowe prengtwercare 
'''

总结:简洁版代替了Rnn的定义与初始权重的定义。预测与训练是一致的。

3.rnn总结一下输入输出维度

  送入for X,T in train_iter里面的X,Y均为(bs,T)
  X直接送入net会先经过one-hot变成(T,bs,V)
  经过net后得到的y_hat为(T*bs,V)
  在net中,如果是调用nn.RNN(len(vocab),num_hiddens),则通过RNN得到的Y尺寸为(T,bs,hiddens),本质上是所有时间步的隐层,需要再接一个LInear(h,V)得到输出y_hat为(T*bs,V)
  如果是从零实现,则得到的每一个Y为(bs,V),再通过dim=0的累加得到y_hat为(T*bs,V)。
  然后在于y(经过转置为(T*bs))进行交叉熵计算loss。

从零实现循环神经网络(一) 加载数据并one_hot编码、模型参数初始化 阅读详情

相关推荐

ModuleNotFoundError: No module named ‘d2l’

打开Anaconda Powershell Prompt ,输入pip install torchtext==

m0_55196097的博客 3217

《动手学深度学习》中d2l库的安装教程(含细节,开盖即食)

​ 在按照《动手学深度学习》这本书时会有需要导入d2l库的使用。​ 首先先随便了解一下d2l库如下:​ d2I是一个与《动手学深度学习》(Dive into Deep Learning)一书配套的开源教学库,它包含了作者李沐设计的深度学习相关代码和示例。这个库旨在帮助读者通过实践经验来理解和掌握深度学习的基础知识和核心算法,如神经网络、卷积神经网络(CNN)、循环神经网络(RNN)等。除了提供理论知识外,d2Il库还通过实际代码应用来帮助读者加深对这些算法的理解。

m0_75243362的博客 5万+

详解循环神经网络(Recurrent Neural Network,RNN)(小白可入)

循环神经网络(Recurrent Neural Network,RNN)是一种擅长处理序列数据的神经网络架构。与传统的前馈神经网络不同,RNN具有内部的循环机制,可以保持序列中的上下文信息,使其特别适用于处理时间序列数据、自然语言处理等任务。

m0_51200050的博客 1562

解决AttributeError: module ‘d2l.torch‘ has no attribute ‘load_data_time_machine‘

原因:d2l版本过高。

Rhett_Butler0922的博客 5633

麒麟OS恢复出厂设置原理与实操:非重装的系统状态回滚

Linux操作系统中的‘恢复出厂设置’并非简单重装或镜像还原,而是一种基于状态快照、包管理与配置模板的可控回滚机制。其核心原理依赖LVM快照技术、RPM包签名验证和预置配置模板,兼顾系统稳定性与用户数据安全。该方案在政务、教育等国产化场景中具有显著技术价值——不格式化硬盘、不丢失/home文档、不重配驱动与授权,大幅降低运维复杂度。典型应用场景包括系统卡顿修复、软件冲突清理、桌面环境异常恢复等。本文深入解析银河麒麟V10的kylin-restore-cli工具链与麒麟管家集成逻辑,聚焦‘恢复出厂设置’这一高

weixin_30879169的博客 770

第二十届全国大学生智能车竞赛-地瓜机器人智慧医疗挑战赛技术解析与实战指南

本文深入解析了第二十届全国大学生智能车竞赛-地瓜机器人智慧医疗挑战赛的核心技术。内容涵盖从零搭建数字孪生环境、实现AI视觉任务(二维码识别、引导线追踪、目标检测)、在边缘设备部署轻量化大模型进行图生文描述,到遥操作与自主控制的平滑切换,并提供了基于ROS2的系统集成与赛场实战指南,助力参赛者高效备赛。

weixin_29252171的博客 2769

d2l@动手学深度学习@pytorch名称和d2l包的搭配安装问题#@save修饰符@在线运行notebook和免费算力

summarytorchtorchaudio从上面的介绍来看,torch是必备的,但是后两者作为功能扩展的增强包License:安装 — 动手学深度学习 2.0.0 documentation (d2l.ai)d2l 第2版中,提示的方式安装PyTorch的CPU或GPU版本:下面提供的时cpu版本(不涉及CUDA的安装)

xuchaoxin1375的博客 7375

平行趋势检验没通过怎么办?别慌,试试三重差分DDD与事件研究法

本文探讨了当平行趋势检验未通过时,如何运用三重差分法(DDD)与事件研究法进行政策评估。通过Stata代码示例和实战案例,详细介绍了DDD的原理、适用场景及实现步骤,并提供了替代方案如合成控制法和匹配DID,帮助研究者获得更准确的因果推断结果。

weixin_28732953的博客 607

从零实现循环神经网络(RNN) - d2l-ai项目深度解析

在传统的机器学习模型中,我们通常假设输入数据是独立同分布的。然而,在处理序列数据(如文本、语音、时间序列)时,这种假设不再成立。序列数据中的每个元素都与其前后的元素存在强烈的依赖关系。 想象一下,你正在阅读一段文字:"今天天气很好,我们去..."。要预测下一个词,你需要理解前面的上下文。传统的全连接神经网络无法有效捕捉这种时序依赖关系,这就是循环神经网络(Recurrent Neural Net...

gitblog_01097的博客 523

高缺失率时空数据插补实战:从随机森林到扩散模型的性能对比

数据缺失是数据分析与机器学习建模中普遍面临的挑战,尤其在时空数据领域,传感器故障、传输中断等问题常导致数据不完整。数据插补技术旨在基于已知数据的模式和关联性,合理估算缺失值,为后续分析提供可靠基础。其核心原理在于利用数据的时空相关性(如时间周期性、空间邻近性)及与外部驱动因素(如交通、气象)的关联构建预测模型。这项技术的价值在于能将不完整的数据集转化为可用于高质量分析和预测的可用资产,广泛应用于环境监测、交通流量预测、金融风控等领域。本文聚焦于一个极具挑战性的场景——PM2.5监测数据缺失率高达82%,通过

weixin_30363285的博客 543

NVIDIA 2025 Board Design Engineer 校招笔试全解析:从基础门电路到理想放大器设计

本文详细解析了NVIDIA 2025届板级设计工程师校招笔试的核心考点与解题策略。内容涵盖从基础门电路、CMOS实现NOR门,到开关电源CCM/DCM模式波形分析与效率计算,以及理想运放电路设计与稳定性优化。旨在帮助考生构建硬件知识体系,掌握工程思维,顺利通过NVIDIA Board Design Engineer校招笔试。

weixin_29172201的博客 195

从零实现循环神经网络:基于d2l-pytorch项目的实践指南

还在为理解循环神经网络(RNN)的内部机制而苦恼吗?想要从零开始构建一个真正的RNN模型,却不知从何下手?本文将带你深入d2l-pytorch项目,通过实战演练完整实现一个字符级语言模型,彻底掌握RNN的核心原理和实现细节。 读完本文你将获得: - ✅ RNN核心数学原理的直观理解 - ✅ 从零实现RNN的完整代码实践 - ✅ 梯度裁剪和困惑度等关键技术的应用 - ✅ 基于《时间机器》文本的语言...

gitblog_01074的博客 431

从HAL库SPI状态机机制剖析:为什么你的DMA发送会卡在BUSY状态?

本文深入剖析了STM32 HAL库中SPI状态机机制导致DMA发送卡在BUSY状态的常见问题。通过分析状态机设计原理,揭示了混合使用阻塞方式和DMA方式时状态切换冲突的根源,并提供了三种实战解决方案:正确配置SPI中断、使用HAL_SPI_Abort()函数以及手动管理状态机,帮助开发者实现稳定流畅的SPI DMA通信。

bush的博客 268

深入理解D2L项目中的循环神经网络(RNN)原理与应用

在深度学习领域,我们经常遇到两种主要类型的数据:表格数据和图像数据。然而,现实世界中大量数据具有**序列特性**(Sequential Nature)——文本、语音、时间序列、用户行为日志等。这些数据的特点是前后元素之间存在**强相关性**,顺序的重排会完全改变其语义含义。 传统的前馈神经网络在处理序列数据时面临根本性挑战:它们缺乏**记忆能力**,无法捕捉时间维度上的依赖关系。这正是循环神经网...

gitblog_00173的博客 378

PaddleOCR全版本完整指南:从入门到精通,全面解析安装部署与高级应用

摘要 本文详细介绍了PaddleOCR的完整安装与使用指南。首先讲解了环境准备步骤,包括Python 3.11虚拟环境创建和PaddlePaddle框架的CPU/GPU版本安装。接着介绍了PaddleOCR库的安装方式,可选功能模块(文档解析、信息抽取、翻译等)及其依赖组。通过示例代码演示了PPStructureV3文档解析功能的基本用法,并提供了安装验证方法。最后针对常见问题(Windows中文用户名报错、模型下载问题)给出解决方案。文章为从入门到精通的PaddleOCR用户提供了全面的技术指导。

算法工程师 1366

Python爬虫实战:高德地图POI信息爬取(餐馆/加油站等),附选址分析技巧

高德API配置AMAP_KEY = "你的高德API Key" # 替换成自己的Key# 爬取参数CITY = "成都" # 城市DISTRICTS = ["锦江区"] # 区域,可添加多个(比如["锦江区", "武侯区"])KEYWORDS_LIST = ["川菜馆", "加油站"] # 要爬取的POI类型TYPES = {"川菜馆": "050101", # 餐饮服务→中餐→川菜馆(高德POI分类编码)"加油站": "110100" # 交通设施→加油站。

专注于Python爬虫开发,分享爬虫技巧、项目实战与反爬经验,使用Scrapy、BeautifulSoup等工具,解决数据抓取难题。 2467

RNN循环神经网络 - PyTorch

动手学深度学习-循环神经网络笔记一、文本预处理1.读取数据集2.Token(词元)化3.构建词表二、读取⻓序列数据1.随机采样2.顺序分区三、RNN从零实现1.预测2.梯度裁剪3.训练四、RNN简洁实现 一、文本预处理 常⻅预处理步骤: 将文本作为字符串加载到内存中。 将字符串拆分为词元(如单词和字符)。 建立一个词表,将拆分的词元映射到数字索引。 将文本转换为数字索引序列,方便模型操作。 1.读取数据集 d2l.DATA_HUB['time_machine'] = (d2l.DATA

weixin_51221144的博客 2358

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

深度循环神经网络在d2l-ai项目中的应用解析

深度循环神经网络在d2l-ai项目中的应用解析 【免费下载链接】d2l-en d2l-ai/d2l-en: 是一个基于 Python 的深度学习教程,它使用了 SQLite 数据库存储数据。适合用于学习深度学习,特别是对于需要使用 Python 和 SQLite 数据库的场景。特点是深度学习教程、Python、SQLit...

gitblog_00315的博客 298

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

D2L.ai循环神经网络RNN教程:从基础LSTM到现代Transformer

深度学习中最强大的序列建模工具——循环神经网络RNN,正在彻底改变我们处理时间序列数据的方式。D2L.ai教程提供了完整的RNN学习路径,从传统的LSTM架构到革命性的Transformer模型,帮助初学者快速掌握这一关键技术。 ## 什么是循环神经网络RNN?🤔 循环神经网络RNN是专门设计用于处理**序列数据**的深度学习模型。与传统的神经网络不同,RNN具有**记忆能力**,能够将之前

gitblog_00700的博客 492

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

D2L.ai时间序列分析:10个RNN和LSTM在时序预测中的实战应用

在深度学习的广阔领域中,时间序列分析是一个至关重要且应用广泛的领域。D2L.ai项目作为深度学习教育的权威资源,提供了关于循环神经网络(RNN)和长短期记忆网络(LSTM)在时序预测中的完整指南。本文将为您介绍如何利用这些强大工具来处理股票价格、天气数据等时序信息。 ## 🔍 什么是时间序列分析? 时间序列分析是指对按时间顺序排列的数据点进行分析的方法。与传统的独立数据分析不同,时间序列数据

gitblog_00358的博客 804

深度学习之循环神经网络RNN

深度学习之循环神经网络RNN

weixin_74009895的博客 1456

深度学习:循环神经网络(RNN)详解

循环神经网络(RNN)通过其递归结构能够有效处理序列数据,捕捉时序中的依赖关系。虽然RNN在许多任务中表现出色,但其存在的梯度消失和梯度爆炸问题限制了它在长序列任务中的应用。为了克服这些局限,LSTM和GRU等变体在保留RNN优势的基础上,通过引入记忆机制和门控机制,有效解决了梯度问题,显著提升了对长时间依赖关系的捕捉能力。随着神经网络的不断发展,RNN及其变体仍然在许多序列任务中扮演着重要角色,尤其是在自然语言处理、语音识别和时间序列分析等领域。然而,随着。

m0_73640344的博客 2987

D2L项目教程:基于RNN的情感分析模型实现

D2L项目教程:基于RNN的情感分析模型实现 【免费下载链接】d2l-en d2l-ai/d2l-en: 是一个基于 Python 的深度学习教程,它使用了 SQLite 数据库存储数据。适合用于学习深度学习,特别是对于需要使用 Python 和 SQLite 数据库的场景。特点是深度学习教程、Python、SQLite...

gitblog_00561的博客 412

终极指南:D2L.ai文本分类中CNN、RNN与Transformer的完整应用解析

文本分类是自然语言处理领域的核心任务之一,广泛应用于情感分析、垃圾邮件检测、新闻主题分类等场景。D2L.ai(《动手学深度学习》)作为全球500多所高校采用的交互式深度学习教材,提供了CNN、RNN和Transformer三大主流模型在文本分类任务中的完整实现方案。本文将系统解析这三种架构的原理差异、适用场景及实战效果,帮助开发者快速掌握文本分类的最佳实践。 ## 文本分类的核心挑战与模型选择

gitblog_00296的博客 1157

Deep-RNN-深度循环神经网络(RNN循环神经网络)

Deep-RNN-深度循环神经网络的概念学习与应用

西小庄村高伟 的博客 1580

循环神经网络(RNN):时序建模的核心引擎与演进之路

在人工智能处理序列数据的战场上,循环神经网络(RNN)如同一个能够理解时间的智者。从 2015 年谷歌神经机器翻译系统颠覆传统方法,到 2023 年 ChatGPT 实现对话连续性,这些突破都植根于 RNN 对时序建模的深刻理解。本文将深入解析 RNN 的技术原理、核心变体及现代演进,揭示其如何在时间维度上构建智能。

WindWant 1535
上一篇: d2l语言模型--生成小批量序列
下一篇: d2l 里面GRU与Lstm实现
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值