深度学习-----------------机器翻译与数据集
目录
- 机器翻译与数据集
- 下载和预处理数据集
- 预处理步骤
- 词元化
- 词汇表
- 该部分总代码
- 固定长度阶段或填充
- 该部分总代码
- 转换成小批量数据集用于训练
- 训练模型
- 总代码
机器翻译与数据集
import os
import torch
from d2l import torch as d2l
下载和预处理数据集
#@save
d2l.DATA_HUB['fra-eng'] = (d2l.DATA_URL + 'fra-eng.zip','94646ad1522d915e7b0f9296181140edcf86a4f5')#@save
def read_data_nmt():"""载入“英语-法语”数据集"""data_dir = d2l.download_extract('fra-eng')with open(os.path.join(data_dir, 'fra.txt'), 'r',encoding='utf-8') as f:return f.read()raw_text = read_data_nmt()
print(raw_text[:75])

预处理步骤
import os
import torch
from d2l import torch as d2l# 下载和预处理数据集
# 将数据集的下载链接和校验码与'fra-eng'标识关联起来
d2l.DATA_HUB['fra-eng'] = (d2l.DATA_URL + 'fra-eng.zip','94646ad1522d915e7b0f9296181140edcf86a4f5')def read_data_nmt():"""载入 “英语-法语” 数据集 """# 下载并解压数据集data_dir = d2l.download_extract('fra-eng')# 读取数据并返回with open(os.path.join(data_dir, 'fra.txt'), 'r', encoding='utf-8') as f:return f.read()# 几个预处理步骤
def preprocess_nmt(text):"""预处理 “英语-法语” 数据集"""# 判断字符是否是特定标点符号并且前一个字符不是空格def no_space(char, prev_char):return char in set(',.!?') and prev_char != ' '# 替换特殊字符为空格,转换为小写text = text.replace('\u202f', ' ').replace('\xa0', ' ').lower()out = [# 对于每个字符,如果它的索引大于0(即不是第一个字符),并且满足 no_space 函数的条件,则在该字符前添加一个空格,否则,直接使用该字符。' ' + char if i > 0 and no_space(char, text[i - 1]) else char# (enumerate 函数将字符串 text 中的每个字符及其索引打包成元组i为下标、char为字符)for i, char in enumerate(text)]return ''.join(out) # 将处理后的字符列表转换为字符串# 调用函数读取数据集
raw_text = read_data_nmt()
# 调用预处理函数处理原始文本
text = preprocess_nmt(raw_text)
# 打印处理后的文本的前80个字符
print(text[:75])

词元化
import os
from d2l import torch as d2l# 下载和预处理数据集
# 将数据集的下载链接和校验码与'fra-eng'标识关联起来
d2l.DATA_HUB['fra-eng'] = (d2l.DATA_URL + 'fra-eng.zip','94646ad1522d915e7b0f9296181140edcf86a4f5')def read_data_nmt():"""载入 “英语-法语” 数据集 """# 下载并解压数据集data_dir = d2l.download_extract('fra-eng')# 读取数据并返回with open(os.path.join(data_dir, 'fra.txt'), 'r', encoding='utf-8') as f:return f.read()# 几个预处理步骤
def preprocess_nmt(text):"""预处理 “英语-法语” 数据集"""# 判断字符是否是特定标点符号并且前一个字符不是空格def no_space(char, prev_char):return char in set(',.!?') and prev_char != ' '# 替换特殊字符为空格,转换为小写text = text.replace('\u202f', ' ').replace('\xa0', ' ').lower()out = [# 对于每个字符,如果它的索引大于0(即不是第一个字符),并且满足 no_space 函数的条件,则在该字符前添加一个空格,否则,直接使用该字符。' ' + char if i > 0 and no_space(char, text[i - 1]) else char# (enumerate 函数将字符串 text 中的每个字符及其索引打包成元组i为下标、char为字符)for i, char in enumerate(text)]return ''.join(out) # 将处理后的字符列表转换为字符串# 指定处理的示例数量。如果为 None,则处理所有行。
def tokenize_nmt(text, num_examples=None):"""词元化 “英语-法语” 数据数据集 """# 存储英语和法语的词元序列source, target = [], []# 将每一行及其索引打包成元组 (i, line)for i, line in enumerate(text.split('\n')):# 如果指定了num_examples且当前行索引i大于num_examples,则结束循环if num_examples and i > num_examples:break# 按制表符分割行parts = line.split('\t')# 如果行中包含了两个部分if len(parts) == 2:# 将英语部分按空格分割为词元,并添加到source列表source.append(parts[0].split(' ')) # 英语# 将法语部分按空格分割为词元,并添加到target列表target.append(parts[1].split(' ')) # 法语return source, target# 调用函数读取数据集
raw_text = read_data_nmt()
# 调用预处理函数处理原始文本
text = preprocess_nmt(raw_text)# 调用函数词元化文本
source, target = tokenize_nmt(text)
# 打印source和target的前6个词元序列
print(source[:6])
print(target[:6])

