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

iis网站可以做没有水印的视频网站

iis网站,可以做没有水印的视频网站,布恩网站删除,海阔淘宝客助手wordpress演示站 | 紫色清新商城模板可以把PyTorch简单看成是Python的深度学习第三方库#xff0c;在PyTorch中定义了适用于深度学习的基本数据结构——张量#xff0c;以及张量的各类计算。其实也就相当于NumPy中定义的Array和对应的科学计算方法#xff0c;正是这些基本数据类型和对应的方法函数#xff0c;… 可以把PyTorch简单看成是Python的深度学习第三方库在PyTorch中定义了适用于深度学习的基本数据结构——张量以及张量的各类计算。其实也就相当于NumPy中定义的Array和对应的科学计算方法正是这些基本数据类型和对应的方法函数为我们进一步在PyTorch上进行深度学习建模提供了基本对象和基本工具。因此在正式使用PyTorch进行深度学习建模之前我们需要熟练掌握PyTorch中张量的基本操作方法。张量作为数组的衍生概念其本身的定义和使用方法和NumPy中的Array非常类似甚至在复现一些简单的神经网络算法场景中我们可以直接使用NumPy中的Array来进行操作。 张量的最基本创建方法和NumPy中创建Array的格式一致都是创建函数(序列)的格式张量创建函数torch.tensor() t torch.tensor([[0,1], [2,3]]) # 通过列表创建张量 # 通过元组创建张量 # torch.tensor((1, 2)) # 通过数组创建张量 # a np.array((1, 2)) # t torch.tensor(a) # 整数型的数组默认创建int32整型类型而张量则默认创建int64长整型类型。 # 创建浮点型数组时张量默认是float32单精度浮点型而Array则是默认float64双精度浮点型。 print(t,t.data) print(id(t),id(t.data)) ## 输出 ## tensor([[0, 1],[2, 3]]) tensor([[0, 1],[2, 3]]) 2036011697072 2036018540848两者返回不同的id但是共享同一个内存 t[0][0]10 t.data[1][0]20 print(t,t.data) print(id(t),id(t.data)) ## 输出 ## tensor([[10, 1],[20, 3]]) tensor([[10, 1],[20, 3]]) 2036011697072 2036019332576属性 grad导数, grad-fn张量所在的导数函数, requires_grad是否执行可导的判定。调用backward计算导数导数是累加的如果每次单独计算需要清空梯度 optimiter.zero_grad()。 属性 is_leaf, retain_grad。判定该元素在计算图中是否为叶子节点当为叶子节点时它的属性requires_grad为False。当requires_grad为True但是用户构建的Tensor表示该张量不是计算结果而是用户构建的初始化张量。在用backward后仅只有 leaf tensor 才会有 grad 属性。如果不是 leaf tensor 需要retain_grad 函数开启grad。 属性ndim和dim函数查看tensor的维度属性shape和size()tensor的形状 ttorch.cat([t,t],0) print(t.ndim,len(t),t.dim()) print(t.shape,t.size()) ## 输出 ## 2 8 2 torch.Size([8, 2]) torch.Size([8, 2])和数组不同对于张量而言数值型和布尔型张量就是最常用的两种张量类型相关类型总结如下。 数据类型dtype32bit浮点数torch.float32或torch.float64bit浮点数torch.float64或torch.double16bit浮点数torch.float16或torch.half8bit无符号整数torch.unit88bit有符号整数torch.int816bit有符号整数torch.int16或torch.short32bit有符号整数torch.int32或torch.int64bit有符号整数torch.int64或torch.long布尔型torch.bool复数型torch.complex64 创建int16整型张量; torch.tensor([1.1, 2.7], dtype torch.int16) 在PyTorch中也支持复数类型对象创建; a torch.tensor(1 2j) # 1是实部、2是虚部; tensor(1.2.j) 和NumPy中array相同当张量各元素属于不同类型时系统会自动进行隐式转化。在使用方法进行类型转化时方法名称则是double。虽然torch.float和double都表示双精度浮点型。 flatten拉平将任意维度张量转化为一维张量,按行排列拉平。注如果将零维张量使用flatten则会将其转化为一维张量。 reshape方法任意变形注意reshape过程中维度的变化reshape转化后的维度由该方法输入的参数“个数”决定。 在很多数值科学计算的过程中都会创建一些特殊取值的张量用于模拟特殊取值的矩阵如全0矩阵、对角矩阵等。因此PyTorch中也存在很多创建特殊张量的函数。 torch.zeros([2, 3]) # 创建全是0的两行、三列的张量矩阵 torch.ones([2, 3]) # 注由于zeros就已经确定了张量元素取值因此该函数传入的参数实际上是决定了张量的形状单位矩阵 torch.eye(5) ## tensor([[1., 0., 0., 0., 0.],[0., 1., 0., 0., 0.],[0., 0., 1., 0., 0.],[0., 0., 0., 1., 0.],[0., 0., 0., 0., 1.]])在PyTorch中需要利用一维张量去创建对角矩阵。 t1 torch.tensor([1, 2]) torch.diag(t1) # 不能使用list直接创建对角矩阵,diag(): argument input (position 1) must be Tensor, not list ## tensor([[1, 0],[0, 2]])rand服从0-1均匀分布的张量 torch.randn(2, 3) torch.normal(2, 3, size (2, 2)) # 均值为2标准差为3的张量;normal服从指定正态分布的张量 torch.randint(1, 10, [2, 4]) # 在1-10之间随机抽取整数组成两行四列的矩阵,randint整数随机采样结果arange/linspace生成数列 torch.arange(5) # 和range相同;tensor([0, 1, 2, 3, 4]) torch.arange(1, 5, 0.5) # 从1到5左闭右开每隔0.5取值一个 torch.linspace(1, 5, 3) # 从1到5左右都包含等距取三个数;tensor([1., 3., 5.])empty生成未初始化的指定形状矩阵 torch.empty(2, 3) ## tensor([[6.8664e-44, 6.8664e-44, 1.1771e-43],[6.7262e-44, 7.0065e-44, 8.1275e-44]]) torch.full([2, 4], 2) tensor([[2, 2, 2, 2],[2, 2, 2, 2]])还能根据指定对象的形状进行数值填充只需要在上述函数后面加上_like即可。 torch.full_like(t1, 2) # 根据t1形状填充数值2 torch.randint_like(t2, 1, 10) # 根据t1形状填充数值1-10,不包括10的整数 t1 torch.tensor([1, 2]) torch.randn_like(t1) # t1是整数而转化后将变为浮点数此时代码将报错normal_kernel_cpu not implemented for Long张量、数组和列表是较为相似的三种类型对象在实际操作过程中经常会涉及三种对象的相互转化。在此前张量的创建过程中我们看到torch.tensor函数可以直接将数组或者列表转化为张量而我们也可以将张量转化为数组或者列表。 t1 torch.tensor([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) t1.numpy() # array([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], dtypeint64) import numpy as np # 当然也可以通过np.array函数直接转化为array np.array(t1) # array([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], dtypeint64) t1# tensor([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) # .tolist方法张量转化为列表 t1.tolist() # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]list函数张量转化为列表 [tensor(1),tensor(2),tensor(3),tensor(4),tensor(5),tensor(6),tensor(7),tensor(8),tensor(9),tensor(10)] # 需要注意的是此时转化的列表是由一个个零维张量构成的列表而非张量的数值组成的列表。在很多情况下我们需要将最终计算的结果张量转化为单独的数值进行输出此时需要使用.item()方法来执行。 Python中其他对象类型一样等号赋值操作实际上是浅拷贝需要进行深拷贝则需要使用clone方法 张量作为有序的序列也是具备数值索引的功能并且基本索引方法和Python原生的列表、NumPy中的数组基本一致当然所有不同的是PyTorch中还定义了一种采用函数来进行索引的方式。张量也是有序序列我们可以根据每个元素在系统内的顺序“编号”来找出特定的元素也就是索引。张量索引出来的结果还是零维张量 而不是单独的数。要转化成单独的数需要使用item()方法。在张量的索引中step位必须大于0 二维张量的索引逻辑和一维张量的索引逻辑基本相同二维张量可以视为两个一维张量组合而成而在实际的索引过程中需要用逗号进行分隔分别表示对哪个一维张量进行索引、以及具体的一维张量的索引。对二维张量来说基本可以视为是对矩阵的索引并且行、列的索引遵照相同的索引规范并用逗号进行分隔。 import torch t2 torch.arange(1, 10).reshape(3, 3) t2 t2[0, 1] # 表示索引第一行、第二个第二列的元素 tensor(2) t2[0][1]# 表示索引第一行、第二个第二列的元素 tensor(2) t2[0, ::2]# 表示索引第一行、每隔两个元素取一个 tensor([1, 3]) t2[0, [0, 2]] # 索引结果同上 t2[::2, ::2] # 表示每隔两行取一行、并且每一行中每隔两个元素取一个 tensor([[1, 3],[7, 9]])在二维张量索引的基础上三维张量拥有三个索引的维度。我们将三维张量视作矩阵组成的序列则在实际索引过程中拥有三个维度分别是索引矩阵、索引矩阵的行、索引矩阵的列。 t3 torch.arange(1, 28).reshape(3, 3, 3) t3 ## tensor([[[ 1, 2, 3],[ 4, 5, 6],[ 7, 8, 9]],[[10, 11, 12],[13, 14, 15],[16, 17, 18]],[[19, 20, 21],[22, 23, 24],[25, 26, 27]]]) t3[1, ::2, ::2] # 索引第二个矩阵行和列都是每隔两个取一个 tensor([[10, 12],[16, 18]]) t3[:: 2, :: 2, :: 2] # 每隔两个取一个矩阵对于每个矩阵来说行和列都是每隔两个取一个 tensor([[[ 1, 3],[ 7, 9]],[[19, 21],[25, 27]]])在PyTorch中我们还可以使用index_select函数通过指定index来对张量进行索引。在index_select函数中第二个参数实际上代表的是索引的维度。对于t1这个一维向量来说由于只有一个维度因此第二个参数取值为0就代表在第一个维度上进行索引。 t1 torch.arange(10) indices torch.tensor([1, 2]) # 需要tensor torch.index_select(t1, 0, indices) ## tensor([1, 2]) t2 torch.arange(12).reshape(4, 3) ## tensor([[ 0, 1, 2],[ 3, 4, 5],[ 6, 7, 8],[ 9, 10, 11]]) torch.index_select(t2, 0, indices) ## tensor([[3, 4, 5],[6, 7, 8]])在正式介绍张量的切分方法之前需要首先介绍PyTorch中的.view()方法。该方法会返回一个类似视图的结果该结果和原张量对象共享一块数据存储空间并且通过.view()方法还可以改变对象结构生成一个不同结构但共享一个存储空间的张量。当然共享一个存储空间也就代表二者是“浅拷贝”的关系修改其中一个另一个也会同步进行更改。“视图”的作用就是节省空间而值得注意的是在接下来介绍的很多切分张量的方法中返回结果都是“视图”而不是新生成一个对象。 chunk函数能够按照某维度对张量进行均匀切分并且返回结果是原张量的视图。 t2 torch.arange(12).reshape(4, 3) tc torch.chunk(t2, 4, dim0) # 在第零个维度上按行进行四等分 ## 返回类型是元组 (tensor([[0, 1, 2]]),tensor([[3, 4, 5]]),tensor([[6, 7, 8]]),tensor([[ 9, 10, 11]]))# chunk返回结果是一个视图不是新生成了一个对象# 修改tc中的值原张量也会对应发生变化当原张量不能均分时chunk不会报错但会返回其他均分的结果 torch.chunk(t2, 3, dim0) # 次一级均分结果 ## (tensor([[0, 1, 2],[3, 4, 5]]),tensor([[ 6, 7, 8],[ 9, 10, 11]]))split既能进行均分也能进行自定义切分。当然需要注意的是和chunk函数一样split返回结果也是view。 t2 torch.arange(12).reshape(4, 3) torch.split(t2, 2, 0) # 第二个参数只输入一个数值时表示均分第三个参数表示切分的维度 torch.split(t2, [1, 3], 0)# 第二个参数输入一个序列时表示按照序列数值进行切分也就是1/3分 ## (tensor([[0, 1, 2]]),tensor([[ 3, 4, 5],[ 6, 7, 8],[ 9, 10, 11]])) torch.split(t2, [1, 1, 2], 0) ## (tensor([[0, 1, 2]]),tensor([[3, 4, 5]]),tensor([[ 6, 7, 8],[ 9, 10, 11]]))注意当第二个参数位输入一个序列时序列的各数值的和必须等于对应维度下形状分量的取值。例如上述代码中是按照第一个维度进行切分而t2总共有4行因此序列的求和必须等于4也就是134而序列中每个分量的取值则代表切块大小。tensor的split方法和array的split方法有很大的区别array的split方法是根据索引进行切分。 import numpy as np x np.array([0,1,2,3,4,5,6,7,8]) print (np.split(x,[3,5,6,9])) ## [array([0, 1, 2]), array([3, 4]), array([5]), array([6, 7, 8]), array([], dtypeint32)]张量的合并操作类似与列表的追加元素可以拼接、也可以堆叠。PyTorch中可以使用cat函数实现张量的拼接。 a torch.zeros(2, 3) b torch.ones(2, 3) c torch.full((3, 3),2) torch.cat([a, b]) # 按照行进行拼接dim默认取值为0 ## tensor([[0., 0., 0.],[0., 0., 0.],[1., 1., 1.],[1., 1., 1.]]) torch.cat([a, b], 1) # 按照列进行拼接 tensor([[0., 0., 0., 1., 1., 1.],[0., 0., 0., 1., 1., 1.]]) torch.cat([a, c], 1) # 形状不匹配时将报错 # Sizes of tensors must match except in dimension 1. Expected size 2 but got size 3 for tensor number 1 in the list.拼接的本质是实现元素的堆积也就是构成a、b两个二维张量的各一维张量的堆积最终还是构成二维向量。 堆叠函数stack;和拼接不同堆叠不是将元素拆分重装而是简单的将各参与堆叠的对象分装到一个更高维度的张量里。 torch.stack([a, b]) # 堆叠之后生成一个三维张量 tensor([[[0., 0., 0.],[0., 0., 0.]],[[1., 1., 1.],[1., 1., 1.]]]) torch.stack([a, b]).shape # torch.Size([2, 2, 3]) torch.stack([a, c]) # 维度不匹配时也会报错 # stack expects each tensor to be equal size, but got [2, 3] at entry 0 and [3, 3] at entry 1通过reshape方法能够灵活调整张量的形状。而在实际操作张量进行计算时往往需要另外进行降维和升维的操作当我们需要除去不必要的维度时可以使用squeeze函数而需要手动升维时则可采用unsqueeze函数。 t torch.zeros(1, 1, 3, 1) #t张量解释一个包含一个三维的四维张量三维张量只包含一个三行一列的二维张量。 ## tensor([[[[0.],[0.],[0.]]]]) torch.squeeze(t) # tensor([0., 0., 0.]) torch.squeeze(t).shape # torch.Size([3]) t1 torch.zeros(1, 1, 3, 2, 1, 2) ## tensor([[[0., 0.],[0., 0.]],[[0., 0.],[0., 0.]],[[0., 0.],[0., 0.]]]) torch.squeeze(t1).shape # torch.Size([3, 2, 2])简单理解squeeze就相当于提出了shape返回结果中的1。unsqeeze函数手动升维 torch.unsqueeze(t, dim 0) # 在第1个维度索引上升高1个维度 torch.unsqueeze(t, dim 2).shape # 在第3个维度索引上升高1个维度 torch.unsqueeze(t, dim 4).shape # 在第5个维度索引上升高1个维度注意理解维度和shape返回结果一一对应的关系shape返回的序列有几个元素张量就有多少维度。 作为PyTorch中执行深度学习的基本数据类型张量Tensor也拥有非常多的数学运算函数和方法以及对应的一系列计算规则。在PyTorch中能够作用与Tensor的运算被统一称作为算子。并且相比于NumPyPyTorch给出了更加规范的算子运算的分类从而方便用户在不同场景下调用不同类型的算子运算。PyToch总共为Tensor设计了六大类数学运算分别是 逐点运算Pointwise Ops指的是针对Tensor中每个元素执行的相同运算操作 规约运算Reduction Ops指的是对于某一张量进行操作得出某种总结值 比较运算Comparison Ops指的是对多个张量进行比较运算的相关方法 谱运算Spectral Ops指的是涉及信号处理傅里叶变化的操作 BLAS和LAPACK运算指的是基础线性代数程序集Basic Linear Algeria Subprograms和线性代数包Linear Algeria Package中定义的、主要用于线性代数科学计算的函数和方法 其他运算Other Ops其他未被归类的数学运算。 t1 torch.arange(3) t t1t1 # tensor([0, 2, 4]) a[2,3,4][1,2,3] # [2, 3, 4, 1, 2, 3] import numpy as np bnp.arange(3)np.arange(3) # array([0, 2, 4])广播的特性是在不同形状的张量进行计算时一个或多个张量通过隐式转化转化成相同形状的两个张量从而完成计算的特性。但并非任何两个不同形状的张量都可以通过广播特性进行计算因此我们需要了解广播的基本规则及其核心依据。标量可以和任意形状的张量进行计算计算过程就是标量和张量的每一个元素进行计算。 t1 1 # 1是标量可以看成是零维 tensor([1, 2, 3]) t1 torch.tensor(1) #tensor([1, 2, 3])相同维度、不同形状的张量之间计算;两个张量的形状上有两个分量不同时只要不同的分量仍然有一个取值为1则仍然可以广播。 在理解相同维度、不同形状的张量广播之后对于不同维度的张量之间的广播其实就会容易很多因为对于不同维度的张量我们首先可以将低维的张量升维然后依据相同维度不同形状的张量广播规则进行广播。而低维向量的升维也非常简单只需将更高维度方向的形状填充为1即可。 逐点运算主要包括数学基本运算、数值调整运算和数据科学运算三块相关函数如下 函数描述torch.add(t1t2 )t1、t2两个张量逐个元素相加等效于t1t2torch.subtract(t1t2)t1、t2两个张量逐个元素相减等效于t1-t2torch.multiply(t1t2)t1、t2两个张量逐个元素相乘等效于t1*t2torch.divide(t1t2)t1、t2两个张量逐个元素相除等效于t1/t2 函数描述torch.abs(t)返回绝对值torch.ceil(t)向上取整torch.floor(t)向下取整torch.round(t)四舍五入取整torch.neg(t)返回相反的数 虽然此类型函数是数值调整函数但并不会对原对象进行调整而是输出新的结果。而若要对原对象本身进行修改则可考虑使用方法_()的表达形式对对象本身进行修改。此时方法就是上述同名函数。 数学运算函数数学公式描述幂运算torch.exp(t)$ y_{i} e^{x_{i}} $返回以e为底、t中元素为幂的张量torch.expm1(t)$ y_{i} e^{x_{i}} $ - 1对张量中的所有元素计算expx - 1torch.exp2(t)$ y_{i} 2^{x_{i}} $逐个元素计算2的t次方。torch.pow(t,n)$\text{out}_i x_i ^ \text{exponent} $返回t的n次幂torch.sqrt(t)$ \text{out}{i} \sqrt{\text{input}{i}} $返回t的平方根torch.square(t)$ \text{out}_i x_i ^ \text{2} $返回输入的元素平方。对数运算torch.log10(t)$ y_{i} \log_{10} (x_{i}) $返回以10为底的t的对数torch.log(t)$ y_{i} \log_{e} (x_{i}) $返回以e为底的t的对数torch.log2(t)$ y_{i} \log_{2} (x_{i}) $返回以2为底的t的对数torch.log1p(t)$ y_i \log_{e} (x_i $ 1)返回一个加自然对数的输入数组。三角函数运算torch.sin(t)三角正弦。torch.cos(t)元素余弦。torch.tan(t)逐元素计算切线。 在数值科学计算中expm1函数和log1p函数是一对对应的函数关系后面再介绍log1p的时候会讲解这对函数的实际作用。开根号也就相当于0.5次幂 log1p是进行$ y_i \log_{e} (x_i $ 1)计算而expm则是进行$ y_{i} e^{x_{i}} $ - 1计算二者互为逆运算。 需要注意的是虽然Python是动态编译的编程语言但在PyTorch中由于会涉及GPU计算因此很多时候元素类型不会在实际执行函数计算时进行调整。此处的科学运算大多数都要求对象类型是浮点型我们需要提前进行类型转化。 而log1p的实际应用场景有两个其一是进行数据分布转化操作另一种则是防止极小的数在进行对数运算时丢失有效位数。 大多数的数理统计分析在建模过程中都对数据的分布有较为严格的要求但真实的数据往往不能满足特定的分布因此很多时候我们会先对其进行一定程度上的数值转化而log运算就是常用的将偏态分布的数据转化为高斯分布所使用的函数并且在此过程中log1p的效果往往会好于log的效果 另一种使用场景当处理的数据数值非常小时使用对数运算往往会因为精度不够而使得计算无法进行log0没有数学意义此时使用log1p则可很好的避免这种情况。 m torch.tensor(-2.6529) * 1e-20 # tensor(-2.6529e-20) # 转化为一个趋近于1的数再运算 torch.log1p(m) # tensor(-2.6529e-20) # 此时直接使用log无法执行运算 torch.log(m) # tensor(nan) # 无法运算就无法还原 torch.exp(torch.log(m)) # tensor(nan) # 无损还原 torch.expm1(torch.log1p(m)) # tensor(-2.6529e-20)在很多场景中由于计算精度问题导致无法计算并进一步导致数据信息损失将会是非常致命的典型场景如PCA主成分分析相关问题会在算法讲解中进一步讨论。 在PyTorch中sort排序函数将同时返回排序结果和对应的索引值的排列。 t torch.tensor([1.0, 3.0, 2.0]) # 升序排列 torch.sort(t) ## torch.return_types.sort( valuestensor([1., 2., 3.]), indicestensor([0, 2, 1])) # 降序排列 torch.sort(t, descendingTrue) ## torch.return_types.sort( valuestensor([3., 2., 1.]), indicestensor([1, 2, 0]))规约运算指的是针对某张量进行某种总结最后得出一个具体总结值的函数。此类函数主要包含了数据科学领域内的诸多统计分析函数如均值、极值、方差、中位数函数等等。 函数描述torch.mean(t)返回张量均值torch.var(t)返回张量方差torch.std(t)返回张量标准差torch.var_mean(t)返回张量方差和均值torch.std_mean(t)返回张量标准差和均值torch.max(t)返回张量最大值torch.argmax(t)返回张量最大值索引torch.min(t)返回张量最小值torch.argmin(t)返回张量最小值索引torch.median(t)返回张量中位数torch.sum(t)返回张量求和结果torch.logsumexp(t)返回张量各元素求和结果适用于数据量较小的情况torch.prod(t)返回张量累乘结果torch.dist(t1, t2)计算两个张量的闵式距离可使用不同范式; torch.dist(t1, t2, 2)torch.topk(t)返回t中最大的k个值对应的指标; torch.topk(t, 2) dist函数可计算闵式距离闵可夫斯基距离通过输入不同的p值可以计算多种类型的距离如欧式距离、街道距离等。闵可夫斯基距离公式如下 $ D(x,y) (\sum{n}_{u1}|x_u-y_u|{p})^{1/p}$ 由于规约运算是一个序列返回一个结果因此若是针对高维张量则可指定某维度进行计算。 # 创建一个3*3的二维向量 t2 torch.arange(12).float().reshape(3, 4) # 按照第一个维度求和每次计算三个、按列求和 torch.sum(t2, dim 0) # tensor([12., 15., 18., 21.]) # 按照第二个维度求和每次计算四个、按行求和 torch.sum(t2, dim 1) # tensor([ 6., 22., 38.]) 比较运算是一类较为简单的运算类型和Python原生大的布尔运算类似常用于不同张量之间的逻辑运算最终返回逻辑运算结果逻辑类型张量。基本比较运算函数如下所示 函数描述torch.eq(t1, t2)比较t1、t2各元素是否相等等效torch.equal(t1, t2)判断两个张量是否是相同的张量torch.gt(t1, t2)比较t1各元素是否大于t2各元素等效torch.lt(t1, t2)比较t1各元素是否小于t2各元素等效torch.ge(t1, t2)比较t1各元素是否大于或等于t2各元素等效torch.le(t1, t2)比较t1各元素是否小于等于t2各元素等效torch.ne(t1, t2)比较t1、t2各元素是否不相同等效!
http://wiki.neutronadmin.com/news/35233/

