【万字详文介绍】:迭代扩张卷积神经网络(IDCNN)

💗💗💗欢迎来到我的博客,你将找到有关如何使用技术解决问题的文章,也会找到某个技术的学习路线。无论你是何种职业,我都希望我的博客对你有所帮助。最后不要忘记订阅我的博客以获取最新文章,也欢迎在文章下方留下你的评论和反馈。我期待着与你分享知识、互相学习和建立一个积极的社区。谢谢你的光临,让我们一起踏上这个知识之旅!
请添加图片描述

文章目录

  • 🍀引言
  • 🍀IDCNN概述
    • 🍀特点与优势
    • 🍀网络结构
  • 🍀实践IDCNN
    • 🍀环境准备
    • 🍀数据集选择
    • 🍀加载和预处理数据
    • 🍀准备训练和测试数据
    • 🍀 定义 IDCNN 模型
    • 🍀模型训练
    • 🍀模型评估
  • 🍀完整的模型代码(示例跑着玩)
  • 🍀完整的模型代码(CoNLL-2003数据集)
  • 🍀完整的模型代码(CoNLL-2003数据集)(CNN版)
  • 🍀对比实验(CoNLL-2003数据集)
  • 🍀结论
  • 🍀参考文献

🍀引言

在深度学习的快速发展中,卷积神经网络(CNN)在图像处理领域表现卓越。然而,处理序列数据(如语音或文本)时,IDCNN(空洞卷积网络)作为一种新兴的模型,展现出优越的性能。本博客将介绍IDCNN的基本概念及其应用实践,帮助您理解并实践这一高效的模型。


🍀IDCNN概述

IDCNN,即空洞卷积网络(Iterated Dilated Convolutional Neural Network),是一种结合了深度卷积层和序列数据处理的新型模型。传统的RNN模型在处理长序列数据时易受梯度消失和梯度爆炸的影响,导致计算效率低下。而IDCNN通过空洞卷积的结构设计,能够在保持高效计算的同时,捕捉到序列中的长距离依赖特性,非常适合用于自然语言处理和序列数据分析等任务。

🍀特点与优势

IDCNN的独特之处在于其网络结构设计,主要体现在以下几个方面:

长距离依赖性:IDCNN利用空洞卷积能够在不增加计算量的情况下扩展感受野,有效捕捉序列数据中的长距离依赖。
高效性:相较于传统的RNN模型,IDCNN在计算上更为高效。它避免了循环结构带来的顺序依赖问题,因此可以实现并行计算。
灵活性:IDCNN支持增量学习,可在数据逐步增多的情况下动态更新模型结构和参数,适应更多样化的应用场景。## 🍀网络结构

  • 长距离依赖性:IDCNN能够有效捕捉序列数据中的长距离依赖。
  • 高效性:与传统的RNN相比,IDCNN在计算上更为高效,适合并行处理。
  • 灵活性:支持增量学习,可以动态更新模型。

🍀网络结构

IDCNN的网络结构通常由多个卷积层和激活函数组成。这些卷积层采用空洞卷积的形式,通过逐层堆叠和扩展感受野的方式,捕捉输入数据中的时序特征。同时,IDCNN可以灵活地与其他网络模块(如CRF层)结合,以实现更精细的序列标注任务。

🍀实践IDCNN

🍀环境准备

在开始构建IDCNN模型前,首先需要配置必要的深度学习环境。常用的Python库包括:

  • PyTorch:用于构建深度学习模型。
  • scikit-learn:提供数据处理和评估的基本工具。
  • NumPy:用于数据处理和矩阵运算。
  • 确保以上库的安装,可以使用以下命令:
pip install torch scikit-learn numpy

🍀数据集选择

IDCNN可以应用于多种序列数据任务中,如文本序列标注、语音识别等。在本文中,我们以自然语言处理中的命名实体识别(NER)任务为例,选择经典的CoNLL-2003数据集。该数据集包含英语句子的序列标注,标签包括人物、地点、组织等实体类型。

🍀加载和预处理数据

加载数据集

dataset = load_dataset("conll2003", trust_remote_code=True)

这里我们加载了 CoNLL-2003 数据集,它是一个常用于命名实体识别(NER)任务的数据集。trust_remote_code=True 参数允许 datasets 库执行远程代码,这在加载该数据集时是必须的。


