HBU深度学习作业9

news2025/2/12 11:12:31

1. 实现SRN

(1)使用Numpy实现SRN 

import numpy as np
 
inputs = np.array([[1., 1.],
                   [1., 1.],
                   [2., 2.]])  # 初始化输入序列
print('inputs is ', inputs)
 
state_t = np.zeros(2, )  # 初始化存储器
print('state_t is ', state_t)
 
w1, w2, w3, w4, w5, w6, w7, w8 = 1., 1., 1., 1., 1., 1., 1., 1.
U1, U2, U3, U4 = 1., 1., 1., 1.
for input_t in inputs:
    print('inputs is ', input_t)
    print('state_t is ', state_t)
    in_h1 = np.dot([w1, w3], input_t) + np.dot([U2, U4], state_t)
    in_h2 = np.dot([w2, w4], input_t) + np.dot([U1, U3], state_t)
    state_t = in_h1, in_h2
    output_y1 = np.dot([w5, w7], [in_h1, in_h2])
    output_y2 = np.dot([w6, w8], [in_h1, in_h2])
    print('output_y is ', output_y1, output_y2)
    print('---------------------')

(2)在1的基础上,增加激活函数tanh

import numpy as np
 
inputs = np.array([[1., 1.],
                   [1., 1.],
                   [2., 2.]])  # 初始化输入序列
print('inputs is ', inputs)
 
state_t = np.zeros(2, )  # 初始化存储器
print('state_t is ', state_t)
 
w1, w2, w3, w4, w5, w6, w7, w8 = 1., 1., 1., 1., 1., 1., 1., 1.
U1, U2, U3, U4 = 1., 1., 1., 1.
print('--------------------------------------')
for input_t in inputs:
    print('inputs is ', input_t)
    print('state_t is ', state_t)
    in_h1 = np.tanh(np.dot([w1, w3], input_t) + np.dot([U2, U4], state_t))
    in_h2 = np.tanh(np.dot([w2, w4], input_t) + np.dot([U1, U3], state_t))
    state_t = in_h1, in_h2
    output_y1 = np.dot([w5, w7], [in_h1, in_h2])
    output_y2 = np.dot([w6, w8], [in_h1, in_h2])
    print('output_y is ', output_y1, output_y2)
    print('---------------------------------------------')

(3)使用nn.RNNCell实现

import torch
 
batch_size = 1
seq_len = 3  # 序列长度
input_size = 2  # 输入序列维度
hidden_size = 2  # 隐藏层维度
output_size = 2  # 输出层维度
 
# RNNCell
cell = torch.nn.RNNCell(input_size=input_size, hidden_size=hidden_size)
# 初始化参数 https://zhuanlan.zhihu.com/p/342012463
for name, param in cell.named_parameters():
    if name.startswith("weight"):
        torch.nn.init.ones_(param)
    else:
        torch.nn.init.zeros_(param)
# 线性层
liner = torch.nn.Linear(hidden_size, output_size)
liner.weight.data = torch.Tensor([[1, 1], [1, 1]])
liner.bias.data = torch.Tensor([0.0])
 
seq = torch.Tensor([[[1, 1]],
                    [[1, 1]],
                    [[2, 2]]])
hidden = torch.zeros(batch_size, hidden_size)
output = torch.zeros(batch_size, output_size)
 
for idx, input in enumerate(seq):
    print('=' * 20, idx, '=' * 20)
 
    print('Input :', input)
    print('hidden :', hidden)
 
    hidden = cell(input, hidden)
    output = liner(hidden)
    print('output :', output)

(4)使用nn.RNN实现

import torch
 
batch_size = 1
seq_len = 3
input_size = 2
hidden_size = 2
num_layers = 1
output_size = 2
 
cell = torch.nn.RNN(input_size=input_size, hidden_size=hidden_size, num_layers=num_layers)
for name, param in cell.named_parameters():  # 初始化参数
    if name.startswith("weight"):
        torch.nn.init.ones_(param)
    else:
        torch.nn.init.zeros_(param)
 
