“一文打尽知识图谱”知识记录一

from transformers import BertTokenizer, BertModel
import torch
# 加载预训练的BERT模型和tokenizer
model_name = 'bert-base-uncased'
tokenizer = BertTokenizer.from_pretrained(model_name)
model = BertModel.from_pretrained(model_name)

# 待编码的文本
text = "Hello, where are you from?"

# 分词并添加特殊标记
tokens = tokenizer.tokenize(text)
tokens = ['[CLS]'] + tokens + ['[SEP]']#CLS为序列开始标记,SEP为结尾标记

# 将分词转换为对应的ID
input_ids = tokenizer.convert_tokens_to_ids(tokens)#将标记转换为数字ID,标记也就是把句子分隔,ID就是把分隔的部分映射到的数字

# 添加padding和attention mask
padding_length = 128 - len(input_ids)#需要补充的长度
input_ids += [0] * padding_length
attention_mask = [1] * len(input_ids)#掩码

# 转换为张量
input_ids = torch.tensor([input_ids])
attention_mask = torch.tensor([attention_mask])

# 获取BERT模型的输出
outputs = model(input_ids, attention_mask)
embeddings = outputs.last_hidden_state  # 可以根据需求选择不同的层或输出

# 提取句子级别的向量表示
sentence_embedding = embeddings.mean(dim=1)
print(embeddings)
# 输出结果
print(sentence_embedding)

                        使用Hugging Face的Transformers库对给定文本进行BERT编码 

Hugging Face 是一家专注于自然语言处理(NLP)技术的公司,它提供了许多优秀的开源工具和库,旨在帮助开发者构建和部署NLP相关的应用程序。

Hugging Face 最著名的贡献是推出了Transformers库,它是一个用于自然语言处理的开源库,提供了一系列预训练的模型(如BERT、GPT等)的实现和预训练模型的预训练权重。这个库极大地简化了使用和部署这些强大的NLP模型的过程,使开发者能够更轻松地利用这些模型进行文本生成、文本分类、问答系统等任务。

除了Transformers库,Hugging Face 还提供了其他有用的工具和库,包括Datasets(用于处理和加载各种NLP数据集)、Tokenizers(用于文本标记和编码)、Accelerate(用于训练和推理加速)、Pipeline(用于快速构建NLP任务的流水线)等等。

"mask"(掩码)通常用来指示哪些输入标记是有效的,哪些是被遮蔽的或被忽略的。

在BERT和其他一些预训练语言模型中,输入中的每个标记都有一个对应的掩码标记,通常用0或1表示。掩码的目的是告诉模型哪些位置的标记应该被忽略。

在BERT中,有两种类型的掩码:

  1. 输入掩码(input mask):用于指示哪些标记是真实的输入标记,哪些是填充标记。填充标记通常用于使输入序列具有相同的长度,因此需要将它们掩盖,以便模型不会在这些位置上进行处理。输入掩码使用1表示真实的输入标记,0表示填充标记。

  2. 掩码语言模型(masked language modeling):在BERT的预训练阶段,一些输入标记会被随机选择并替换为特殊的[MASK]标记。这样模型在训练时需要预测被掩盖标记的正确词汇。这种操作有助于模型学习上下文和语义信息。掩码语言模型的标记用1表示,其他标记用0表示。

掩码在模型训练和推理过程中扮演重要角色,它们帮助模型关注有效的输入标记并提供上下文信息。

model的完整参数可以包括以下内容,具体取决于所使用的深度学习模型和框架的实现

  1. input_ids(必需):输入序列的token ID列表。
  2. attention_mask(必需):输入序列的二进制掩码,用于指示真实的输入和填充的部分。
  3. token_type_ids(可选):用于区分输入序列中不同部分的token类型的列表,例如在BERT中区分句子A和句子B。
  4. position_ids(可选):用于指示输入序列中每个token的位置信息的列表,例如在Transformer模型中。
  5. head_mask(可选):一个或多个掩码列表,用于指定模型中要屏蔽的注意力头。
  6. inputs_embeds(可选):代替input_ids的嵌入输入,通常是一个嵌入矩阵。
  7. 其他模型特定的参数:不同的模型可能具有其他特定的参数,例如用于控制生成文本样式的参数、温度参数等。

下面是一些常见的基于语义相似度的评分函数:

  1. 余弦相似度(Cosine Similarity):将文本表示为向量,通过计算两个向量之间的余弦夹角来度量它们之间的相似度。较大的余弦相似度表示两个文本在语义上更相似。

  2. 词嵌入相似度(Word Embedding Similarity):使用预训练的词嵌入模型(如Word2Vec、GloVe、BERT等)将文本转换为向量表示,然后计算向量之间的相似度。这种方法利用词嵌入模型捕捉词语的语义信息,从而度量文本之间的语义相似度。

  3. 编码器-解码器模型相似度(Encoder-Decoder Model Similarity):使用编码器-解码器模型(如Seq2Seq模型、Transformer模型)将文本转换为固定长度的向量表示,然后计算向量之间的相似度。这种方法将文本转换为语义表示,并通过度量向量之间的相似度来评估文本之间的语义相似度。

  4. 基于语法树的相似度(Tree-based Similarity):将文本解析成语法树,然后比较两个语法树之间的结构和节点之间的相似度来评估语义相似度。这种方法考虑了语法结构对语义的影响,可以更准确地度量文本之间的语义相似度。

全连接层

全连接层(Fully Connected Layer),也称为密集连接层或线性层,是深度学习中常用的一种层类型。它是神经网络中最基本的层之一,常用于将输入数据与权重进行线性组合和非线性变换。

全连接层的输入是一个一维向量(或者说是扁平化的输入),每个元素都与该层的每个神经元相连。每个神经元都有一个权重与对应的输入相乘,并加上偏置项(bias),然后通过一个非线性激活函数进行激活,得到该神经元的输出。

在全连接层中,每个神经元都可以看作是一个线性映射,它将输入数据映射到一个新的空间,并通过非线性激活函数引入非线性特征。这样的设计可以使神经网络能够学习更复杂的特征和模式。

全连接层通常用于神经网络的最后几层,用于将高级抽象的特征映射到最终的输出类别或回归值。在深度学习模型中,全连接层经常与其他类型的层(如卷积层、池化层等)交替使用,以构建更复杂的模型架构。