标签编码

label_encoder = LabelEncoder()
label_encoder.fit([label for labels in dataset['train']['ner_tags'] for label in labels])
num_labels = len(label_encoder.classes_)

这里使用 scikit-learn 中的 LabelEncoder 将 NER 标签(即标注)转换为整数 ID,称为标签编码。num_labels 表示标签的种类数,用于定义模型的输出维度。

构建词汇表

word_to_index = {"<PAD>": 0}
for tokens in dataset["train"]["tokens"]:
    for token in tokens:
        if token not in word_to_index:
            word_to_index[token] = len(word_to_index)

我们通过 word_to_index 字典为每个唯一单词分配一个整数 ID。特殊标记 “” 用于填充短句子,它的 ID 为 0。这个词汇表帮助我们将单词转换为整数索引。

数据预处理函数

def preprocess_data(split):
    sentences = []
    labels = []
    max_len = 50  # 假设每个句子都填充或截断到长度为50

    for item in dataset[split]:
        tokens = item['tokens']
        ner_tags = item['ner_tags']

        token_ids = [word_to_index.get(token, 0) for token in tokens]
        label_ids = label_encoder.transform(ner_tags)

        if len(token_ids) > max_len:
            token_ids = token_ids[:max_len]
            label_ids = label_ids[:max_len]
        else:
            token_ids = token_ids + [0] * (max_len - len(token_ids))
            label_ids = list(label_ids) + [0] * (max_len - len(label_ids))

        sentences.append(token_ids)
        labels.append(label_ids)

    return torch.tensor(sentences), torch.tensor(labels)

preprocess_data 函数的主要功能是:

  • 使用 word_to_index 将单词转换为整数 ID。
  • 使用 label_encoder 将标签转换为整数 ID。
  • 将每个句子填充或截断至固定长度 max_len(这里假设为 50),确保输入尺寸一致。

🍀准备训练和测试数据

X_train, y_train = preprocess_data("train")
X_test, y_test = preprocess_data("test")

train_dataset = TensorDataset(X_train, y_train)
test_dataset = TensorDataset(X_test, y_test)

train_loader = DataLoader(train_dataset, batch_size=16, shuffle=True)
test_loader = DataLoader(test_dataset, batch_size=16)

我们对训练和测试集分别进行了预处理,并创建了 TensorDataset 对象。然后用 DataLoader 包装这些数据集,以便在训练过程中能够方便地进行批量处理和随机打乱。

🍀 定义 IDCNN 模型

class IDCNN(nn.Module):
    def __init__(self, input_dim, hidden_dim, output_dim):
        super(IDCNN, self).__init__()
        self.embedding = nn.Embedding(input_dim, hidden_dim)
        self.conv1 = nn.Conv1d(hidden_dim, hidden_dim, kernel_size=3, dilation=1, padding=1)
        self.conv2 = nn.Conv1d(hidden_dim, hidden_dim, kernel_size=3, dilation=2, padding=2)
        self.conv3 = nn.Conv1d(hidden_dim, hidden_dim, kernel_size=3, dilation=4, padding=4)
        self.fc = nn.Linear(hidden_dim, output_dim)

IDCNN 模型(膨胀卷积网络)定义了一个嵌入层和多个卷积层,其中卷积层使用不同的膨胀率(dilation)来捕捉不同长度的特征。

  • self.embedding:嵌入层,将输入的单词索引映射到一个 hidden_dim 维度的嵌入向量。
  • self.conv1、self.conv2、self.conv3:三层卷积,分别具有不同的膨胀率(1、2 和 4),以捕捉不同的上下文信息。
  • self.fc:全连接层,将卷积层的输出映射到标签空间,输出维度为 output_dim。

前向传播

def forward(self, x):
    x = self.embedding(x)  # (batch_size, sequence_length, hidden_dim)
    x = x.permute(0, 2, 1)  # 转换维度以适应Conv1d
    x = torch.relu(self.conv1(x))
    x = torch.relu(self.conv2(x))
    x = torch.relu(self.conv3(x))
    x = x.permute(0, 2, 1)  # 转换维度以适应全连接层
    x = self.fc(x)
    return x