# 线性层
liner = torch.nn.Linear(hidden_size, output_size)
liner.weight.data = torch.Tensor([[1, 1], [1, 1]])
liner.bias.data = torch.Tensor([0.0])
 
inputs = torch.Tensor([[[1, 1]],
                       [[1, 1]],
                       [[2, 2]]])
hidden = torch.zeros(num_layers, batch_size, hidden_size)
out, hidden = cell(inputs, hidden)
 
print('Input :', inputs[0])
print('hidden:', 0, 0)
print('Output:', liner(out[0]))
print('--------------------------------------')
print('Input :', inputs[1])
print('hidden:', out[0])
print('Output:', liner(out[1]))
print('--------------------------------------')
print('Input :', inputs[2])
print('hidden:', out[1])
print('Output:', liner(out[2]))

2. 实现“序列到序列”

import torch

input_size = 4
hidden_size = 4
batch_size = 1

idx2char = ['e', 'h', 'l', 'o']
x_data = [1, 0, 2, 2, 3]
y_data = [3, 1, 2, 3, 2]

one_hot_lookup = [[1, 0, 0, 0],
                  [0, 1, 0, 0],
                  [0, 0, 1, 0],
                  [0, 0, 0, 1]]

x_one_hot = [one_hot_lookup[x] for x in x_data]

inputs = torch.Tensor(x_one_hot).view(-1, batch_size, input_size)
labels = torch.LongTensor(y_data).view(-1, 1)


class Model(torch.nn.Module):
    def __init__(self, input_size, hidden_size, batch_size):
        super(Model, self).__init__()
        self.batch_size = batch_size
        self.input_size = input_size
        self.hidden_size = hidden_size
        self.rnncell = torch.nn.RNNCell(input_size=self.input_size,
                                        hidden_size=self.hidden_size)

    def forward(self, input, hidden):
        hidden = self.rnncell(input, hidden)
        return hidden

    def init_hidden(self):
        return torch.zeros(self.batch_size, self.hidden_size)


net = Model(input_size, hidden_size, batch_size)
criterion = torch.nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(net.parameters(), lr=0.1)

for epoch in range(15):  # 循环15轮
    loss = 0
    optimizer.zero_grad()  # 每一次计算前先把梯度归零
    hidden = net.init_hidden()  # 初始化 h_0
    print('Predicted string:', end='')
    for input, label in zip(inputs, labels):  # 输入seq_length, batch_size, input_size
        hidden = net(input, hidden)
        loss += criterion(hidden, label)  # 所有的损失要用累加,不能用item
        _, idx = hidden.max(dim=1)  # 找到hidden 里面最大的值,认为是最有可能的
        print(idx2char[idx.item()], end='')
    loss.backward()  # 反向传播
    optimizer.step()  # 更新参数
    print(', Epoch [%d/15] loss=%.4f' % (epoch + 1, loss.item()))

3. “编码器-解码器”的简单实现

import torch
import numpy as np
import torch.nn as nn
import torch.utils.data as Data

device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
# S: Symbol that shows starting of decoding input
# E: Symbol that shows starting of decoding output
# ?: Symbol that will fill in blank sequence if current batch data size is short than n_step

letter = [c for c in 'SE?abcdefghijklmnopqrstuvwxyz']
letter2idx = {n: i for i, n in enumerate(letter)}

seq_data = [['man', 'women'], ['black', 'white'], ['king', 'queen'], ['girl', 'boy'], ['up', 'down'], ['high', 'low']]

# Seq2Seq Parameter
n_step = max([max(len(i), len(j)) for i, j in seq_data])  # max_len(=5)
n_hidden = 128
n_class = len(letter2idx)  # classfication problem
batch_size = 3


