首页 科技内容详情
AllbetGmaing开户(www.aLLbetgame.us):CNN卷积神经网络详解

AllbetGmaing开户(www.aLLbetgame.us):CNN卷积神经网络详解

分类:科技

网址:

反馈错误: 联络客服

点击直达

皇冠APP下载

www.huangguan.us)是一个开放皇冠即时比分、皇冠官网注册的平台。皇冠注册平台(www.huangguan.us)提供最新皇冠登录,皇冠APP下载包含新皇冠体育代理、会员APP。

,

支解线----------------------------------
  这里更新过一次,在同伙的提醒下,我发现这份代码不是很容易懂。我使用了Pytorch给的官方demo重新实现了LeNet,并做出了详细注释,若是明白下面代码有问题,可以先看我的这篇文章,它能够
辅助你更好的明白这篇文章中的代码,文章地址->:CNN的Pyorch实现(LeNet)
支解线----------------------------------

前言

  在学盘算机视觉的这段时间里整理了不少的条记,想着就把这些条记再重新整理出来,然后写成Blog和人人一起分享。现在的设计如下(以下网络所有使用Pytorch搭建):

专题一:盘算机视觉基础

  • 先容CNN网络(盘算机视觉的基础)
  • 浅谈VGG网络,先容ResNet网络(网络特点是越来越深)
  • 先容GoogLeNet网络(网络特点是越来越宽)
  • 先容DenseNet网络(一个看似十分NB然则却现实上用得不多的网络)
  • 整理时代还会分享一些自己正在加入的竞赛的Baseline

专题二:GAN网络

  • 搭建通俗的GAN网络
  • 卷积GAN
  • 条件GAN
  • 模式溃逃的问题及网络优化

  以上会有相关代码实践,代码是基于Pytorch框架。话不多说,我们先举行专题一的第一部门先容,卷积神经网络。

一、CNN解决了什么问题?

  在CNN泛起之前,对于图像的处置一直都是一个很大的问题,一方面由于图像处置的数据量太大,好比一张512 x 512的灰度图,它的输入参数就已经到达了252144个,更别说1024x1024x3之类的彩色图,这也导致了它的处置成本十分昂贵且效率极低。另一方面,图像在数字化的历程中很难保证原有的特征,这也导致了图像处置的准确率不高。

  而CNN网络能够很好的解决以上两个问题。对于第一个问题,CNN网络它能够很好的将庞大的问题简朴化,将大量的参数降维成少量的参数再做处置。也就是说,在大部门的场景下,我们使用降维不会影响效果。好比在一样平常生涯中,我们用一张1024x1024x3示意鸟的彩色图和一张100x100x3示意鸟的彩色图,我们基本上都能够用肉眼鉴别出这是一只鸟而不是一只狗。这也是卷积神经网络在图像分类里的一个主要应用。【ps:卷积神经网络可以对一张图片举行是猫照样狗举行分类。若是一张图片里有猫有狗有鸡,我们要划分识别出每个区域的动物,并用颜色支解出来,基础的CNN网络还能够使用吗?这是一个拓展思索,有兴趣的读者可以看一下FCN网络。对比之下能够更好的明白CNN网络】

  对于第二个问题,CNN网络行使了类似视觉的方式保留了图像的特征,当图像做翻转、旋转或者变换位置的时刻,它也能有用的识别出来是类似的图像。

  以上两个问题的解决,都是由于CNN网络具有以下优势和特点:局部区域毗邻、权值共享。在注释这三个特点之前,我们先看一下CNN网络的三大主要结构,卷积层、池化层(或者叫做汇聚层)、全毗邻层。

二、CNN网络的结构

2.1 卷积层 - 提取特征