前向传播过程中:

  • 使用嵌入层将输入转换为嵌入向量。
  • 使用三层膨胀卷积提取特征。
  • 使用全连接层将特征映射到输出空间。

🍀模型训练

for epoch in range(num_epochs):
    model.train()
    total_loss = 0
    for inputs, labels in train_loader:
        optimizer.zero_grad()
        outputs = model(inputs)
        outputs = outputs.view(-1, output_dim)
        labels = labels.view(-1)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()
        total_loss += loss.item()
    print(f"Epoch [{epoch + 1}/{num_epochs}], Loss: {total_loss / len(train_loader):.4f}")

在训练过程中:

  • optimizer.zero_grad() 清除上一步的梯度。
  • outputs 将模型输出调整为 (batch_size * sequence_length, output_dim) 以便于计算损失。
  • oss.backward() 反向传播计算梯度。
  • optimizer.step() 更新模型参数。
  • 每个 epoch 结束后打印平均损失。

🍀模型评估

model.eval()
all_preds = []
all_labels = []

with torch.no_grad():
    for inputs, labels in test_loader:
        outputs = model(inputs)
        outputs = outputs.view(-1, output_dim)
        _, preds = torch.max(outputs, dim=1)
        all_preds.extend(preds.cpu().numpy())
        all_labels.extend(labels.view(-1).cpu().numpy())

在评估阶段,关闭梯度计算以提高效率。我们获取每个输入的预测标签,并将其保存到 all_preds 中,用于后续的评估。

删除填充部分

true_labels = [label for label, pred in zip(all_labels, all_preds) if label != 0]
true_preds = [pred for label, pred in zip(all_labels, all_preds) if label != 0]

由于使用了填充,我们需要将填充的标签去除,仅保留真实标签。

输出分类报告

print(classification_report(true_labels, true_preds, target_names=[str(label) for label in label_encoder.classes_], zero_division=0))

使用 classification_report 打印分类报告,显示每个标签的精确度、召回率和 F1 分数。这些指标帮助我们评估模型的表现。

这样整个代码就完成了。这个流程实现了一个简单的命名实体识别模型,并在 CoNLL-2003 数据集上进行训练和评估,接下来我会将完整的代码放到下面,并在结尾附上使用CNN的评估结果供大家对比参考~

🍀完整的模型代码(示例跑着玩)

下面使用的数据是自定义的数据

import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import DataLoader, TensorDataset
from sklearn.metrics import classification_report
import numpy as np

# 定义IDCNN模型
class IDCNN(nn.Module):
    def __init__(self, input_dim, hidden_dim, output_dim):
        super(IDCNN, self).__init__()
        # 三层空洞卷积,使用不同的dilation值
        self.conv1 = nn.Conv1d(input_dim, hidden_dim, kernel_size=3, dilation=1, padding=1)
        self.conv2 = nn.Conv1d(hidden_dim, hidden_dim, kernel_size=3, dilation=2, padding=2)
        self.conv3 = nn.Conv1d(hidden_dim, hidden_dim, kernel_size=3, dilation=4, padding=4)
        # 全连接层,用于输出最终的类别
        self.fc = nn.Linear(hidden_dim, output_dim)

    def forward(self, x):
        # 输入x的维度为 (batch_size, input_dim, sequence_length)
        x = torch.relu(self.conv1(x))
        x = torch.relu(self.conv2(x))
        x = torch.relu(self.conv3(x))
        # 对卷积输出维度进行平均池化,减少维度
        x = x.mean(dim=2)
        x = self.fc(x)
        return x

# 生成一些假数据,模拟序列标注任务
# 假设输入维度为128,隐藏层维度为256,输出类别数为10
input_dim = 128
hidden_dim = 256
output_dim = 10
sequence_length = 50
batch_size = 16
num_epochs = 10

# 创建随机的数据和标签
X_train = torch.randn(1000, input_dim, sequence_length)  # 1000个样本
y_train = torch.randint(0, output_dim, (1000,))          # 每个样本对应一个标签
X_test = torch.randn(200, input_dim, sequence_length)    # 200个测试样本
y_test = torch.randint(0, output_dim, (200,))            # 每个测试样本对应一个标签

# 创建数据加载器
train_dataset = TensorDataset(X_train, y_train)
train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True)
test_dataset = TensorDataset(X_test, y_test)
test_loader = DataLoader(test_dataset, batch_size=batch_size)

