Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
T
Toy-MT-Introduction
概览
Overview
Details
Activity
Cycle Analytics
版本库
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
问题
0
Issues
0
列表
Board
标记
里程碑
合并请求
0
Merge Requests
0
CI / CD
CI / CD
流水线
作业
日程表
图表
维基
Wiki
代码片段
Snippets
成员
Collapse sidebar
Close sidebar
活动
图像
聊天
创建新问题
作业
提交
Issue Boards
Open sidebar
NiuTrans
Toy-MT-Introduction
Commits
41482568
Commit
41482568
authored
May 14, 2020
by
曹润柘
Browse files
Options
Browse Files
Download
Plain Diff
合并分支 'caorunzhe' 到 'master'
Caorunzhe 查看合并请求
!182
parents
68f1ed1a
278abb77
隐藏空白字符变更
内嵌
并排
正在显示
3 个修改的文件
包含
11 行增加
和
8 行删除
+11
-8
Book/Chapter6/Chapter6.tex
+6
-6
Book/Chapter6/Figures/figure-structure-of-a-recurrent-network-model.tex
+1
-1
Book/Chapter7/Figures/figure-machine-translation-performance-curve.tex
+4
-1
没有找到文件。
Book/Chapter6/Chapter6.tex
查看文件 @
41482568
...
@@ -27,7 +27,7 @@
...
@@ -27,7 +27,7 @@
\parinterval
纵观机器翻译的发展历程,神经机器翻译诞生很晚。无论是早期的基于规则的方法,还是逐渐发展起来的基于实例的方法,再到上世纪末的统计方法,每次机器翻译框架级的创新都需要很长时间的酝酿,而技术走向成熟甚至需要更长的时间。但是,神经机器翻译的出现和后来的发展速度多少有些令人``出人意料''。神经机器翻译的概念出现在2013-2014年间,当时机器翻译领域的主流方法仍然是统计机器翻译。虽然那个时期深度学习已经在图像、语音等领域取得令人瞩目的效果,但是对于自然语言处理来说深度学习仍然不是主流。这也导致当时的研究者对神经机器翻译这种方法还有一些排斥。
\parinterval
纵观机器翻译的发展历程,神经机器翻译诞生很晚。无论是早期的基于规则的方法,还是逐渐发展起来的基于实例的方法,再到上世纪末的统计方法,每次机器翻译框架级的创新都需要很长时间的酝酿,而技术走向成熟甚至需要更长的时间。但是,神经机器翻译的出现和后来的发展速度多少有些令人``出人意料''。神经机器翻译的概念出现在2013-2014年间,当时机器翻译领域的主流方法仍然是统计机器翻译。虽然那个时期深度学习已经在图像、语音等领域取得令人瞩目的效果,但是对于自然语言处理来说深度学习仍然不是主流。这也导致当时的研究者对神经机器翻译这种方法还有一些排斥。
\parinterval
不过,有人也意识到了神经机器翻译在表示学习等方面的优势。特别是,以Yoshua Bengio团队为代表的研究力量对包括机器翻译在内的序列到序列问题进行了广泛而深入的研究,注意力机制等新的模型不断被推出。这使得神经机器翻译系统在翻译品质上逐渐体现出优势,甚至超越了当时的统计机器翻译系统。正当大家在讨论神经机器翻译是否能取代统计机器翻译成为下一代机器翻译
的
范式的时候,谷歌、百度等企业推出以神经机器翻译技术为内核的在线机器翻译服务,在很多场景下的翻译品质显著超越了当时最好的统计机器翻译系统。这也引发了学术界和产业界对神经机器翻译的讨论。随着关注度的不断升高,神经机器翻译的研究吸引了更多的科研机构和企业的投入,神经机器翻译系统的翻译品质得到进一步提升。
\parinterval
不过,有人也意识到了神经机器翻译在表示学习等方面的优势。特别是,以Yoshua Bengio团队为代表的研究力量对包括机器翻译在内的序列到序列问题进行了广泛而深入的研究,注意力机制等新的模型不断被推出。这使得神经机器翻译系统在翻译品质上逐渐体现出优势,甚至超越了当时的统计机器翻译系统。正当大家在讨论神经机器翻译是否能取代统计机器翻译成为下一代机器翻译范式的时候,谷歌、百度等企业推出以神经机器翻译技术为内核的在线机器翻译服务,在很多场景下的翻译品质显著超越了当时最好的统计机器翻译系统。这也引发了学术界和产业界对神经机器翻译的讨论。随着关注度的不断升高,神经机器翻译的研究吸引了更多的科研机构和企业的投入,神经机器翻译系统的翻译品质得到进一步提升。
\parinterval
在短短5-6年间,神经机器翻译从一个新生的概念已经成长为机器翻译领域的最前沿技术之一,在各种机器翻译评测和应用中呈全面替代统计机器翻译之势。比如,从近几年WMT、CCMT等评测的结果来看,神经机器翻译已经处于绝对的统治地位,在不同语种和领域的翻译任务中,成为各参赛系统的标配。此外,从ACL等自然语言处理顶级会议的发表论文看,神经机器翻译是毫无疑问的焦点,在论文数量上呈明显的增长趋势,这也体现了学术界对该方法的热情。至今,无论是国外的著名企业,如谷歌、微软、脸书,还是国内的团队,如百度、腾讯、阿里巴巴、有道、搜狗、小牛翻译,都推出了自己研发的神经机器翻译系统,整个研究和产业生态欣欣向荣。图
\ref
{
fig:6-1
}
展示了包含神经机器翻译在内的机器翻译发展简史。
\parinterval
在短短5-6年间,神经机器翻译从一个新生的概念已经成长为机器翻译领域的最前沿技术之一,在各种机器翻译评测和应用中呈全面替代统计机器翻译之势。比如,从近几年WMT、CCMT等评测的结果来看,神经机器翻译已经处于绝对的统治地位,在不同语种和领域的翻译任务中,成为各参赛系统的标配。此外,从ACL等自然语言处理顶级会议的发表论文看,神经机器翻译是毫无疑问的焦点,在论文数量上呈明显的增长趋势,这也体现了学术界对该方法的热情。至今,无论是国外的著名企业,如谷歌、微软、脸书,还是国内的团队,如百度、腾讯、阿里巴巴、有道、搜狗、小牛翻译,都推出了自己研发的神经机器翻译系统,整个研究和产业生态欣欣向荣。图
\ref
{
fig:6-1
}
展示了包含神经机器翻译在内的机器翻译发展简史。
...
@@ -78,7 +78,7 @@
...
@@ -78,7 +78,7 @@
\vspace
{
0.5em
}
\vspace
{
0.5em
}
\item
2016年谷歌发布了基于多层循环神经网络方法的GNMT系统。该系统集成了当时的神经机器翻译技术,并进行了诸多的改进。它的性能显著优于基于短语的机器翻译系统
\cite
{
Wu2016GooglesNM
}
,引起了研究者的广泛关注。在之后不到一年的时间里,Facebook采用卷积神经网络(CNN)研发了新的神经机器翻译系统
\cite
{
DBLP:journals/corr/GehringAGYD17
}
,实现了比基于循环神经网络(RNN)系统更高的翻译水平,并大幅提升翻译速度。
\item
2016年谷歌发布了基于多层循环神经网络方法的GNMT系统。该系统集成了当时的神经机器翻译技术,并进行了诸多的改进。它的性能显著优于基于短语的机器翻译系统
\cite
{
Wu2016GooglesNM
}
,引起了研究者的广泛关注。在之后不到一年的时间里,Facebook采用卷积神经网络(CNN)研发了新的神经机器翻译系统
\cite
{
DBLP:journals/corr/GehringAGYD17
}
,实现了比基于循环神经网络(RNN)系统更高的翻译水平,并大幅提升翻译速度。
\vspace
{
0.5em
}
\vspace
{
0.5em
}
\item
2017年,谷歌的Ashish Vaswani等人提出了新的翻译模型Transformer。其完全抛弃了CNN、RNN等结构,仅仅通过自注意力机制(
self-a
ttentiion)和前向神经网络,不需要使用序列对齐的循环框架就展示出强大的性能,并且巧妙的解决了翻译中长距离依赖问题
\cite
{
NIPS2017
_
7181
}
。Transformer是第一个完全基于注意力机制搭建的模型,不仅训练速度更快,在翻译任务上也获得了更好的结果,一跃成为目前最主流的神经机器翻译框架。
\item
2017年,谷歌的Ashish Vaswani等人提出了新的翻译模型Transformer。其完全抛弃了CNN、RNN等结构,仅仅通过自注意力机制(
Self-A
ttentiion)和前向神经网络,不需要使用序列对齐的循环框架就展示出强大的性能,并且巧妙的解决了翻译中长距离依赖问题
\cite
{
NIPS2017
_
7181
}
。Transformer是第一个完全基于注意力机制搭建的模型,不仅训练速度更快,在翻译任务上也获得了更好的结果,一跃成为目前最主流的神经机器翻译框架。
\vspace
{
0.5em
}
\vspace
{
0.5em
}
\end{itemize}
\end{itemize}
...
@@ -257,7 +257,7 @@ NMT & $ 21.7^{\ast}$ & $18.7^{\ast}$ & -1
...
@@ -257,7 +257,7 @@ NMT & $ 21.7^{\ast}$ & $18.7^{\ast}$ & -1
\sectionnewpage
\sectionnewpage
\section
{
编码器-解码器框架
}
\section
{
编码器-解码器框架
}
\parinterval
说到神经机器翻译就不得不提
{
\small\bfnew
{
编码器-解码器模型
}}
\index
{
编码器-解码器模型
}
(Encoder-Decoder Paradigm)
\index
{
Encoder-Decoder Paradigm
}
,或
{
\small\bfnew
{
编码器-解码器框架
}}
\index
{
编码器-解码器框架
}
。本质上,编码器-解码器模型是描述输入-输出之间关系的一种方式。编码器-解码器这个概念在日常生活中并不少见。例如在电视系统上为了便于视频的传播,会使用各种编码器将视频编码成数字信号,在客户端,相应的解码器组件会把收到的数字信号解码为视频。另外一个更贴近生活的例子是电话
。
它通过对声波和电信号进行相互转换,达到传递声音的目的。这种``先编码,再解码''的思想被应用到密码学、信息论等多个领域。
\parinterval
说到神经机器翻译就不得不提
{
\small\bfnew
{
编码器-解码器模型
}}
\index
{
编码器-解码器模型
}
(Encoder-Decoder Paradigm)
\index
{
Encoder-Decoder Paradigm
}
,或
{
\small\bfnew
{
编码器-解码器框架
}}
\index
{
编码器-解码器框架
}
。本质上,编码器-解码器模型是描述输入-输出之间关系的一种方式。编码器-解码器这个概念在日常生活中并不少见。例如在电视系统上为了便于视频的传播,会使用各种编码器将视频编码成数字信号,在客户端,相应的解码器组件会把收到的数字信号解码为视频。另外一个更贴近生活的例子是电话
,
它通过对声波和电信号进行相互转换,达到传递声音的目的。这种``先编码,再解码''的思想被应用到密码学、信息论等多个领域。
\parinterval
不难看出,机器翻译问题也完美的贴合编码器-解码器结构的特点。可以将源语言编码为类似信息传输中的数字信号,然后利用解码器对其进行转换,生成目标语言。下面就来看一下神经机器翻译是如何在编码器-解码器框架下进行工作的。
\parinterval
不难看出,机器翻译问题也完美的贴合编码器-解码器结构的特点。可以将源语言编码为类似信息传输中的数字信号,然后利用解码器对其进行转换,生成目标语言。下面就来看一下神经机器翻译是如何在编码器-解码器框架下进行工作的。
...
@@ -422,7 +422,7 @@ NMT & $ 21.7^{\ast}$ & $18.7^{\ast}$ & -1
...
@@ -422,7 +422,7 @@ NMT & $ 21.7^{\ast}$ & $18.7^{\ast}$ & -1
\parinterval
第五章已经对循环神经网络的基本知识进行过介绍。这里再回顾一下。简单来说,循环神经网络由循环单元组成。对于序列中的任意时刻,都有一个循环单元与之对应,它会融合当前时刻的输入和上一时刻循环单元的输出,生成当前时刻的输出。这样每个时刻的信息都会被传递到下一时刻,这也间接达到了记录历史信息的目的。比如,对于序列
$
\mathbf
{
x
}
=
\{
x
_
1
, x
_
2
,..., x
_
m
\}
$
,循环神经网络会按顺序输出一个序列
$
\mathbf
{
h
}
=
\{
\mathbf
{
h
}_
1
,
\mathbf
{
h
}_
2
,...,
\mathbf
{
h
}_
m
\}
$
,其中
$
\mathbf
{
h
}_
i
$
表示
$
i
$
时刻循环神经网络的输出(通常为一个向量)。
\parinterval
第五章已经对循环神经网络的基本知识进行过介绍。这里再回顾一下。简单来说,循环神经网络由循环单元组成。对于序列中的任意时刻,都有一个循环单元与之对应,它会融合当前时刻的输入和上一时刻循环单元的输出,生成当前时刻的输出。这样每个时刻的信息都会被传递到下一时刻,这也间接达到了记录历史信息的目的。比如,对于序列
$
\mathbf
{
x
}
=
\{
x
_
1
, x
_
2
,..., x
_
m
\}
$
,循环神经网络会按顺序输出一个序列
$
\mathbf
{
h
}
=
\{
\mathbf
{
h
}_
1
,
\mathbf
{
h
}_
2
,...,
\mathbf
{
h
}_
m
\}
$
,其中
$
\mathbf
{
h
}_
i
$
表示
$
i
$
时刻循环神经网络的输出(通常为一个向量)。
\parinterval
图
\ref
{
fig:6-9
}
展示了一个循环神经网络处理序列问题的实例。当前时刻循环单元的输入由上一个时刻的输入和当前时刻的输入组成,因此也可以理解为,网络当前时刻计算得到的输出是由之前的序列共同决定的,即网络在不断地传递信息的过程中记忆了历史信息。以最后一个时刻的循环单元为例,它在对``开始''这个单词的信息进行处理时,参考了之前所有词(``<
e
os>
\
让
\
我们'')的信息。
\parinterval
图
\ref
{
fig:6-9
}
展示了一个循环神经网络处理序列问题的实例。当前时刻循环单元的输入由上一个时刻的输入和当前时刻的输入组成,因此也可以理解为,网络当前时刻计算得到的输出是由之前的序列共同决定的,即网络在不断地传递信息的过程中记忆了历史信息。以最后一个时刻的循环单元为例,它在对``开始''这个单词的信息进行处理时,参考了之前所有词(``<
s
os>
\
让
\
我们'')的信息。
%----------------------------------------------
%----------------------------------------------
\begin{figure}
[htp]
\begin{figure}
[htp]
...
@@ -1026,7 +1026,7 @@ L(\mathbf{Y},\widehat{\mathbf{Y}}) = \sum_{j=1}^n L_{\textrm{ce}}(\mathbf{y}_j,\
...
@@ -1026,7 +1026,7 @@ L(\mathbf{Y},\widehat{\mathbf{Y}}) = \sum_{j=1}^n L_{\textrm{ce}}(\mathbf{y}_j,\
% NEW SUBSUB-SECTION
% NEW SUBSUB-SECTION
%----------------------------------------------------------------------------------------
%----------------------------------------------------------------------------------------
\subsubsection
{
长
参数初始化
}
\subsubsection
{
参数初始化
}
\parinterval
神经网络的参数主要是各层中的线性变换矩阵和偏置。在训练开始时,需要对参数进行初始化。但是,由于神经机器翻译的网络结构复杂,因此损失函数往往不是凸函数,不同初始化会导致不同的优化结果。而且在大量实践中已经发现,神经机器翻译模型对初始化方式非常敏感,性能优异的系统往往需要特定的初始化方式。
\parinterval
神经网络的参数主要是各层中的线性变换矩阵和偏置。在训练开始时,需要对参数进行初始化。但是,由于神经机器翻译的网络结构复杂,因此损失函数往往不是凸函数,不同初始化会导致不同的优化结果。而且在大量实践中已经发现,神经机器翻译模型对初始化方式非常敏感,性能优异的系统往往需要特定的初始化方式。
...
@@ -1214,7 +1214,7 @@ L(\mathbf{Y},\widehat{\mathbf{Y}}) = \sum_{j=1}^n L_{\textrm{ce}}(\mathbf{y}_j,\
...
@@ -1214,7 +1214,7 @@ L(\mathbf{Y},\widehat{\mathbf{Y}}) = \sum_{j=1}^n L_{\textrm{ce}}(\mathbf{y}_j,\
\label
{
eq:6-37
}
\label
{
eq:6-37
}
\end{eqnarray}
\end{eqnarray}
\noindent
这里,
$
\{
\hat
{
y
}_{
j
1
}
,...,
\hat
{
y
}_{
jk
}
\}
$
表示对于位置
$
j
$
翻译概率最大的
$
K
$
的
单词,
$
\{
\hat
{
\mathbf
{
y
}}_{
<j
^{
\ast
}}
\}
$
表示前
$
j
-
1
$
步top-K单词组成的所有历史。
${
\hat
{
\mathbf
{
y
}}_{
<j
^{
\ast
}}}$
可以被看作是一个集合,里面每一个元素都是一个目标语单词序列,这个序列是前面生成的一系列top-K单词的某种组成。
$
\textrm
{
P
}
(
y
_
j |
\{
\hat
{
\mathbf
{
y
}}_{
<
{
j
^{
\textrm
{
*
}}}}
\}
,
\mathbf
{
x
}
)
$
表示基于
\{
$
\hat
{
\mathbf
{
y
}}_{
<j
^{
\ast
}}
$
\}
的某一条路径生成
$
y
_
j
$
的概率
\footnote
{
严格来说,P
$
(
y
_
j |
{
\hat
{
\mathbf
{
y
}}_{
<j
^{
\ast
}}
}
)
$
不是一个准确的数学表达,这里通过这种写法强调
$
y
_
j
$
是由
\{
$
\hat
{
\mathbf
{
y
}}_{
<j
^{
\ast
}}
$
\}
中的某个译文单词序列作为条件生成的。
}
。这种方法也被称为
{
\small\bfnew
{
束搜索
}}
\index
{
束搜索
}
(Beam Search)
\index
{
Beam Search
}
,意思是搜索时始终考虑一个集束内的候选。
\noindent
这里,
$
\{
\hat
{
y
}_{
j
1
}
,...,
\hat
{
y
}_{
jk
}
\}
$
表示对于位置
$
j
$
翻译概率最大的
前
$
K
$
个
单词,
$
\{
\hat
{
\mathbf
{
y
}}_{
<j
^{
\ast
}}
\}
$
表示前
$
j
-
1
$
步top-K单词组成的所有历史。
${
\hat
{
\mathbf
{
y
}}_{
<j
^{
\ast
}}}$
可以被看作是一个集合,里面每一个元素都是一个目标语单词序列,这个序列是前面生成的一系列top-K单词的某种组成。
$
\textrm
{
P
}
(
y
_
j |
\{
\hat
{
\mathbf
{
y
}}_{
<
{
j
^{
\textrm
{
*
}}}}
\}
,
\mathbf
{
x
}
)
$
表示基于
\{
$
\hat
{
\mathbf
{
y
}}_{
<j
^{
\ast
}}
$
\}
的某一条路径生成
$
y
_
j
$
的概率
\footnote
{
严格来说,P
$
(
y
_
j |
{
\hat
{
\mathbf
{
y
}}_{
<j
^{
\ast
}}
}
)
$
不是一个准确的数学表达,这里通过这种写法强调
$
y
_
j
$
是由
\{
$
\hat
{
\mathbf
{
y
}}_{
<j
^{
\ast
}}
$
\}
中的某个译文单词序列作为条件生成的。
}
。这种方法也被称为
{
\small\bfnew
{
束搜索
}}
\index
{
束搜索
}
(Beam Search)
\index
{
Beam Search
}
,意思是搜索时始终考虑一个集束内的候选。
\parinterval
不论是贪婪搜索还是束搜索都是一个自左向右的过程,也就是每个位置的处理需要等前面位置处理完才能执行。这是一种典型的
{
\small\bfnew
{
自回归模型
}}
\index
{
自回归模型
}
(Autoregressive Model)
\index
{
Autoregressive Model
}
,它通常用来描述时序上的随机过程,其中每一个时刻的结果对时序上其他部分的结果有依赖
\cite
{
NIPS2017
_
7181
}
。相对应的,也有
{
\small\bfnew
{
非自回归模型
}}
\index
{
非自回归模型
}
(Non-autoregressive Model)
\index
{
Non-autoregressive Model
}
,它消除了不同时刻结果之间的直接依赖
\cite
{
Gu2017NonAutoregressiveNM
}
。由于自回归模型是当今神经机器翻译主流的推断方法,这里仍以自回归的贪婪搜索和束搜索为基础进行讨论。
\parinterval
不论是贪婪搜索还是束搜索都是一个自左向右的过程,也就是每个位置的处理需要等前面位置处理完才能执行。这是一种典型的
{
\small\bfnew
{
自回归模型
}}
\index
{
自回归模型
}
(Autoregressive Model)
\index
{
Autoregressive Model
}
,它通常用来描述时序上的随机过程,其中每一个时刻的结果对时序上其他部分的结果有依赖
\cite
{
NIPS2017
_
7181
}
。相对应的,也有
{
\small\bfnew
{
非自回归模型
}}
\index
{
非自回归模型
}
(Non-autoregressive Model)
\index
{
Non-autoregressive Model
}
,它消除了不同时刻结果之间的直接依赖
\cite
{
Gu2017NonAutoregressiveNM
}
。由于自回归模型是当今神经机器翻译主流的推断方法,这里仍以自回归的贪婪搜索和束搜索为基础进行讨论。
...
...
Book/Chapter6/Figures/figure-structure-of-a-recurrent-network-model.tex
查看文件 @
41482568
...
@@ -16,7 +16,7 @@
...
@@ -16,7 +16,7 @@
\node
[anchor=north,rnnnode,fill=blue!30!white] (e2) at ([yshift=-1em]node12.south)
{
\scriptsize
{}}
;
\node
[anchor=north,rnnnode,fill=blue!30!white] (e2) at ([yshift=-1em]node12.south)
{
\scriptsize
{}}
;
\node
[anchor=north,rnnnode,fill=blue!30!white] (e3) at ([yshift=-1em]node13.south)
{
\scriptsize
{}}
;
\node
[anchor=north,rnnnode,fill=blue!30!white] (e3) at ([yshift=-1em]node13.south)
{
\scriptsize
{}}
;
\node
[anchor=north,rnnnode,fill=blue!30!white] (e4) at ([yshift=-1em]node14.south)
{
\scriptsize
{}}
;
\node
[anchor=north,rnnnode,fill=blue!30!white] (e4) at ([yshift=-1em]node14.south)
{
\scriptsize
{}}
;
\node
[anchor=north,inner sep=2pt] (w1) at ([yshift=-1em]e1.south)
{
\footnotesize
{$
<
$
e
os
$
>
$}}
;
\node
[anchor=north,inner sep=2pt] (w1) at ([yshift=-1em]e1.south)
{
\footnotesize
{$
<
$
s
os
$
>
$}}
;
\node
[anchor=north,inner sep=2pt] (w2) at ([yshift=-1em]e2.south)
{
\footnotesize
{
让
}}
;
\node
[anchor=north,inner sep=2pt] (w2) at ([yshift=-1em]e2.south)
{
\footnotesize
{
让
}}
;
\node
[anchor=north,inner sep=2pt] (w3) at ([yshift=-1em]e3.south)
{
\footnotesize
{
我们
}}
;
\node
[anchor=north,inner sep=2pt] (w3) at ([yshift=-1em]e3.south)
{
\footnotesize
{
我们
}}
;
\node
[anchor=north,inner sep=2pt] (w4) at ([yshift=-1em]e4.south)
{
\footnotesize
{
开始
}}
;
\node
[anchor=north,inner sep=2pt] (w4) at ([yshift=-1em]e4.south)
{
\footnotesize
{
开始
}}
;
...
...
Book/Chapter7/Figures/figure-machine-translation-performance-curve.tex
查看文件 @
41482568
...
@@ -14,7 +14,9 @@
...
@@ -14,7 +14,9 @@
{
\footnotesize
{
\footnotesize
\node
[anchor=south] (n4) at ([xshift=7em,yshift=5em]n1.north)
{
性能快速爬升阶段
}
;
\node
[anchor=south] (n4) at ([xshift=7em,yshift=5em]n1.north)
{
性能快速爬升阶段
}
;
\node
[anchor=west] (n5) at ([xshift=0em,yshift=-2em]n4.west)
{
数据的作用会非常明显
}
;
\node
[anchor=west] (n5) at ([xshift=0em,yshift=-2em]n4.west)
{
数据的作用会非常明显
}
;
\draw
[-,very thick,draw=red] ([xshift=0.7em,yshift=3em]n1.north) .. controls +(north:5.9em) and +(south:0em) .. ([xshift=10em,yshift=9.6em]n1.north);
}
}
\draw
[-,thick] ([xshift=2.3em,yshift=-2em]n4.east)--([xshift=2.3em,yshift=2em]n4.north east);
%
\draw [-,thick] ([xshift=2.3em,yshift=-2em]n4.east)--([xshift=2.3em,yshift=2em]n4.north east);
\end{scope}
\end{scope}
\end{tikzpicture}
\end{tikzpicture}
\ No newline at end of file
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论