def make_data(seq_data):
    enc_input_all, dec_input_all, dec_output_all = [], [], []

    for seq in seq_data:
        for i in range(2):
            seq[i] = seq[i] + '?' * (n_step - len(seq[i]))  # 'man??', 'women'

        enc_input = [letter2idx[n] for n in (seq[0] + 'E')]  # ['m', 'a', 'n', '?', '?', 'E']
        dec_input = [letter2idx[n] for n in ('S' + seq[1])]  # ['S', 'w', 'o', 'm', 'e', 'n']
        dec_output = [letter2idx[n] for n in (seq[1] + 'E')]  # ['w', 'o', 'm', 'e', 'n', 'E']

        enc_input_all.append(np.eye(n_class)[enc_input])
        dec_input_all.append(np.eye(n_class)[dec_input])
        dec_output_all.append(dec_output)  # not one-hot

    # make tensor
    return torch.Tensor(enc_input_all), torch.Tensor(dec_input_all), torch.LongTensor(dec_output_all)


'''
enc_input_all: [6, n_step+1 (because of 'E'), n_class]
dec_input_all: [6, n_step+1 (because of 'S'), n_class]
dec_output_all: [6, n_step+1 (because of 'E')]
'''
enc_input_all, dec_input_all, dec_output_all = make_data(seq_data)


class TranslateDataSet(Data.Dataset):
    def __init__(self, enc_input_all, dec_input_all, dec_output_all):
        self.enc_input_all = enc_input_all
        self.dec_input_all = dec_input_all
        self.dec_output_all = dec_output_all

    def __len__(self):  # return dataset size
        return len(self.enc_input_all)

    def __getitem__(self, idx):
        return self.enc_input_all[idx], self.dec_input_all[idx], self.dec_output_all[idx]


loader = Data.DataLoader(TranslateDataSet(enc_input_all, dec_input_all, dec_output_all), batch_size, True)


# Model
class Seq2Seq(nn.Module):
    def __init__(self):
        super(Seq2Seq, self).__init__()
        self.encoder = nn.RNN(input_size=n_class, hidden_size=n_hidden, dropout=0.5)  # encoder
        self.decoder = nn.RNN(input_size=n_class, hidden_size=n_hidden, dropout=0.5)  # decoder
        self.fc = nn.Linear(n_hidden, n_class)

    def forward(self, enc_input, enc_hidden, dec_input):
        # enc_input(=input_batch): [batch_size, n_step+1, n_class]
        # dec_inpu(=output_batch): [batch_size, n_step+1, n_class]
        enc_input = enc_input.transpose(0, 1)  # enc_input: [n_step+1, batch_size, n_class]
        dec_input = dec_input.transpose(0, 1)  # dec_input: [n_step+1, batch_size, n_class]

        # h_t : [num_layers(=1) * num_directions(=1), batch_size, n_hidden]
        _, h_t = self.encoder(enc_input, enc_hidden)
        # outputs : [n_step+1, batch_size, num_directions(=1) * n_hidden(=128)]
        outputs, _ = self.decoder(dec_input, h_t)

        model = self.fc(outputs)  # model : [n_step+1, batch_size, n_class]
        return model


model = Seq2Seq().to(device)
criterion = nn.CrossEntropyLoss().to(device)
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)

for epoch in range(5000):
    for enc_input_batch, dec_input_batch, dec_output_batch in loader:
        # make hidden shape [num_layers * num_directions, batch_size, n_hidden]
        h_0 = torch.zeros(1, batch_size, n_hidden).to(device)

        (enc_input_batch, dec_intput_batch, dec_output_batch) = (
            enc_input_batch.to(device), dec_input_batch.to(device), dec_output_batch.to(device))
        # enc_input_batch : [batch_size, n_step+1, n_class]
        # dec_intput_batch : [batch_size, n_step+1, n_class]
        # dec_output_batch : [batch_size, n_step+1], not one-hot
        pred = model(enc_input_batch, h_0, dec_intput_batch)
        # pred : [n_step+1, batch_size, n_class]
        pred = pred.transpose(0, 1)  # [batch_size, n_step+1(=6), n_class]
        loss = 0
        for i in range(len(dec_output_batch)):
            # pred[i] : [n_step+1, n_class]
            # dec_output_batch[i] : [n_step+1]
            loss += criterion(pred[i], dec_output_batch[i])
        if (epoch + 1) % 1000 == 0:
            print('Epoch:', '%04d' % (epoch + 1), 'cost =', '{:.6f}'.format(loss))

        optimizer.zero_grad()
        loss.backward()
        optimizer.step()