总结起来,全连接层是深度学习中的一种基本层类型,它通过将输入数据与权重进行线性组合和非线性变换,引入非线性特征,从而实现更复杂的特征表示和模式学习。

全连接层实例

假设我们有一个简单的全连接神经网络,输入是一个二维向量 [x1, x2],输出是一个二分类问题,即预测输入属于类别 0 还是类别 1。该神经网络包含一个全连接层和一个输出层。

全连接层的权重矩阵为:

W = [[w11, w12], [w21, w22]]

偏置项为:

偏置项的作用是引入了一个额外的可调参数,使得神经网络可以更好地适应各种数据分布和模式。它可以调整神经元的灵敏度和偏好,从而增加神经网络的表达能力。

b = [b1, b2]

其中 w11, w12, w21, w22, b1, b2 是待学习的参数。

输入向量 [x1, x2] 经过全连接层的线性变换为:

z = [z1, z2] = [x1*w11 + x2*w21 + b1, x1*w12 + x2*w22 + b2]

这里,z1z2 分别是两个神经元的线性组合输出。

然后,我们可以将 z1z2 经过一个激活函数,比如 sigmoid 函数,得到激活后的输出:

a = [a1, a2] = [sigmoid(z1), sigmoid(z2)]

最后,这些激活值作为输入传递到输出层进行分类,比如使用 softmax 函数将其归一化为概率分布,得到最终的预测结果。

这个例子展示了一个简单的全连接层的应用。通过权重矩阵的线性变换和激活函数的非线性变换,全连接层可以将输入数据映射到一个更高维的特征空间,并生成适合于分类任务的特征表示。

激活函数

激活函数(Activation Function)是神经网络中的一种非线性函数,它作用于神经元的输出,将其转化为非线性的形式。激活函数的引入能够增加神经网络的表达能力,使其能够更好地适应非线性数据和复杂模式。

激活函数通常被应用于神经网络的隐藏层和输出层,将线性变换的结果进行非线性映射。它的输入是神经元的加权和(权重与输入的线性组合),输出是激活后的数值。

常见的激活函数包括:

  1. Sigmoid 函数:将输入映射到 (0, 1) 的区间,公式为 f(x) = 1 / (1 + exp(-x))
  2. Tanh 函数:将输入映射到 (-1, 1) 的区间,公式为 f(x) = (exp(x) - exp(-x)) / (exp(x) + exp(-x))
  3. ReLU 函数(Rectified Linear Unit):对于非负的输入,输出为输入值本身;对于负的输入,输出为 0,公式为 f(x) = max(0, x)
  4. Leaky ReLU 函数:与 ReLU 类似,但对于负的输入,输出为一个小的斜率值而不是 0,公式为 f(x) = max(ax, x),其中 a 是一个小的正数。
  5. Softmax 函数:常用于多分类问题的输出层,将输入映射为概率分布,使得各个类别的概率和为 1,公式为 f(x_i) = exp(x_i) / sum(exp(x_j)),其中 x_i 是输入向量中的第 i 个元素。

编码模型

线性模型:

  1. 头部实体表示:首先,对于给定的三元组(头部实体,关系,尾部实体),头部实体会被表示为一个向量或嵌入。

  2. 投影到表征空间:将头部实体的表示通过投影操作映射到一个表征空间中。这个表征空间通常与尾部实体的表示空间相同或相似。

  3. 关系表示:使用线性映射或双线性映射将投影后的头部实体表示与尾部实体表示结合起来,得到表示它们之间关系的向量。

具体来说,可以使用以下方式进行头部实体和尾部实体的表示结合

  1. 拼接(Concatenation):将头部实体的表示向量和尾部实体的表示向量按照某个维度进行拼接,得到一个更长的向量。例如,如果头部实体的表示向量是 a,尾部实体的表示向量是 b,则拼接后的表示向量为 [a, b]。

  2. 相加(Addition):将头部实体的表示向量和尾部实体的表示向量逐元素相加,得到一个新的表示向量。例如,如果头部实体的表示向量是 a,尾部实体的表示向量是 b,则相加后的表示向量为 a + b。

  3. 加权相加(Weighted Addition):将头部实体的表示向量和尾部实体的表示向量进行加权相加,其中权重可以通过学习得到或手动设置。这样可以在结合过程中对不同实体的重要性进行调节。

分解模型:

旨在将关系数据分解为低秩矩阵以进行表征学习。

神经网络模型:

CNN卷积神经网络 

CNN的核心思想是通过卷积层和池化层来提取图像中的局部特征,并利用这些特征进行分类、检测或其他相关任务。相比于传统的全连接神经网络,CNN 在处理图像数据时能够更好地利用局部关系和共享权重的特性

CNN的基本组成部分包括:

  1. 卷积层(Convolutional Layer):卷积层通过应用一系列的滤波器(也称为卷积核)来提取图像的特征。每个滤波器会在图像上进行滑动操作,计算局部区域与滤波器之间的卷积运算,生成特征图。卷积层可以有效地捕捉图像的局部空间特征,例如边缘、纹理等。

  2. 池化层(Pooling Layer):池化层用于减小特征图的维度并保留关键特征。常见的池化操作包括最大池化(Max Pooling)和平均池化(Average Pooling),它们分别在局部区域中选择最大值或平均值作为池化结果。池化操作可以减少特征图的大小,提高模型的计算效率,并对输入数据的平移、旋转等变化具有一定的不变性。

  3. 激活函数(Activation Function):在卷积层和池化层之后,通常会应用激活函数对特征图进行非线性映射,增加网络的表达能力。常用的激活函数包括ReLU(Rectified Linear Unit)、Sigmoid和TanH等。

  4. 全连接层(Fully Connected Layer)/(Dense layer):在经过卷积层和池化层后,最后一部分是全连接层,它将特征图展平成一维向量,并通过一系列全连接操作进行分类、回归或其他任务的处理。

CNN简单例子,用于图像分类任务

import tensorflow as tf
from tensorflow.keras import layers