卷积运算

  领会卷积层,我们先要领会一下卷积运算。别看它叫做卷积,然则和严酷意义上的数学卷积是差其余。深度学习所谓的卷积运算是相互关( cross-correlation )运算。【现实上,经由数学证实发现无论用严酷卷积或相互关运算,卷积层的输出不会受太大影响。而相互关运算比严酷卷积运算精练的多,以是我们一样平常都接纳相互关运算来替换严酷意义上的卷积运算。】我们以二维数据为例(高 x 宽),不思量图像的通道个数,假设输入的高度为3、宽度为3的二维张量,卷积核的高度和宽度都是2,而卷积核窗口的形状由内核的高度和宽度决议:

  二维的相互关运算。阴影部门是第一个输出元素,以及用于盘算这个输出的输入和核张量元素: 0 x 0 + 1x1 + 3x2 +4x3 = 19。由此可见相互关运算就是一个乘积求和的历程。在二维相互关运算中,卷积窗口从输入张量的左上角最先,从左到右、从上到下滑动。这里我们设置步长为1,即每次跨越一个距离。当卷积窗口滑到新一个位置时,包罗在该窗口中的部门张量与卷积核张量举行按元素相乘,获得的张量再求和获得一个单一的标量值,由此我们获得了这一位置的输出张量值。 【我们这里频仍提到了张量,张量(Tensor)是一个多维数组,它是标量、向量、矩阵的高维拓展。】

  看了上面的内容,可能有读者最先思索,若是这个输入矩阵是 4x4,卷积核是3x3,步长为1的时刻,在向右移动时,我们发现若是要和卷积核举行卷积操作,左便的输入矩阵还缺少了一列;在行的偏向也是云云。若是我们忽略边缘的像素,我们可能就丢失了边缘的细节。那么这种情形下我们若那边理呢?这时我们可以举行填充操作(padding),在用pytorch实现时我们可以在Convd函数中对padding举行设置,这里我们可以设置padding=1,就能够在行和列上向外扩充一圈。【ps:现实受骗处置对照大的图片,且义务是分类义务时,我们可以不用举行padding。由于对于大部门的图像分类义务,边缘的细节是是无关紧要的,且边缘的像素点相比于总的像向来讲,占比是很小的,对于整个图像分类的义务效果影响不大】

  对于卷积操作,我们有一个统一的盘算公式。且学会相关的盘算对于领会感受野和网络的搭建至关主要。学会相关的盘算,我们在搭建自己的网络或者复现别人的网络,才气够确定好填充padding、步长stride以及卷积核kernel size的参数巨细。一样平常这里有一个统一的公式:

假设图像的尺寸是 input x input,卷积核的巨细是kernel,填充值为padding,步长为stride,卷积后输出的尺寸为output x output,则卷积后,尺寸的盘算公式为:

\[output = \frac{input - kernel + 2 * padding}{stride} + 1 \]

ps:若是输入的图像尺寸是 mxn类型的,可以通过裁剪 or 插值转换成 mxm or nxn类型的图像;或者划分盘算图像的高和宽巨细也可以,公式都是类似的。