def translate(word):
    enc_input, dec_input, _ = make_data([[word, '?' * n_step]])
    enc_input, dec_input = enc_input.to(device), dec_input.to(device)
    # make hidden shape [num_layers * num_directions, batch_size, n_hidden]
    hidden = torch.zeros(1, 1, n_hidden).to(device)
    output = model(enc_input, hidden, dec_input)
    # output : [n_step+1, batch_size, n_class]

    predict = output.data.max(2, keepdim=True)[1]  # select n_class dimension
    decoded = [letter[i] for i in predict]
    translated = ''.join(decoded[:decoded.index('E')])

    return translated.replace('?', '')


print('test')
print('man ->', translate('man'))
print('mans ->', translate('mans'))
print('king ->', translate('king'))
print('black ->', translate('black'))
print('up ->', translate('up'))

4.简单总结nn.RNNCell、nn.RNN

参考链接:

【PyTorch学习笔记】21:nn.RNN和nn.RNNCell的使用-CSDN博客

【学习笔记】RNN算法的pytorch实现 - Lugendary - 博客园 (cnblogs.com)

torch 循环神经网络torch.nn.RNN()和 torch.nn.RNNCell()-CSDN博客 

torch.nn.RNN()调用的是循环神经网络最原始的形态,这种没法处理比较长的时间序列,后面的变体Lstm和GRU解决了这个问题,这里只是用torch.nn.RNN()展示一下循环神经网络的一些基本参数等信息,当然有些大神也是直接调用这个去搭建一些自己需要的网络结构。

import torch
from torch.autograd import Variable
from torch import nn

input_size = 10
batch_size = 5

hidden_size = 20
num_layers = 2
#定义一个最简单的循环神经网络,网络输入的特征维度为10,隐层的节点数目为20个,有2层
model = nn.RNN(input_size=input_size, hidden_size=hidden_size, num_layers=num_layers)

x = torch.rand(3, batch_size, input_size) #这里理解为生成batch_size条数据,每条数据长度为3,特征维度为input_size
h0 = torch.zeros(num_layers, batch_size, hidden_size) #这里定义最初始输入的记忆状态,直接设置为0就行
y, h = model(x, h0)

print('y.shape=', y.shape)
print('h.shape=', h.shape)

 

上面搭建了一个最简单的示例,解释下y和h的输出都表示什么,这对后面的使用影响比较大,循环神经网络是这样的,一条时间序列的长度为3,那么就对应了3个时刻,前面一个时刻模型的神经元的输出会作为下一个时刻模型神经元的输入,假设模型的所有神经元表示为H,h表示所有神经元的输出,h也叫记忆单元。那么在最开始的时间t0,计算过程就是

h1 = H(h0 + x0) #h0为初始化输入,可以直接设置为0
#因为时间序列每个元素都需要对应一个输出,于是0时刻,第1个元素对应的输出为
out1 = h1[-1] #也就是所有神经元输出的最后一层
开始循环如下:
h2 = H(h1 +  x1)
out2 = h2[-1]
h3 = H(h2 +  x2)
out3 = h3[-1]

最后训练结束,输出的h就是最后一个时刻模型所有神经元的输出,也就是h3,我们上面定义的模型有2层,每层神经元数目为20,于是得到的输出尺寸应该为[2, 20],又因为上面我设置了5条神经元数据,每条都对应一个[2, 20]的输出矩阵,所以最终的输出矩阵尺寸为[2, 5, 20],记得中间的维度是针对第几条数据,希望读者能理解输出和输入都是表示什么。

那么很好理解了吧,模型最后输出的y,就是每个时刻元素的输出,也就是[out1, out2, out3],每个out都是模型最后一层神经元的输出,尺寸为[1, 20],这里我设置的数据每条时间序列有3个元素,每个元素对应一个时刻的输出,于是尺寸为[3, 20],又因为有5条数据,所以最终尺寸为[3, 5, 20]。