# 初始化模型、损失函数和优化器
model = IDCNN(input_dim=input_dim, hidden_dim=hidden_dim, output_dim=output_dim)
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)

# 训练模型
for epoch in range(num_epochs):
    model.train()
    for inputs, labels in train_loader:
        # 前向传播
        outputs = model(inputs)
        loss = criterion(outputs, labels)

        # 反向传播和优化
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()

    print(f"Epoch [{epoch+1}/{num_epochs}], Loss: {loss.item():.4f}")

# 模型评估
model.eval()
all_preds = []
all_labels = []

with torch.no_grad():
    for inputs, labels in test_loader:
        outputs = model(inputs)
        _, preds = torch.max(outputs, dim=1)
        all_preds.extend(preds.cpu().numpy())
        all_labels.extend(labels.cpu().numpy())

# 输出分类报告
print(classification_report(all_labels, all_preds, target_names=[f"Class {i}" for i in range(output_dim)], zero_division=1))

运行结果如下:
在这里插入图片描述

🍀完整的模型代码(CoNLL-2003数据集)

import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import DataLoader, TensorDataset
from sklearn.metrics import classification_report
from datasets import load_dataset
from sklearn.preprocessing import LabelEncoder
import numpy as np

# 1. 加载并预处理数据

# 加载CoNLL-2003数据集,添加 trust_remote_code=True 参数
dataset = load_dataset("conll2003", trust_remote_code=True)


# 标签编码
label_encoder = LabelEncoder()
label_encoder.fit([label for labels in dataset['train']['ner_tags'] for label in labels])
num_labels = len(label_encoder.classes_)

# 构建词汇表(为了演示简单化,实际应用中建议使用预训练词向量,如GloVe或BERT)
word_to_index = {"<PAD>": 0}
for tokens in dataset["train"]["tokens"]:
    for token in tokens:
        if token not in word_to_index:
            word_to_index[token] = len(word_to_index)


# 数据预处理函数
def preprocess_data(split):
    sentences = []
    labels = []
    max_len = 50  # 假设每个句子都填充或截断到长度为50

    for item in dataset[split]:
        tokens = item['tokens']
        ner_tags = item['ner_tags']

        # 将tokens转换为词ID,labels转换为标签ID
        token_ids = [word_to_index.get(token, 0) for token in tokens]  # 简单示例,使用词ID
        label_ids = label_encoder.transform(ner_tags)

        # 确保 token_ids 和 label_ids 的长度相同
        if len(token_ids) > max_len:
            token_ids = token_ids[:max_len]
            label_ids = label_ids[:max_len]
        else:
            token_ids = token_ids + [0] * (max_len - len(token_ids))
            label_ids = list(label_ids) + [0] * (max_len - len(label_ids))

        sentences.append(token_ids)
        labels.append(label_ids)

    return torch.tensor(sentences), torch.tensor(labels)


# 准备训练和测试数据
X_train, y_train = preprocess_data("train")
X_test, y_test = preprocess_data("test")

train_dataset = TensorDataset(X_train, y_train)
test_dataset = TensorDataset(X_test, y_test)

train_loader = DataLoader(train_dataset, batch_size=16, shuffle=True)
test_loader = DataLoader(test_dataset, batch_size=16)


# 2. 定义IDCNN模型
class IDCNN(nn.Module):
    def __init__(self, input_dim, hidden_dim, output_dim):
        super(IDCNN, self).__init__()
        self.embedding = nn.Embedding(input_dim, hidden_dim)
        self.conv1 = nn.Conv1d(hidden_dim, hidden_dim, kernel_size=3, dilation=1, padding=1)
        self.conv2 = nn.Conv1d(hidden_dim, hidden_dim, kernel_size=3, dilation=2, padding=2)
        self.conv3 = nn.Conv1d(hidden_dim, hidden_dim, kernel_size=3, dilation=4, padding=4)
        self.fc = nn.Linear(hidden_dim, output_dim)

    def forward(self, x):
        x = self.embedding(x)  # (batch_size, sequence_length, hidden_dim)
        x = x.permute(0, 2, 1)  # 转换维度以适应Conv1d
        x = torch.relu(self.conv1(x))
        x = torch.relu(self.conv2(x))
        x = torch.relu(self.conv3(x))
        x = x.permute(0, 2, 1)  # 转换维度以适应全连接层
        x = self.fc(x)
        return x