权重共享

  我们在前面有提到过CNN网络的一个特征是权重共享(share weights)也正是体现在通道处置的历程中。一样平常的神经网络层与层之间的毗邻是,每个神经元与上一层的所有神经元毗邻,这些毗邻线的权重自力于其他的神经元,以是假设上一层是m个神经元,当前层是n个神经元,那么共有mxn个毗邻,也就有mxn个权重。权重矩阵是mxn的形式。那么CNN是若何呢?权重共享是什么意思?我们引入下面这样一张图来辅助我们明白:

  我们先说明上图中各个模块的矩阵花样及关系:

  • 输入矩阵花样:(样本数,图像高度,图像宽度,图像通道数)
  • 输出矩阵花样:(样本数,图像高度、图像宽度、图像通道数)
  • 卷积核的花样:(卷积核高度、卷积核宽度、输入通道数、输出通道数)
  • 卷积核的输入通道数(in depth)由输入矩阵的通道数所决议。(红色标注)
  • 输出矩阵的通道数(out depth)由卷积核的输出通道所决议。(绿色标注)
  • 输出矩阵的高度和宽度,由输入矩阵、卷积核巨细、步长、填充配合决议,详细盘算公式见上文。

  当输入一张巨细为8x8x3的彩色图时,我们已经提前设计好了卷积核后的输出通道为5,即卷积核的个数为5【即五个偏置,一个卷积核一个偏置】(通道数的设计一样平常是实验后获得的较优效果)。每个卷积核去和输入图像在通道上逐一对应举行卷积操作(即相互关操作,除非刻意强调,这里所说的卷积都是相互关,步长为1,填充为0),获得了3个6x6的feature map。然后再将三个6x6的Feature map根据Eletwise相加举行通道融合获得最终的feature map,巨细为6x6(也就是将获得的三个矩阵逐元素相加,之后所有元素再加上该矩阵的偏置值,获得新的6x6矩阵)。权重共享也是体现在这个历程中。我们单独提取出第一个卷积核,当它的第一个通道(3x3)与输入图像的第一个通道(8x8)举行卷积操作时,根据通俗的神经网络毗邻方式其权重矩阵是9 x 81。然则这里我们要注重,我们在窗口滑动举行卷积的操作权重是确定的,都是以输入图像的第一个通道为模板,卷积核的第一个通道3x3矩阵为权重值,然后获得卷积效果。这个历程中权重矩阵就是3x3,且多次应用于每次盘算中。权重的个数有9x81削减到3x3,极大的削减了参数的数目。综合起来,对于第一个卷积核来讲,它的权重矩阵就是3x3x3+1,整个卷积历程的权重巨细为3x3x3x5+5,而不是8x8x3x3x3x3x5。权重共享大大削减了模子的训练参数。权重共享意味着当前隐藏层中的所有神经元都在检测图像差异位置处的统一个特征,即检测特征相同。因此也将输入层到隐藏层的这种映射称为特征映射。由上我们可以明白,从某种意义上来说,通道就是某种意义上的特征图。输出的统一张特征图上的所有元素共享一个卷积核,即共享一个权重。通道中某一处(特征图上某一个神经元)数值的巨细就是当前位置对当前特征强弱的反映。而为什么在CNN网络中我们会增添通道数目,实在就是在增添通道的历程中区学习图像的多个差异特征。

希罕毗邻

  通过上面临于卷积的历程以及权重共享的注释,我们能够总结出CNN的另一个特征。有心的读者实在能够自己总结出来。我们在上面提到过,对于通俗的神经网络,隐藏层和输入层之间的神经元是接纳全毗邻的方式。然而CNN网络并不是云云。它的在局部区域确立毗邻,即希罕毗邻。好比,对于一张输入的单通道的8x8图片,我们用3x3的卷积核和他举行卷积,卷积核中的每个元素的值是和8x8矩阵中选取了3x3的矩阵做卷积运算,然后通过滑动窗口的方式,卷积核中的每个元素(也就是神经元)只与上一层的所有神经元中的9个举行毗邻。相比于神经元之间的全毗邻方式,希罕毗邻极洪水平上的削减了参数的数目,同时也一定水平上阻止了模子的过拟合。这种算法的灵感是来自动物视觉的皮层结构,其指的是动物视觉的神经元在感知外界物体的历程中起作用的只有一部门神经元。在盘算机视觉中,像素之间的相关性与像素之间的距离同样相关,距离较近的像素间相关性强,距离较远则相关性对照弱,由此可见局部相关性理论也适用于盘算机视觉的图像处置。因此,局部感知(希罕毗邻)接纳部门神经元接受图像信息,再通过综合所有的图像信息到达增强图像信息的目的。(至于我们为什么现在经常接纳3x3卷积核,由于实验效果告诉我们,3x3卷积核经常能到达更好的实验效果。)