这里注意下,RNN的输入格式不同于CNN,CNN模型的输入尺寸是batch_size放前面,也就是[batch_size, input_size_1, input_size_2],而RNN是放中间,也就是
[input_size_1, batch_size, input_size_2],希望各位同学注意下。

这里需要对比的是RNNCell,我们上面提到上述过程是一个循环的过程,唯一区别就是,RNN是读取了0时刻的隐层信息h0,剩下的过程是自动循环完成的,而RNNCell就需要自己写循环处理了,代码如下:

import torch
from torch.autograd import Variable
from torch import nn

input_size = 10
batch_size = 5

hidden_size = 20
num_layers = 2
#定义一个最简单的循环神经网络,网络输入的特征维度为10,隐层的节点数目为20个
model = nn.RNNCell(input_size=input_size, hidden_size=hidden_size)

x = torch.rand(3, batch_size, input_size) #这里理解为生成batch_size条数据,每条数据长度为3,特征维度为input_size
h0 = torch.zeros(batch_size, hidden_size) #这里定义最初始输入的记忆状态,直接设置为0就行

for i in range(3):
    h0 = model(x[i], h0)
    y = h0
    print(y.shape)

RNNCell是单层结构,所以每次的输出,就是对应时刻元素x的输出。 

5.谈一谈对“序列”、“序列到序列”的理解

参考链接:

序列到序列 | 机器之心 (jiqizhixin.com)

使用Python实现深度学习模型:序列到序列模型(Seq2Seq) - 华为云开发者联盟 - 博客园 (cnblogs.com)

什么是序列?

序列数据(Sequence Data) 是指按照一定顺序排列的数据集合,其中的每个元素被称为序列的一个项(item)。

序列数据的特点是按顺序排列,元素之间存在时间或空间上的依赖关系。

什么是序列到序列?

序列到序列学习(Seq2Seq)是指训练模型从而把一个域的序列(比如英语语句)转化为另一个域的序列(比如法语中的对应语句):

 这是一种通用的端到端序列学习方法,它基于编码-解码(Encoder - Decoder)的架构。一般情况下,输入序列和输出序列有不同的长度(比如机器翻译)。这就需要一个更高级的设置,尤其在没有进一步语境的「序列到序列模型」时。下面是其工作原理:

  • 一个 RNN 层(或其中的堆栈)作为「编码器」:它处理输入序列并反馈其内部状态。注意我们抛弃了编码器 RNN 的输出,只恢复其状态。该状态在下一步中充当解码器的「语境」。
  • 另一个 RNN 层作为「解码器」:在给定目标序列先前字母的情况下,它被训练以预测目标序列的下一个字符。具体讲,它被训练把目标序列转化为相同序列,但接下来被一个时间步抵消,这一训练过程在语境中被称为「teacher forcing」。更重要的是,编码器把其状态向量用作初始状态,如此编码器获得了其将要生成的信息。实际上,在给定 targets[...t] 的情况下,解码器学习生成 targets[t+1...],前提是在输入序列上。

什么是序列到序列模型?

Seq2Seq 模型通常由两个主要部分组成:编码器(Encoder)和解码器(Decoder)。编码器将输入序列编码成一个固定长度的上下文向量(context vector),然后解码器根据这个上下文向量生成目标序列。

编码器(Encoder)

编码器是一个循环神经网络(RNN),如 LSTM 或 GRU,用于处理输入序列,并生成一个上下文向量。这个向量总结了输入序列的全部信息。

解码器(Decoder)

解码器也是一个 RNN,使用编码器生成的上下文向量作为初始输入,并逐步生成目标序列的每一个元素。

训练过程

在训练过程中,解码器在每一步生成一个单词,并使用该单词作为下一步的输入。这种方法被称为教师强制(Teacher Forcing)。

6.总结本周理论课和作业,写心得体会

 参考链接:

RNN Layer - mathor (wmathor.com)

人工智能 - 循环神经网络RNN完全解析:从基础理论到PyTorch实战 - 个人文章 - SegmentFault 思否

 

 

 这次作业主要是熟悉RNN的基本原理、RNN与CNN和DNN的不同与联系

