建网站权威机构,公司官网建设方案,网站搭建价格,企业申请域名序列模型的使用示例 1 RNN原理1.1 序列模型的输入输出1.2 循环神经网络#xff08;RNN#xff09;1.3 RNN的公式表示2 数据的尺寸 3 PyTorch中查看RNN的参数4 PyTorch中实现RNN#xff08;1#xff09;RNN实例化#xff08;2#xff09;forward函数#xff08;3#xf… 序列模型的使用示例 1 RNN原理1.1 序列模型的输入输出1.2 循环神经网络RNN1.3 RNN的公式表示2 数据的尺寸 3 PyTorch中查看RNN的参数4 PyTorch中实现RNN1RNN实例化2forward函数3多层RNN的参数尺寸 5 实战 1 RNN原理
1.1 序列模型的输入输出
假如你想要建立一个序列模型它的输入语句是这样的 “Harry Potter and Herminoe Granger invented a new spell.”(句中的人名都是出自于 J.K.Rowling 笔下的系列小说 Harry Potter)。假如你想要建立一个能够自动识别句中人名的序列模型那么这就是一个命名实体识别问题。命名实体识别系统可以用来查找不同类型的文本中的人名、公司名、时间、地点、国家名和货币名等等。
将输入的句子定义为x上述的输入语句中共有9个单词可以对输入进行编号用 x t x^{t} xt 来索引句子中第t个单词的位置。假如这个序列模型有一个输出序列使得输入的每个单词都对应一个输出值这个值为1表示对应的输入单词是人名的一部分为0表示不是人名的一部分同时用 y t y^{t} yt 对输出进行编号如下图所示
同时我们用 T x T_x Tx 来表示输入序列的长度这个例子中输入是9个单词所以 T x 9 T_x 9 Tx9 同样可用 T y T_y Ty 来表示输出序列的长度。输出序列的长度可以和输入序列的相同也可以不同。
之前我们在DNN中用 x ( i ) x^{(i)} x(i) 表示第i个训练样本这里我们可以用 x ( i ) t x^{(i)t} x(i)t 来表示第i个样本的第t个元素 T x ( i ) T{x}^{(i)} Tx(i) 代表第i个训练样本的输入序列长度。同样的用 y ( i ) t y^{(i)t} y(i)t 来表示第i个样本的第t个元素对应的输出值 T y ( i ) T{y}^{(i)} Ty(i) 代表第i个训练样本的输出序列长度。
我们该怎样表示序列中的一个单词呢比如Harry这个单词对应的索引 x ( 1 ) x^{(1)} x(1) 是什么自然语言处理Natural Language Process简称NLP中想要表示一个句子里的单词第一件事是做一张词表有时也称为词典我们这里用10000个单词的词典举例。
当词典构建好之后遍历数据集给数据集中的每一个单词匹配一个one-hot编码即用一个10000维的向量表示例如单词a出现在词典中的第一个位置那么当输入a时就生成一个10000维的向量该向量的第一个元素是1其他都是0。
因此给定上述输入语句可以生成如下的向量
图中其实就是One-hot向量因为向量中只有一个位置是1其余都是0。
如果遇到不在词典中的单词那么就创建一个叫做 Unknow Word 的伪单词用UNK作为标记来表示不在词表中的单词。
这里我们用的词典只有一万个单词正常商业应用的词典词汇量3万至5万比较常见10万的也有某些大型互联网公司用的词典其单词数量甚至超过百万。
1.2 循环神经网络RNN
这节我们来谈一谈怎样建立模型来实现从X到Y的映射。
我们先尝试一下标准神经网络。前面的例子“Harry Potter and Herminoe Granger invented a new spell.”有9个单词因此需要把这9个单词一次性输入网络如图所示
为了方便输入可以将单词索引成一个整数但使用标准神经网络有以下两个问题
上述例子是9个单词所以输入单元是9个但如果另一条句子有10个单词那么这张网络将不再适用。这种网络并不共享从文本的不同位置上学到的特征。具体来说经过训练后的神经网络当Harry出现在位置 x 1 x^{1} x1 时会将其判定为人名的一部分那么如果Harry 出现在其他位置比如 x 8 x^{8} x8 时很有可能因为位置不同权重参数不同神经网络不会将其认为是人名的组成部分。
为了解决上述问题这里引入循环神经网络的概念。
还是“Harry Potter and Herminoe Granger invented a new spell.”这句话如果从左往右逐个读取单词当读到第一个单词Harry时将其对应的One-hot向量 x 1 x^{1} x1 输入到神经网络输出 y ^ 1 \hat{y} ^{1} y^1并判断其是否为人名的一部分用下面的图表示 这里只有两层神经网络一个隐藏层图中的小圆圈可以认为是神经元一个输出层。设隐藏层的激活值为 a 1 a^{1} a1 输入第一个单词的过程称为时间步1。
接着读取第二个单词将 x 2 x^{2} x2 输入神经网络 x 2 x^{2} x2 乘以权重之后并不是马上激活而是要先加上来自时间步1的激活值 a 1 a^{1} a1然后再将相加后的结果激活获得激活值 a 2 a^{2} a2 最后计算输出层获得预测值 y ^ 2 \hat{y} ^{2} y^2。这样说不太准确但这样说方便理解后面会详细讲解
依此类推在计算激活值的时候加入上一时步的激活值直至整条语句读取结束这就是循环神经网络结构如下
为了使各个部分结构一致在零时刻需要构造一个激活值 a 0 a^{0} a0 这通常是个零向量加上激活值 a 0 a^{0} a0 后的结构如下图所示
在某些文献中你看到的循环神经网络有可能是下面这种形式
在每一个时间步中输入 x t x ^{t} xt 输出 y t y ^{t} yt 用一个带箭头的圆圈表示把激活值重新输入网络圆圈上面加上一个方块表示激活值输回网络会延迟一个时间步。
循环神经网络每个时间步的参数也是一致的也就是说第一次输入时的网络和第二次、第三次、第t次输入时网络的参数完全一致。
因为只有一个隐藏层因此我们设隐藏层的权重参数为Wax各个时步的Wax相同。我们设水平联系的权重参数为Waa在计算本时步激活值的时候把上一层的激活值乘以Waa然后再加到本时步各个时步的Waa相同。本时步的激活值算出来之后需要计算输出值这时需要乘以一个输出权重Wya再将结果激活作为输出值。Wax、Waa、Wya这些参数第一个下标表示用来计算什么第二个下标表示这个参数该乘什么。
将以上参数标在图片中则是下面这个结果
标在简化循环图中则是下面的结果
1.3 RNN的公式表示
如果把上面的过程用公式表达则如下所示 a 1 g ( W a a a 0 W a x x 1 b a ) y 1 g ( W y a a 1 b y ) \begin{array}{l} a^{1}g\left(W_{a a} a^{0}W_{a x} x^{1}b_{a}\right) \\ y^{1}g\left(W_{y a} a^{1}b_{y}\right) \end{array} a1g(Waaa0Waxx1ba)y1g(Wyaa1by)
这里面g表示激活函数一般情况下隐藏层使用tanh作为激活函数有时也用Relu输出层看网络要解决的问题如果是二分类问题就用sigmoid如果是k分类问题就用softmax。如果想区分隐藏层和输出层的激活函数那么可以对g标号如下所示 a t g 1 ( W a a a t − 1 W a x x t b a ) y t g 2 ( W y a a t b y ) \begin{array}{l} a^{t}g_1\left(W_{a a} a^{t-1}W_{a x} x^{t}b_{a}\right) \\ y^{t}g_2\left(W_{y a} a^{t}b_{y}\right) \end{array} atg1(Waaat−1Waxxtba)ytg2(Wyaatby)
其中计算激活值的公式可以简化表示如下 a ⟨ t ⟩ g 1 ( W a [ a ⟨ t − 1 ⟩ , x ⟨ t ⟩ ] T b a ) a^{\langle t\rangle}g_{1}\left(W_{a}\left[a^{\langle t-1\rangle}, x^{\langle t\rangle}\right]^{T}b_{a}\right) a⟨t⟩g1(Wa[a⟨t−1⟩,x⟨t⟩]Tba) 这里 W a [ W a a , W a x ] W_{a}\left[W_{a a}, W_{a \mathrm{x}}\right] Wa[Waa,Wax]。
假设单词库里有一万个单词那么 x t x^{t} xt 的维度为10000, 1若隐藏层有100个神经元那么 a t a^{t} at 的维度为100, 1 [ a t − 1 , x t ] T \left[a^{t-1}, x^{t}\right]^{T} [at−1,xt]T 的维度为10100, 1。Waa的维度就是100,100Wax的维度就是10010000把这两个矩阵整合之后Wa就是100,10100。
同样对于输出层的公式也可以使用更简单的方式重写 y t g 2 ( W y a t b y ) y^{t}g_{2}\left(W_{y} a^{t}b_{y}\right) ytg2(Wyatby) 现在 W y W_y Wy 和 b y b_y by、 W a W_a Wa 和 b a b_a ba下标表示的是分别会输出什么类型的量。
使用上述记法当我们建立更复杂模型时就能够简化我们要用到的符号。
如果将循环神经网络的结果画得更工整一点将是下面的图形 这种结构的循环神经网络有一个缺点就是在计算t时步时仅仅使用了t时步以前的计算结果没有使用t时步之后的结果。比如现在有两个句子“Teddy Roosevelt was a great President.”中文意思是 西奥多罗斯福是一位伟大的总统因为他的小名也叫泰迪因此也经常被称为“Teddy Roosevel”“Teddy bears are on sale!”正在销售泰迪熊如果使用相同的循环神经网络从左往右扫描句子那么获得的第一个单词都是Teddy因为是第一个都没有从上一层传过来的激活值那么会获得相同的输出前者Teddy是人名后者是熊因此两者的输出必有一个有错。 针对这个问题可以使用双向循环神经网络。不过本文的重点是RNN的原理和过程以及在PyTorch中的数据处理目的是了解这一类模型的调用的和数据处理方式讲原理只是为了后面讲接口时能更直观。
2 数据的尺寸
这里先说明一下本节的资料来源和上节不一样因此符号定义和上面的有所不同了解原理即可。
RNN每次输入一个单词那么 x t x_t xt 就是该单词对应的One-hot向量尺寸为[vector_length]或[1,vector_length]向量长度也是特征长度因此也可以用[feature len]或者[1, feature len]来表示。
使用PyTorch的并行技术给模型喂数据的时候每次都喂一个batch。假设每个batch由5个句子各出一个单词组成则batch_size5那么就相当于有5条生产线这5条生产线共享参数每次喂数据的时候都是给这5条生产线各喂一个单词所以 x t x_t xt 的尺寸为[batch_size, vector_length]。
如果觉得每次输入一个单词太慢那么可以一次输入 假如每条句子都是8个单词那么x的尺寸是[8, 5, feature len]如果每次输入的单词个数是seq len那么x的尺寸是[batch_size, seq len, feature len]seq len表示句子长度。
为了便于探讨RNN中参数的尺寸下面我们不对输出层加激活函数假设第t时步的计算过程如下图所示
这里 W x h W_{xh} Wxh 、 W h h W_{hh} Whh 、 W h y W_{hy} Why 第一个下标表示这个参数该乘什么第二个下标表示这个参数用来计算什么和前面介绍原理时刚好相反。
上图中 x t x_t xt 是每个时步输入的数据它的尺寸是[batch_size, feature len]假设隐藏层的神经元个数为hidden length那么隐藏层的输出 h t h_t ht 的尺寸就是[batch_size, hidden len]。
那么 W x h W_{xh} Wxh 参数的尺寸为[feature len, hidden len]它的意义是压缩数据的维度将 x t x_t xt 的特征长度由feature len压缩为hidden len。 因为循环神经网络每个时间步的参数一致所以 h t − 1 h_{t-1} ht−1 的尺寸也为[batch_size, hidden len] h t − 1 W h h h_{t-1} W_{h h} ht−1Whh 的尺寸要和 x t W x h b h x_{t} W_{x h}b_{h} xtWxhbh 的一致因此 W h h W_{hh} Whh 的尺寸为[hidden len, hidden len]。
一般情况下 y t y_t yt 的特征长度为1因此其尺寸为[batch_size, 1]那么 W h h W_{h h} Whh 的尺寸为[hidden len, 1]。
3 PyTorch中查看RNN的参数
import torch
import torch.nn as nnmodel nn.RNN(input_size10, hidden_size5, num_layers1)
循环层的输入是10即表示输入数据对应的One-hot向量长度是10隐藏层里有5个元素循环层有1层
print(model) # 打印网络的结构
print(model._parameters.keys()) # 打印参数结构
打印参数的尺寸
print(----------------------------------------)
print(model.weight_ih_l0.size()) # W_xh.T
print(model.weight_hh_l0.size()) # W_hh.T
print(model.bias_hh_l0.size())
print(model.bias_ih_l0.size())
参数名的末尾l0表示第0层0 layer
如果RNN有3层那么会有l0l1l2输出
RNN(10, 5)
odict_keys([weight_ih_l0, weight_hh_l0, bias_ih_l0, bias_hh_l0])
----------------------------------------
torch.Size([5, 10])
torch.Size([5, 5])
torch.Size([5])
torch.Size([5])上面这段程序有几点需要注意 1 model.weight_ih_l0并不是 W x h W_{xh} Wxh而是 W x h T W_{xh}{ }^{T} WxhT即是转置后的结果。 2 隐藏层使用的结构是这样的 h t tanh ( x t W x h b x h h t − 1 W h h b h h ) h_{t}\tanh \left(x_{t} W_{x h}b_{x h}h_{t-1} W_{h h}b_{h h}\right) httanh(xtWxhbxhht−1Whhbhh)我们一般写式子的时候常常把 b x h b_{x h} bxh 和 b h h b_{h h} bhh 合并成 b h b_{h} bh 。 3 上面的model中没有计算 y t y_t yt 的模块如果需要计算 y t y_t yt 的模块需要增加一个线性层模块见实战环节。
4 PyTorch中实现RNN
1RNN实例化
调用nn.RNN可以创建RNN模型它的__init__有四个参数 input_size单词的编码长度 hidden_size隐藏层的单元个数 num_layerRNN的层数默认为1 batch_first表示batch_size这个维度是否在最前面默认为FalseFalse表示输入数据的结构是[seq len,batch_size,feature]为True则表示输入数据的结构是[batch_size,seq len,feature] 通过nn.RNN创建的RNN模型没有线性层需要自己手动添加。 因为我们习惯将batch_size维度放到最前面下面的关于输入输出尺寸的讨论都是在batch_firstTrue的情形下。
2forward函数
输入输出分别为
out, ht forward(self, x, h0)假如有3句话三条生产线每句话都有5个单词单词用长度为100的向量来编码那么x的尺寸为[3, 5, 100]RNN中可以使用并行化技术一次性把所有的x输入到RNN中不需要一个单词一个单词地喂。
out是每个时间步的最后一个隐藏层的输出尺寸为[batch_size, Seq len, hidden]其中Seq len是每句话的单词数量比如可以是5。 无论RNN有多少层out的尺寸都是[batch_size, Seq len, hidden]也就是说RNN中各个隐藏层的神经元数量都是hidden。
ht是最后一个时间步的每一层的输出尺寸为[batch_size, num_layers, hidden len]而第一个时间步由于没有上一轮的输入因此第一时步使用h0h0的尺寸也为[batch_size, num_layers, hidden len]。
3多层RNN的参数尺寸
rnn nn.RNN(100, 10, 2, batch_firstTrue)实例化一个2层的RNN2层指的是隐藏层数量这个两层的模型输入样本的特征长度为100输出长度为10那么第一层的输出数据的特征长度是多少 每个时步第一层的输出的长度就是10也就是说多层RNN在第一层就完成了数据的维度压缩。
5 实战
房价预测模型已知某地区连续50个月的房价根据已有数据预测第51个月的房价。 使用RNN来预测代码如下
import numpy as np
import torch
from matplotlib import pyplot as plt
import torch.nn as nn
import torch.optim as optim
import torch.functional as F
房价预测模型超参数
num_time_steps 50 # 50个时步
input_size 1 # 数据编码长度是1
hidden_size 16 # 隐藏层有16个单元
output_size 1 # 输出层只有1个单元
lr 0.01 # 学习率是0.01class Net(nn.Module):def __init__(self, ):super(Net, self).__init__()循环层self.rnn nn.RNN(input_sizeinput_size,hidden_sizehidden_size,num_layers1,batch_firstTrue,)batch_first默认为FalseFalse表示输入数据的结构是[seq len,batch_size,feature],为True表示输入数据的结构是[batch_size,seq len,feature]参数初始化# for p in self.rnn.parameters():# nn.init.normal_(p, mean0.0, std0.001)线性层self.linear nn.Linear(hidden_size, output_size)def forward(self, x, hidden_prev):out, hidden_prev self.rnn(x, hidden_prev)x的尺寸为[batch_size, seq len, feature len]out的尺寸为[batch_size, seq len, hidden_size]out out.view(-1, hidden_size) # 打平的目的是为了送到线性层这里假设标签是二维的其尺寸为[50, 16]为了让标签值和预测值能够进行比较因此将out打平打平后50等效于“batch_size维度为50”out self.linear(out)out out.unsqueeze(dim0) # 插入真正的batch_size维度如果不插入一个新的维度那么out的输出将变成[50, 1]而在定义数据时y被定义成了[1, 50, 1]因此需要插入一个新的维度其实上面的步骤可以先不打平而是先输入到线性层输出的结果直接是[1,50,1]return out, hidden_prev需要注意的是房价预测模型其自变量不是月份而是前面若干个月的房价
也就是说上述Net中的x是房价不是时间。
因此model Net()
criterion nn.MSELoss()
optimizer optim.Adam(model.parameters(), lr)hidden_prev torch.zeros(1, 1, hidden_size) # h0的初始值# 训练
for iter in range(1000):start np.random.randint(3, size1)[0]从0,1,2里面随机抽取一个数为什么要从3个数字里面抽一个因为如果每次都是从0开始RNN很容易记住time_steps np.linspace(start, start 10, num_time_steps)data np.sin(time_steps)data data.reshape(num_time_steps, 1)x torch.tensor(data[:-1]).float().view(1, num_time_steps - 1, 1)y torch.tensor(data[1:]).float().view(1, num_time_steps - 1, 1)由于前面实例化的时候batch_firstTrue这里将 x 和 y 重塑成[1, 49, 1]之后数据的batch_size 1但有49条生产线房价可以有一个数来表征因此feature len1因为num_time_steps50因此有50个时步所以data的下标是0-49data[:-1]表示从data[0]到data[48]data[1:]表示从data[1]到data[49]该算法的思路就是根据第1天的房价x[0]预测第2天的房价output[0]再将其与第二天的真实房价y[0]进行对比求出第一天的误差。其他天的误差也是类似最后根据前49天的房价x求出从第2-50天的房价预测值利用第2-50天的房价真实值与预测值之间的误差训练模型。这就是为什么训练的时候 x 和 y 的长度是49的原因。output, hidden_prev model(x, hidden_prev)hidden_prev hidden_prev.detach()detach()的作用是脱离原来的计算图使其不再需要梯度信息这样参数反向传播因为该算法每轮迭代都使用上一轮迭代的hidden_prev如果hidden_prev不与原来的计算图脱钩那么求导的时候会沿着hidden_prev进入上一轮迭代的计算图这样就会报错说视图在计算图上求两次导loss criterion(output, y)model.zero_grad()loss.backward()# for p in model.parameters():# print(p.grad.norm())# torch.nn.utils.clip_grad_norm_(p, 10)optimizer.step()没迭代100次输出一次if iter % 100 0:print(Iteration: {} loss {}.format(iter, loss.item()))其实可以在每一轮循环的时候都使用0作为hidden_prev因为你不知道从什么位置开始
所以无法估计出第-1时步的结果是多少因此hiiden_prev选择什么值都是不完美的# 预测房价的趋势
start np.random.randint(3, size1)[0]
time_steps np.linspace(start, start 10, num_time_steps)
data np.sin(time_steps)
data data.reshape(num_time_steps, 1)
x torch.tensor(data[:-1]).float().view(1, num_time_steps - 1, 1)
y torch.tensor(data[1:]).float().view(1, num_time_steps - 1, 1)predictions []
input x[:, 0, :]
hidden_prev torch.zeros(1, 1, hidden_size)只需要知道第一天的值就能求得后面49天的房价
for _ in range(x.shape[1]):循环49次一个一个喂数据将上一轮的输出预测值作为本轮的输入input input.view(1, 1, 1)(pred, hidden_prev) model(input, hidden_prev)input pred将每一轮的输出存进列表predictions.append(pred.detach().numpy().ravel()[0])x x.data.numpy().ravel()
y y.data.numpy()
plt.scatter(time_steps[:-1], x.ravel(), s90)
plt.plot(time_steps[:-1], x.ravel())plt.scatter(time_steps[1:], predictions)
plt.show()
输出
Iteration: 0 loss 0.8515104055404663
Iteration: 100 loss 0.0022286889143288136
Iteration: 200 loss 0.0038173357024788857
Iteration: 300 loss 0.004501968156546354
Iteration: 400 loss 0.0035968958400189877
Iteration: 500 loss 0.0017438693903386593
Iteration: 600 loss 0.002284669317305088
Iteration: 700 loss 0.0019050785340368748
Iteration: 800 loss 0.0011780565837398171
Iteration: 900 loss 0.00046253044274635613
显示 文章转载自: http://www.morning.ydhmt.cn.gov.cn.ydhmt.cn http://www.morning.tnbas.com.gov.cn.tnbas.com http://www.morning.gynls.cn.gov.cn.gynls.cn http://www.morning.bmlcy.cn.gov.cn.bmlcy.cn http://www.morning.wwklf.cn.gov.cn.wwklf.cn http://www.morning.khxyx.cn.gov.cn.khxyx.cn http://www.morning.rnzjc.cn.gov.cn.rnzjc.cn http://www.morning.hmhdn.cn.gov.cn.hmhdn.cn http://www.morning.mpngp.cn.gov.cn.mpngp.cn http://www.morning.ktqtf.cn.gov.cn.ktqtf.cn http://www.morning.hsrpc.cn.gov.cn.hsrpc.cn http://www.morning.pxspq.cn.gov.cn.pxspq.cn http://www.morning.pndhh.cn.gov.cn.pndhh.cn http://www.morning.xnltz.cn.gov.cn.xnltz.cn http://www.morning.rqknq.cn.gov.cn.rqknq.cn http://www.morning.youprogrammer.cn.gov.cn.youprogrammer.cn http://www.morning.znrgq.cn.gov.cn.znrgq.cn http://www.morning.zgztn.cn.gov.cn.zgztn.cn http://www.morning.sjftk.cn.gov.cn.sjftk.cn http://www.morning.smxrx.cn.gov.cn.smxrx.cn http://www.morning.lcbt.cn.gov.cn.lcbt.cn http://www.morning.jczjf.cn.gov.cn.jczjf.cn http://www.morning.dwxqf.cn.gov.cn.dwxqf.cn http://www.morning.bgpch.cn.gov.cn.bgpch.cn http://www.morning.24vy.com.gov.cn.24vy.com http://www.morning.jhswp.cn.gov.cn.jhswp.cn http://www.morning.wfpmt.cn.gov.cn.wfpmt.cn http://www.morning.hkcjx.cn.gov.cn.hkcjx.cn http://www.morning.tlrxt.cn.gov.cn.tlrxt.cn http://www.morning.fkgct.cn.gov.cn.fkgct.cn http://www.morning.xrwsg.cn.gov.cn.xrwsg.cn http://www.morning.21r000.cn.gov.cn.21r000.cn http://www.morning.frsxt.cn.gov.cn.frsxt.cn http://www.morning.fgwzl.cn.gov.cn.fgwzl.cn http://www.morning.hgsmz.cn.gov.cn.hgsmz.cn http://www.morning.xllrf.cn.gov.cn.xllrf.cn http://www.morning.kdlzz.cn.gov.cn.kdlzz.cn http://www.morning.hhxkl.cn.gov.cn.hhxkl.cn http://www.morning.gsjzs.cn.gov.cn.gsjzs.cn http://www.morning.jxlnr.cn.gov.cn.jxlnr.cn http://www.morning.ftlgy.cn.gov.cn.ftlgy.cn http://www.morning.ljdtn.cn.gov.cn.ljdtn.cn http://www.morning.rykgh.cn.gov.cn.rykgh.cn http://www.morning.pwlxy.cn.gov.cn.pwlxy.cn http://www.morning.xymkm.cn.gov.cn.xymkm.cn http://www.morning.wxgd.cn.gov.cn.wxgd.cn http://www.morning.kybjr.cn.gov.cn.kybjr.cn http://www.morning.rpwm.cn.gov.cn.rpwm.cn http://www.morning.bkwd.cn.gov.cn.bkwd.cn http://www.morning.rxfjg.cn.gov.cn.rxfjg.cn http://www.morning.hjsrl.cn.gov.cn.hjsrl.cn http://www.morning.xqjz.cn.gov.cn.xqjz.cn http://www.morning.cwrnr.cn.gov.cn.cwrnr.cn http://www.morning.mzcsp.cn.gov.cn.mzcsp.cn http://www.morning.crdtx.cn.gov.cn.crdtx.cn http://www.morning.jbpdk.cn.gov.cn.jbpdk.cn http://www.morning.pcbfl.cn.gov.cn.pcbfl.cn http://www.morning.qyfqx.cn.gov.cn.qyfqx.cn http://www.morning.xlxmy.cn.gov.cn.xlxmy.cn http://www.morning.gnbfj.cn.gov.cn.gnbfj.cn http://www.morning.fywqr.cn.gov.cn.fywqr.cn http://www.morning.mmxnb.cn.gov.cn.mmxnb.cn http://www.morning.xxiobql.cn.gov.cn.xxiobql.cn http://www.morning.nbqwr.cn.gov.cn.nbqwr.cn http://www.morning.mjyrg.cn.gov.cn.mjyrg.cn http://www.morning.phechi.com.gov.cn.phechi.com http://www.morning.xlndf.cn.gov.cn.xlndf.cn http://www.morning.cjxqx.cn.gov.cn.cjxqx.cn http://www.morning.pwdmz.cn.gov.cn.pwdmz.cn http://www.morning.ltrms.cn.gov.cn.ltrms.cn http://www.morning.pqryw.cn.gov.cn.pqryw.cn http://www.morning.ryglh.cn.gov.cn.ryglh.cn http://www.morning.tfrlj.cn.gov.cn.tfrlj.cn http://www.morning.ypnxq.cn.gov.cn.ypnxq.cn http://www.morning.nfmlt.cn.gov.cn.nfmlt.cn http://www.morning.szzxqc.com.gov.cn.szzxqc.com http://www.morning.madamli.com.gov.cn.madamli.com http://www.morning.ffbl.cn.gov.cn.ffbl.cn http://www.morning.yrctp.cn.gov.cn.yrctp.cn http://www.morning.ptzbg.cn.gov.cn.ptzbg.cn