绘制每个文本序列所包含的标记数量的直方图。
import os
import torch
from d2l import torch as d2l# 下载和预处理数据集
# 将数据集的下载链接和校验码与'fra-eng'标识关联起来
d2l.DATA_HUB['fra-eng'] = (d2l.DATA_URL + 'fra-eng.zip','94646ad1522d915e7b0f9296181140edcf86a4f5')def read_data_nmt():"""载入 “英语-法语” 数据集 """# 下载并解压数据集data_dir = d2l.download_extract('fra-eng')# 读取数据并返回with open(os.path.join(data_dir, 'fra.txt'), 'r', encoding='utf-8') as f:return f.read()# 几个预处理步骤
def preprocess_nmt(text):"""预处理 “英语-法语” 数据集"""# 判断字符是否是特定标点符号并且前一个字符不是空格def no_space(char, prev_char):return char in set(',.!?') and prev_char != ' '# 替换特殊字符为空格,转换为小写text = text.replace('\u202f', ' ').replace('\xa0', ' ').lower()out = [# 对于每个字符,如果它的索引大于0(即不是第一个字符),并且满足 no_space 函数的条件,则在该字符前添加一个空格,否则,直接使用该字符。' ' + char if i > 0 and no_space(char, text[i - 1]) else char# (enumerate 函数将字符串 text 中的每个字符及其索引打包成元组i为下标、char为字符)for i, char in enumerate(text)]return ''.join(out) # 将处理后的字符列表转换为字符串# 指定处理的示例数量。如果为 None,则处理所有行。
def tokenize_nmt(text, num_examples=None):"""词元化 “英语-法语” 数据数据集 """# 存储英语和法语的词元序列source, target = [], []# 将每一行及其索引打包成元组 (i, line)for i, line in enumerate(text.split('\n')):# 如果指定了num_examples且当前行索引i大于num_examples,则结束循环if num_examples and i > num_examples:break# 按制表符分割行parts = line.split('\t')# 如果行中包含了两个部分if len(parts) == 2:# 将英语部分按空格分割为词元,并添加到source列表source.append(parts[0].split(' ')) # 英语# 将法语部分按空格分割为词元,并添加到target列表target.append(parts[1].split(' ')) # 法语return source, target# 调用函数读取数据集
raw_text = read_data_nmt()
# 调用预处理函数处理原始文本
text = preprocess_nmt(raw_text)# 调用函数词元化文本
source, target = tokenize_nmt(text)
# 设置图形大小
d2l.set_figsize()
# 绘制每个文本序列所包含的标记数量的直方图,根据句子长度做的直方图
_, _, patches = d2l.plt.hist([[len(l)for l in source], [len(l) for l in target]],label = ['source','target']) # 添加标签
# 遍历第二个直方图的每个矩形
for patch in patches[1].patches:# 设置矩形的填充样式为斜线patch.set_hatch('/')
# 添加图例,位于右上角
d2l.plt.legend(loc='upper right')
d2l.plt.show()

词汇表
# 创建源语言的词汇表对象
src_vocab = d2l.Vocab(source, min_freq=2,reserved_tokens=['<pad>', '<bos>', '<eos>']) # pad表示句子的填充,bos 表示句子开始,eos表示句子结束,min_freq=2表示句子长度小于2个就不要了
# 计算词汇表的大小
print(len(src_vocab))