总结:尺度的卷积操作

  在举行上面的注释后,信托人人已经对于什么是卷积,卷积的两点特点:希罕链接和权重共享已经有了领会。下面我们来总结一样平常意义的尺度的卷积操作:当输入的feature map数目(即输入的通道数)是N,卷积层filter(卷积核)个数是M时,则M个filter中,每一个filter都有N个channel,都要划分和输入的N个通道做卷积,获得N个特征图,然后将这N个feature map按Eletwise相加(即:举行通道融合),再加上该filter对应的偏置(一个filter对应一个共享偏置),作为该卷积核所得的特征图。同理,对其他M-1个filter也举行以上操作。以是最终该层的输出为M个feature map(即:输出channel即是filter的个数)。可见,输出的统一张特征图上的所有元素共享统一个卷积核,即共享一个权重。差异特征图对应的卷积核差异。

卷积的意义

  若是用图像处置上的专业术语,我们可以将卷积叫做锐化。卷积实在是想要强调某些特征,然后将特征强化后提取出来,差异卷积核关注图片上差其余特征,好比有的更关注边缘而有的更关注中央地带等。当完成几个卷积层后(卷积 + 激活函数 + 池化)【后面解说激活函数和池化】,如图所示:

  在CNN中,我们就是通过不停的改变卷积核矩阵的值来关注差其余细节,提取差其余特征。也就是说,在我们初始化卷积核的矩阵值(即权重参数)后,我们通过梯度下降不停降低loss来获得最好的权重参数,整个历程都是自动调整的。

1x1卷积的重大意义

  根据原理讲,我是不应这么快就引入1x1卷积的,不外思量到它在种种网络中应用的主要性而且也不难明白,就在这里提前和人人注释一下1x1卷积是什么,作用是什么。

  若是有读者在明白完上文所提到的卷积后,可能会发出疑问:卷积的本质不是有用的提取相邻像素间的相关特征吗?1x1卷积核的每个通道和上一层的通道举行卷积操作的时刻不是没法识别相邻元素了吗?

  实在否则,1x1卷积层简直是在高度和宽度的维度上失去了识别相邻元素间的相互作用的能力,而且通过1x1卷积核后的输出效果的高和宽与上一层的高和宽是相同的。然则,通道数目可能是差其余。而1x1卷积的唯一盘算也正是发生在通道上。它通过改变1x1卷积核的数目,实现了多通道的线性叠加,使得差其余feature map举行线性叠加。我们通过下图来更好的熟悉1x1卷积的作用:

  上图使用了2个通道的1x1卷积核与3个通道的3x3输入矩阵举行卷积操作。由图可知,这里的输入和输出具有相同的高度和宽度,输出的每个元素都是从输入图像的统一位置的元素的线性组合。我们可以将1x1卷积层看做是每个像素位置应用的全毗邻层。同时,我们发现输出效果的通道数目发生了改变,这也是1x1卷积的一个主要应用。可以对输出通道举行升维或者降维,而且不改变图像尺寸的巨细,有利于跨通道的信息交流的内在。降维之后我们可以使得参数数目变得更少,训练更快,内存占用也会更少。若是是在GPU上训练,显存就加倍珍贵了。

  卷积网络的一个异常主要的应用就是ResNet网络,而ResNet网络结构,已经应用于种种大型网络中,可以说是随处可见。这里先贴个ResNet中应用了1x1卷积的残差块,后面会有一篇文章来解读ResNet网络:ResNet paper download

Allbet Gmaing开户

欢迎进入Allbet Gmaing开户(www.aLLbetgame.us),欧博官网是欧博集团的官方网站。欧博官网开放Allbet注册、Allbe代理、Allbet电脑客户端、Allbet手机版下载等业务。

