当前位置: 首页 > news >正文

深度学习-----------------机器翻译与数据集

目录

  • 机器翻译与数据集
    • 下载和预处理数据集
    • 预处理步骤
    • 词元化
    • 词汇表
      • 该部分总代码
    • 固定长度阶段或填充
      • 该部分总代码
    • 转换成小批量数据集用于训练
    • 训练模型
    • 总代码

机器翻译与数据集

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

测试目的&#xff1a; 验证DUT在Tester订阅事件组后&#xff0c;能够响应Tester触发的triggerEventUINT8Reliable方法&#xff0c;并将TestEventUINT8Reliable事件发送到订阅请求中端点选项指定的IP地址和端口。 描述 本测试用例旨在确保DUT能够正确处理事件组的订阅请求&am…...

32 C 语言指针的长度与运算(指针加减整数、指针自增自减、同类型指针相减、指针的比较运算)

目录 1 指针的长度 2 指针与整数的加减运算 3 指针自增与自减 4 同类型指针相减 5 指针的比较运算 6 测试题 1 指针的长度 在 C 语言中&#xff0c;sizeof 运算符可以用来计算指针的长度。指针的长度实际上与指针所指向的数据类型无关&#xff0c;而是与系统的位数&…...

【系统架构设计师】经典论文:轮软件三层架构设计

更多内容请见: 备考系统架构设计师-核心总结目录 文章目录 摘要正文总结摘要 本人于 2022 年 1 月参与了中石化 XX 油田 XX 采油厂“用电管理系统”的项目建设,该系统建设目标是实现分单位、分线路、分系统评价、优化、考核,全面提升采油厂用 电管理水平。在该项目组中我担…...

(C语言贪吃蛇)13.实现贪吃蛇四方向的移动

目录 前言 原代码预览 解决方法⚠️ 运行效果 总结 前言 我们上节通过Linux线程实现了两个while(1)同时运行&#xff0c;这样就可以一边控制方向一遍刷新出贪吃蛇的身体节点了。本节我们就来实现贪吃蛇四方向的移动。 (此图片为最终效果) 原代码预览 我们之前的代码是通过…...

Spring Boot + MyBatis 项目中常用注解详解(万字长篇解读)

Spring Boot MyBatis 项目中常用注解详解 在现代Java开发中&#xff0c;Spring Boot和MyBatis是两大热门框架&#xff0c;广泛应用于构建高效、可维护的企业级应用。两者结合使用&#xff0c;可以充分发挥各自的优势&#xff0c;提高开发效率和代码质量。在这个过程中&#x…...

AWS Network Firewall -NAT网关配置只应许白名单域名出入站

1. 创建防火墙 选择防火墙的归属子网&#xff08;选择公有子网&#xff09; 2. 创建规则白名单域名放行 3. 绑定相关规则 继续往下拉 绑定非托管规则 4. 配置网络路由 相关规则 参考图 解释 防火墙的归属公有子网路由表规则机器实例的规则子网路由表规则nat网管路…...

【C语言系统编程】【第二部分:并发编程】2.3 实践与案例分析

2.3 实践与案例分析 2.3.1 案例分析&#xff1a;多线程文件搜索程序 本文中&#xff0c;我们将通过一个多线程文件搜索程序的案例&#xff0c;展示如何在实际项目中应用多线程编程技术&#xff0c;并具体介绍任务分解、线程创建、结果汇总及锁机制的应用。 2.3.1.1 任务分解…...

React -AppVarContext.Provider 提供者组件

AppVarContext.Provider 是一个 React 上下文提供者&#xff0c;通常用于在组件树中提供共享的状态或数据。下面将详细解释 AppVarContext.Provider 的作用和如何使用它。展示如何使用 AppVarContext.Provider 来管理全局状态 1. 什么是上下文&#xff08;Context&#xff09;…...

【Python】解密用户代理:使用 Python User Agents 库探索浏览器和设备信息