# 构建CNN模型
model = tf.keras.Sequential([
    layers.Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1)),
    layers.MaxPooling2D((2, 2)),
    layers.Conv2D(64, (3, 3), activation='relu'),
    layers.MaxPooling2D((2, 2)),
    layers.Conv2D(64, (3, 3), activation='relu'),
    layers.Flatten(),
    layers.Dense(64, activation='relu'),
    layers.Dense(10, activation='softmax')
])

# 编译模型
model.compile(optimizer='adam',
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])

# 加载数据集
(x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data()

# 数据预处理
x_train = x_train.reshape(-1, 28, 28, 1) / 255.0
x_test = x_test.reshape(-1, 28, 28, 1) / 255.0

# 训练模型
model.fit(x_train, y_train, epochs=5, batch_size=64)

# 评估模型
loss, accuracy = model.evaluate(x_test, y_test)
print(f'Test loss: {loss:.4f}')
print(f'Test accuracy: {accuracy:.4f}')

Keras 

Keras的主要作用是简化深度学习模型的构建和训练过程,使得深度学习变得更加容易上手和快速实现。以下是Keras的一些具体作用:

  1. 模型构建:Keras提供了丰富的预定义层和模型,可以用于构建各种类型的神经网络。通过简洁而直观的API,用户可以轻松地定义模型的结构,包括层的堆叠、连接方式和参数设置等。

  2. 模型训练:Keras提供了常用的优化器和损失函数,可以帮助用户定义模型的训练目标和优化算法。通过调用model.compile()方法指定优化器和损失函数,以及可选的评估指标,用户可以准备好模型进行训练。

  3. 数据处理:Keras提供了一系列用于数据预处理和数据生成的工具,例如图像处理、序列填充、数据增强等。这些工具能够帮助用户处理输入数据,使其符合模型的输入要求,并提供更好的训练效果。

  4. 模型评估:Keras提供了各种常用的评估指标,可以用于评估模型在训练和测试集上的性能。用户可以通过调用model.evaluate()方法来计算模型在给定数据集上的指标值,如准确率、损失值等。

  5. 模型保存与加载:Keras允许用户将训练好的模型保存为文件,以便后续使用或分享。通过调用model.save()方法,用户可以将模型的结构和参数保存到磁盘上。此外,Keras还支持加载已保存的模型,以便进行预测或继续训练。

Tensorflow

TensorFlow是一个开源的深度学习框架,它提供了丰富的工具和库,用于构建、训练和部署机器学习和深度学习模型。TensorFlow的主要作用如下:

  1. 模型构建:TensorFlow提供了一个灵活的计算图模型来定义和构建机器学习模型。用户可以使用TensorFlow的高级API(如Keras)或底层API(如tf.Module和tf.keras.layers)来创建各种类型的模型,包括神经网络、循环神经网络、卷积神经网络等。

  2. 自动求导:TensorFlow内置了自动求导功能,可以自动计算模型中各个参数对于损失函数的梯度。这使得用户可以方便地进行梯度下降等优化算法的实现,用于训练模型并更新参数。

  3. 分布式计算:TensorFlow支持分布式计算,可以在多个GPU或多台机器上并行训练和推断模型。这种能力使得TensorFlow非常适合处理大规模的数据和复杂的模型,提高了训练和推理的效率。

  4. 部署和生产环境:TensorFlow提供了一系列的工具和接口,用于将训练好的模型部署到生产环境中进行推理。这包括将模型转换为可部署的格式(如SavedModel或TensorFlow Lite)、使用TensorFlow Serving进行模型服务、在移动设备上进行模型推理等。

  5. 科学计算和数据处理:TensorFlow提供了丰富的数学运算库和数据处理工具,可用于各种科学计算和数据处理任务。它支持张量操作、矩阵运算、图像处理、文本处理等,为用户提供了处理和转换数据的强大功能。

MNIST(Modified National Institute of Standards and Technology)数据集

MNIST(Modified National Institute of Standards and Technology)数据集是一个常用的手写数字识别数据集。它由来自美国国家标准与技术研究所的人类手写数字图像组成,包括0到9的数字。MNIST数据集一共包含60,000个训练样本和10,000个测试样本,每个样本都是一个28x28像素的灰度图像。数据集被分为训练集和测试集,每个集合包含图像数据和相应的标签。

MNIST数据集被广泛用于机器学习和深度学习的算法验证和性能评估。它是一个相对较小和简单的数据集,适合用于初学者学习和实践图像分类任务。许多经典的机器学习和深度学习模型都在MNIST数据集上进行了验证和测试。

通过使用MNIST数据集,研究人员和开发者可以训练模型来学习识别手写数字。这项任务是图像分类的一个经典问题,涉及将输入图像映射到相应的数字类别。通过使用MNIST数据集,可以构建和评估各种图像分类算法,并比较它们在这个任务上的性能。

Sequential模型

Sequential是TensorFlow中的一个模型类,用于构建顺序模型(Sequential Model)。顺序模型是一种简单的神经网络模型,由多个层按顺序组成,数据流从模型的输入经过每一层直至输出。

Sequential模型中,可以通过逐个添加层的方式来构建网络结构。每个层都会接收上一层的输出作为输入,并将自己的输出传递给下一层。这种顺序的层堆叠方式使得模型的搭建非常方便和直观。

例如,在上述代码中,model = tf.keras.Sequential([...])通过传入层的列表来构建顺序模型。列表中的每个元素代表一个层,按顺序排列。数据在模型中按照列表中层的顺序流动,依次经过卷积层、池化层、展平层和全连接层,最后输出分类结果。

Sequential模型适用于简单的模型结构,其中层之间没有复杂的连接关系,每个层只有一个输入和一个输出。对于更复杂的模型结构,可以使用Keras的函数式API或子类化API来构建模型。

需要注意的是,Sequential模型只能表示单输入和单输出的模型。如果模型具有多个输入或多个输出,或者需要实现非顺序的连接,就需要使用其他更灵活的模型构建方式。

卷积核

卷积核(Convolutional Kernel)是卷积神经网络中的一个重要概念,也称为滤波器(Filter)或特征检测器(Feature Detector)。

在卷积神经网络的卷积层中,卷积核是一个小矩阵,它通过滑动窗口的方式在输入数据上进行卷积运算。卷积核的大小通常是正方形或矩形,并且由一组可学习的权重参数组成。

卷积核的作用是对输入数据进行局部特征提取。通过对输入数据的不同位置应用卷积核,可以获得不同位置的特征表示。卷积核的权重参数决定了它对输入数据的响应方式,可以学习到不同类型的特征,如边缘、纹理、形状等。

在卷积层中,通过在输入数据上滑动卷积核,并对卷积核与输入数据进行点乘操作,得到卷积运算的结果,即特征图(Feature Map)。卷积核的数量决定了输出特征图的通道数,每个卷积核生成一个通道的特征图。

通过不同的卷积核组合,卷积神经网络能够自动学习输入数据的不同层次的特征表示,从低级的局部特征到高级的语义特征,逐渐提取出图像中的重要信息,用于后续的分类、检测或其他任务。

通道

在计算机图像处理和深度学习中,通道(channel)是指图像或特征图中的一个独立的颜色通道或特征通道。通常,彩色图像由多个颜色通道组成,而灰度图像只有一个通道。

在彩色图像中,常用的表示方式是使用RGB通道,其中R代表红色通道,G代表绿色通道,B代表蓝色通道。每个通道存储了图像中对应颜色的强度值。通过组合这些颜色通道的强度值,可以生成彩色图像。

在深度学习中,卷积神经网络(CNN)处理图像时,每个卷积层输出的特征图也可以看作是不同的通道。每个通道对应一个卷积核,通过卷积操作提取图像的不同特征。这些特征通道包含了不同层次的图像信息,用于模型的学习和分类。

因此,通道可以理解为图像或特征图中独立的数据维度,它们分别存储了不同的颜色信息或特征信息,用于表示和处理图像数据。

layers.Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1)) 是用于构建卷积层的代码。

  • layers.Conv2D: 这是一个卷积层的类。
  • 32: 表示该卷积层输出的通道数,即输出的特征图数量。
  • (3, 3): 表示卷积核的大小,这里是一个 3x3 的卷积核。
  • activation='relu': 激活函数的选择,这里使用的是ReLU激活函数,它在输入大于0时返回输入值,小于等于0时返回0。
  • input_shape=(28, 28, 1): 输入数据的形状,表示输入的是一个 28x28 的单通道图像。其中,28 是图像的高度,28 是图像的宽度,1 表示输入的通道数为1(灰度图像)。