2.2 激活函数

  由前述可知,在CNN中,卷积操作只是加权求和的线性操作。若神经网络中只用卷积层,那么无论有若干层,输出都是输入的线性组合,网络的表达能力有限,无法学习到非线性函数。因此CNN引入激活函数,激活函数是个非线性函数,常用于卷积层和全毗邻层输出的每个神经元,给神经元引入了非线性因素,使网络的表达能力更强,险些可以迫近随便函数,这样的神经网络就可应用到众多的非线性模子中,我们可以用公式来界说隐藏层的每个神经元输出公式:

\[y_l^i = W_l \times x_{l-1}^{n \times n} + b_l \]

其中,\(b_l\)是该感知与毗邻的共享偏置,\(W_l\)​是个nxn的共享权重矩阵,\(X_{l-1}^{n \times n}\)​代表在输入层的nxn的矩形区域的特征值。

  当激活函数作用于卷积层的输出时:

\[y_l^i = \sigma (W_l \times x_{l-1}^{n \times n} + b_l) \]

这里的\(\sigma\)是神经元的激励函数,可以是Sigmoid、tanh、ReLU等函数。

2.3 池化层(下采样) - 数据降维,阻止过拟合

  在CNN中,池化层通常在卷积或者激励函数的后面,池化的方式有两种,全最大池化或者平均池化,池化主要有三个作用:

  • 一是降低卷积层对目的位置的敏感度,即实现局部平移稳固性,当输入有一定的平移时,经由池化后输出不会发生改变。CNN通过引入池化,使得其特征提取不会由于目的位置转变而受到较大的影响。
  • 二是降低对空间降采样示意的敏感性
  • 三是能够对其举行降维压缩,以加速运算速率 ,防止过拟合。

  与卷积层类似的是,池化层运算符有一个牢靠的窗口组成,该窗口也是凭证步幅巨细在输入的所有区域上滑动,为牢靠的形状窗口遍历每个位置盘算一个输出。

输出的张量高度为2,宽度为2,这四个元素为每个池化窗口中的最大值(stride=1,padding=0):

  然则,差异于卷积层中的输入与卷积核之间的相互关盘算,池化层不包罗参数。池化层的运算符是确定性的,我们通常盘算池化窗口中所有元素的最大值或平均值(些操作划分被称为最大池化层和平均池化层),而不是像卷积层那样将各通道的输入在相互关操作后举行eletwise特征融合,这也意味着池化层的输出通道数和输入通道数目是相同的。池化操作的盘算一样平常形式为,设输入图像尺寸为WxHxC,宽x高x深度,卷积核的尺寸为FxF,S:步长,则池化后图像的巨细为:

\[W = \frac{W-F}{S} +1 \\ H = \frac{H-F}{S} + 1 \]

2.4 全毗邻层 - 分类,输出效果

  我们刚给讲了卷积层、池化层和激活函数,这些在全毗邻层之前层的作用都是将原始数据映射到隐层特征空间来提取特征,而全毗邻层的作用就是将学习到的特征示意映射到样本的符号空间。换句话说,就是把特征正和岛一起(高度提纯特征),利便交给最后的分类器或者回归。

  我们也可以把全毗邻层的历程看做一个卷积历程,例如某个网络在经由卷积、ReLU激活后获得3x3x5的输出,然后经由全毗邻层转换成1x4096的形式:

  从上图我们可以看出,我们用一个3x3x5的filter去卷积激活函数的输出,获得的效果是全毗邻层的一个神经元,由于我们有4096个神经元,我们现实上就是用一个3x3x5x4096的卷积层去卷积激活函数的输出【不带偏置】。因此全毗邻层中的每个神经元都可以看成一个不带偏置加权平均的多项式,我们可以简朴写成$y_l^i = W_l \times x_{l-1}^{n \times n} $​。​

  这一步卷积另有一个异常主要的作用,就是把漫衍式特征representation映射到样本符号空间,简朴说就是把特征整合到一起,输出为一个值,这样可以大大削减特征位置对分类带来的影响。

  从上面的图,我们可以看出,猫在差其余位置,输出的特征值相同,然则位置差异;对于电脑来说,特征值相同,然则特征值位置差异,那分类效果可能是纷歧样的。此时全毗邻层的作用就是,在展平后忽略其空间结构特征,不管它在哪儿,只要它有这个猫,那么就能判别它是猫。这也说明晰它是一个跟全局图像的问题有关的问题(例如:图像是否包罗一只猫呢)。这也说明晰全毗邻层的结构不适适用于在方位上找patter的义务,例如支解义务(后面的FCN就是将全毗邻层改成了卷积层)。不外全毗邻层有一个很大的瑕玷,就是参数过于多。以是后面的像ResNet网络、GoogLeNet都已经接纳全局平均池化取代全毗邻层来融合学到的特征。另外,参数多了也引发了另外一个问题,模子庞大度提升,学习能力太好容易造成过拟合。

