当前位置: 首页 > news >正文

【AI?】

25082508 2508

从函数到神经网络

  • 符号主义

符号主义

函数可以表示一切

func describe the world

image-20250806181907718请添加图片描述

问题来了,找不到足够丝滑的函数「难以找到」

  • 联结主义

联结主义

猜&简化

先猜一个函数f(x)=wx+bf(x)=wx+bf(x)=wx+b,然后不断调整w和b,逐渐逼近真实答案「一个足够接近真实答案的近似解」
f(x)=wx+bf(x)=wx+b f(x)=wx+b
找不到完全吻合的函数,差不多就行了「简化问题」

效果出乎意料的好,很少的参数即可实现任务。

问题:f(x)=wx+bf(x)=wx+bf(x)=wx+b线性函数太简单,不足以描述更复杂的关系

  • 激活函数

激活函数

把原本死气沉沉的线性关系,盘活了。「比如平方,将直线变为抛物线」

注意:每个输入xix_ixi都要对应一个wiw_iwi
f(x)=g(wx+b)f(x)=\textcolor {red}{g(}wx+b\textcolor {red}{)} f(x)=g(wx+b)
image-20250806185113305
请添加图片描述

通过线性变换和非线性激活函数的不断组合和套娃,可以表达很复杂的关系
f(x1,x2)=g(w3g(w1x1+w2x2+b)+b2)f(x_1,x_2)=g(w_3{\color{gray}g(w_1x_1+w_2x_2+b)}+b_2) f(x1,x2)=g(w3g(w1x1+w2x2+b)+b2)
image-20250806185028559

请添加图片描述

但是写成函数看太恶心了,所以画成了「神经网络」

  • 神经网络

神经网络

每个小圈称为「神经元」。

中间结果「或者说前半部分计算结果」称为「隐藏层」。

从左到右一点点把函数计算出来,称为「前向传播」。

image-20250806185258287

请添加图片描述

我们的目的:求出w、b,使这个函数可以很好的拟合真实数据「已知的输入x」

总结

从符号主义试图用完美函数描述世界却因规律难寻遇阻,到联结主义退而求其次用简单线性函数f(x)=wx+b“连蒙带猜”近似规律,虽凭少量参数简化问题但受限于线性表达能力;随后激活函数通过非线性变换“盘活”线性关系,让每个输入x对应独立权重w,再经“线性变换+非线性激活”的多层套娃实现复杂关系建模;而神经网络正是这种嵌套结构的可视化呈现,其核心目标始终是求解最优权重w和偏置b,以精准拟合真实数据

计算神经网络的参数

本节目的:
1. 如何量化「拟合程度」?
2. 找一个线性函数f(x),称「线性回归」。
3. 

问题:什么样的w、b才是好的呢?

拟合的好,才是真的好。

问题:什么叫「拟合的好」?如何表达?

  • 损失函数

损失函数&均方误差&线性回归

预测数据与真实数据之间差距的总和。可以反映当前这个线性函数跟与真实数据的拟合度。

image-20250806201054098

请添加图片描述

  • 最小二乘法

带绝对值不够平滑,求平方。这种优化方法称为「最小二乘法」。

再根据验本数量平均一下,消除样本数量大小的影响,就得到了一种计算损失的函数:

  • 均方误差(Mean-Square Error, MSE)

Loss(w,b)=1N∑i=1N(yi−yi^)2Loss(w,b)=\frac1{N}\sum_{i=1}^{N}(y_i-\hat{y_i})^2 Lossw,b=N1i=1N(yiyi^)2

目标:求让Loss函数最小的那个点,对应的w和b。

方法:让该损失函数的导数=0,求极值点。

因为是关于w和b的二元函数,因此要求出「偏导」(固定一方为常数)。

image-20250806234226017

请添加图片描述

上面这个「通过寻找==一个线性函数==,来拟合x和y的关系」,就是机器学习中最基本的一种分析方法:「线性回归」

  • 线性回归

神经网络是通过线性函数与非线性激活函数的不断组合和套娃,形成的一种极为复杂的非线性函数模型

其损失函数是远比一个线性函数要复杂的非线性函数,往往不能导数=0直接求出最小值,那该怎么办呢?

  • 梯度下降

梯度下降

简单粗暴:一点点试

增大w,若Loss减小,则继续增大w。b同理。「直到让Loss足够小」