RNN 主要由输入层、隐藏层和输出层组成。其中,隐藏层之间的节点不再无连接,而是有连接的,并且隐藏层的输入不仅包括输入层的输出,还包括上一时刻隐藏层的输出。

 

对于初学者而言,搜资料的时候这个图会频繁出现,不好理解

真正的图长这样,这样看就舒服多了

还有就是RNN中的权值共享。

 无论是W、U、V在每个时间步上都是同一个

若说CNN是空间上的权值共享,那么RNN就是时间步上的共享

参数共享在一定程度上可以对文本处理中的每个单元实现“相对公平”,虽然这不一定是好事,后续LSTM以及attention的提出则打破了这种公平。

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

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

相关文章

泛化调用 :在没有接口的情况下进行RPC调用

什么是泛化调用? 在RPC调用的过程中,调用端向服务端发起请求,首先要通过动态代理,动态代理可以屏蔽RPC处理流程,使得发起远程调用就像调用本地一样。 RPC调用本质:调用端向服务端发送一条请求消息&#x…

纯Go语言开发人脸检测、瞳孔/眼睛定位与面部特征检测插件-助力GoFly快速开发框架

前言​ 开发纯go插件的原因是因为目前 Go 生态系统中几乎所有现有的人脸检测解决方案都是纯粹绑定到一些 C/C 库,如 ​​OpenCV​​ 或 ​​​dlib​​​,但通过 ​​​cgo​​​ 调用 C 程序会引入巨大的延迟,并在性能方面产生显著的权衡。…

基于SpringBoot实现的编程训练系统(代码+论文)

🎉博主介绍:Java领域优质创作者,阿里云博客专家,计算机毕设实战导师。专注Java项目实战、毕设定制/协助 📢主要服务内容:选题定题、开题报告、任务书、程序开发、项目定制、论文辅导 💖精彩专栏…

【Spring】Spring IOCDI:架构旋律中的“依赖交响”与“控制华章”

前言 🌟🌟本期讲解关于Spring IOC&DI的详细介绍~~~ 🌈感兴趣的小伙伴看一看小编主页:GGBondlctrl-CSDN博客 🔥 你的点赞就是小编不断更新的最大动力 🎆那么…

webpack(react)基本构建

文章目录 概要整体架构流程技术名词解释技术细节小结 概要 Webpack 是一个现代 JavaScript 应用程序的静态模块打包工具。它的主要功能是将各种资源(如 JavaScript、CSS、图片等)视为模块,并将它们打包成一个或多个输出文件,以便…

mysql--二进制安装编译安装yum安装

二进制安装 创建用户和组 [rootlocalhost ~]# groupadd -r -g 306 mysql [rootlocalhost ~]# useradd -r -g 306 -u 306 -d /data/mysql mysql 创建文件夹并添加所属文件用户和组 [rootlocalhost ~]# mkdir -p /data/mysql [rootlocalhost ~]# chown mysql:mysql /data/mysql …

DRM(数字权限管理技术)防截屏录屏----ffmpeg安装

提示:ffmpeg安装 文章目录 [TOC](文章目录) 前言一、下载二、配置环境变量三、运行ffmpeg四、文档总结 前言 FFmpeg是一套可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序。采用LGPL或GPL许可证。它提供了录制、转换以及流化音视频的…

MongoDB集群分片安装部署手册

文章目录 一、集群规划1.1 集群安装规划1.2 端口规划1.3 目录创建 二、mongodb安装(三台均需要操作)2.1 下载、解压2.2 配置环境变量 三、mongodb组件配置3.1 配置config server的副本集3.1.1 config配置文件3.1.2 config server启动3.1.3 初始化config …

小程序-基于java+SpringBoot+Vue的乡村研学旅行平台设计与实现

项目运行 1.运行环境:最好是java jdk 1.8,我们在这个平台上运行的。其他版本理论上也可以。 2.IDE环境:IDEA,Eclipse,Myeclipse都可以。推荐IDEA; 3.tomcat环境:Tomcat 7.x,8.x,9.x版本均可 4.硬件环境&#xff1a…

Ubuntu 包管理