# 参数设置
input_dim = len(word_to_index)
hidden_dim = 128
output_dim = num_labels
num_epochs = 5

# 初始化模型、损失函数和优化器
model = IDCNN(input_dim=input_dim, hidden_dim=hidden_dim, output_dim=output_dim)
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)

# 3. 训练模型
for epoch in range(num_epochs):
    model.train()
    total_loss = 0
    for inputs, labels in train_loader:
        optimizer.zero_grad()
        outputs = model(inputs)
        outputs = outputs.view(-1, output_dim)
        labels = labels.view(-1)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()
        total_loss += loss.item()
    print(f"Epoch [{epoch + 1}/{num_epochs}], Loss: {total_loss / len(train_loader):.4f}")

# 4. 模型评估
model.eval()
all_preds = []
all_labels = []

with torch.no_grad():
    for inputs, labels in test_loader:
        outputs = model(inputs)
        outputs = outputs.view(-1, output_dim)
        _, preds = torch.max(outputs, dim=1)
        all_preds.extend(preds.cpu().numpy())
        all_labels.extend(labels.view(-1).cpu().numpy())

# 删除填充部分的标签和预测
true_labels = [label for label, pred in zip(all_labels, all_preds) if label != 0]
true_preds = [pred for label, pred in zip(all_labels, all_preds) if label != 0]

# 输出分类报告
print(classification_report(true_labels, true_preds, target_names=[str(label) for label in label_encoder.classes_], zero_division=0))

运行代码如下:

在这里插入图片描述

🍀完整的模型代码(CoNLL-2003数据集)(CNN版)

要将模型从 IDCNN(膨胀卷积神经网络)更改为 普通的CNN,只需去掉膨胀率设置,将卷积层的 dilation 参数设置为 1(即默认值)。普通的CNN可以通过堆叠多个卷积层来实现。

  • 我们将 IDCNN 类改名为 CNN。
  • 在每个卷积层(conv1、conv2 和 conv3)中,去掉了 dilation 参数(默认为1),并保持了 padding=1。这样,每个卷积层会像普通的卷积操作那样,只关注相邻元素。
import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import DataLoader, TensorDataset
from sklearn.metrics import classification_report
from datasets import load_dataset
from sklearn.preprocessing import LabelEncoder
import numpy as np

# 1. 加载并预处理数据

# 加载CoNLL-2003数据集,添加 trust_remote_code=True 参数
dataset = load_dataset("conll2003", trust_remote_code=True)

# 标签编码
label_encoder = LabelEncoder()
label_encoder.fit([label for labels in dataset['train']['ner_tags'] for label in labels])
num_labels = len(label_encoder.classes_)

# 构建词汇表(为了演示简单化,实际应用中建议使用预训练词向量,如GloVe或BERT)
word_to_index = {"<PAD>": 0}
for tokens in dataset["train"]["tokens"]:
    for token in tokens:
        if token not in word_to_index:
            word_to_index[token] = len(word_to_index)

# 数据预处理函数
def preprocess_data(split):
    sentences = []
    labels = []
    max_len = 50  # 假设每个句子都填充或截断到长度为50

    for item in dataset[split]:
        tokens = item['tokens']
        ner_tags = item['ner_tags']

        # 将tokens转换为词ID,labels转换为标签ID
        token_ids = [word_to_index.get(token, 0) for token in tokens]  # 简单示例,使用词ID
        label_ids = label_encoder.transform(ner_tags)

        # 确保 token_ids 和 label_ids 的长度相同
        if len(token_ids) > max_len:
            token_ids = token_ids[:max_len]
            label_ids = label_ids[:max_len]
        else:
            token_ids = token_ids + [0] * (max_len - len(token_ids))
            label_ids = list(label_ids) + [0] * (max_len - len(label_ids))

        sentences.append(token_ids)
        labels.append(label_ids)

    return torch.tensor(sentences), torch.tensor(labels)

# 准备训练和测试数据
X_train, y_train = preprocess_data("train")
X_test, y_test = preprocess_data("test")