w变化一点使得Loss会变化多少,其实就是损失函数对w的偏导数 ∂L(w,b)∂w\frac{\partial L(w, b)}{\partial w}wL(w,b) 。b同理。

我们要做的就是让w和b向偏导数「梯度」的反方向变化,变化的快慢(变化幅度)再加一个系数η\etaη学习率」来控制:
wnew=w−η∂L(w,b)∂ww_{new} = w-\eta\frac{\partial L(w, b)}{\partial w} wnew=wηwL(w,b)

解释:为何朝着偏导数「梯度」的反方向变化?

调整方向:反着偏导数来

  • 如果 (∂L(w,b)∂w\frac{\partial L(w, b)}{\partial w}wL(w,b)) 是 正的「正相关」:说明 w 越大 Loss 越大(或减小 w 会让 Loss 减小 )→ 为了让 Loss 变小,w 要减去梯度
  • 负相关同理,w越大Loss越小,w要加上梯度。

不管正负,让 w 向 “偏导数的反方向” 变化,就能一步步让 Loss 减小。

学习率 (η=0.01\eta=0.01η=0.01),就表示每次只按照 “偏导数的 1%” 来调整 w,慢慢逼近最优值。

不断变化w和b,让Loss逐渐减小,进而求出最终的w和b的过程,就叫「梯度下降」。

其中,「梯度」指的是所有参数偏导数的向量集合。对于含 w 和 b 两个参数的函数,梯度为 (∇L(w,b)=(∂L(w,b)∂w,∂L(w,b)∂b)\nabla L(w, b) = \left( \frac{\partial L(w, b)}{\partial w}, \frac{\partial L(w, b)}{\partial b} \right)L(w,b)=(wL(w,b),bL(w,b)))。它不仅包含每个参数的偏导数大小,还整体表示 Loss 函数在当前参数点上变化最快的方向和幅度.

问题又来了,有了求出最小值的公式「梯度下降」,但这个公式里的偏导数 ∂L(w,b)∂w\frac{\partial L(w, b)}{\partial w}wL(w,b) 怎么求呢?

  • 链式法则

链式法则&反向传播&训练

神经网络整体虽然复杂,但层与层之间的关系却十分简单(一个非线性激活函数罢了)

以图中最难求的w1w_1w1为例「w2w_2w2、a同理,不过层数更少」,我们想知道w1w_1w1变化一个单位,损失函数Loss变化了多少。

先看w1w_1w1变化1单位,会使得a变化多少,再看a变化1单位,会使y^\hat yy^变化多少,再看y^\hat yy^变化1单位,会使Loss变化多少。将三者乘起来,就得到w1w_1w1变化1单位,损失函数Loss变化多少了。亦即我们想求的偏导数。

image-20250807223046147

请添加图片描述

若想不通可以联想齿轮。计算第一个转一圈会使得最后一个转多少圈。
∂L∂w1=∂L∂y^∂y^∂a∂a∂w1\frac{\partial L}{\partial w_1}=\frac{\partial L}{\partial \hat y}\frac{\partial \hat y}{\partial a}\frac{\partial a}{\partial w_1} w1L=y^Lay^w1a
这其实就是偏导数的链式求导,也称为「链式法则」。(微积分的复合函数求导)

由于我们可以从Loss开始自右向左依次求导,然后逐步更新每一层的参数w和b,而由于链式法则,前一层的偏导数的值后面也会用到,所以不用每次都重新计算,让这些值从右向左一点点传播过来即可。形象的称之为「反向传播」

  • 反向传播
  • 训练

根据之前的知识,我们通过输入x计算输出y,得到Loss后再通过反向传播计算损失函数关于每个参数的梯度,每个参数都向梯度的反方向变化一点点,这就完成了神经网络的一次训练。

通过一点点变化,直到损失函数足够小,就找到了我们想要的「符号」f(xn)f(x_n)f(xn)

听起来简单,但真实问题往往存在各种难题。

总结

要判断w和b是否“好”,核心看模型对数据的「拟合程度」——而拟合好坏由损失函数量化:它计算预测值与真实值的差距总和,差距越小拟合越好。最常用的是均方误差(MSE),通过对误差平方后取平均(Loss(w,b)=1N∑i=1N(yi−yi^)2)(Loss(w,b)=\frac{1}{N}\sum_{i=1}^{N}(y_i-\hat{y_i})^2)(Loss(w,b)=N1i=1N(yiyi^)2),既避免绝对值的不平滑,又消除样本数量影响。