该部分总代码
import os
import torch
from d2l import torch as d2l# 下载和预处理数据集
# 将数据集的下载链接和校验码与'fra-eng'标识关联起来
d2l.DATA_HUB['fra-eng'] = (d2l.DATA_URL + 'fra-eng.zip','94646ad1522d915e7b0f9296181140edcf86a4f5')def read_data_nmt():"""载入 “英语-法语” 数据集 """# 下载并解压数据集data_dir = d2l.download_extract('fra-eng')# 读取数据并返回with open(os.path.join(data_dir, 'fra.txt'), 'r', encoding='utf-8') as f:return f.read()# 几个预处理步骤
def preprocess_nmt(text):"""预处理 “英语-法语” 数据集"""# 判断字符是否是特定标点符号并且前一个字符不是空格def no_space(char, prev_char):return char in set(',.!?') and prev_char != ' '# 替换特殊字符为空格,转换为小写text = text.replace('\u202f', ' ').replace('\xa0', ' ').lower()out = [# 对于每个字符,如果它的索引大于0(即不是第一个字符),并且满足 no_space 函数的条件,则在该字符前添加一个空格,否则,直接使用该字符。' ' + char if i > 0 and no_space(char, text[i - 1]) else char# (enumerate 函数将字符串 text 中的每个字符及其索引打包成元组i为下标、char为字符)for i, char in enumerate(text)]return ''.join(out) # 将处理后的字符列表转换为字符串# 指定处理的示例数量。如果为 None,则处理所有行。
def tokenize_nmt(text, num_examples=None):"""词元化 “英语-法语” 数据数据集 """# 存储英语和法语的词元序列source, target = [], []# 将每一行及其索引打包成元组 (i, line)for i, line in enumerate(text.split('\n')):# 如果指定了num_examples且当前行索引i大于num_examples,则结束循环if num_examples and i > num_examples:break# 按制表符分割行parts = line.split('\t')# 如果行中包含了两个部分if len(parts) == 2:# 将英语部分按空格分割为词元,并添加到source列表source.append(parts[0].split(' ')) # 英语# 将法语部分按空格分割为词元,并添加到target列表target.append(parts[1].split(' ')) # 法语return source, target# 调用函数读取数据集
raw_text = read_data_nmt()
# 调用预处理函数处理原始文本
text = preprocess_nmt(raw_text)# 调用函数词元化文本
source, target = tokenize_nmt(text)
# 创建源语言的词汇表对象
src_vocab = d2l.Vocab(source, min_freq=2,reserved_tokens=['<pad>', '<bos>', '<eos>']) # pad表示句子的填充,bos 表示句子开始,eos表示句子结束,min_freq=2表示句子长度小于2个就不要了
# 计算词汇表的大小
print(len(src_vocab))
固定长度阶段或填充
序列样本都有一个固定的长度截断或填充文本序列
# 序列样本都有一个固定长度截断或填充文本序列
def truncate_pad(line, num_steps, padding_token):"""截断或填充文本序列"""# 如果文本序列长度超过了指定的长度if len(line) > num_steps:# 截断文本序列,取前num_steps个词元return line[:num_steps]# 填充文本序列,添加padding_token直到长度达到num_stepsreturn line + [padding_token] * (num_steps - len(line))
# 对源语言的第一个文本序列进行截断或填充
print(truncate_pad(src_vocab[source[0]], 10, src_vocab['<pad>']))
该部分总代码
import os
import torch
from d2l import torch as d2l# 下载和预处理数据集
# 将数据集的下载链接和校验码与'fra-eng'标识关联起来
d2l.DATA_HUB['fra-eng'] = (d2l.DATA_URL + 'fra-eng.zip','94646ad1522d915e7b0f9296181140edcf86a4f5')def read_data_nmt():"""载入 “英语-法语” 数据集 """# 下载并解压数据集data_dir = d2l.download_extract('fra-eng')# 读取数据并返回with open(os.path.join(data_dir, 'fra.txt'), 'r', encoding='utf-8') as f:return f.read()# 几个预处理步骤
def preprocess_nmt(text):"""预处理 “英语-法语” 数据集"""# 判断字符是否是特定标点符号并且前一个字符不是空格def no_space(char, prev_char):return char in set(',.!?') and prev_char != ' '# 替换特殊字符为空格,转换为小写text = text.replace('\u202f', ' ').replace('\xa0', ' ').lower()out = [# 对于每个字符,如果它的索引大于0(即不是第一个字符),并且满足 no_space 函数的条件,则在该字符前添加一个空格,否则,直接使用该字符。' ' + char if i > 0 and no_space(char, text[i - 1]) else char# (enumerate 函数将字符串 text 中的每个字符及其索引打包成元组i为下标、char为字符)for i, char in enumerate(text)]return ''.join(out) # 将处理后的字符列表转换为字符串# 指定处理的示例数量。如果为 None,则处理所有行。
def tokenize_nmt(text, num_examples=None):"""词元化 “英语-法语” 数据数据集 """# 存储英语和法语的词元序列source, target = [], []# 将每一行及其索引打包成元组 (i, line)for i, line in enumerate(text.split('\n')):# 如果指定了num_examples且当前行索引i大于num_examples,则结束循环if num_examples and i > num_examples:break# 按制表符分割行parts = line.split('\t')# 如果行中包含了两个部分if len(parts) == 2:# 将英语部分按空格分割为词元,并添加到source列表source.append(parts[0].split(' ')) # 英语# 将法语部分按空格分割为词元,并添加到target列表target.append(parts[1].split(' ')) # 法语return source, target# 序列样本都有一个固定长度截断或填充文本序列
def truncate_pad(line, num_steps, padding_token):"""截断或填充文本序列"""# 如果文本序列长度超过了指定的长度if len(line) > num_steps:# 截断文本序列,取前num_steps个词元return line[:num_steps]# 填充文本序列,添加padding_token直到长度达到num_stepsreturn line + [padding_token] * (num_steps - len(line))# 调用函数读取数据集
raw_text = read_data_nmt()
# 调用预处理函数处理原始文本
text = preprocess_nmt(raw_text)# 调用函数词元化文本
source, target = tokenize_nmt(text)
# 创建源语言的词汇表对象
src_vocab = d2l.Vocab(source, min_freq=2,reserved_tokens=['<pad>', '<bos>', '<eos>']) # pad表示句子的填充,bos 表示句子开始,eos表示句子结束,min_freq=2表示句子长度小于2个就不要了
# 对源语言的第一个文本序列进行截断或填充
print(truncate_pad(src_vocab[source[0]], 10, src_vocab['<pad>']))
转换成小批量数据集用于训练
def build_array_nmt(lines, vocab, num_steps):"""将机器翻译的文本序列转换成小批量"""# 遍历lines中的每个句子(每个句子是一个词元列表),并将每个词元通过vocab字典转换成对应的索引值,从而得到一个由索引列表组成的列表。lines = [vocab[l] for l in lines]print(lines)print('<eos>')# 每个句子后面加一个截止符'<eos>'lines = [l + [vocab['<eos>']] for l in lines]# 构建小批量数据集的张量表示,将索引列表转换成为PyTorch张量arrayarray = torch.tensor([truncate_pad(l, num_steps, vocab['<pad>']) for l in lines])# sum(1)沿着第一个维度(即每个句子的长度方向)求和,得到每个句子的实际长度valid_len = (array != vocab['<pad>']).type(torch.int32).sum(1)# 返回小批量数据集的张量表示和实际长度return array, valid_len # valid_len 为原始句子的实际长度v
示例:

