Dawn's Blogs

分享技术 记录成长

0%

论文

Relation Classification via Convolutional Deep Neural Network

  • 发布年份:2014
  • 会议:COLING
  • 作者:Daojian Zeng,Kang Liu,Siwei Lai,Guangyou Zhou and Jun Zhao
  • 机构:National Laboratory of Pattern Recognition,Institute of Automation
  • 贡献:第一次在 relation classification 领域运用 convolutional DNN
  • 数据集: SemEval-2010 Task 8 dataset, http://docs.google.com/View?id=dfvxd49s。该数据集包含 10717 条被标注的数据(包括 8000 条训练用例和 2717 条测试用例。

模型结构

整个模型得架构如下:

  • Input:带有两个被标记单词的一句话。
  • Word Representation:将每个单词转为词嵌入。
  • Feature Extraction:分别提取单词级别的特征和句子级别的特征,然后将两个特征向量连接起来。
  • Output:简单的线性层+softmax 分类。

1665645411026

阅读全文 »

分布式事务

分布式事务,分为两类:

  • 内部分布式事务:分布式数据库(Spanner、TiDB)跨节点的内部事务。
  • 异构分布式事务:跨服务、跨数据库的事务。

DTM 用于解决异构分布式事务的一致性问题。在下文中,分布式事务特指异构分布式事务。以下是异构分布式事务(跨数据库、跨服务、混合)的示意图。

1665576572271

事务的一致性:

  • 本地事务使用 MVCC 技术,支持高并发(隔离级别为 Repeatable Read)下的一致性。
  • 内部分布式事务也可以通过 MVCC 技术,保证严格的一致性。
  • 异构分布式事务,因为没有统一的版本号,无法做 MVCC。目前没用支持跨数据库的严格一致性方案。
阅读全文 »

DMCNN 简介

DMCNN 由以下组成:

  • Embedding Learning:采用 Skip-gram 预训练模型。
  • Lexical Feature Representation:触发词和论元的上下文 token,并将这些拼接起来形成词汇级特征表示向量L。
  • DMCNN 结构:
    • 输入包括三个部分 CWF(Context-Word Feature)、PF(Position Feature)、EF(Event-type feature,在本模型复现中没用用到)。
    • 多个 filter 进行卷积,每一个 filter 生成一个feature map,把每一个 feature map 分为三个部分,对这三个部分分别进行 max-pool 操作就是动态池化操作,得到向量 P。
  • 分类输出:将P和L连接起来,送入一个分类器中。

1664963639460

阅读全文 »

1
2
3
4
5
6
7
8
9
10
11
12
import json
import numpy as np
import joblib

with open('./preprocess/dataset.json', 'r') as f:
dataset = json.load(f)

len(dataset)
# 1665

MAX_SEQUENCE_LENGTH = 85 # 句子最大长度
EVENT_TYPE = 7 # 事件类型数量

Word2Vec

生成 embedding_index

这里用的预训练Word2Vec语料为 sgns.weibo.bigram-char,建立一个字典 embedding_index,用来记录 word 与 vec 的映射。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from keras.preprocessing.text import Tokenizer
from keras.preprocessing.sequence import pad_sequences

embeddings_index = {}
with open('path-to/sgns.weibo.bigram-char', encoding='utf-8') as f:
lines = f.readlines()
lines = [l.strip() for l in lines]
print(lines[0]) # 195197 300,共有195197个词,embedding-dim为300

for line in lines[1:]:
word, coefs = line.split(maxsplit=1)
coefs = np.fromstring(coefs, 'f', sep=' ') # 转为vec
embeddings_index[word] = coefs

print('Found %s word vectors.' % len(embeddings_index))
# Found 195197 word vectors.
阅读全文 »

代码来源:https://github.com/RMSnow/KG-Course,代码目录结构如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
- EventExtraction/
- data/
- preprocess/(数据预处理)
- CEC/(原数据文件)
- dataset.json(实验数据集)
- preprocess.ipynb(预处理、数据分析的代码)
- data_load.ipynb(制作模型所需要的各项输入、输出矩阵)
- *.npy(模型的输入与输出)
- model/
- img/(由keras自动生成的模型架构图)
- model/(训练好的模型参数文件)
- predict/(模型预测输出的矩阵)
- dataset_split.py(训练集/测试集划分)
- DMCNN.py(DMCNN模型与CNN模型)
- TextCNN.py(TextCNN模型)
- train.py(训练、预测所需的各项函数)
- *.ipynb(训练过程、模型预测、性能结果等)
- readme.md

数据格式为 XML 格式,如下。其中 Event 记录了每一个标签,在 Event 标签下 Denoter 标签为触发词

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
<?xml version="1.0" encoding="UTF-8"?>