这句代码创建了一个卷积层,它接收一个大小为 28x28、通道数为 1 的输入图像,并输出 32 个大小为 26x26 的特征图。输出特征图的大小是通过在输入图像上应用 3x3 的卷积核计算得到的。激活函数ReLU应用在每个特征图上,以引入非线性性质

为什么要引入非线性性质呢?

因为线性变换(如线性映射或线性组合)的叠加仍然是线性的,而深度神经网络的目标是学习更加复杂和非线性的函数关系。通过在特征图上应用ReLU激活函数,可以使网络具有更强的表达能力,能够学习和表示更复杂的特征和模式。

layers.MaxPooling2D((2, 2))

最大池化操作,(2,2)表示池化窗口的大小

最大池化的作用:

  1. 降低特征图的空间尺寸:通过池化操作,特征图的宽度和高度会减小,从而减少了模型的参数数量和计算量。
  2. 保留主要特征:最大池化选择每个区域中的最大值作为输出,这样可以保留最显著的特征,有助于提取图像中的重要细节和纹理。

紧跟在卷积层后面,通过降低特征图的尺寸和提取关键特征,进一步提高模型的表达能力和性能。

layers.Flatten()——展平层

在卷积神经网络中,前面的卷积层和池化层等操作会生成多维的特征图(或特征矩阵)。而在某些任务中,我们需要将这些多维的特征表示转换为一维的向量,以便与后续的全连接层进行连接。

layers.Flatten() 就是一个用于展平操作的层。它会将输入数据的所有维度除了批量维度(即第一个维度)之外都展平为一维。这样,不论输入的特征图的尺寸如何,都可以将其转换为固定长度的一维向量。

例如,如果输入的特征图的尺寸是 (batch_size, height, width, channels),那么 layers.Flatten() 操作会将其转换为形状为 (batch_size, height * width * channels) 的一维向量。

展平操作通常用于将卷积神经网络中的特征提取部分与后续的全连接层进行连接,从而将特征提取和分类/回归等任务相结合。

layers.Dense(64, activation='relu')

全连接层是神经网络中的一种常见层类型,它的每个神经元都与上一层的所有神经元相连接。在这个代码中,layers.Dense(64, activation='relu') 表示创建了一个具有64个神经元的全连接层,并且激活函数为ReLU。

参数说明:

  • 64:表示该层的输出维度为64。也就是说,该层的输出是一个长度为64的向量
  • activation='relu':表示该层的激活函数是ReLU。激活函数在神经网络中引入非线性性质,使得模型可以学习更加复杂的特征和模式。

该全连接层接收前面卷积层或池化层的输出作为输入,并将其与权重相乘,加上偏置,并通过ReLU激活函数进行非线性变换。这样可以引入非线性性质,使得模型能够更好地拟合非线性的关系和特征。

全连接层通常用于将卷积神经网络的特征提取部分与最后的分类层相连接,以实现对提取到的特征进行分类、回归或其他任务的处理。

神经元

在神经网络中,神经元是模拟生物神经元的基本单位。它接收来自其他神经元的输入,并产生输出信号。神经元在神经网络中负责信息传递和处理。

在人工神经网络中,一个神经元通常由以下组成部分组成:

  • 输入权重(Input weights):每个输入都有一个对应的权重,用于调整输入的重要性。
  • 总和函数(Summation function):将所有输入与对应的权重相乘,并将它们的总和计算出来。
  • 激活函数(Activation function):将总和函数的输出进行非线性变换,产生神经元的输出。
  • 偏置(Bias):每个神经元还可以有一个偏置项,它是一个常数,用于调整神经元的整体活动水平。

当输入信号通过输入权重加权后,传递到总和函数中,总和函数将计算所有加权输入的总和。然后,总和函数的输出将通过激活函数进行非线性变换,产生神经元的输出。这个输出将传递给下一层的神经元或作为整个网络的输出。

