\parinterval 人工神经网络的第一个发展阶段是在二十世纪40年代到70年代,这个时期的人工神经网络还停留在利用线性模型模拟生物神经元的阶段,比如使用线性加权函数来描述输入$\mathbf x $和输出$ y $之间的联系:$ f(\mathbf x,\mathbf w)=x_1\cdot w_1+\dots+ x_n \cdot w_n $,举一个简单例子,输入$\mathbf x $是这个地区的坐标和时间,然后输出$ y $是这个地区的温度,尽管真实的问题可能要复杂的多,但是线性模型确实有能力去拟合简单的函数关系。
\parinterval 人工神经网络的第一个发展阶段是在二十世纪40年代到70年代,这个时期的人工神经网络还停留在利用线性模型模拟生物神经元的阶段,比如使用线性加权函数来描述输入$\mathbf x $和输出$ y $之间的联系:$ f(\mathbf x,\mathbf w)=x_1\cdot w_1+\dots+ x_n \cdot w_n $,举一个简单例子,输入$\mathbf x $是这个地区的坐标和时间,输出$ y $是这个地区的温度,尽管真实的问题可能要复杂的多,但是线性模型确实有能力去拟合简单的函数关系。
\parinterval 那激活函数又是什么?神经元在接收到经过线性变换的结果后,通过激活函数的处理,得到最终的输出$\mathbf y $。激活函数的目的是解决实际问题中的非线性变换,线性变换只能拟合直线,而激活函数的加入,使神经网络具有了拟合曲线的能力。 特别是在实际问题中,很多现象都无法用简单的线性关系描述,这时激活函数的非线性就为我们描述更加复杂的问题提供了工具。
\parinterval 一个张量$\mathbf x $若要与矩阵$\mathbf w $做矩阵乘法,则$\mathbf x $的第一维度需要与$\mathbf w $的行数大小相等,即:若张量$\mathbf x $的形状为$\cdot\times n $,$\mathbf w $须为$ n\timesm$的矩阵。
\parinterval 一个张量$\mathbf x $若要与矩阵$\mathbf w $做矩阵乘法,则$\mathbf x $的第一维度需要与$\mathbf w $的行数大小相等,即:若张量$\mathbf x $的形状为$\cdot\times n $,$\mathbf w $须为$ n\times\cdot$的矩阵。
\parinterval 前向计算实现如图\ref{fig:weather-forward}所示,图中对各张量和其他参数的形状做了详细说明,类似shape(3)这种形式代表维度为3的1阶张量,shape(3,2)代表2阶张量,其中第1阶有3个维度,第2阶有2个维度,也可以将其理解为$3\ast2$的矩阵。输入$\mathbf x $是一个1阶张量,该阶有3个维度,分别对应天空状况、低空气温、水平气压三个方面。输入数据经过隐藏层的线性变换$\mathbf x\cdot\mathbf w^1+\mathbf b^1$和Tanh激活函数后,得到新的张量$\mathbf a $,张量$\mathbf a $也是一个1阶张量,该阶有2个维度,分别对应着从输入数据中提取出的温度和风速两方面特征;神经网络在获取到天气情况的特征$\mathbf a $后,继续对其进行线性变换$\mathbf a\cdot\mathbf w^2+ b^2$($ b^2$是标量)和Sigmoid激活函数后,得到神经网络的最终输出$ y $,即神经网络此时预测的穿衣指数。
\parinterval 前向计算实现如图\ref{fig:weather-forward}所示,图中对各张量和其他参数的形状做了详细说明,类似shape(3)这种形式代表维度为3的1阶张量,shape(3,2)代表2阶张量,其中第1阶有3个维度,第2阶有2个维度,也可以将其理解为$3\ast2$的矩阵。输入$\mathbf x $是一个1阶张量,该阶有3个维度,分别对应天空状况、低空气温、水平气压三个方面。输入数据经过隐藏层的线性变换$\mathbf x\cdot\mathbf w^1+\mathbf b^1$和tanh激活函数后,得到新的张量$\mathbf a $,张量$\mathbf a $也是一个1阶张量,该阶有2个维度,分别对应着从输入数据中提取出的温度和风速两方面特征;神经网络在获取到天气情况的特征$\mathbf a $后,继续对其进行线性变换$\mathbf a\cdot\mathbf w^2+ b^2$($ b^2$是标量)和sigmoid激活函数后,得到神经网络的最终输出$ y $,即神经网络此时预测的穿衣指数。
\parinterval 对于第$ i $个样本$(\mathbf{x_i},\mathbf{\widetilde y_i})$,如果把损失函数$ Loss(\mathbf{\widetilde y_i},\mathbf{y_i})$看作是参数$\mathbf w $的函数\footnote{为了简化描述,我们用$\mathbf w $表示神经网络中的所有参数}。因为输出$\mathbf{y_i}$是由输入$\mathbf{x_i}$和模型参数$\mathbf w $决定,因此也把损失函数写为$ L(\mathbf{x_i},\mathbf{\widetilde y_i};\mathbf w)$。参数学习过程可以被描述为
\parinterval 对于第$ i $个样本$(\mathbfx_i,\mathbf{\widetilde y}_i)$,如果把损失函数$ Loss(\mathbf{\widetilde y}_i,\mathbf y_i)$看作是参数$\mathbf w $的函数\footnote{为了简化描述,我们用$\mathbf w $表示神经网络中的所有参数}。因为输出$\mathbf y_i $是由输入$\mathbf x_i $和模型参数$\mathbf w $决定,因此也把损失函数写为$ L(\mathbf x_i,\mathbf{\widetilde y}_i;\mathbf w)$。参数学习过程可以被描述为
\noindent 其中,$\mathbf h_t $表示$ t $时刻循环单元的输出,$\mathbf h_{t-1}$表示$ t-1$时刻循环单元的输出,$\mathbf U $和$\mathbf W $是模型的参数。可以看出,循环单元的结构其实很简单,只是一个对$\mathbf h_{t-1}$和$\mathbf x_t $的线性变换再加上一个Tanh函数。通过读入上一时刻的输出,当前时刻可以访问以前的历史信息。这个过程可以循环执行,这样就完成了对所有历史信息的建模。$\mathbf h_t $可以被看作是序列在$ t $时刻的一种表示,也可以被看作是网络的一个隐藏层。进一步,$\mathbf h_t $可以被送入输出层,得到$ t $时刻的输出:
\noindent 其中,$\mathbf h_t $表示$ t $时刻循环单元的输出,$\mathbf h_{t-1}$表示$ t-1$时刻循环单元的输出,$\mathbf U $和$\mathbf W $是模型的参数。可以看出,循环单元的结构其实很简单,只是一个对$\mathbf h_{t-1}$和$\mathbf x_t $的线性变换再加上一个tanh函数。通过读入上一时刻的输出,当前时刻可以访问以前的历史信息。这个过程可以循环执行,这样就完成了对所有历史信息的建模。$\mathbf h_t $可以被看作是序列在$ t $时刻的一种表示,也可以被看作是网络的一个隐藏层。进一步,$\mathbf h_t $可以被送入输出层,得到$ t $时刻的输出:
\parinterval GPT模型仍然使用标准的语言建模的思路,即通过前$ n-1$个词预测第$ n $个词。但是在网络结构上,GPT模型使用了Transformer(图\ref{fig:gpt}),而且模型参数会在目标任务上进行有监督的微调。与ELMO模型的做法不同,GPT不需要对目标任务构建新的模型结构,而是直接在Transformer语言表示模型的最后一层加上Softmax层作为任务的输出层。实验结果证明,GPT模型的性能较ELMO模型更为优越,在12个NLP任务中取得了9个任务当时最好的结果。
\parinterval GPT模型仍然使用标准的语言建模的思路,即通过前$ n-1$个词预测第$ n $个词。但是在网络结构上,GPT模型使用了Transformer(图\ref{fig:gpt}),而且模型参数会在目标任务上进行有监督的微调。与ELMO模型的做法不同,GPT不需要对目标任务构建新的模型结构,而是直接在Transformer语言表示模型的最后一层加上softmax层作为任务的输出层。实验结果证明,GPT模型的性能较ELMO模型更为优越,在12个NLP任务中取得了9个任务当时最好的结果。