<Body>
<Title>澳大利亚2014年火灾:高温致一夜间发生几百起火灾</Title>
<ReportTime type="absTime">2014年1月15日</ReportTime>
<Content>
<Paragraph>
<Sentence>
<Event eid="e1" type="thoughtevent">
<Time tid="t1" type="relTime">1月15日,</Time> 据外媒
<Participant sid="s1">《俄罗斯报》</Participant> 报道
<Denoter type="statement" did="d1"></Denoter>
</Event>
<Event eid="e2">位于
<Location lid="l2">北半球</Location>
<Participant sid="s2">澳大利亚</Participant> 现在正
<Denoter did="d2" type="movement">处于</Denoter>
<Object oid="o2">炎热的夏季</Object>
</Event>
<Event eid="e3">而近日也到了高温酷暑的时候,当地时间
<Time tid="t3" type="relTime">1月14日晚</Time>
<Location lid="l3">澳大利亚南部</Location> 一夜间发生至少250起
<Denoter type="emergency" did="d3">火灾</Denoter>
</Event>
</Sentence>
<Sentence>受炎热天气及雷雨天气影响,
<Event eid="e4">
<Location lid="l4">澳大利亚南部</Location>一夜间发生至少250起
<Denoter did="d4" type="emergency">火灾</Denoter>,灾情多集中在维多利亚州。
</Event>
</Sentence>
<Sentence>
<Event eid="e5">火灾发生后,
<Participant sid="s5">救援人员</Participant> 立即
<Denoter did="d5" type="operation">展开</Denoter>
<Object oid="o5">救灾行动</Object>
</Event>
</Sentence>
<Sentence>目前,大部分起火点火势已被控制。</Sentence>
</Paragraph>
</Content>
<eRelation relType="Thoughtcontent" thoughtevent_eid="e1" thoughtcontent_eids="e2-e5"/>
<eRelation relType="Follow" bevent_eid="e4" aevent_eid="e5"/>
</Body>
阅读全文 »

Micro

Micro 是用来构建和管理分布式程序的系统,组成如下:

  • Runtime(运行时):用来管理配置、认证、网络等。

  • Framework(程序开发框架):用来编写微服务。

  • Clients(多语言客户端)支持多语音访问服务端。

Runtime

Runtime(运行时)是工具集,组成:

  • api:api 网关,把微服务组合起来,形成单一的入口方便调用。
  • broker:允许处理异步消息的代理。
  • network:通过微网络服务构建多云网络。
  • new:服务模板生成器。
  • proxy:建立在 Go Micro 上的透明服务代理。
  • registry:一个服务资源管理器,通过注册的方式提供服务发现以及查找服务。
  • store:简单的状态存储。
  • web:Web 仪表盘,通过 Web 仪表盘的方式浏览服务。

Framework(go-micro)

go-micro 是 Micro 的一种 Framework,是对分布式系统的高度抽象、提供分布式系统开发的核心库、可插拔的架构,按需使用。组件如下:

  • 注册(Registry):提供了服务发现机制。
  • 选择器(Selector):能够实现负载均衡。
  • 传输(Transport):服务和服务之间的通信。
  • Broker:提供异步消息的消息发布/订阅接口。
  • 编码(Codec):消息传输的编码与解码。
  • Server、Client:服务的提供者和使用者。

go-micro 的通信如下:

  • Server 通过 Registry 将服务注册到服务注册中心,Client 通过 Selector 从服务注册中心进行服务发现。
  • Client 通过 Broker 发布消息到消息中间件中,Server 通过 Broker 从消息中间件中读取订阅消息。

1663591380963

阅读全文 »

gRPC

介绍

  • gRPC 是一个高性能、开源、通用的RPC框架。
  • 基于 HTTP 2.0 开发,支持双向流、消息头压缩、单 TCP 的多路复用等特性。
  • 支持多语言,默认采用 Protocol Buffers 数据序列化协议。
  • gRPC 开发的核心在于编写 *.proto 文件,它定义了 gRPC 的服务和消息,根据这个文件可以生成多语言的标准代码(所以只需要传送 *.proto 文件,就可以生成多语言支持的代码)。

调用流程

gRPC的整体流程如下:

  • 客户端通过 Protocol Buffers 协议序列化发送请求到服务端。
  • 服务器收到请求后将请求内容反序列化,本地调用函数并返回结果。
  • 服务端将结果通过 Protocol Buffers 协议序列化后,回送响应。
  • 客户端反序列化请求内容,得到远程调用结果。
阅读全文 »

海象运算符

从 Python 3.8 开始,加入了海象运算符 :=,语法格式是 variable_name := expression

用法

用于 if-else 条件表达式中

1
2
if a := 5 > 1:
print("do sth")

用于 while 循环

1
2
3
4
5
6
7
8
9
10
# 常规写法
n = 3
while n:
    print('do sth!')
    n -= 1