train_dataset = TensorDataset(X_train, y_train)
test_dataset = TensorDataset(X_test, y_test)

train_loader = DataLoader(train_dataset, batch_size=16, shuffle=True)
test_loader = DataLoader(test_dataset, batch_size=16)

# 2. 定义普通CNN模型
class CNN(nn.Module):
    def __init__(self, input_dim, hidden_dim, output_dim):
        super(CNN, self).__init__()
        self.embedding = nn.Embedding(input_dim, hidden_dim)
        # 普通卷积网络,不使用膨胀卷积
        self.conv1 = nn.Conv1d(hidden_dim, hidden_dim, kernel_size=3, padding=1)
        self.conv2 = nn.Conv1d(hidden_dim, hidden_dim, kernel_size=3, padding=1)
        self.conv3 = nn.Conv1d(hidden_dim, hidden_dim, kernel_size=3, padding=1)
        self.fc = nn.Linear(hidden_dim, output_dim)

    def forward(self, x):
        x = self.embedding(x)  # (batch_size, sequence_length, hidden_dim)
        x = x.permute(0, 2, 1)  # 转换维度以适应Conv1d
        x = torch.relu(self.conv1(x))
        x = torch.relu(self.conv2(x))
        x = torch.relu(self.conv3(x))
        x = x.permute(0, 2, 1)  # 转换维度以适应全连接层
        x = self.fc(x)
        return x

# 参数设置
input_dim = len(word_to_index)
hidden_dim = 128
output_dim = num_labels
num_epochs = 5

# 初始化普通CNN模型、损失函数和优化器
model = CNN(input_dim=input_dim, hidden_dim=hidden_dim, output_dim=output_dim)
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)

# 3. 训练模型
for epoch in range(num_epochs):
    model.train()
    total_loss = 0
    for inputs, labels in train_loader:
        optimizer.zero_grad()
        outputs = model(inputs)
        outputs = outputs.view(-1, output_dim)
        labels = labels.view(-1)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()
        total_loss += loss.item()
    print(f"Epoch [{epoch + 1}/{num_epochs}], Loss: {total_loss / len(train_loader):.4f}")

# 4. 模型评估
model.eval()
all_preds = []
all_labels = []

with torch.no_grad():
    for inputs, labels in test_loader:
        outputs = model(inputs)
        outputs = outputs.view(-1, output_dim)
        _, preds = torch.max(outputs, dim=1)
        all_preds.extend(preds.cpu().numpy())
        all_labels.extend(labels.view(-1).cpu().numpy())

# 删除填充部分的标签和预测
true_labels = [label for label, pred in zip(all_labels, all_preds) if label != 0]
true_preds = [pred for label, pred in zip(all_labels, all_preds) if label != 0]

# 输出分类报告
print(classification_report(true_labels, true_preds, target_names=[str(label) for label in label_encoder.classes_], zero_division=0))

运行结果如下:
在这里插入图片描述

🍀对比实验(CoNLL-2003数据集)

模型PrecisionRecallF1-Score
CNN0.830.490.60
IDCNN0.820.530.64

从结果来看,IDCNN 的召回率和 F1-Score 略优于 CNN,显示出 IDCNN 模型在捕捉命名实体的特征方面具有一定优势。

🍀结论

IDCNN作为一种新兴的序列数据处理模型,凭借其高效性和灵活性在自然语言处理、语音识别等领域展现出广泛的应用潜力。通过空洞卷积的结构设计,IDCNN可以在保证计算效率的同时捕捉长距离依赖关系,为序列标注任务提供了有效的解决方案。

🍀参考文献

  1. Yu, F., & Koltun, V. (2016). Multi-Scale Context Aggregation by Dilated Convolutions. arXiv preprint arXiv:1511.07122.
  2. Ma, J., & Hovy, E. (2016). End-to-end sequence labeling via bi-directional LSTM-CNNs-CRF. arXiv preprint arXiv:1603.01354.
  3. He, K., Zhang, X., Ren, S., & Sun, J. (2016). Deep residual learning for image recognition. In Proceedings of the IEEE conference on computer vision and pattern recognition (pp. 770-778).

请添加图片描述

挑战与创造都是很痛苦的,但是很充实。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

(转载)Tools for Learning LLVM TableGen