目标是找到使Loss最小的w和b:

  • 简单线性回归可直接求Loss函数导数为0的极值点(用偏导,因w、b是二元变量)。
  • 但神经网络是复杂非线性模型,无法直接求解析解,需用梯度下降:通过“试错”调整w和b——每次沿Loss对w(或b)偏导数的反方向更新(因偏导正→增w会增Loss,需减w;偏导负则反之),更新幅度由学习率(η) 控制(w=w−η∂L∂w)(w = w-\eta\frac{\partial L}{\partial w})(w=wηwL),逐步逼近Loss最小值。

梯度下降的关键是求偏导,神经网络多层结构需用链式法则:像齿轮传动,逐层计算参数变化对Loss的影响(如∂L∂w1=∂L∂y^⋅∂y^∂a⋅∂a∂w1)\frac{\partial L}{\partial w_1}=\frac{\partial L}{\partial \hat{y}}\cdot\frac{\partial \hat{y}}{\partial a}\cdot\frac{\partial a}{\partial w_1})w1L=y^Lay^w1a)。而从Loss出发自右向左逐层传递偏导值、更新参数的过程,就是反向传播

最终,通过==“正向计算输出→算Loss→反向传播求梯度→梯度下降调参数”==的反复训练,直到Loss足够小,就得到了最优的w和b。

调教神经网络的方法

过拟合&泛化能力

只要构造一个足够复杂的函数「复杂神经网络」,那么不就可以表达世间万物了吗?

之前我们的目标是「拟合的好」,但过于复杂函数会出现一种在训练数据上表现完美「损失极小」,但在没见过数据上表现很糟糕的现象。

这种现象,我们称为「过拟合」。

在没见过数据上的表现,我们称为「泛化能力」

  • 过拟合
  • 泛化能力

如图所示的「复杂神经网络」的训练效果甚至不如一个线性模型。所以说模型并非越复杂越好(把噪声和随机波动也给学会了)。

image-20250814113400190

请添加图片描述

数据增强&正则化&Dropout

那么如何解决「过拟合」这个问题呢?

  • 数据增强

第一种方法:从数据和模型本身入手,简化模型复杂度。

增加训练数据的量。相对的模型复杂度也会变简单「简单模型也能有效拟合」。「数据越多,模型受噪声影响越小(易区分规律与噪声)」

有时我们确实无法收集或懒得收集更多的数据,直接在原有数据基础上创造新的数据。比如在图像数据中,对图像进行旋转、翻转、裁剪、加噪声等操作,创建更多的训练样本。称为「数据增强」。刚好训练了一个不因输入一点小小变化,对结果产生很大波动的模型「鲁棒性」。

  • 正则化

第二种方法:从训练过程入手,抑制参数野蛮生长。

训练本身就是不断调整参数的过程。有个简单到难以置信的方法:停止训练

但模型会比较粗糙。更精细的抑制参数野蛮增长的方法:给损失函数**加上一项参数本身**的绝对值∣w∣|w|w「目标是让损失函数最小化,若参数增幅过大会让损失函数变大,达成抑制目的」,我们称该项为「惩罚项」。

同控制损失函数下降力度的「学习率」一样,给惩罚项增加一个控制惩罚力度的系数「正则化系数」。这种控制参数的参数,我们称之为「超参数」。

image-20250814113820521

请添加图片描述

除此之外,还有一种简单到令人发指的方法。

  • Dropout「暂时失效」

每次训练部分参数,临时简化模型结构,让整体参数都差不多。

为防止模型过度依赖少量参数,在训练过程中,每次随机丢弃部分参数,让模型不得不依赖更多的普通参数。结果表明,该方法抑制过拟合很有效。由深度学习之父 Hinton 提出。

其他

计算优化
收敛加速方法
梯度异常应对
训练核心问题
mini-batch
动量法
RMSProp
Adam
梯度裁剪
残差网络
权重初始化
归一化
梯度消失/梯度爆炸
收敛速度
计算开销

从矩阵到CNN

矩阵运算

  • 矩阵运算

我们将神经网络的一层中麻烦的“加减乘除”写法替换为“矩阵运算”,如图所示:

image-20250814115517979

请添加图片描述

Y=g(WX+b)Y=g(WX+b) Y=g(WX+b)
但是神经网络的「层」并没有体现在公式中。

