浅析神经网络 Neural Networks

浅析神经网络 Neural Networks目录 前情概要 该主题分享的目的是:   不局限于前端,拓展知识学习领域,不设边界。   以下仅代表我个人学习总结,如有问题,虚心请教,并及时修正。 另外本次分享不会有大段大段代码,主要是理解为什么这

目录

image.png

前情概要

  • 该主题分享的目的是:
    •   不局限于前端,拓展知识学习领域,不设边界。
    •   以下仅代表我个人学习总结,如有问题,虚心请教,并及时修正。

另外本次分享不会有大段大段代码,主要是理解为什么这么做。

在开始分享主题之前,我们可以先思考下,不管你用什么语言 (解释类型语言 或 编译类型语言),你写一堆的字符串,一顿解析编译后,从汇编语言再到最后的机器语言 0 / 1,即是CPU”认识”的。CPU用来计算和控制计算机系统的一套指令的集合。电路实现这种运算。运算又是规则。以上,每一个步骤的描述都是为了应对日益复杂的问题,不断抽象的过程。

不管我们怎么抽象,都离不开计算,计算又离不开数学(利用抽象和逻辑能力) 。我们今天主题跟抽象、计算、数学这几个词,是很有关系的。

回到本次分享的主题,人工智能又是什么?简单的说是有海量数据 -> 归纳出规则 -> 解决问题。

Artificial intelligence is intelligence demonstrated by machines.

你会想这跟智能没啥关系啊 ~ 我个人理解智能是玄学,那人工智能是什么?

浅析神经网络 Neural Networks

任正非说: 人工智能是统计学。

统计学: 是应用数学的一个分支,主要通过利用概率论建立数学模型,收集所观察系统的数据,进行量化的分析、总结,并进而进行推断和预测,为相关决策提供依据和参考。

Statistics is the study and manipulation of data, including ways to gather, review, analyze, and draw conclusions from data.

人工智能包括机器学习,例如线性回归、逻辑回归、贝叶斯模型、NN等。通过某个模型结构,基于训练数据,得出相应关系的概率。深度学习又是机器学习的一个分支,是基于NN神经网络为基本架构的拓展,常见的CNN(图像处理)、RNN(语音识别)等。

概念上就不做过多解释了,我直接上参考的结论吧。

参考:

浅析神经网络 Neural Networks

  • 机器学习:一切通过优化方法挖掘数据中规律的学科。
  • 深度学习:一切运用了神经网络作为参数结构进行优化的机器学习算法。
  • 强化学习:不仅能利用现有数据,还可以通过对环境的探索获得新数据,并利用新数据循环往复地更新迭代现有模型的机器学习算法。
  • 深度强化学习:一切运用了神经网络作为参数结构进行优化的强化学习算法。

前情概要的小总结: 应对海量数据,我们需要通过一些方法 (工具? 抽象能力?计算?算法、数学?…),俗称AI,来帮助我们解决问题。

回归模型

线性回归

例子 🌰

我们先通过一个简单的例子,来看基于tensorflow.js实现的线性模型。

linjiayu6.github.io/Tensorflow.…

首先,在屏幕上点几个离散点。

浅析神经网络 Neural Networks

一直点击【模型训练】,我们希望得到训练好的线性模型 (y = ax + b),其中a,b是需要我们通过几个点训练出的值。

浅析神经网络 Neural Networks

最后得出: Y = 1.040215015411377 X + 0.33632710576057434。

  • 看到这里你会问,这怎么实现?我们来看看 代码
    • 确认模型 y = ax + b
    • x, y 数据需要处理成矩阵,叫做x特征值,y是实际结果值。
    • a,b 是需要我们通过某种方法预测出来的值。
    • 训练模型 涉及 损失函数、梯度下降等。
    • 得到训练好的模型。
import * as tf from '@tensorflow/tfjs'

window.a = tf.variable(tf.scalar(Math.random()))
window.b = tf.variable(tf.scalar(Math.random()))

// 建立模型 y = ax + b 
const model = (xs, a, b) => xs.mul(a).add(b)