前提 最近在学习有关llvm的东西&#xff0c;其中TableGen占了一部分&#xff0c;所以想特意学习下TableGen相关的语法。这里找到了LLVM官网的一篇介绍TableGen的博客&#xff0c;学习并使用机器翻译为中文。在文章的最后也添加了一些学习TableGen的资源。 原文地址&#xff1…

明源地产ERP WFWebService.asmx 反序列化RCE漏洞复现

0x01 产品简介 明源地产ERP是一款专为房地产行业设计的企业资源规划(ERP)系统,系统集成了项目管理、财务管理、客户关系管理、营销管理等多个模块,旨在帮助房地产企业提升运营效率、降低成本和提高客户满意度。它充分考虑了房地产行业的特性和需求,通过整合企业的各个业务…

AIGC时代LaTeX排版的应用、技巧与未来展望

文章目录 一、LaTeX简介与基础设置二、常用特殊符号与公式排版三、图片与表格的插入与排版四、自动编号与交叉引用五、自定义命令与样式六、LaTeX在AIGC时代的应用与挑战七、LaTeX的未来展望《LaTeX 入门实战》内容简介作者简介目录前言/序言读者对象本书内容充分利用本书 在AI…

redis:set集合命令,内部编码,使用场景

个人主页 &#xff1a; 个人主页 个人专栏 &#xff1a; 《数据结构》 《C语言》《C》《Linux》《网络》 《redis学习笔记》 文章目录 前言命令SADDSMEMBERSSISMEMBERSCARDSPOPSMOVESREM集合间操作SINTERSINTERSTORESUNIONSUNIONSTORESDIFFSDIFFSTORE 内部编码使用场景总结 前言…

智慧工地:引领工地管理和监测的革新

一、智慧工地是什么 智慧工地是智慧地球理念在工程领域的具体应用&#xff0c;是工程全生命周期管理的崭新理念。通过运用信息化手段&#xff0c;智慧工地利用三维设计平台对工程项目进行精确设计和施工模拟&#xff0c;重点关注施工过程管理&#xff0c;建立互联协同、智能生…

如何在Linux系统中使用Netcat进行网络调试

文章目录 Netcat简介安装Netcat在Debian/Ubuntu系统中安装在CentOS/RHEL系统中安装 Netcat基本命令Netcat基本用法示例1&#xff1a;监听端口示例2&#xff1a;连接到远程主机 Netcat选项-l选项-p选项-v选项 Netcat模式监听模式连接模式 Netcat排除和包含排除端口包含端口 Netc…

《AI产品经理手册》——解锁AI时代的商业密钥

在当今这个日新月异的AI时代&#xff0c;每一位产品经理都面临着前所未有的挑战与机遇&#xff0c;唯有紧跟时代潮流&#xff0c;深入掌握AI技术的精髓&#xff0c;才能在激烈的市场竞争中独占鳌头。《AI产品经理手册》正是这样一部为AI产品经理量身定制的实战宝典&#xff0c;…

多核架构的基本概念

目录 1.为什么使用多核 2.多核分类 2.1 同构和异构 2.2 SMP和AMP 3 小结 1.为什么使用多核 这个问题个人认为可以从两个方面来看&#xff1a; 性能问题 随着汽车ECU对集成化的要求越来越高&#xff0c;把多个ECU功能集中到一个多核MCU的需求也越来越明显。 以汽车制动…

NeurIPS 2024 | 机器人操纵世界模型来了,成功率超过谷歌RT-1 26.6%

对于人类而言&#xff0c;一旦掌握了 “打开瓶盖” 的动作&#xff0c;面对 “拧紧螺丝” 这样的任务通常也能游刃有余&#xff0c;因为这两者依赖于相似的手部动作。然而&#xff0c;对于机器人来说&#xff0c;即使是这样看似简单的任务转换依然充满挑战。例如&#xff0c;换…

OceanBase V4.3.3,首个面向实时分析场景的GA版本发布

在10月23日举办的 OceanBase年度发布会 上&#xff0c;我们怀着激动之情&#xff0c;正式向大家宣布了 OceanBase 4.3.3 GA 版的正式发布&#xff0c;这也是OceanBase 为实时分析&#xff08;AP&#xff09;场景打造的首个GA版本。 2024 年初&#xff0c;我们推出了 4.3.0 版本…