我们将x、yx、yxy、隐藏层等通通抽象为「第aaa层」。将“第几层”用lll表示,就得到了:
A[L]=g(W[L]A[L−1]+b[L]){\color{red}A^{[L]}}=g(W^{[L]}{\color{red}A^{[L-1]}}+b^{[L]}) A[L]=g(W[L]A[L1]+b[L])
既简化了写法,又可以利用GPU并行计算特性,加速神经网络的训练和推理过程。

image-20250814115822220

请添加图片描述

全连接层&卷积核&池化层

  • 全连接层

我们注意到,每个神经元「小圆圈」都与前一层所有的神经元相连接,称这样一层神经元为「全连接层(FC)」。也就是说,还有不是全连接层的「层」。

  • 卷积核

全连接层的局限性,一个30x30的图片,900个输入,假设后一层有1000神经元,那么就是90万参数。

在灰度图片中找一个3x3的矩阵,与一个确定的3x3矩阵「卷积核」对应位置相乘再求和,遍历原图所得的新数值形成一个新图像,这种运算,我们称为「卷积运算」。

在传统图像处理领域,卷积核是已知的。

而在深度学习领域,卷积核的值也是参数wiw_iwi,是被训练出来的一组值。

将神经网络其中一个全连接层替换为「卷积层」,就大大减少了权重参数的数量,还能更有效的捕捉图片的局部特征,可谓一举两得。

从公式上看,将原来的矩阵叉乘替换为了卷积运算。
A[L]=g(W[L]∗A[L−1]+b[L])A^{[L]}=g(W^{[L]}{\color{red}*}A^{[L-1]}+b^{[L]}) A[L]=g(W[L]A[L1]+b[L])
至此,神经网络也不用画成一个个的小圈了,而是用更简洁的方块表示。

除了卷积层外,还有「池化层」。作用是对卷积后的特征图像进行「降维」,减少计算量同时保留主要特征。

  • 池化层
  • 卷积神经网络(CNN)

「全连接层」、「卷积层」、「池化层」都可以有多个,由它们组成的适用于图像识别领域的实际网络结构,我们称为「卷积神经网络(CNN)」。

image-20250814121939759

请添加图片描述

从词嵌入到RNN

词向量&词嵌入

给你几个字,让你生成后面一个字。给你一句话,然你判断每个词的褒贬。

把文字作为参数,要先把文字「编码」为计算机能识别的01数字。

  • 词向量:通过词语编码得到的向量

有两种极端编码方式:

  1. 一个数字对应一个词语。词表大小对应数字标识范围大小。缺点非常明显:维度太低「一维向量」,且数字标识本身无法衡量词与词之间相关性。
  2. 准备一个超级大的向量,每个词只有向量中一个位置是1,剩余全0。这种编码方式称为「one-hot 独热编码」。缺点:维度太高,太稀疏,且每个向量都是正交的,且仍无法找到词间相关性。(若将向量中每个位置看做特征,那其特征极其死板「是不是“该词”」)
  • 词嵌入 word embedding

维度太高太低都不好,那就弄个不高不低的,称为「词嵌入」,一种高效好用的编码方式。

通过词嵌入编码方式得到的词向量,维度适中。其向量的每个位置依然可以理解为某个特征值,不过该「特征值」是训练出来的,人类可能完全无法理解。

由词向量组成的矩阵,称为「嵌入矩阵」。(由经典训练方法word2vec得出)

image-20250814154251848

请添加图片描述

词向量维度远高于三维,因此其所在空间维度也很高,称为「潜空间」。

如何表示词间语义上的相关性呢?

向量点积&余弦相似度

  • 向量点积
  • 余弦相似度

a⋅b=∑i=1naibi\mathbf{a} \cdot \mathbf{b} = \sum_{i=1}^{n} a_i b_i ab=i=1naibi

cos⁡(θ)=a⋅b∥a∥⋅∥b∥\cos(\theta) = \frac{\mathbf{a} \cdot \mathbf{b}}{\lVert \mathbf{a} \rVert \cdot \lVert \mathbf{b} \rVert} cos(θ)=abab

通过求出向量间相关性,进而表示词语间相关性。「虽能算出但不够直观Embedding projector - visualization of high-dimensional data投射到三维,可视化观词间关系」

此时,词就可以编码为向量,送到输入端的神经元了。