# 使用列表推导式更新 lines
lines = [[vocab[l] for l in sentence] for sentence in lines]print(lines) # 输出: [[1, 2], [3, 4, 5]]

训练模型
def load_data_nmt(batch_size, num_steps, num_examples=600):"""返回翻译数据集的迭代器和词汇表"""# 预处理原始数据集text = preprocess_nmt(read_data_nmt())# 对预处理后的文本进行词元化source, target = tokenize_nmt(text, num_examples)# 创建源语言词汇表对象src_vocab = d2l.Vocab(source, min_freq=2,reserved_tokens=['<pad>', '<bos>', '<eos>'])# 创建目标语言词汇表对象tgt_vocab = d2l.Vocab(target, min_freq=2,reserved_tokens=['<pad>', '<bos>', '<eos>'])# 将源语言文本序列转换为小批量数据集的张量表示和实际长度src_array, src_valid_len = build_array_nmt(source, src_vocab, num_steps)# 将目标语言文本序列转换为小批量数据集的张量表示和实际长度tgt_array, tgt_valid_len = build_array_nmt(target, tgt_vocab, num_steps)# 构建数据集的张量表示和实际长度的元组data_arrays = (src_array, src_valid_len, tgt_array, tgt_valid_len)# 加载数据集并创建迭代器data_iter = d2l.load_array(data_arrays, batch_size)# 返回数据迭代器和源语言、目标语言的词汇表对象return data_iter, src_vocab, tgt_vocab