Python User Agents 是一个专为解析 User Agent 字符串而设计的 Python 库。它能够轻松识别访问设备的类型&#xff08;如移动设备、桌面设备或平板&#xff09;&#xff0c;并获取设备、浏览器、操作系统等详细信息。借助它&#xff0c;开发者可以更好地了解访问用户的设备属性…...

以串口接口为例介绍关于BSP底层架构开发的迭代过程

以串口接口为例介绍关于BSP底层架构开发的迭代过程 文章目录 以串口接口为例介绍关于BSP底层架构开发的迭代过程架构概述初代BSP二代BSP:三代BSP:四代BSP:架构概述 单片机开发有四个阶段: 阶段一:单一单片机的功能实现阶段 此阶段你开始熟悉STM32F1系列的单片机,并利用…...

Label-Studio ML利用yolov8模型实现自动标注

引言 Label Studio ML 后端是一个 SDK&#xff0c;用于包装您的机器学习代码并将其转换为 Web 服务器。Web 服务器可以连接到正在运行的 Label Studio 实例&#xff0c;以自动执行标记任务。我们提供了一个示例模型库&#xff0c;您可以在自己的工作流程中使用这些模型&#x…...

【PostgreSQL】实战篇——用户管理、角色和权限控制的高级用法及技巧

数据库中用户管理、角色和权限控制不仅仅是基础的安全措施&#xff0c;更是实现复杂应用需求和优化数据库性能的重要手段。 通过深入理解这些概念&#xff0c;数据库管理员可以更有效地管理用户访问、确保数据安全&#xff0c;并优化系统性能。以下是对这些概念的详细介绍以及…...

Leetcode: 0011-0020题速览

Leetcode: 0011-0020题速览 本文材料来自于LeetCode solutions in any programming language | 多种编程语言实现 LeetCode、《剑指 Offer&#xff08;第 2 版&#xff09;》、《程序员面试金典&#xff08;第 6 版&#xff09;》题解 遵从开源协议为知识共享 版权归属-相同方式…...

Hive数仓操作(七)

一、 Hive动态分区表 1. 动态分区与静态分区的区别 分区定义&#xff1a; 静态分区&#xff1a;在插入数据时&#xff0c;需要手动指定分区字段的值。动态分区&#xff1a;分区字段的值是根据数据中的某个字段自动生成的&#xff0c;用户只需指定分区字段的类型。 数据加载方…...

Redis进阶篇 - 缓存穿透、缓存击穿、缓存雪崩问题及其解决方案

文章目录 1 文章概述2 缓存穿透2.1 什么是缓存穿透&#xff1f;2.2 缓存穿透的解决方法2.2.1 做好参数校验2.2.2 缓存无效Key2.2.3 使用布隆过滤器2.2.4 接口限流 3 缓存击穿3.1 什么是缓存击穿&#xff1f;3.2 缓存击穿的解决方法3.2.1 调整热点数据过期时间3.2.2 热点数据预热…...

一天认识一个硬件之电源

无论是台式机还是笔记本&#xff0c;都离不开电源&#xff0c;台式机和笔记本电脑的电源都承担着将交流电转换为直流电&#xff0c;并为电脑内部各个部件提供稳定电力供应的重要任务。今天就来分享一下台式机和笔记本的电源区别 设计和功率 台式机电源&#xff1a;设计为内置…...

关于BSV区块链覆盖网络的常见问题解答(上篇)

​​发表时间&#xff1a;2024年9月20日 在BSV区块链上的覆盖网络服务为寻求可扩展、安全、高效交易处理解决方案的开发者和企业家开辟了新的视野。 作为开创性的曼达拉升级的一部分&#xff0c;覆盖网络服务提供了一个强大的框架&#xff0c;用于管理特定类型的交易和数据访问…...

VUE 开发——Node.js学习(一)

一、认识Node.js Node.js是一个跨平台JavaScript运行环境&#xff0c;使开发者可以搭建服务器端的JavaScript应用程序 使用Node.js编写服务器端程序——编写数据接口、前端工程化&#xff1b; Node.js环境没有BOM和DOM&#xff1b; Node.js安装&#xff1a;下载node-v16.19…...