APT&dpkg 查看已安装包 查看所有已经安装的包 dpkg -l 查找包 apt search <package_name>搜索软件包列表&#xff0c;找到与搜索关键字匹配的包 dpkg与grep结合查找特定的包 dpkg -s <package>&#xff1a;查看某个安装包的详细信息 安装包 apt安装命令 更新…

mac访达打开终端

选择文件夹打开 选中文件夹&#xff0c;然后右键即可&#xff1a; 在当前文件夹打开 在访达的当前文件夹长按option键 左下角出现当前文件夹路径 右键即可打开终端

数据结构--二叉树的创建和遍历

目录 引入 定义 性质 二叉树的创建 迭代法 注意事项&#xff1a; 递归法 注意事项&#xff1a; 二叉树的遍历 深度优先 广度优先 先序遍历&#xff08;前序遍历&#xff09; 中序遍历 后序遍历 层序遍历 查找树结构中是否存在某数值 方法一&#xff1a; 方法…

Linux零基础入门--Makefile和make--纯干货无废话!!

Makefile的概念与使用 Makefile其实是linux中的一种包含构建指令的文件&#xff0c;用于自动化构建 一个工程中的源文件不计数&#xff0c;其按类型、功能、模块分别放在若干个目录中&#xff0c;makefile定义了一系列的 规则来指定&#xff0c;哪些文件需要先编译&#xff0c;…

数据结构与算法——N叉树(自学笔记)

本文参考 N 叉树 - LeetBook - 力扣&#xff08;LeetCode&#xff09;全球极客挚爱的技术成长平台 遍历 前序遍历&#xff1a;A->B->C->E->F->D->G后序遍历&#xff1a;B->E->F->C->G->D->A层序遍历&#xff1a;A->B->C->D->…

如何使用 Chrome 无痕浏览模式访问网站?

无痕浏览&#xff08;Incognito Mode&#xff09;是 Google Chrome 浏览器提供的一种隐私保护功能&#xff0c;它允许用户在一个独立的会话中浏览网页&#xff0c;而不会记录用户的浏览历史、下载历史、表单数据等。这对于希望保护个人隐私或进行临时性匿名浏览的用户来说非常有…

0.shell 脚本执行方式

1.脚本格式要求 &#x1f951;脚本以 #!/bin/bash 开头 &#x1f966; 脚本要有可执行权限 2.执行脚本的两种方式 &#x1f96c; 方式1&#xff1a;赋予x执行权限 &#x1f952; ​​​​​​​方式2&#xff1a; sh执行 ​​​​​​​

基于大数据python 酒店数据分析可视化大屏系统(源码+LW+部署讲解+数据库+ppt)

&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01; 很对人不知道选题怎么选 不清楚自己适合做哪块内容 都可以免费来问我 避免后期給自己答辩找麻烦 增加难度&#xff08;部分学校只有一次答辩机会 没弄好就延迟…

扩展欧几里得——acwing

数论—快速幂&#xff0c;欧几里得及其扩展&#xff0c;逆元&#xff0c;单位元_数论单位元函数-CSDN博客 之前做的数论笔记&#x1f446;&#x1f446;&#x1f446; 题目一&#xff1a;扩展欧几里得算法 877. 扩展欧几里得算法 - AcWing题库 分析 代码 #include<bits/…

数字信号处理实验报告四:IIR数字滤波器设计及软件实现

1.实验目的 (1)熟悉用双线性变换法设计IIR数字滤波器的原理与方法; (2)学会调用MATLAB信号处理工具箱中滤波器设计函数(或滤波器设计分析工具fdatool)设计各种IIR数字滤波器,学会根据滤波需求确定滤波器指标参数。 (3)掌握IIR数字滤波器的MATLAB实现方法。 (3)…

53 基于单片机的8路抢答器加记分

目录 一、主要功能 二、硬件资源 三、程序编程 四、实现现象 一、主要功能 首先有三个按键 分别为开始 暂停 复位&#xff0c;然后八个选手按键&#xff0c;开机显示四条杠&#xff0c;然后按一号选手按键&#xff0c;数码管显示&#xff13;&#xff10;&#xff0c;这…