三、Pytorch实现LeNet网络

  LeNet模子是最早宣布的卷积神经网络之一,它是由AT&T贝尔实验室的研究院Yann LeCun在1989年提出的,目的是识别图像中的手写数字,揭晓了第一篇通过反向流传乐成训练卷积神经网络的研究。我们现在通过pytorch来实现:LeNet - Paper Download 。

  LeNet它虽然很小,然则包罗了深度学习的基本模块。我们先对LeNet结构举行一个详细的剖析,这也是我们搭建任何一个神经网络之前要提前知道的:

  每个卷积块中的基本单元是一个卷积层、一个Sigmod激活函数和平均池化层。(虽然ReLU函数和最大池化层很有用,然则那时还没有泛起)。每个卷积层使用5x5卷积核和一个Sigmoid激活函数。第一个卷积层有6个输出通道,第二个卷积层有16个输出通道。每个2x2赤化操作通过空间下采样将维数削减4倍。卷积的输出形状由(批量巨细,通道数,高度,宽度)决议。LeNet中有三个全毗邻层,划分有120、84、10个输出,由于我们在执行手写数字的分类义务(一共有0-9共10个数字),以是输出层的10维对应于最后输出的效果的数目。

把上面的模子简化一下,网络结构也许就是这个样子:

3.1 模子界说

import torch
from torch import nn
from d2l import torch as d2l


class Reshape(torch.nn.Module):
    def forward(self, x):
        # 通过view函数把图像展成尺度的Tensor吸收花样,即(样本数目,通道数,高,宽)
        return x.view(-1, 1, 28, 28)

net = torch.nn.Sequential(
    Reshape(),
    # 第一个卷积块,这里用到了padding=2
    nn.Conv2d(1, 6, kernel_size=5, padding=2), 
    nn.Sigmoid(),
    nn.AvgPool2d(kernel_size=2, stride=2),
    
    # 第二个卷积块
    nn.Conv2d(6, 16, kernel_size=5), 
    nn.Sigmoid(),
    nn.AvgPool2d(kernel_size=2, stride=2),
    
    # 浓密块(三个全毗邻层)
    nn.Flatten(),
    nn.Linear(16 * 5 * 5, 120), nn.Sigmoid(),
    nn.Linear(120, 84), nn.Sigmoid(),
    nn.Linear(84, 10))
X = torch.rand(size=(1, 1, 28, 28), dtype=torch.float32)
for layer in net:
    X = layer(X)
    print(layer.__class__.__name__,'output shape: \t',X.shape)

输出效果为:

3.2 模子训练(使用GPU训练)

我们用LeNet在Fashion-MNIST数据集上测试模子显示效果:

batch_size = 256
train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size=batch_size)