假设词向量的维度是300维,那么一句五个词的话所需要的输入端神经元就是1500个。

问题来了,一是输入层太大。二是随话中词语数量变化,导致输入端是变长的。三是无法体现词间先后顺序,仅平铺开输入「类似那个30*30导致90万参数的图片,缺点很多,不可取」。

图像处理领域采用卷积来提取图像特征,自然语言处理领域如何解决词间顺序问题呢?

RNN

  • RNN

经典神经网络无法表达词间先后顺序,因此我们添加一个隐藏状态,在词间传递。

我们在第一个词经过非线性变化后,先不输出结果Y1Y_1Y1,而是输出一个中间结果H1H_1H1「隐藏状态」,再经过一次非线性变换得到Y1Y_1Y1

中间隐藏状态H1H_1H1用来加入第二个词一起参与运算,这样就达到了「传达前词信息」的目的。

image-20250814160242375

请添加图片描述

称之为「循环神经网络 RNN」,和经典神经网络相比,只是多了一个前一时刻的隐藏状态而已。
h<t>=g1(WxhX<t>+Whhh<t−1>+bh)y<t>=g2(Whyh<t>+by)h^{<t>} = g_1(W_{xh} X^{<t>} + {\color{red}W_{hh} h^{<t-1>}} + b_h)\\ y^{<t>} = g_2(W_{hy} h^{<t>} + b_y) h<t>=g1(WxhX<t>+Whhh<t1>+bh)y<t>=g2(Whyh<t>+by)
image-20250814160000015

请添加图片描述

可以看出,RNN有两个严重问题:

  1. 无法捕捉长期依赖「信息随时间步增多逐渐丢失」
  2. 无法并行计算「必需按序处理」

为了解决问题,人们引入了GRU和LSTM「只能缓解无法根治,已过时」。

那么我们是否有一种可以彻底抛弃顺序计算,直接一眼把全部信息尽收眼底的新方案呢?

  • 恭迎 TRANSFORMER!
image-20250814161846476

请添加图片描述

简单而强大的Transformer

线性映射

  • 线性映射:注意力前置条件

首先,我们给每个词向量加一个「位置编码」,表示词在句中的位置。得到一个含有位置信息的词向量。

此时,词还注意不到其他词的存在。

我们用三个矩阵Wq、Wk、WvW_q、W_k、W_vWqWkWv「训练出来的」分别与第一个词向量相乘,得到三个向量q1、k1、v1q_1、k_1、v_1q1k1v1,对其他词向量也做相同运算。

将所有向量的q、k、vq、k、vqkv拼成矩阵Q、K、VQ、K、VQKV「实际运算时直接矩阵相乘得到」。

qi=Wqxiki=Wkxivi=WvxiQ=[q1Tq2T⋮qnT]=Wq[x1Tx2T⋮xnT]=WqX% 单个词向量生成q、k、v {\color{red}\mathbf{q}_i} = \mathbf{W}_q \mathbf{x}_i \\ {\color{red}\mathbf{k}_i} = \mathbf{W}_k \mathbf{x}_i \\ {\color{red}\mathbf{v}_i} = \mathbf{W}_v \mathbf{x}_i \\ % 矩阵形式(拼接所有词向量的q、k、v) \mathbf{Q} = \begin{bmatrix} \mathbf{q}_1^T \\ \mathbf{q}_2^T \\ \vdots \\ \mathbf{q}_n^T \end{bmatrix} = \mathbf{W}_q \begin{bmatrix} \mathbf{x}_1^T \\ \mathbf{x}_2^T \\ \vdots \\ \mathbf{x}_n^T \end{bmatrix} = \mathbf{W}_q \mathbf{X} \\ qi=Wqxiki=Wkxivi=WvxiQ=q1Tq2TqnT=Wqx1Tx2TxnT=WqX

注意力!

  • Attention!注意力

接下来让q1与k2q_1与k_2q1k2做点积得到系数a12a_{12}a12,表示「在第一个词的视角下,第一个词和第二个词的相似度」。

同理得到系数a13、a14、a11a_{13}、a_{14}、a_{11}a13a14a11

然后将系数分别与各词的vvv向量相乘再相加,得到向量a1a_1a1。表示「在第一个词视角下,按照和它相似度权重,将所有词向量加为一个整体」(包含了全部上下文信息的第一个词的新向量)。【有点类似基因】