相关文章:

  • 三明商城网站开发设计西安建设网站制作
  • 成都学生网站制作title 株洲网站建设
  • 网站建设 套餐沭阳住房城乡建设局网站
  • php网站开发技术与开源系统应用 实训指导书网站下载地址
  • 网站开发设计怎么找客户网站建设制作方法
  • 玉溪网站开发公司合肥360seo排名
  • 河北网站建设推广公司十大网页设计网站
  • 做网站php和asp哪个好关键词查询网址
  • 百度怎么做网站排名珠海市建设局网站
  • 中小企业的网站建设临沂网站制作策划
  • 哪个网站是vue做的如何在jsp上做网站页面代码
  • 北京建机网站阿里云网站建设 部署与发布
  • 摄影网站模板源码建设审批网站查询
  • 企业大型网站开发网站模板设计一建建设网站
  • 网站全背景做多大也是网络品牌建设和推广的基础
  • 网站建设详方案支付宝网页版登录入口
  • 做语音聊天网站要多少钱三亚网站运营托管介绍
  • 怎么查询一个网站有没有做竞价swoole wordpress
  • 描述photoshop在网站建设中的作用与特点.设计师兼职平台
  • 网站权重收录官网推广方案seo
  • 建设厅教育培训网站小程序定制开发要多少钱
  • 郑州网站建设找三牛wordpress 3.8 问题
  • wordpress网站安全性发布产品的免费平台有哪些
  • 广州seo网站多少钱基于MVC网站建设课程设计报告
  • 网站吸引人的功能石家庄大型网络公司
  • 网站大全官网专门做鞋子的网站
  • 智慧团建信息系统网站登录手把手教你搭建自己的网站
  • dns解析失败登录不了网站WordPress中文企业免费主题
  • 中山网页建站模板深圳调查公司哪家好
  • 一家网站建设公司需要什么资质泰兴企业网站建设