def evaluate_accuracy_gpu(net, data_iter, device=None): #@save
    """使用GPU盘算模子在数据集上的精度。"""
    if isinstance(net, torch.nn.Module):
        net.eval()  # 设置为评估模式
        if not device:
            device = next(iter(net.parameters())).device
    # 准确展望的数目,总展望的数目
    metric = d2l.Accumulator(2)
    for X, y in data_iter:
        if isinstance(X, list):
            X = [x.to(device) for x in X]
        else:
            X = X.to(device)
        y = y.to(device)
        metric.add(d2l.accuracy(net(X), y), y.numel())
    return metric[0] / metric[1]

#@save
def train_ch6(net, train_iter, test_iter, num_epochs, lr, device):
    """用GPU训练模子。"""
    def init_weights(m):
        if type(m) == nn.Linear or type(m) == nn.Conv2d:
            nn.init.xavier_uniform_(m.weight)
    net.apply(init_weights)
    print('training on', device)
    net.to(device)
    optimizer = torch.optim.SGD(net.parameters(), lr=lr)
    loss = nn.CrossEntropyLoss()
    animator = d2l.Animator(xlabel='epoch', xlim=[1, num_epochs],
                            legend=['train loss', 'train acc', 'test acc'])
    timer, num_batches = d2l.Timer(), len(train_iter)
    for epoch in range(num_epochs):
        # 训练损失之和,训练准确率之和,类型数
        metric = d2l.Accumulator(3)
        net.train()
        for i, (X, y) in enumerate(train_iter):
            timer.start()
            optimizer.zero_grad()
            X, y = X.to(device), y.to(device)
            y_hat = net(X)
            l = loss(y_hat, y)
            l.backward()
            optimizer.step()
            with torch.no_grad():
                metric.add(l * X.shape[0], d2l.accuracy(y_hat, y), X.shape[0])
            timer.stop()
            train_l = metric[0] / metric[2]
            train_acc = metric[1] / metric[2]
            if (i + 1) % (num_batches // 5) == 0 or i == num_batches - 1:
                animator.add(epoch + (i + 1) / num_batches,
                             (train_l, train_acc, None))
        test_acc = evaluate_accuracy_gpu(net, test_iter)
        animator.add(epoch + 1, (None, None, test_acc))
    print(f'loss {train_l:.3f}, train acc {train_acc:.3f}, '
          f'test acc {test_acc:.3f}')
    print(f'{metric[2] * num_epochs / timer.sum():.1f} examples/sec '
          f'on {str(device)}')

3.3 训练和评估模子

``

lr, num_epochs = 0.9, 10
train_ch6(net, train_iter, test_iter, num_epochs, lr, d2l.try_gpu())

这个是我的训练效果,也许就酱紫,竣事了却束了,累死我了。

引用:

https://www.cnblogs.com/chumingqian/articles/11495364.html

https://blog.csdn.net/u011240016/article/details/78475043

https://mp.weixin.qq.com/s/eOM3YHPkCCmMpLrv4ZDhBA

https://zhuanlan.zhihu.com/p/33841176

https://blog.csdn.net/weixin_45829462/article/details/106548749

  • 欧博aLLbet(www.aLLbetgame.us) @回复Ta

    2021-09-29 00:04:29 

    时代,杨九郎先后一共有过三个同伴,第一任同伴是九字科的大师哥张九龄,第二任是于谦先生的二徒弟冯照洋,第三任也是现任,是云字科的大师哥张云雷。美滴很!

  • 澳洲幸运5彩票开奖网(a55555.net) @回复Ta

    2021-10-05 00:01:47 

    郑文灿也提到,桃园海岸线全长46公里,其中广达961公顷的「许厝港国家级主要溼地」,市府2019年起睁开溼地生态复育、拆除非法鱼塭,现在候鸟种类跨越200种且数目生长5倍,今年已投入1亿元打造全长200公尺的许厝港自行车景观大桥,跨越老街溪及双溪口溪,预计明年9月完工,将串联许厝港溼地与草漯沙丘两大生态旅游亮点,展现桃园海岸特色。哈哈,好欢乐

发布评论