// 1. training, y值
const training = ({ points, trainTimes }) => {
  for (var i = 0; i < trainTimes; i++) {
    const learningRate = 0.1 // 学习率
    const optimizer = tf.train.sgd(learningRate); // 随机梯度下降
    const ys = tf.tensor1d(points.map(points => points.y)) // 样本y值
    // loss(训练好的模型y'值 - 样本y值)的损失到最小。
    optimizer.minimize(() => loss(predict(points.map((points) => points.x)), ys));
  }
}

// 2. predict, x值输入, 线性方程 y = ax + b
const predict = x => {
  return tf.tidy(() => {
    const xs = tf.tensor1d(x)
    const predictYs = model(xs, window.a, window.b)
    return predictYs
  })
}

// 3. 评价过程, 也是损失函数: 均方差 求出最小的
const loss = (predictYs, ys) => predictYs.sub(ys).square().mean()
export default {
  training, predict
}

浅析神经网络 Neural Networks

我们使用了一些数据,通过TensorFlow.js一些方法的调用,得到了一条和这几个点拟合程度较好的线性模型。为了探究具体的实现,详看一下几个概念。

损失函数

损失函数是用来评估模型的好坏,即模型预测值和真实值的误差, 损失越小, 模型越好。We measure the “accuracy” of our hypothesis function by using a cost function

平方误差函数 广泛应用在 回归的问题 square error function is commonly used for “regression” problems

浅析神经网络 Neural Networks

目标是: 所有橘色线(让黑色点和红色点之间的线),即预测结果和实际结果间的误差最小。

损失函数: 用于度量建模误差的,为了得到误差的最小值。统计学中通常使用平方误差方法。

统计学中的平方误差(损失)函数


  • J ( θ 0 , θ 1 ) = 1 2 m i = 1 m ( y i y i ) 2 = 1 2 m i = 1 m ( h θ ( x i ) y i ) 2 J(θ_0, θ_1) = \frac{1}{2m} \sum_{i=1}^m (y_i’ – y_i)^2 = \frac{1}{2m} \sum_{i=1}^m (h_θ(x_i) – y_i)^2

    • h θ ( x ) = θ 0 + θ 1 x h_θ(x) = θ_0 + θ_1x

    • 1 2 m \frac{1}{2m}
      系数是为了后续在梯度下降中便于求解使用的。导数会抵消掉
      1 2 \frac{1}{2}

梯度下降

梯度下降还会涉及到 特征值缩放、均值归一化处理等。这里也不做过多扩展。

  • 好处是: 每个特性向量值均缩放到一个区间内,梯度下降速度会更快。

想象你在山顶上了,需要下山,有很多条道儿可以走。

  • 如果你步伐迈的太大,意味着你可能会很快下山,但也有可能走太多的弯路,花费更多时间。
  • 如果你步伐迈的太小,意味着你可能不能很快下山,但也可能会在过程中找到最佳下山路径,用了最少时间。

浅析神经网络 Neural Networks

简单的例子,带你了解梯度下降

浅析神经网络 Neural Networks

过往实验例子 训练模型不会以一个固定值来训练,会开始步子大些,后续逐渐变小。

该例子通过图像直观说明学习率(步伐多大)对模型的影响 (eg: 收敛、欠拟合)。

梯度下降目的: 用来求解损失函数的最小值的方法。得到局部最优解的方法。

浅析神经网络 Neural Networks

帮您简单回忆一下,什么是导数呢? 导数是微小的变化量。

浅析神经网络 Neural Networks

类比
线性回归模型
h θ ( x ) = θ 0 + θ 1 x h_θ(x) = θ_0 + θ_1x
目标是 下山
θ 0 θ 1 θ_0 θ_1
损失函数表示 下山如何费力最小
J ( θ 0 , θ 1 ) = 1 2 m i = 1 m ( y i y i ) 2 = 1 2 m i = 1 m ( h θ ( x i ) y i ) 2 J(θ_0, θ_1) = \frac{1}{2m} \sum_{i=1}^m (y_i’ – y_i)^2 = \frac{1}{2m} \sum_{i=1}^m (h_θ(x_i) – y_i)^2
梯度下降(Repeat) 具体细节:

α α
步子迈多大
d d θ j J ( θ 0 , θ 1 ) \frac{d}{dθ_j} J(θ_0, θ_1)

每次朝着哪个方向走经过不停的调整步伐和下山的方向,最后成功下山,并以最小费力方式。