TS-AWG控制电光调制器:推动科技应用新发展的利器

一、电光调制有什么用&#xff1f; 如今&#xff0c;基于光学、光子学和脉冲激光以及电光调制器的应用正变得极为流行&#xff0c;最新一代科学家正在为其实际应用开辟新领域&#xff0c;如汽车激光雷达、医疗解决方案、航空航天和国防、量子和激光传感器。 测试挑战、上市时…

程序员开发速查表

作为一名苦逼的程序员&#xff0c;在开发的过程中&#xff0c;我们总是在各种编程语言中来回穿梭&#xff0c;忙完后端整前端&#xff0c;还得做一部分的运维工作&#xff0c;忙的我们有时候忘记语法&#xff0c;忘记编写规则&#xff0c;甚至混淆。这时候我们就希望有一个综合…

要在微信小程序中让一个 `view` 元素内部的文字水平垂直居中,可以使用 Flexbox 布局

文章目录 主要特点&#xff1a;基本用法&#xff1a;常用属性&#xff1a; 要在微信小程序中让一个 view 元素内部的文字水平垂直居中&#xff0c;可以使用 Flexbox 布局。以下是如何设置样式的示例&#xff1a; .scan-button {display: flex; /* 启用 Flexbox 布局 */justify…

docker pull 拉取镜像失败,使用Docker离线包

1、登录并注册Github&#xff0c;然后在Github中搜索并打开“wukongdaily/DockerTarBuilder” 项目&#xff0c;在该项目主页点击“Fork”。 然后点 “Create Fork”&#xff0c;将项目创建到自己的Github主页。 2、接着在自己创建过来的这个项目中点击“Actions” 3、然后…

基于Leaflet的自助标绘源码解析-其它对象解析

目录 前言 一、整体类图介绍 1、整体类图 二、进攻方向类对象标绘实现 1、基础配置 2、各组成部分的绘制 三、集结地对象的标绘实现 1、对象图形绘制 四、钳击对象的标绘实现 1、基础配置 2、各部分标绘 五、总结 前言 在之前的自助标绘相关博文中&#xff0c;我们…

基于机器学习的健身房会员健康风险分类及预测分析

1.项目背景 随着健康意识的提升和健身文化的普及&#xff0c;人们对科学健身和个性化训练的需求日益增长&#xff0c;健身房会员的锻炼模式和健康管理需求呈现出新的特点&#xff0c;本项目使用基于真实健身模式生成的973位会员数据进行深入分析&#xff0c;探索不同会员群体的…

如何在本地Linux服务器搭建WordPress网站结合内网穿透随时随地可访问

文章目录 前言1. 安装WordPress2. 创建WordPress数据库3. 安装相对URL插件4. 安装内网穿透发布网站4.1 命令行方式&#xff1a;4.2. 配置wordpress公网地址 5. 配置WordPress固定公网地址 前言 本文主要介绍如何在Linux Ubuntu系统上使用WordPress搭建一个本地网站&#xff0c…

30条勒索病毒处置原则

当前&#xff0c;勒索病毒在全球范围内肆虐&#xff0c;成为企业数据资产安全的头号威胁。这些狡猾的恶意软件&#xff0c;如同网络空间中的幽灵&#xff0c;不断寻找并利用系统的漏洞&#xff0c;通过加密数据或窃取敏感信息&#xff0c;向企业索取高额赎金。一旦感染&#xf…

【MongoDB】Windows/Docker 下载安装,MongoDB Compass的基本使用、NoSQL、MongoDB的基础概念及基础用法(超详细)

文章目录 Windows下载MongoDB Compass使用NoSQL的基本概念MongoDB常用术语MongoDB与RDBMS区别MongoDB的CRUD 更多相关内容可查看 Docker安装MongoDB可查看&#xff1a;Docker-安装MongoDB Windows下载 官网下载地址&#xff1a;https://www.mongodb.com/try/download/communi…

爬虫学习4

from threading import Thread#创建任务 def func(name):for i in range(100):print(name,i)if __name__ __main__:#创建线程t1 Thread(targetfunc,args("1"))t2 Thread(targetfunc, args("2"))t1.start()t2.start()print("我是诛仙剑")from …