同理,其余词得到自己的新词向量a2、a3、a4a_2、a_3、a_4a2a3a4「完成了包含自己位置信息和其他词上下文信息的壮举」。
a1j=q1⋅kj(j=1,2,3,4)a1=∑j=14a1j⋅vj系数矩阵A=Q⋅K⊤a=A⋅V% 相似度系数计算(以第一个词视角为例) a_{1j} = \mathbf{q}_1 \cdot \mathbf{k}_j \quad (j = 1, 2, 3, 4)\\ % 第一个词的上下文向量(未归一化版本) \mathbf{a}_1 = \sum_{j=1}^{4} a_{1j} \cdot \mathbf{v}_j\\ % 矩阵形式(批量计算) 系数矩阵A = \mathbf{Q} \cdot \mathbf{K}^\top\\ \mathbf{a} = A \cdot \mathbf{V} a1j=q1kj(j=1,2,3,4)a1=j=14a1jvj系数矩阵A=QKa=AV
image-20250814180154821

请添加图片描述

  • 多头注意力

之前的前置工作是制作了一组QKV矩阵,现在我们用两组W权重矩阵计算出两组QKV,称之为「Head 头」。

给每个词两组学习上下文机会。即「两头注意力」。

image-20250814171814381

请添加图片描述

经过「注意力」运算后得到a1h1a_{1h_1}a1h1a1h2a_{1h_2}a1h2,拼接成全新的a1a_{1}a1。「并非简单拼接,还经过了一次线性变换」

  • transformer

Attention(Q,K,V)=softmax(QKTdk)V\text{Attention}(Q, K, V) = \text{softmax}\left( \frac{QK^T}{\sqrt{d_k}} \right) V Attention(Q,K,V)=softmax(dkQKT)V

MultiHead(Q,K,V)=Concat(head1,…,headh)WOwhere headi=Attention(QWiQ,KWiK,VWiV)\text{MultiHead}(Q, K, V) = \text{Concat}(\text{head}_1, \ldots, \text{head}_h) W^O \\ \text{where } \text{head}_i = \text{Attention}(QW_i^Q, KW_i^K, VW_i^V) MultiHead(Q,K,V)=Concat(head1,,headh)WOwhere headi=Attention(QWiQ,KWiK,VWiV)

引用

【一小时从函数到Transformer!一路大白话彻底理解AI原理】https://www.bilibili.com/video/BV1NCgVzoEG9?p=4&vd_source=cce88d7fe1e543210d68fa276e5b4dd4

http://www.dtcms.com/a/563004.html

相关文章:

  • 校园网自助网站程序员不是做网站的
  • seo做什么网站赚钱wordpress调整logo大小
  • 旅游网站建设的课题研究的主要内容商务网页设计与制作 百度百科
  • 怀化市住房与城乡建设厅网站南昌市经济技术开发区属于哪个区
  • 网站的系统建设方式有哪些方面淘宝店网站建设
  • wordpress改网站信息电商网站开发教材
  • 手机网站建设介绍清爽网站
  • 网站性能优化方法wordpress无法显示图片
  • SAP PP生产补料单功能分享
  • php公司网站系统拼多多一件代发免费货源
  • 昆明专业网站建设模板长沙网站se0推广优化公司
  • 东莞 网站建设 保健品火车头采集器wordpress下载
  • 网站响应式图片切换代码seo站外推广有哪些
  • 网站网页设计海报图片久安网络微信网站建设
  • 做网站视频一般上传到哪里代练平台
  • 济南专业网站制作公司wordpress丢失网络连接
  • 网站域名到期会怎么样网站备案系统验证码出错的解决方案
  • 公司重名 做网站计算机专业网站开发方向
  • 建设一个网站要学什么音乐 版权 做视频网站
  • 成品ppt网站佛山seo结算
  • 如何在头条上做网站推广建设机械网站渠道
  • 指针深入第三弹--回调函数,qsort函数使用的运用
  • 微网站分享功能推广新网站
  • 酒店电子商务网站建设阿德莱德做网站
  • 最新网站建设网站策划做啥
  • 原创文章网站开发教程网络哪家公司比较好
  • 网站备案 新网永久新域名225222
  • 网络营销导向企业网站建设的一般原则是什么?动画制作培训学院
  • 仿冒网站制作eclipse 网站开发源码
  • 网站制作学校百度大数据中心