总代码
import os
import torch
from d2l import torch as d2l# 下载和预处理数据集
# 将数据集的下载链接和校验码与'fra-eng'标识关联起来
d2l.DATA_HUB['fra-eng'] = (d2l.DATA_URL + 'fra-eng.zip','94646ad1522d915e7b0f9296181140edcf86a4f5')def read_data_nmt():"""载入 “英语-法语” 数据集 """# 下载并解压数据集data_dir = d2l.download_extract('fra-eng')# 读取数据并返回with open(os.path.join(data_dir, 'fra.txt'), 'r', encoding='utf-8') as f:return f.read()# 几个预处理步骤
def preprocess_nmt(text):"""预处理 “英语-法语” 数据集"""# 判断字符是否是特定标点符号并且前一个字符不是空格def no_space(char, prev_char):return char in set(',.!?') and prev_char != ' '# 替换特殊字符为空格,转换为小写text = text.replace('\u202f', ' ').replace('\xa0', ' ').lower()out = [# 对于每个字符,如果它的索引大于0(即不是第一个字符),并且满足 no_space 函数的条件,则在该字符前添加一个空格,否则,直接使用该字符。' ' + char if i > 0 and no_space(char, text[i - 1]) else char# (enumerate 函数将字符串 text 中的每个字符及其索引打包成元组i为下标、char为字符)for i, char in enumerate(text)]return ''.join(out) # 将处理后的字符列表转换为字符串# 指定处理的示例数量。如果为 None,则处理所有行。
def tokenize_nmt(text, num_examples=None):"""词元化 “英语-法语” 数据数据集 """# 存储英语和法语的词元序列source, target = [], []# 将每一行及其索引打包成元组 (i, line)for i, line in enumerate(text.split('\n')):# 如果指定了num_examples且当前行索引i大于num_examples,则结束循环if num_examples and i > num_examples:break# 按制表符分割行parts = line.split('\t')# 如果行中包含了两个部分if len(parts) == 2:# 将英语部分按空格分割为词元,并添加到source列表source.append(parts[0].split(' ')) # 英语# 将法语部分按空格分割为词元,并添加到target列表target.append(parts[1].split(' ')) # 法语return source, target# 序列样本都有一个固定长度截断或填充文本序列
def truncate_pad(line, num_steps, padding_token):"""截断或填充文本序列"""# 如果文本序列长度超过了指定的长度if len(line) > num_steps:# 截断文本序列,取前num_steps个词元return line[:num_steps]# 填充文本序列,添加padding_token直到长度达到num_stepsreturn line + [padding_token] * (num_steps - len(line))# 转换成小批量数据集用于训练
def build_array_nmt(lines, vocab, num_steps):"""将机器翻译的文本序列转换成小批量"""# 遍历lines中的每个句子(每个句子是一个词元列表),并将每个词元通过vocab字典转换成对应的索引值,从而得到一个由索引列表组成的列表。lines = [vocab[l] for l in lines]# 每个句子后面加一个截止符'<eos>'lines = [l + [vocab['<eos>']] for l in lines]# 构建小批量数据集的张量表示,将索引列表转换成为PyTorch张量arrayarray = torch.tensor([truncate_pad(l, num_steps, vocab['<pad>']) for l in lines])# sum(1)沿着第一个维度(即每个句子的长度方向)求和,得到每个句子的实际长度valid_len = (array != vocab['<pad>']).type(torch.int32).sum(1)# 返回小批量数据集的张量表示和实际长度return array, valid_len # valid_len 为原始句子的实际长度# 训练模型
def load_data_nmt(batch_size, num_steps, num_examples=600):"""返回翻译数据集的迭代器和词汇表"""# 预处理原始数据集text = preprocess_nmt(read_data_nmt())# 对预处理后的文本进行词元化source, target = tokenize_nmt(text, num_examples)# 创建源语言词汇表对象src_vocab = d2l.Vocab(source, min_freq=2,reserved_tokens=['<pad>', '<bos>', '<eos>'])# 创建目标语言词汇表对象tgt_vocab = d2l.Vocab(target, min_freq=2,reserved_tokens=['<pad>', '<bos>', '<eos>'])# 将源语言文本序列转换为小批量数据集的张量表示和实际长度src_array, src_valid_len = build_array_nmt(source, src_vocab, num_steps)# 将目标语言文本序列转换为小批量数据集的张量表示和实际长度tgt_array, tgt_valid_len = build_array_nmt(target, tgt_vocab, num_steps)# 构建数据集的张量表示和实际长度的元组data_arrays = (src_array, src_valid_len, tgt_array, tgt_valid_len)# 加载数据集并创建迭代器data_iter = d2l.load_array(data_arrays, batch_size)# 返回数据迭代器和源语言、目标语言的词汇表对象return data_iter, src_vocab, tgt_vocab# 读出 “英语-法语” 数据集中第一个小批量数据
# 加载翻译数据集的迭代器和词汇表,设置每个小批量的大小和序列长度
train_iter, src_vocab, tgt_vocab = load_data_nmt(batch_size=2, num_steps=8)
# 遍历数据迭代器,获取每个小批量的数据和有效长度
# X是英语、Y是法语
for X, X_valid_len, Y, Y_valid_len in train_iter:# 打印源语言序列的张量表示(整数类型)print('X:', X.type(torch.int32))# 打印源语言序列的有效长度print('valid lengths for X:', X_valid_len)# 打印目标语言序列的张量表示(整数类型)print('Y:', Y.type(torch.int32))# 打印目标语言序列的有效长度print('valid lengths for Y:', Y_valid_len)# 跳出循环,只打印第一个小批量数据break