神经元的目的是对输入进行加权和组合,并通过激活函数引入非线性性质,以实现对复杂模式和关系的建模能力。整个神经网络由许多这样的神经元组成,通过它们之间的连接传递和处理信息,从而实现对输入数据的学习和预测能力。

model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])

  • optimizer='adam': 设置了优化器,这里使用了Adam优化器。Adam是一种常用的优化算法,它结合了动量法和自适应学习率的方法,能够有效地进行模型参数的更新和优化。
  • loss='sparse_categorical_crossentropy': 设置了损失函数,这里使用了稀疏分类交叉熵损失函数。对于多分类问题,交叉熵损失函数常用于衡量模型输出与真实标签之间的差异,稀疏分类交叉熵适用于标签以整数形式表示的情况。
  • metrics=['accuracy']: 设置了评估指标,这里使用了准确率作为评估指标。准确率是一种常用的分类指标,用于衡量模型在预测时的准确性。

Adam算法——自适应矩估计

Adam(Adaptive Moment Estimation)是一种常用的优化算法,用于训练神经网络和深度学习模型。它结合了动量法和自适应学习率的方法,能够有效地进行模型参数的更新和优化。

Adam算法的主要思想是根据参数的一阶矩估计(即均值)和二阶矩估计(即方差)来调整学习率。它在每个参数维度上都维护了一个适应性的学习率,并且通过自适应地调整学习率的大小,能够在不同参数维度上采用不同的学习率。

具体而言,Adam算法使用了以下三个重要的步骤来更新模型参数:

  1. 计算梯度:根据当前的参数值,通过反向传播计算模型在训练数据上的梯度。
  2. 计算一阶矩估计:利用梯度的一阶矩估计(即均值)来估计参数的移动方向和速度。
  3. 计算二阶矩估计:利用梯度的二阶矩估计(即方差)来估计参数的移动步幅。

Adam算法的更新规则综合了上述步骤的计算结果,并使用动量(momentum)来加速参数更新的过程。它具有以下优点:

  • 自适应学习率:Adam算法能够根据每个参数的二阶矩估计自适应地调整学习率的大小。对于稀疏梯度和大范围参数的情况,它能够更准确地调整学习率,提高训练效果。
  • 考虑动量:Adam算法使用动量来加速参数更新的过程,从而在优化过程中更快地收敛到最优解。
  • 鲁棒性:Adam算法对于大多数超参数的选择比较鲁棒,对于不同的任务和模型具有一定的适应性。

稀疏分类交叉熵损失函数

稀疏分类交叉熵(Sparse Categorical Crossentropy)是一种常用的损失函数,特别适用于多类别分类问题中的离散标签情况。它用于衡量模型预测结果与真实标签之间的差异,并作为优化算法的目标函数,帮助模型学习正确分类。

在分类问题中,每个样本通常被标记为一个离散的类别,而不是一个向量表示的连续值。稀疏分类交叉熵损失函数通过将真实标签表示为整数形式,与模型的预测结果进行比较,计算模型的预测错误程度。

具体而言,稀疏分类交叉熵损失函数的计算包括以下步骤:

  1. 将真实标签进行 one-hot 编码:将离散的真实标签转换为与预测结果相同维度的 one-hot 向量,其中正确类别的位置为 1,其他位置为 0。
  2. 计算交叉熵损失:将模型的预测结果和真实标签进行比较,并计算交叉熵损失值。交叉熵损失衡量了预测结果与真实标签之间的差异程度,即模型对正确类别的预测概率与真实类别的匹配程度。

稀疏分类交叉熵损失函数与普通的分类交叉熵损失函数的区别在于输入的真实标签的表示方式。在稀疏分类交叉熵中,真实标签以整数形式提供,而在分类交叉熵中,真实标签通常以 one-hot 向量的形式提供。

稀疏分类交叉熵损失函数在多类别分类问题中广泛应用,特别适用于类别较多的情况。它可以作为模型的目标函数,通过优化算法(如 Adam)来最小化损失,从而使模型更好地学习分类任务。

one-hot向量

One-hot向量是一种用于表示离散类别的编码方式。它是一个二进制向量,其中只有一个元素为1,其余元素都为0。在一个one-hot向量中,1的位置表示对应的类别,而0表示非该类别。

举个例子来说明,假设有三个类别:狗、猫和鸟。使用one-hot向量表示这三个类别可以如下所示:

  • 狗:[1, 0, 0]
  • 猫:[0, 1, 0]
  • 鸟:[0, 0, 1]

在上述表示中,每个类别都有一个对应的位置为1,表示该类别,而其他位置都为0,表示非该类别。

使用one-hot向量的好处是能够将离散的类别信息转化为计算机可以处理的数值表示。在机器学习和深度学习中,经常需要将类别信息转换为数值向量,以便进行模型训练和预测。通过使用one-hot向量,可以将类别之间的关系消除,并且可以直接应用于一些分类算法和神经网络模型中。

总结来说,one-hot向量是一种将离散类别表示为二进制编码的方式,其中只有一个位置为1,其他位置为0,用于表示类别信息,并在机器学习和深度学习中广泛应用于分类任务。