θ j = θ j α d d θ j J ( θ 0 , θ 1 ) θ_j = θ_j – α \frac{d}{dθ_j} J(θ_0, θ_1)

Repeat until converage

θ 0 = θ 0 α 1 m i = 1 m ( h θ ( x i ) y i ) θ_0 = θ_0- α \frac{1}{m} \sum_{i=1}^m (h_θ(x_i) – y_i)


θ 1 = θ 1 α 1 m i = 1 m ( h θ ( x i ) y i ) x i θ_1 = θ_1- α \frac{1}{m} \sum_{i=1}^m (h_θ(x_i) – y_i) x_i

以上结论,计算推导过程。高数知识只要知道复合函数求导就ok了。浅析神经网络 Neural Networks

小总结

我们再来回顾下刚才的代码例子。

浅析神经网络 Neural Networks

  1. 确认目标: 你此刻站在山顶⛰,规划下山路径(
    h θ ( x ) = θ 0 + θ 1 x h_θ(x) = θ_0 + θ_1x
    ),想要下山(
    θ 0 θ 1 θ_0 θ_1
    )
  1. 在你没有开始行动前,就已经得到了下山最不费力的方法(损失函数)
    J ( θ 0 , θ 1 ) = 1 2 m i = 1 m ( y i y i ) 2 = 1 2 m i = 1 m ( h θ ( x i ) y i ) 2 J(θ_0, θ_1) = \frac{1}{2m} \sum_{i=1}^m (y_i’ – y_i)^2 = \frac{1}{2m} \sum_{i=1}^m (h_θ(x_i) – y_i)^2
    )
  1. 当你走每一步,会调整下山步伐α 和方向
    d d θ j J ( θ 0 , θ 1 ) \frac{d}{dθ_j} J(θ_0, θ_1)
    的规划

    1.   (梯度下降
      θ j = θ j α d d θ j J ( θ 0 , θ 1 ) θ_j = θ_j – α \frac{d}{dθ_j} J(θ_0, θ_1)
      )
  1. 不停的重复第三步,最后成功下山。

是不是看到这里,发现模型的训练,也没有那么难啦。

逻辑回归

在线性回归模型中,我们了解到了模型、损失函数、梯度下降的含义。

逻辑回归对我们理解NN 神经网络有很大的帮助。

逻辑回归的现实意义是分类问题。eg: 预测用户是否喜欢该类视频?预测该用户是男还是女?

例如我们预测该图片是否是只猫🐈:

  • 🐈 模型: 我们有 n个猫的特征features (毛发、眼睛、鼻子…. ),通过这些特征来预测一个图片是否是猫🐈。
  • 预测的结果标识 / 逻辑回归:
    0 < h θ ( x ) < 1 0< h_θ(x) < 1
    ,有多大的概率。

    •   从模型和预测的结果来看,已经不是线性模型可以覆盖到的情况了。下面介绍下逻辑回归的模型。

浅析神经网络 Neural Networks

模型

如果要实现上述例子,就需要明白逻辑回归的模型。

除了sigmoid,还有一些其他方法例如 relu tanh,在NN中被使用。

浅析神经网络 Neural Networks

损失函数

逻辑回归和线性回归的损失函数是不同的。线性回归损失函数(平方损失函数) 是在在满足高斯分布 / 正态分布的条件下推导得到的,而逻辑回归假设样本满足伯努利分布。故需要重新定义损失函数。

损失函数为: (是从 最大似然估计 得来的)


J ( θ ) = 1 m [ i = 1 m ( y ( i ) log h θ ( x ( i ) ) + ( 1 y ( i ) ) log ( 1 h θ ( x ( i ) ) ) ] J(\theta) = -\frac{ 1 }{ m }[\sum_{ i=1 }^{ m } ({y^{(i)} \log h_\theta(x^{(i)}) + (1-y^{(i)}) \log (1-h_\theta(x^{(i)})})]

简单解释下损失函数的含义:

  • 对单一样本
    C ( θ ) = y l o g h θ ( x ) + ( 1 y ) log ( 1 h θ ( x ) ) ] C(\theta)={y log h_\theta(x) + (1-y) \log (1-h_\theta(x)})]
  • 预测结果只有 是和不是 两种情况,即
    y = 1 y = 1

    y = 0 y = 0

    •   展开后为
      C ( θ ) = { l o g ( 1 h θ ( x ) ) , y = 0 l o g ( h θ ( x ) ) , y = 1 C(\theta) = \{_{-log(1-h_\theta(x)), y=0}^{-log(h_\theta(x)),y=1}
y 损失函数 损失函数
C ( θ ) C(\theta)

h θ ( x ) h_\theta(x)
之间关系

y = 1 y = 1

C ( θ ) = y l o g h θ ( x ) + ( 1 y ) log ( 1 h θ ( x ) ) ] C(\theta)={y log h_\theta(x) + (1-y) \log (1-h_\theta(x)})]