相关文章:
深度学习-----------------机器翻译与数据集
目录 机器翻译与数据集下载和预处理数据集预处理步骤词元化词汇表该部分总代码 固定长度阶段或填充该部分总代码 转换成小批量数据集用于训练训练模型总代码 机器翻译与数据集 import os import torch from d2l import torch as d2l下载和预处理数据集 #save d2l.DATA_HUB[fr…...
SOMEIP_ETS_151: SD_Send_triggerEventUINT8Reliable_Eventgroup_2
测试目的: 验证DUT在Tester订阅事件组后,能够响应Tester触发的triggerEventUINT8Reliable方法,并将TestEventUINT8Reliable事件发送到订阅请求中端点选项指定的IP地址和端口。 描述 本测试用例旨在确保DUT能够正确处理事件组的订阅请求&am…...
32 C 语言指针的长度与运算(指针加减整数、指针自增自减、同类型指针相减、指针的比较运算)
目录 1 指针的长度 2 指针与整数的加减运算 3 指针自增与自减 4 同类型指针相减 5 指针的比较运算 6 测试题 1 指针的长度 在 C 语言中,sizeof 运算符可以用来计算指针的长度。指针的长度实际上与指针所指向的数据类型无关,而是与系统的位数&…...
【系统架构设计师】经典论文:轮软件三层架构设计
更多内容请见: 备考系统架构设计师-核心总结目录 文章目录 摘要正文总结摘要 本人于 2022 年 1 月参与了中石化 XX 油田 XX 采油厂“用电管理系统”的项目建设,该系统建设目标是实现分单位、分线路、分系统评价、优化、考核,全面提升采油厂用 电管理水平。在该项目组中我担…...
(C语言贪吃蛇)13.实现贪吃蛇四方向的移动
目录 前言 原代码预览 解决方法⚠️ 运行效果 总结 前言 我们上节通过Linux线程实现了两个while(1)同时运行,这样就可以一边控制方向一遍刷新出贪吃蛇的身体节点了。本节我们就来实现贪吃蛇四方向的移动。 (此图片为最终效果) 原代码预览 我们之前的代码是通过…...
Spring Boot + MyBatis 项目中常用注解详解(万字长篇解读)
Spring Boot MyBatis 项目中常用注解详解 在现代Java开发中,Spring Boot和MyBatis是两大热门框架,广泛应用于构建高效、可维护的企业级应用。两者结合使用,可以充分发挥各自的优势,提高开发效率和代码质量。在这个过程中&#x…...
AWS Network Firewall -NAT网关配置只应许白名单域名出入站
1. 创建防火墙 选择防火墙的归属子网(选择公有子网) 2. 创建规则白名单域名放行 3. 绑定相关规则 继续往下拉 绑定非托管规则 4. 配置网络路由 相关规则 参考图 解释 防火墙的归属公有子网路由表规则机器实例的规则子网路由表规则nat网管路…...
【C语言系统编程】【第二部分:并发编程】2.3 实践与案例分析
2.3 实践与案例分析 2.3.1 案例分析:多线程文件搜索程序 本文中,我们将通过一个多线程文件搜索程序的案例,展示如何在实际项目中应用多线程编程技术,并具体介绍任务分解、线程创建、结果汇总及锁机制的应用。 2.3.1.1 任务分解…...
React -AppVarContext.Provider 提供者组件
AppVarContext.Provider 是一个 React 上下文提供者,通常用于在组件树中提供共享的状态或数据。下面将详细解释 AppVarContext.Provider 的作用和如何使用它。展示如何使用 AppVarContext.Provider 来管理全局状态 1. 什么是上下文(Context)…...
【Python】解密用户代理:使用 Python User Agents 库探索浏览器和设备信息
Python User Agents 是一个专为解析 User Agent 字符串而设计的 Python 库。它能够轻松识别访问设备的类型(如移动设备、桌面设备或平板),并获取设备、浏览器、操作系统等详细信息。借助它,开发者可以更好地了解访问用户的设备属性…...
以串口接口为例介绍关于BSP底层架构开发的迭代过程
以串口接口为例介绍关于BSP底层架构开发的迭代过程 文章目录 以串口接口为例介绍关于BSP底层架构开发的迭代过程架构概述初代BSP二代BSP:三代BSP:四代BSP:架构概述 单片机开发有四个阶段: 阶段一:单一单片机的功能实现阶段 此阶段你开始熟悉STM32F1系列的单片机,并利用…...
Label-Studio ML利用yolov8模型实现自动标注
引言 Label Studio ML 后端是一个 SDK,用于包装您的机器学习代码并将其转换为 Web 服务器。Web 服务器可以连接到正在运行的 Label Studio 实例,以自动执行标记任务。我们提供了一个示例模型库,您可以在自己的工作流程中使用这些模型&#x…...
【PostgreSQL】实战篇——用户管理、角色和权限控制的高级用法及技巧
数据库中用户管理、角色和权限控制不仅仅是基础的安全措施,更是实现复杂应用需求和优化数据库性能的重要手段。 通过深入理解这些概念,数据库管理员可以更有效地管理用户访问、确保数据安全,并优化系统性能。以下是对这些概念的详细介绍以及…...
Leetcode: 0011-0020题速览
Leetcode: 0011-0020题速览 本文材料来自于LeetCode solutions in any programming language | 多种编程语言实现 LeetCode、《剑指 Offer(第 2 版)》、《程序员面试金典(第 6 版)》题解 遵从开源协议为知识共享 版权归属-相同方式…...
Hive数仓操作(七)
一、 Hive动态分区表 1. 动态分区与静态分区的区别 分区定义: 静态分区:在插入数据时,需要手动指定分区字段的值。动态分区:分区字段的值是根据数据中的某个字段自动生成的,用户只需指定分区字段的类型。 数据加载方…...
Redis进阶篇 - 缓存穿透、缓存击穿、缓存雪崩问题及其解决方案
文章目录 1 文章概述2 缓存穿透2.1 什么是缓存穿透?2.2 缓存穿透的解决方法2.2.1 做好参数校验2.2.2 缓存无效Key2.2.3 使用布隆过滤器2.2.4 接口限流 3 缓存击穿3.1 什么是缓存击穿?3.2 缓存击穿的解决方法3.2.1 调整热点数据过期时间3.2.2 热点数据预热…...
一天认识一个硬件之电源
无论是台式机还是笔记本,都离不开电源,台式机和笔记本电脑的电源都承担着将交流电转换为直流电,并为电脑内部各个部件提供稳定电力供应的重要任务。今天就来分享一下台式机和笔记本的电源区别 设计和功率 台式机电源:设计为内置…...
关于BSV区块链覆盖网络的常见问题解答(上篇)
发表时间:2024年9月20日 在BSV区块链上的覆盖网络服务为寻求可扩展、安全、高效交易处理解决方案的开发者和企业家开辟了新的视野。 作为开创性的曼达拉升级的一部分,覆盖网络服务提供了一个强大的框架,用于管理特定类型的交易和数据访问…...
VUE 开发——Node.js学习(一)
一、认识Node.js Node.js是一个跨平台JavaScript运行环境,使开发者可以搭建服务器端的JavaScript应用程序 使用Node.js编写服务器端程序——编写数据接口、前端工程化; Node.js环境没有BOM和DOM; Node.js安装:下载node-v16.19…...
角膜移植难题现,传统方式缺陷显,创新水凝胶破局
大家好!今天来了解一篇天然聚合物衍生光固化生物粘附水凝胶研究——《Natural polymer-derived photocurable bioadhesive hydrogels for sutureless keratoplasty》发表于《Bioactive Materials》。本文介绍了一种用于无缝合角膜移植术的天然聚合物衍生光固化生物粘…...
生成xcframework
打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式,可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...
基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真
目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销,平衡网络负载,延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…...
前端倒计时误差!
提示:记录工作中遇到的需求及解决办法 文章目录 前言一、误差从何而来?二、五大解决方案1. 动态校准法(基础版)2. Web Worker 计时3. 服务器时间同步4. Performance API 高精度计时5. 页面可见性API优化三、生产环境最佳实践四、终极解决方案架构前言 前几天听说公司某个项…...
如何在看板中体现优先级变化
在看板中有效体现优先级变化的关键措施包括:采用颜色或标签标识优先级、设置任务排序规则、使用独立的优先级列或泳道、结合自动化规则同步优先级变化、建立定期的优先级审查流程。其中,设置任务排序规则尤其重要,因为它让看板视觉上直观地体…...
服务器硬防的应用场景都有哪些?
服务器硬防是指一种通过硬件设备层面的安全措施来防御服务器系统受到网络攻击的方式,避免服务器受到各种恶意攻击和网络威胁,那么,服务器硬防通常都会应用在哪些场景当中呢? 硬防服务器中一般会配备入侵检测系统和预防系统&#x…...
cf2117E
原题链接:https://codeforces.com/contest/2117/problem/E 题目背景: 给定两个数组a,b,可以执行多次以下操作:选择 i (1 < i < n - 1),并设置 或,也可以在执行上述操作前执行一次删除任意 和 。求…...
Frozen-Flask :将 Flask 应用“冻结”为静态文件
Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是:将一个 Flask Web 应用生成成纯静态 HTML 文件,从而可以部署到静态网站托管服务上,如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...
镜像里切换为普通用户
如果你登录远程虚拟机默认就是 root 用户,但你不希望用 root 权限运行 ns-3(这是对的,ns3 工具会拒绝 root),你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案:创建非 roo…...
Mac软件卸载指南,简单易懂!
刚和Adobe分手,它却总在Library里给你写"回忆录"?卸载的Final Cut Pro像电子幽灵般阴魂不散?总是会有残留文件,别慌!这份Mac软件卸载指南,将用最硬核的方式教你"数字分手术"࿰…...
Cloudflare 从 Nginx 到 Pingora:性能、效率与安全的全面升级
在互联网的快速发展中,高性能、高效率和高安全性的网络服务成为了各大互联网基础设施提供商的核心追求。Cloudflare 作为全球领先的互联网安全和基础设施公司,近期做出了一个重大技术决策:弃用长期使用的 Nginx,转而采用其内部开发…...