(x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data()
数据集分为测试集和训练集

x_train = x_train.reshape(-1, 28, 28, 1) / 255.0

  1. x_train是训练数据集的输入特征,它是一个四维数组,表示由多张灰度图像组成的图像集。每张图像的大小为28x28像素。

  2. x_train.reshape(-1, 28, 28, 1)将训练数据集的形状调整为(-1, 28, 28, 1)。其中,-1表示自动计算该维度的大小,28x28表示每张图像的尺寸,而1表示图像的通道数。这里将图像集中的每张图像由原来的二维数组形式调整为具有单通道的三维数组形式。

  3. / 255.0将调整后的图像集进行归一化操作,将像素值缩放到0到1之间。这里将每个像素值除以255,原因是图像的像素值通常是在0到255之间的整数,通过除以255可以将像素值归一化到0到1的浮点数范围内,方便模型进行处理。

总之,这行代码将训练数据集的形状调整为合适的输入形式,并对像素值进行归一化处理,以便在训练模型之前进行有效的预处理。

model.fit(x_train, y_train, epochs=5, batch_size=64)

  1. x_train是训练数据集的输入特征,包含了多张图像。

  2. y_train是训练数据集的标签,表示每张图像对应的类别或标记。

  3. epochs=5表示要对整个训练数据集进行5次迭代训练。每个epoch表示对整个数据集进行一次完整的前向传播和反向传播。

  4. batch_size=64表示每次迭代使用的样本批次大小为64。训练数据集会被分成多个批次,每个批次包含64个样本。模型在每个批次上计算损失值,并根据损失值进行参数更新。

通过执行model.fit(x_train, y_train, epochs=5, batch_size=64),模型将根据训练数据集进行多次迭代,逐渐调整权重和偏置,以最小化损失函数并提高模型的准确性。训练过程中将自动执行前向传播、反向传播和参数更新等步骤,直到达到指定的训练轮数(epochs)为止。

loss, accuracy = model.evaluate(x_test, y_test)

  1. x_test是测试数据集的输入特征,包含了多张图像。

  2. y_test是测试数据集的标签,表示每张图像对应的类别或标记。

  3. model.evaluate(x_test, y_test)会使用测试数据集对模型进行评估,并返回评估结果。

  4. loss是模型在测试数据集上的损失值,表示模型在预测过程中与实际标签之间的差异程度。损失值越小表示模型的预测结果越接近真实标签。

  5. accuracy是模型在测试数据集上的准确率,表示模型在测试数据集上分类正确的样本比例。准确率越高表示模型的预测结果越准确。

通过执行loss, accuracy = model.evaluate(x_test, y_test),可以获取模型在测试数据集上的损失值和准确率,以评估模型在未见过的数据上的性能表现。

GCN

GCN(Graph Convolutional Network)是一种基于图结构的深度学习模型。它是一种卷积神经网络(Convolutional Neural Network)的变体,专门用于处理图数据。

GCN通过利用图的邻接矩阵和节点特征进行图卷积操作,从而学习节点的表示向量。与传统的CNN不同,GCN考虑了图数据的拓扑结构和节点之间的关系。它在节点的特征表示中融入了邻居节点的信息,通过图卷积操作将邻居节点的特征进行聚合和传播,从而得到更丰富和具有语义关联的节点表示。

GCN的基本原理是通过迭代地更新节点的表示向量,利用节点特征和邻居节点的信息来进行节点表示的学习。这种迭代更新的过程可以通过多个图卷积层来实现,每个图卷积层都会更新节点的表示向量,并利用邻接矩阵和节点特征进行信息传递和聚合。

GCN在图结构数据的应用场景中具有广泛的应用,如社交网络分析、推荐系统、图像分割、节点分类等。它能够有效地捕捉节点之间的关系和图的全局结构,对于处理具有复杂拓扑结构的数据具有很强的表达能力。

图卷积计算公式

熵 

 就是描述信息的不确定的程度,统计学中,对事件的 发生情况可以通过概率P定量的描述出来,熵也是一种统计学 定量描述,是对信息的不确定程度的描述,这种描述也是通过“概率P”来描述的。
计算公式:

 交叉熵

主要度量两个概率分布间的差异性信息。

 

GCN实例 

        Zachary 空手道俱乐部是一个被广泛使用的社交网络,其中的节点代表空手道俱乐部的成员,边代表成员之间的相互关系。当年,Zachary 在研究空手道俱乐部的时候,管理员和教员发生了冲突,导致俱乐部一分为二。下图显示了该网络的图表征,其中的节点标注是根据节点属于俱乐部的哪个部分而得到的,蓝色和红色分别表示属于管理员和教员阵营的节点。

 

#构建GCN
from networkx import to_numpy_matrix
import networkx as nx
import numpy as np
import matplotlib.pyplot as plt
zkc =nx.karate_club_graph()#创建空的跆拳道俱乐部图
order = sorted(list(zkc.nodes()))
A = to_numpy_matrix(zkc, nodelist=order)#邻接矩阵
I = np.eye(zkc.number_of_nodes())#单位矩阵
A_hat = A + I#加入self-loops:A*X(特征集合) 的结点表示中,并没有加自己的特征值。
D_hat = np.array(np.sum(A_hat, axis=0))[0]#计算度矩阵
D_hat = np.matrix(np.diag(D_hat))



def plot_graph(G, weight_name=None):
    plt.figure()
    pos = nx.spring_layout(G)
    edges = G.edges()
    weights = None

    if weight_name:
        weights = [int(G[u][v][weight_name]) for u, v in edges]
        labels = nx.get_edge_attributes(G, weight_name)
        nx.draw_networkx_edge_labels(G, pos, edge_labels=labels)
        nx.draw_networkx(G, pos, edges=edges, width=weights);
    else:
        nodelist1 = []
        nodelist2 = []
        for i in range(34):
            if zkc.nodes[i]['club'] == 'Mr. Hi':
                nodelist1.append(i)
            else:
                nodelist2.append(i)
        # nx.draw_networkx(G, pos, edges=edges);
        nx.draw_networkx_nodes(G, pos, nodelist=nodelist1, node_size=300, node_color='r', alpha=0.8)
        nx.draw_networkx_nodes(G, pos, nodelist=nodelist2, node_size=300, node_color='b', alpha=0.8)
        nx.draw_networkx_edges(G, pos, edgelist=edges, alpha=0.4)
plot_graph(zkc)
#添加权重
W_1 = np.random.normal(
    loc=0, scale=1, size=(zkc.number_of_nodes(), 4))
W_2 = np.random.normal(
    loc=0, size=(W_1.shape[1], 2))
#定义激活函数relu
def relu(x):
    return (abs(x) + x) / 2
#计算
def gcn_layer(A_hat, D_hat, X, W):
    return relu(D_hat**-1 * A_hat * X * W)
H_1 = gcn_layer(A_hat, D_hat, I, W_1)
H_2 = gcn_layer(A_hat, D_hat, H_1, W_2)
output = H_2
feature_representations = {
    node: np.array(output)[node]
    for node in zkc.nodes()}
feature_representations
plt.figure()
for i in range (34):
    if zkc.nodes[i]['club'] == 'Mr. Hi':
        plt.scatter(np.array(output)[i,0],np.array(output)[i,1] ,color = 'b',alpha=0.5,s = 100)
    else:
        plt.scatter(np.array(output)[i,0],np.array(output)[i,1] ,color = 'r',alpha=0.5,s = 100)
plt.show()

networkx 

NetworkX是一个用于创建、操作和研究复杂网络结构的Python软件包。它提供了丰富的工具和函数,用于构建、分析和可视化各种类型的网络,包括无向图、有向图、加权图等。NetworkX提供了灵活的数据结构,使得用户可以方便地表示节点和边,并进行各种操作和分析。

使用NetworkX,你可以创建一个空白的网络,添加节点和边,计算网络中的度分布、聚集系数、最短路径等指标,进行节点中心性分析,执行社区检测算法,进行网络可视化等。它还提供了许多功能强大的算法和工具,用于研究网络结构、进行复杂网络分析和建模。

zkc =nx.karate_club_graph()

karate_club_graph是NetworkX库中的一个内置函数,用于生成Zachary的空手道俱乐部网络。这个网络具有34个节点和78条边,每个节点代表俱乐部的一个成员,边表示成员之间的关系。这个网络常用于社交网络分析和图算法的演示。

order = sorted(list(zkc.nodes()))

具体来说,代码首先使用list(zkc.nodes())将图zkc中的节点转换为列表形式,然后使用sorted()函数对该列表进行排序。排序后的结果是节点的标识按升序排列的新列表。

排序节点的目的是为了在后续处理中按照一定的顺序进行操作。对节点进行排序可以使得节点在列表中的索引与其标识对应,方便后续根据索引访问和操作节点。例如,可以通过order[i]来获取排序后的第i个节点的标识。

to_numpy_matrix(zkc, nodelist=order)

to_numpy_matrix函数将图的节点按照给定的顺序(在这里是nodelist=order)转换为一个Numpy数组表示的邻接矩阵。

D_hat = np.array(np.sum(A_hat, axis=0))[0]

  • np.sum(A_hat, axis=0):这部分代码计算了A_hat矩阵每列元素的和,axis=0表示按列求和。结果是一个行向量,表示每个节点的度(即与该节点相连的边的数量)。

  • np.array(...)[0]:这部分代码将上一步计算得到的行向量转换为一个Numpy数组,并取该数组的第一个元素。这是因为np.sum函数返回的结果是一个1维数组,我们只需要其中的一个值作为度矩阵的对角线元素。

D_hat = np.array(np.sum(A_hat, axis=0))

 D_hat = np.matrix(np.diag(D_hat))

  • np.diag(D_hat):这部分代码将一维数组D_hat的元素按顺序放置在对角线上,其他位置上的元素都为零。这样得到的结果是一个对角矩阵,对角线上的元素就是原始一维数组的元素。

  • np.matrix(...):这部分代码将对角矩阵转换为NumPy的矩阵对象。使用np.matrix()函数可以创建一个特殊类型的矩阵对象,它支持更多的矩阵操作。

pos = nx.spring_layout(G)

pos 是一个包含了每个节点的坐标信息的字典。它将被用于在绘制图形时指定节点的位置。

绘制标签

在绘图中,绘制标签指的是在图形中的节点或边上添加文本或数值信息,以提供额外的可视化表示或描述。标签可以是节点的名称、属性值、边的权重、边的类型等。

def gcn_layer(A_hat, D_hat, X, W):
    return relu(D_hat**-1 * A_hat * X * W)

这段代码实现了一个GCN(Graph Convolutional Network)的层操作

具体地,该函数实现了一个GCN层的计算过程,输入参数包括:

  • A_hat: 归一化后的邻接矩阵,表示图中节点之间的连接关系。
  • D_hat: 归一化后的度矩阵的对角线,表示节点的度信息。
  • X: 输入特征矩阵,表示每个节点的特征向量。
  • W: 权重矩阵,表示该层的学习参数。

函数的计算过程如下:

  1. D_hat**-1: 对归一化的度矩阵的对角线进行逆操作,得到每个节点的度的倒数。
  2. A_hat * X: 将归一化的邻接矩阵与输入特征矩阵相乘,表示将节点的邻居特征进行聚合。
  3. D_hat**-1 * A_hat * X: 将步骤2的结果乘以每个节点的度的倒数,进行归一化操作。
  4. D_hat**-1 * A_hat * X * W: 将归一化后的特征矩阵与权重矩阵相乘,进行线性变换。
  5. relu(): 对结果进行ReLU激活函数的操作,引入非线性性质。

最终,该函数返回经过GCN层计算后的特征矩阵。该层的计算过程将邻居节点的特征聚合并进行线性变换,通过激活函数引入非线性性质,以提取和表达节点在图结构中的关联信息。

feature_representations = {
    node: np.array(output)[node]
    for node in zkc.nodes()}

在给定的图 zkc 中,对于每个节点,代码通过调用某个模型(未给出)的输出结果 output,将其转换为一个NumPy数组。然后,使用字典推导式遍历图中的每个节点,将节点索引作为键,将对应节点的特征表示作为值,构建了一个名为 feature_representations(特征表示) 的字典。 

plt.scatter

plt.scatter(x, y, s=None, c=None, marker=None, cmap=None, alpha=None)
  • x:数据点的 x 坐标,可以是一个数组或列表。
  • y:数据点的 y 坐标,可以是一个数组或列表。
  • s:数据点的大小(可选),可以是一个标量或与 xy 等长的数组。
  • c:数据点的颜色(可选),可以是一个标量、与 xy 等长的数组,或表示颜色的字符串。
  • marker:数据点的标记形状(可选),默认为圆形。常用的标记形状包括 'o'(圆形)、's'(正方形)、'+'(加号)等。
  • cmap:颜色映射(可选),用于为每个数据点指定一个颜色映射。常用的颜色映射有 'viridis''jet''rainbow' 等。
  • alpha:数据点的透明度(可选),取值范围为 0 到 1。

实例结果示意图

 RNN(循环神经网络)

RNN(Recurrent Neural Network,循环神经网络)是一种广泛应用于序列数据处理的神经网络模型。相比于传统的前馈神经网络,RNN 具有记忆和持续状态的能力,可以处理可变长度的输入序列。

RNN 的核心思想是引入循环结构,将当前时刻的输入与前一时刻的隐藏状态进行结合,然后通过激活函数产生当前时刻的输出和新的隐藏状态。这种循环的结构使得 RNN 在处理序列数据时可以保留过去的信息,并在当前时刻的计算中考虑上下文依赖关系。

RNN 的一个关键特性是参数共享。在同一个 RNN 模型中,每个时刻都使用相同的权重参数进行计算,因此模型可以处理任意长度的序列,并且参数数量不会随序列长度而增加。

RNN 在自然语言处理、语音识别、机器翻译等任务中得到广泛应用。然而,传统的 RNN 在处理长序列时容易遇到梯度消失或梯度爆炸的问题,导致难以捕捉长距离依赖关系。为了解决这个问题,出现了一些 RNN 的变种,如长短时记忆网络(LSTM)和门控循环单元(GRU),它们引入了门控机制来控制信息的流动,有效地缓解了梯度问题,并增强了 RNN 模型的记忆能力。

RNN具有短期记忆功能

 

对于右图,RNN每一时刻的隐藏状态不仅由该时刻的输入决定,还取决于上一时刻的隐藏状态的值,如右图中间模型当t时刻输入后,St取决于Xt和S(t-1)所以左图中当输入x后,会不断重复w过程,每次的s的值都是由本次的x和上次的s综合决定的,最后输出o 

 梯度爆炸与梯度消失

当往回看时,在反向传播过程中每一时刻倒退回上一时刻需要乘以一个参数,那么如果这个参数大于1,在最后的误差会不断乘以一个大于1的参数然后越往前越大,最终这个误差会变得巨大(指数增长速度非常快),我们将其称之为梯度爆炸(如下图左);反之,若这个参数小于1,那么在经过无数次的相乘后,在最后的误差到了前面会无限趋近于0,我们将其称之为梯度消失(如下图右)。

RNN实例 

 

"""
构建RNN
input_size:这个参数表⽰的输⼊数据的维度
hidden_size :可以理解为在 CNN 中,⼀个卷积层的输出维度⼀样。这⾥表⽰将前⾯的 input_size 映射到⼀个什么维度上。
num_layers:表⽰循环的层数。举个栗⼦,将 num_layers 设置为 2,也就是将两个 RNN 堆叠在⼀起,第⼀层的输出作为第⼆层的输⼊
"""
class RNN(nn.Module):
    def __init__(self, input_size, hidden_size, output_size, num_layers=1):
        super(RNN, self).__init__()
        self.hidden_size = hidden_size
        self.num_layers = num_layers
        self.rnn = nn.RNN(input_size, hidden_size, num_layers)
        self.linear = nn.Linear(hidden_size, output_size)
        self.softmax = nn.LogSoftmax(dim=-1)

    def forward(self, input, hidden):
        # 将input和之前的网络中的隐藏层参数合并。
        input = input.view(len(input), 1, -1)
        rr, hidden = self.rnn(input, hidden)  # 计算隐藏层参数
        output = self.softmax(self.linear(rr))  # 计算网络输出的结果
        return output, hidden

    def init_hidden(self):
        # 初始化隐藏层参数hidden
        return torch.zeros(self.num_layers, 1, self.hidden_size)

def __init__(self, input_size, hidden_size, output_size, num_layers=1)

这是模型类的构造函数,用于初始化模型的参数。参数input_size表示输入特征的维度,hidden_size表示隐藏层的维度,output_size表示输出的维度,num_layers表示RNN层的数量。

self.rnn = nn.RNN(input_size, hidden_size, num_layers)

在这个例子中,通过使用 nn.RNN(input_size, hidden_size, num_layers) 创建了一个 RNN 层对象,并将其赋值给 self.rnn。这意味着模型中的 self.rnn 属性是一个 RNN 层,该层的输入特征维度为 input_size,隐藏状态维度为 hidden_size,堆叠层数为 num_layers

super

super() 是一个内置函数,用于调用父类的方法。在面向对象的编程中,一个类可以继承另一个类,子类可以继承父类的属性和方法。当子类需要扩展父类的方法时,可以使用 super() 函数来调用父类的方法。

input = input.view(len(input), 1, -1)

通过 view 函数将输入数据的维度进行调整,将其转换为形状为 (序列长度, 1, 输入特征维度) 的张量,以符合 RNN 模型的输入要求。

rr

rr 是 RNN 模型的输出结果,它表示经过 RNN 层计算后得到的隐藏状态序列。在每个时间步上,RNN 模型会根据当前的输入和之前的隐藏状态计算出一个新的隐藏状态,并将其作为下一个时间步的输入。

LSTM

具有长期记忆功能

1.支线rnn每次输入后LSTM对输入进行判断,按内容重要程度按比例存入主线
2.LSTM具有忘记功能,当本次支线输入的内容影响主线的输出并且LSMT判断影响是对的,比如主线上之前的内容判断目的地是重庆,而支线本次的输入说目的地是上海,而LSTM判断认为目的地更有可能是上海,那么它就会将主线上影响输出目的地是重庆的内容删除,然后将本次支线上影响输出目的地是上海的内容按比例存入主线
3.最终LSTM将根据主线和支线综合判断输出

Transformer

传统的序列模型(如循环神经网络RNN)在处理长序列时存在一些问题,如难以捕捉长距离依赖关系和并行计算的困难。Transformer模型通过引入自注意力机制(self-attention)来解决这些问题。

Transformer模型由编码器和解码器组成,每个部分都由多个层堆叠而成。编码器负责将输入序列转换为一系列高级表示,而解码器则利用这些表示生成输出序列。

自注意力机制允许模型在处理序列时将不同位置的信息进行关联。它通过计算输入序列中不同位置的注意力权重来决定每个位置的表示应该如何受到其他位置的影响。这种机制使得模型能够捕捉到长距离的依赖关系,并且可以并行计算,从而提高了计算效率。

除了自注意力机制,Transformer还引入了残差连接和层归一化等技术,以加强模型的训练和优化能力。此外,Transformer还使用了位置编码来保留输入序列中的顺序信息。

 图解transformer

一文打尽知识图谱(超级干货,建议收藏!) - 知乎​​​​​​

GCN的案例链接

RNN的案例链接

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值