y = 1 y = 1
代入公式
=>

C ( θ ) = l o g ( h θ ( x ) ) C(\theta)= -log(h_\theta(x))
浅析神经网络 Neural Networks当预测值
h θ ( x ) = 1 h_\theta(x) = 1
,误差为0。反之随着
h θ ( x ) h_\theta(x)
变小误差变大。

y = 0 y = 0

C ( θ ) = y l o g h θ ( x ) + ( 1 y ) log ( 1 h θ ( x ) ) ] C(\theta)={y log h_\theta(x) + (1-y) \log (1-h_\theta(x)})]


y = 0 y = 0
代入公式
=>

C ( θ ) = l o g ( 1 h θ ( x ) ) C(\theta)= -log(1 – h_\theta(x))
浅析神经网络 Neural Networks当预测值
h θ ( x ) = 0 h_\theta(x) = 0
,误差为0。反之随着
h θ ( x ) h_\theta(x)
变大误差变大。

有了损失函数的定义后,和线性回归一样的道理,我们需要计算出 损失函数
J ( θ ) J(\theta)
最小的时候
θ \theta
值。

梯度下降

浅析神经网络 Neural Networks

逻辑回归demo,感兴趣可以去看看,跟线性回归的套路是一样的,建立模型,定义好损失函数,训练数据不停对模型进行训练处理,最后得到训练好的模型。

浅析神经网络 Neural Networks

小总结

逻辑回归模型 1.
z = θ 0 x 0 + θ 1 x 1 + θ 2 x 2 + . . . = θ T X z = θ_0x_0 + θ_1x_1 + θ_2x_2 + … = θ^TX


θ = [ θ 0 θ 1 θ 2 θ 3 . . . . . θ n ] θ = [θ_0 θ_1 θ_2 θ_3 …..θ_n]