角膜移植难题现,传统方式缺陷显,创新水凝胶破局

大家好&#xff01;今天来了解一篇天然聚合物衍生光固化生物粘附水凝胶研究——《Natural polymer-derived photocurable bioadhesive hydrogels for sutureless keratoplasty》发表于《Bioactive Materials》。本文介绍了一种用于无缝合角膜移植术的天然聚合物衍生光固化生物粘…...

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…...

MongoDB学习和应用(高效的非关系型数据库)

一丶 MongoDB简介 对于社交类软件的功能&#xff0c;我们需要对它的功能特点进行分析&#xff1a; 数据量会随着用户数增大而增大读多写少价值较低非好友看不到其动态信息地理位置的查询… 针对以上特点进行分析各大存储工具&#xff1a; mysql&#xff1a;关系型数据库&am…...

Frozen-Flask :将 Flask 应用“冻结”为静态文件

Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是&#xff1a;将一个 Flask Web 应用生成成纯静态 HTML 文件&#xff0c;从而可以部署到静态网站托管服务上&#xff0c;如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...

数据库分批入库

今天在工作中&#xff0c;遇到一个问题&#xff0c;就是分批查询的时候&#xff0c;由于批次过大导致出现了一些问题&#xff0c;一下是问题描述和解决方案&#xff1a; 示例&#xff1a; // 假设已有数据列表 dataList 和 PreparedStatement pstmt int batchSize 1000; // …...

多模态大语言模型arxiv论文略读(108)

CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文标题&#xff1a;CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文作者&#xff1a;Sayna Ebrahimi, Sercan O. Arik, Tejas Nama, Tomas Pfister ➡️ 研究机构: Google Cloud AI Re…...

加密通信 + 行为分析:运营商行业安全防御体系重构

在数字经济蓬勃发展的时代&#xff0c;运营商作为信息通信网络的核心枢纽&#xff0c;承载着海量用户数据与关键业务传输&#xff0c;其安全防御体系的可靠性直接关乎国家安全、社会稳定与企业发展。随着网络攻击手段的不断升级&#xff0c;传统安全防护体系逐渐暴露出局限性&a…...

基于stm32F10x 系列微控制器的智能电子琴(附完整项目源码、详细接线及讲解视频)

注&#xff1a;文章末尾网盘链接中自取成品使用演示视频、项目源码、项目文档 所用硬件&#xff1a;STM32F103C8T6、无源蜂鸣器、44矩阵键盘、flash存储模块、OLED显示屏、RGB三色灯、面包板、杜邦线、usb转ttl串口 stm32f103c8t6 面包板 …...

stm32进入Infinite_Loop原因(因为有系统中断函数未自定义实现)

这是系统中断服务程序的默认处理汇编函数&#xff0c;如果我们没有定义实现某个中断函数&#xff0c;那么当stm32产生了该中断时&#xff0c;就会默认跑这里来了&#xff0c;所以我们打开了什么中断&#xff0c;一定要记得实现对应的系统中断函数&#xff0c;否则会进来一直循环…...

ZYNQ学习记录FPGA(二)Verilog语言

一、Verilog简介 1.1 HDL&#xff08;Hardware Description language&#xff09; 在解释HDL之前&#xff0c;先来了解一下数字系统设计的流程&#xff1a;逻辑设计 -> 电路实现 -> 系统验证。 逻辑设计又称前端&#xff0c;在这个过程中就需要用到HDL&#xff0c;正文…...

【Qt】控件 QWidget

控件 QWidget 一. 控件概述二. QWidget 的核心属性可用状态&#xff1a;enabled几何&#xff1a;geometrywindows frame 窗口框架的影响 窗口标题&#xff1a;windowTitle窗口图标&#xff1a;windowIconqrc 机制 窗口不透明度&#xff1a;windowOpacity光标&#xff1a;cursor…...