# 升级写法
n = 3
while (n := n - 1) + 1
    print('do sth!')

加 1 是因为在循环条件判断之前,n 已经减 1 了。

读取文件

1
2
3
fp = open("test.txt""r")
while line := fp.readline():
    print(line)
阅读全文 »

装饰器

装饰器(Decorators),是 Python 中修改其他函数的功能的函数,有助于让我们的代码更简短。

比如可以用一个简易的装饰器,定义一个函数执行之前或者执行之后做的额外工作

1
2
3
4
5
6
7
8
9
10
11
# 这是一个装饰器
def a_new_decorator(a_func):

def wrapTheFunction():
print("I am doing some boring work before executing a_func()")

a_func()

print("I am doing some boring work after executing a_func()")

return wrapTheFunction

当一个函数需要这个装饰器时,可以这样调用:

1
2
3
4
5
6
7
8
9
10
def a_function_requiring_decoration():
print("I am the function which needs some decoration to remove my foul smell")

a_function_requiring_decoration = a_new_decorator(a_function_requiring_decoration)
#now a_function_requiring_decoration is wrapped by wrapTheFunction()

a_function_requiring_decoration()
#outputs:I am doing some boring work before executing a_func()
# I am the function which needs some decoration to remove my foul smell
# I am doing some boring work after executing a_func()

@ 符号

以上就是一个手动实现的装饰器,可以用 @ 符号来更简单的实现。事实上,@a_new_decorator 就是以下语句的简易声明

a_function_requiring_decoration = a_new_decorator(a_function_requiring_decoration)

1
2
3
4
5
6
7
8
@a_new_decorator
def a_function_requiring_decoration():
print("I am the function which needs some decoration to remove my foul smell")

a_function_requiring_decoration()
#outputs: I am doing some boring work before executing a_func()
# I am the function which needs some decoration to remove my foul smell
# I am doing some boring work after executing a_func()

但是,运行如下代码会存在一个问题

1
2
print(a_function_requiring_decoration.__name__)
# Output: wrapTheFunction

因为函数 a_function_requiring_decoration 被重写了,所以这个函数被 warpTheFunction 替代了,这里就需要 functools.wraps

functools.wraps

修改修饰器的声明方式即可解决上述问题:

1
2
3
4
5
6
7
8
9
from functools import wraps

def a_new_decorator(a_func):
@wraps(a_func)
def wrapTheFunction():
print("I am doing some boring work before executing a_func()")
a_func()
print("I am doing some boring work after executing a_func()")
return wrapTheFunction
阅读全文 »

CNN

对于图片而言,通常使用 CNN(卷积神经网络)。

简化全连接神经网络

若使用全连接神经网络,则参数很多,容易过拟合。

对于图片检测而言,也行不需要看整张图片,只需要看到图片的一部分(所以提出 Receptive Field),就可以检测 pattern。CNN 的简化方式就是一个 Receptive Field 对应于一个神经网络单元。典型的 Receptive Field 设置如下:

  • 一个 Receptive Field 包含了图片的所有 channel(深度),长度 × 宽度被称为 kernel size。
  • Receptive Field 移动的距离称为步长(stride)
  • 若 Receptive Field 超出了图片的范围,需要填充(padding)

1657158365832

共享参数

对于图像识别而言,同一个 pattern 的位置可能不同,Receptive Field 用于检测 pattern。

所以对于不同位置的 Receptive Field,可以共享参数(因为尽管这些 Receptive Field 在不同位置,但是它们在检测同一个 pattern)。

1657158755492

Convolutional Layer

Respective Field + 参数共享 = Convolutional Layer(卷积层)。

卷积层中含有很多 filter(一个 filter 相当于一个 Respective Field,filter 中的参数相当于 Respective Field 送入神经网络单元的权重/参数)。

卷积层产生的输出称之为 Feature Map,这可以看作是一个新的图片,图片的 channel 等于 filter 的个数。

池化

池化(Pooling)相当于缩小图片,在人类看来缩小图片,不会影响到 pattern 的检测。

如,Max Pooling:将图片分成多块,提取出每个块中最大的值。

组合起来

在卷积和池化之后,将得到的结果(相比于原始图片小了很多)送入全连接神经网络,就得到了完整的 CNN 网络。

1657160205164

RNN

基本结构

RNN 中,会将上一次输入的产生的东西保存下来,作为本次的一个输入。

分为 Elman Network 和 Jordan Network:

  • Elman Network:保存的是 hiden layer 的值。
  • Jordan Network:保存的是 output 的值。

1657161992754

双向 RNN

RNN 可以是双向的,训练一个正向 RNN 和一个逆向 RNN,将正向和逆向的输出合并起来进行输出。

1657162262353

LSTM

LSTM(Long Short-term Memory)

1657162786833

1657163055876

1657164185170