x = [ x 0 x 1 x 2 x 3 . . . . . x n ] x = [x_0 x_1 x_2 x_3 …..x_n]
2. Sigmoid Function
g ( z ) = 1 1 + e ( z ) g(z) = \frac{1}{ 1 + e^{(-z)}}
3.
h θ ( x ) = g ( z ) = 1 1 + e ( θ T X ) h_θ(x) = g(z) = \frac{1}{ 1 + e^{(-θ^TX)}}
值在[0, 1]
目标是
θ = [ θ 0 θ 1 θ 2 θ 3 . . . . . θ n ] θ = [θ_0 θ_1 θ_2 θ_3 …..θ_n]
损失函数
J ( θ ) = 1 m [ i = 1 m ( y ( i ) log h θ ( x ( i ) ) + ( 1 y ( i ) ) log ( 1 h θ ( x ( i ) ) ) ] J(\theta) = -\frac{ 1 }{ m }[\sum_{ i=1 }^{ m } ({y^{(i)} \log h_\theta(x^{(i)}) + (1-y^{(i)}) \log (1-h_\theta(x^{(i)})})]
梯度下降
θ j = θ j α d d θ j J ( θ 0 , θ 1 ) θ_j = θ_j – α \frac{d}{dθ_j} J(θ_0, θ_1)

Repeat until converage

θ j = θ j α 1 m i = 1 m ( h θ ( x ( i ) ) y ( i ) ) x j ( i ) θ_j = θ_j- α \frac{1}{m} \sum_{i=1}^m (h_θ(x^{(i)}) – y^{(i)}) x_j^{(i)}

以上结论,计算推导过程。高数知识只要知道复合函数求导就ok了。浅析神经网络 Neural Networks

总结

我们大致了解了线性和逻辑回归的模型,也理解了损失函数和梯度下降的意义。

但面对着日益复杂的情况,如此简单的模型是无法满足现实情况的。尤其当特征值很多的时候,即
X = [ x 0 x 1 x 2 x 3 . . . . . x n ] X = [x_0 x_1 x_2 x_3 …..x_n]
对计算是非常大的负荷。例如我们对一张图片进行预测是否是车,如果该图片像素是100*100 *3, 即有3w个特征值,这显然对计算来说是很不合理的。

这也就是为什么,我们需要神经网络NN,以及CNN、RNN 等这些更复杂的模型。

神经网络

学习资料: 3blue1brown-深度学习(英文搬运)_哔哩哔哩_bilibili

什么是神经网络

生物上的神经元,有输入和输出层,输入层接受其他神经元的信息,输出层以电脉冲的形式发给其他神经元。

当🧠大脑在思考的时候,一枚可爱的神经元在干什么? 每个树突收到其他神经元发出的刺激脉冲后,当这些刺激脉冲叠加后,达到一定的强度阈值,就会产生动作电位,并沿着轴突发送电信号。故以此来不停的传递。

该过程可类比于有很多条水管(树突),水管粗细不一,故输入的流速也不一样,开始放水(信号),当水桶里水足够多并达到阈值的时候 (激活),会从右侧轴突流出来。流出的水会再次流向下一个水桶。

浅析神经网络 Neural Networks

浅析神经网络 Neural Networks

来源: 来自google搜索图

Neural Networks: 算法来模拟人的大脑。本质还是构建模型,并通过数学运算得到预测结果。人认识某个动物是大熊猫是一样的,我们对熊猫的特征认知,例如大熊猫只有黑白色、只在四川、只吃竹子等等。故对NN模型的训练道理是一样的。

NN 神经网络是最基本的的算法模型,像深度学习的CNN 卷积神经网络对图像的处理;RNN 循环神经网络对语言模型的研究等等,各种复杂的模型,都是基于NN拓展的。

神经网络模型

浅析神经网络 Neural Networks

层:

  • 1个输入层: Input Layer。eg: 图上输入层有3个特征值。
  • N隐藏层: Hidden Layers。eg: 图上有两个隐藏层。
  • 1个输出层: Output Layer。eg: 对某个结果的预测。

每一层都有很多个神经元 Neuron。对于一个神经元的结构如下:

浅析神经网络 Neural Networks

一个神经元的模型

说明:

  • 特征值 features:
    X = [ x 0 , x 1 , x 2 , . . . , x n ] X = [x_0, x_1, x_2, …, x_n]
  • 权重值 weights:
    W = [ w 0 , w 1 , w 2 , . . . , w n ] W = [w_0, w_1, w_2, …, w_n]
    每个神经元连接的线 (概念也可以理解为
    θ \theta
    )
  • 激活函数 activation function 例如常见的sigmoid、tanh、Relu方法

一个神经元内部计算:


  • Z = W T X + b i a s Z = W^TX + bias

  • A = s i g m o i d ( Z ) A = sigmoid(Z)

是不是也不难看懂,其实每一个小的神经元,类似一个逻辑回归。

通常对于激活函数 activation function,如图上使用 sigmoid的使用,会使用Relu。

正向传播

创建模型,定义每层的结构,并以此往后传递。

简单的理解是: 将多个逻辑回归模型组合在一起。

浅析神经网络 Neural Networks

我们建立一个简单的NN模型,只有一个hidden layer,会有2个预测结果的输出。

Eg: (只是个例子说明) 该模型是预测是猫还是狗,X 特征值代表 毛发、眼睛、鼻子、嘴巴,输出层会判断猫还是狗的概率更大些。

针对已经建立的模型,像逻辑回归一样,明确每一个神经元连接的信息。

例如 按照我们上面对一个神经元模型的创建,建立每个神经元的公式。

以下为了理解 激活函数 activation function用了 sigmoid function

浅析神经网络 Neural Networks

浅析神经网络 Neural Networks

正向传播: 沿着从输入层到输出层,依次计算,并存储神经网络的中间变量。

此时,我们的目标值是每一层的 W 和 b。

反向传播

按照我们回归模型的套路是,在已经创建好的模型基础上,评估损失函数。

其实理解了逻辑回归的损失函数,不难理解这个公式。

我们暂不去看正则化的处理 (正则化我的理解是: 向模型加入某些规则,加入先验,缩小解空间,减小求出错误解的可能性)。NN损失函数的定义非常的明确,是每个分类的损失函数加和。

浅析神经网络 Neural Networks

浅析神经网络 Neural Networks

反向传播算法的目的是: 计算每一层的参数 w b 对总损失函数的影响。

浅析神经网络 Neural Networks

Repeat until converage


  • w ( 2 ) = w ( 2 ) α d J d w ( 2 ) w^{(2)} = w^{(2)} – α \frac{dJ}{dw^{(2)}}

  • b ( 2 ) = b ( 2 ) α d J d b ( 2 ) b^{(2)} = b^{(2)} – α \frac{dJ}{db^{(2)}}

  • w ( 1 ) = w ( 1 ) α d J d w ( 1 ) w^{(1)} = w^{(1)} – α \frac{dJ}{dw^{(1)}}

  • b ( 1 ) = b ( 1 ) α d J d b ( 1 ) b^{(1)} = b^{(1)} – α \frac{dJ}{db^{(1)}}

例子 🌰

代码: 用NN识别一只🐈,以下为代码片段。

  1. 加载数据、处理数据。省略代码说明。
  1. 建立模型,定义向前传播。
 # Sigmoid
def sigmoid (z):
    return 1 / ( 1 + np . exp(-z))
# Sigmoid Derivatives
def sigmoid_derivatives (a):
    return a * (1 - a)


def forward_propagation (W, b, X):
    # W, B: 一列为一组数据
    Z = np . dot(W . T, X) + b
    A = sigmoid(Z)
    return A
  1. 定义损失函数。
def loss_function (y, a):
    # one sample
    return -y * np . log(a) - (1 - y) * np . log(1 - a)
    
def Loss_Fn (Y, A):
    # all samples (1, 209)
    m = Y . shape[1]
    # log(0)会遇到报错情况
    epsilon = 1e-5
    J = (1 / m) * np . sum(-Y * np . log(A + epsilon) - (1 - Y) * np . log(1 - A + epsilon))
    return J
  1. 梯度下降,定义向后传播。
def backward_propagation (Y, A, X):
    # eg: A: 1 * m, Y: 1 * m X: 3 * m
    m = A . shape[1]
    dL_dZ = A - Y

    dL_dW = (1 / m) * np . dot(X, (A - Y) . T)
    dL_dB = (1 / m) * np . sum(A - Y)
    
    return dL_dW, dL_dB
  1. 训练模型。(这只是一层模型,如果有很多层的话,详看 两层NN demo)。
def train (X, Y, alpha, iterations):
    # ......
    # hyperparameters
    # alpha = 0.005
    # iterations = 2000

    # 1. Initializing parameters - 目标
    W, b = initialize_parameters(input_nums, output_nums)
    J_arr = []

    # 4. iterations: 2,3,4
    for i in range(iterations): # 不停训练
        # 2. Forward Propagation 向前传播
        A = forward_propagation(W, b, X)

        # 3. Backward Propagation 向后传播,梯度下降
        dL_dW, dL_dB = backward_propagation(Y, A, X)
        W -= alpha * dL_dW # 类似下山步伐和方向
        b -= alpha * dL_dB # 类似下山步伐和方向
  
    return W, b, J_arr

总结

上述,我只是简单介绍了一点有关NN模型的基础知识,实际上有关神经网络的知识还很多。本次分享的初衷是通过一些对模型基础的理解 + TensorFlow.js,前端同学也可以玩玩机器学习。

在我们的业务场景里,常见算法对业务赋能的场景,例如在出读阅卷中的图像识别 (eg: 对于一张试卷结构和标志点等识别)。

❤️ 谢谢支持

以上便是本次分享的全部内容,希望对你有所帮助^_^

喜欢的话别忘了 分享、点赞、收藏 三连哦~。

欢迎关注公众号 ELab团队 收货大厂一手好文章~

字节跳动校/社招内推码:W7HD8A6

投递链接: jobs.toutiao.com/s/dQ2dogm

今天的文章浅析神经网络 Neural Networks分享到此就结束了,感谢您的阅读。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/21609.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注