1.神经网络基础知识

所有有用的计算机系统都有一个输入和一个输出, 并在输入和输出之间进行某种类型的计算。 神经网络也是如此。

当我们不能精确知道一些事情如何运作时, 我们可以尝试使用模型来估计其运作方式, 在模型中, 包括了我们可以调整的参数。 如果我们不知道如何将千米转换为英里, 那么我们可以使用线性函数作为模型, 并使用可调节的梯度值作为参数。

改进这些模型的一种好方法是, 基于模型和已知真实示例之间的比较, 得到模型偏移的误差值, 调整参数——迭代。


我们使用简单的数学, 理解了线性分类器输出误差值和可调节斜率参数之间的关系。 也就是说, 我们知道了在何种程度上调整斜率, 可以消除输出误差值:
y = A x y=Ax y=Ax

E = ( Δ A ) x E=(\Delta A)x E=(ΔA)x

使用朴素的调整方法会出现一个问题, 即改进后的模型只与最后一次训练样本最匹配, “有效地”忽略了所有以前的训练样本。

image-20230825223804481

解决这个问题的一种好方法是使用学习率, 调节改进速率, 这样单一的训练样本就不能主导整个学习过程。
Δ A = 学习率 L ( E / x ) \Delta A={\text{学习率}}L(E/x) ΔA=学习率L(E/x)
来自真实世界的训练样本可能充满噪声或包含错误。 适度更新有助于限制这些错误样本的影响。


线性分类器可以学习部分布尔函数:

image-20230825224216722

如果数据本身不是由单一线性过程支配, 那么一个简单的线性分类器不能对数据进行划分。 例如, 由逻辑XOR运算符支配的数据说明了这一点。

但是解决方案很容易, 你只需要使用多个线性分类器来划分由单一直线无法分离的数据。

image-20230825224246752


生物大脑的基本单元——即神经元——可以接收一个电输入,输出另一个电信号,但是我们不能将神经元表示为线性函数,因为神经元不会立即反应, 而是会抑制输入, 直到输入增强,强大到可以触发输出。 你可以这样认为, 在产生输出之前, 输入必须到达一个阈值。

image-20230825230346774

我们可以使用更平滑的S形函数制作神经网络

image-20230825230443868

S函数,有时也称为逻辑函数:
y = 1 1 + e − x y=\frac{1}{1+e^{-x}} y=1+ex1
当然,生物神经元可以接受许多输入,在函数中,对于所有这些输入, 我们只需对它们进行相加,得到最终总和, 作为S函数的输入, 然后输出结果。 这实际上反映了神经元的工作机制。

image-20230825231204029

每个神经元接受来自其之前多个神经元的输入,并且如果神经元被激发了, 它也同时提供信号给更多的神经元。

将这种自然形式复制到人造模型的一种方法是, 构建多层神经元, 每一层中的神经元都与在其前后层的神经元互相连接。

image-20230825231316729

我们可以在多层神经元的连接上添加权重,从而弱化或放大信号,其权重值会随着神经网络的学习而按需变化,因此对于解决特定任务所需最小数量的连接冗余几个连接,也无伤大雅,因为它们的权重会逐渐接近零,即断开了链接。

image-20230825234906484


为了简化神经网络的计算,我们使用矩阵

image-20230825235119252

第一个矩阵包含两层节点之间的权重。 第二个矩阵包含第一层输入层的信号。 通过两个矩阵相乘, 我们得到的答案是输入到第二层节点组合调节后的信号。

image-20230825235150779
组合调节后的信号 X = 权重矩阵 W ⋅ 输入矩阵 I {\text{组合调节后的信号}}X={\text{权重矩阵}}W \cdot {\text{输入矩阵}}I 组合调节后的信号X=权重矩阵W输入矩阵I
表达式X = W I适用于前后层之间的计算,之后对X矩阵的各值带入S函数计算即可


最左边的输入为输入层,最右边的输出为输出层,中间的多层为隐藏层


我们可以通过输出的误差来反向调节输入(反向传播),一种思想就是在所有造成误差的节点中平分误差,另一种思想是不等分误差。 与前一种思想相反, 我们为较大链接权重的连接分配更多的误差,因为这些链接对造成误差的贡献较大。
误差 e 1 ⋅ w 1 , 1 w 1 , 1 + w 2 , 2 {\text{误差}}e_1 \cdot {\frac {w_{1,1}}{w_{1,1}+w_{2,2}} } 误差e1w1,1+w2,2w1,1
对于多层网络,我们从最终输出层往回工作,对于隐藏层的节点, 我们没有目标值或所希望的输出值。 我们只有最终输出层节点的目标值, 这个目标值来自于训练样本数据。隐藏层第一个节点具有两个链接, 这两个链接将这个节点连接到两个输出层节点。 我们知道, 沿着各个链接可以分割输出误差, 就像我们先前所做的一样。 这意味着, 对于中间层节点的每个链接, 我们得到了某种误差值。 我们可以重组这两个链接的误差, 形成这个节点的误差。 实际上我们没有中间层节点的目标值, 因此这种方法算得上第二最佳方法

image-20230826103416874
e h i d d e n , 1 = 链接 w 1 , 1 上的分割误差 + 链接 w 1 , 2 上的分割误差 = e o u t p u t , 1 ⋅ w 1 , 1 w 1 , 1 + w 2 , 2 + e o u t p u t , 2 ⋅ w 1 , 2 w 1 , 1 + w 2 , 2 \begin{aligned} e_{hidden,1} &= {\text{链接}}w_{1,1}上的分割误差 + {\text{链接}}w_{1,2}上的分割误差 \\ &=e_{output,1} \cdot {\frac {w_{1,1}}{w_{1,1}+w_{2,2}}} + e_{output,2} \cdot {\frac {w_{1,2}}{w_{1,1}+w_{2,2}}} \end{aligned} ehidden,1=链接w1,1上的分割误差+链接w1,2上的分割误差=eoutput,1w1,1+w2,2w1,1+eoutput,2w1,1+w2,2w1,2
image-20230826104030405

我们可以为隐藏层的误差构建矩阵,从而简化运算

image-20230826105155199

分数的分母是一种归一化因子。 如果我们忽略了这个因子, 那么我们仅仅失去后馈误差的大小。

image-20230826105231291

实践证明, 这种相对简单的误差信号反馈方式, 与我们先前相对复杂的方式一样有效。


知道了误差,我们使用梯度下降——每走一步就观察地形,一步步下山——的方式更新权重,同时,要更好地到达目标,我们要动态地变化“步幅”,这就需要使用合适的误差函数:

image-20230826114106696

我们更喜欢使用第三种误差函数, 而不喜欢使用第二种误差函数, 原因有以下几点:

  1. 使用误差的平方, 我们可以很容易使用代数计算出梯度下降的斜率。
  2. 误差函数平滑连续, 这使得梯度下降法很好地发挥作用——没有间断, 也没有突然的跳跃。
  3. 越接近最小值, 梯度越小, 这意味着, 如果我们使用这个函数调节步长, 超调的风险就会变得较小。

要使用梯度下降的方法, 现在我们需要计算出误差函数相对于权重的斜率。此处,我们感兴趣的是, 误差函数是如何依赖于神经网络中的链接权重的。 换句话说:“误差对链接权重的改变有多敏感? ”
∂ E ∂ w j , k \frac{\partial E}{\partial w_{j,k}} wj,kE
这个表达式表示了当权重 wj,k 改变时, 误差E是如何改变的。 这是误差函数的斜率, 也就是我们希望使用梯度下降的方法到达最小值的方向。

image-20230826153052402

首先展开误差函数, 这是对目标值和实际值之差的平方进行求和, 这是针对所有n个输出节点的和。
∂ E ∂ w j , k = ∂ ∑ n ( t n − o n ) 2 ∂ w j , k \frac{\partial E}{\partial w_{j,k}}={\frac{\partial \sum_n(t_n-o_n)^2}{\partial w_{j,k}}} wj,kE=wj,kn(tnon)2
节点n的输出 on 只取决于连接到这个节点的链接, 因此我们可以直接简化这个表达式。这意味着, 由于 wj,k 是链接到节点k的权重, 因此节点k的输出 ok 只取决于权重 wj,k ,除了权重 wj,k 所链接的节点(也就是 ok )外,我们可以从和中删除所有的 on , 这就完全删除了令人厌烦的求和运算。
∂ E ∂ w j , k = ∂ ( t k − o k ) 2 ∂ w j , k \frac{\partial E}{\partial w_{j,k}}={\frac{\partial(t_k-o_k)^2}{\partial w_{j,k}}} wj,kE=wj,k(tkok)2
使用链式法则可得
∂ E ∂ w j , k = ∂ ( t k − o k ) 2 ∂ o k ⋅ ∂ o k ∂ w j , k = − 2 ( t k − o k ) ⋅ ∂ o k ∂ w j , k \begin{aligned} \frac{\partial E}{\partial w_{j,k}}&={\frac{\partial(t_k-o_k)^2}{\partial o_k}} \cdot {\frac{\partial o_k}{\partial w_{j,k}}}\\ &=-2(t_k - o_k)\cdot {\frac{\partial o_k}{\partial w_{j,k}}} \end{aligned} wj,kE=ok(tkok)2wj,kok=2(tkok)wj,kok
ok 是节点k的输出,是在连接输入信号上进行加权求和, 在所得到结果上应用S函数得到的结果。
∂ E ∂ w j , k = − 2 ( t k − o k ) ⋅ ∂ s i g m o i d ( ∑ j w j , k ⋅ o j ) ∂ w j , k \frac{\partial E}{\partial w_{j,k}}=-2(t_k - o_k) \cdot {\frac{\partial {sigmoid(\sum_jw_{j,k}\cdot o_j)}}{\partial w_{j,k}}} wj,kE=2(tkok)wj,ksigmoid(jwj,koj)
oj 是前一个隐藏层节点的输出, 而不是最终层的输出 ok

S函数的微分公式:
∂ s i g m o i d ( x ) ∂ x = s i g m o i d ( x ) ⋅ ( 1 − s i g m o i d ( x ) ) \frac{\partial sigmoid(x)}{\partial x}=sigmoid(x) \cdot (1-sigmoid(x)) xsigmoid(x)=sigmoid(x)(1sigmoid(x))
带入可得:
∂ E ∂ w j , k = − 2 ( t k − o k ) ⋅ ∂ s i g m o i d ( ∑ j w j , k ⋅ o j ) ∂ ∑ j w j , k ⋅ o j ⋅ ∂ ∑ j w j , k ⋅ o j ∂ w j , k = − 2 ( t k − o k ) ⋅ s i g m o i d ( ∑ j w j , k ⋅ o j ) ⋅ ( 1 − s i g m o i d ( ∑ j w j , k ⋅ o j ) ) ⋅ ∂ ∑ j w j , k ⋅ o j ∂ w j , k = − 2 ( t k − o k ) ⋅ s i g m o i d ( ∑ j w j , k ⋅ o j ) ⋅ ( 1 − s i g m o i d ( ∑ j w j , k ⋅ o j ) ) ⋅ o j \begin{aligned} \frac{\partial E}{\partial w_{j,k}}&=-2(t_k - o_k) \cdot {\frac{\partial {sigmoid(\sum_jw_{j,k}\cdot o_j)}}{\partial \sum_jw_{j,k}\cdot o_j}}\cdot {\frac{\partial \sum_jw_{j,k}\cdot o_j}{\partial w_{j,k}}}\\ &=-2(t_k - o_k) \cdot sigmoid(\sum_jw_{j,k}\cdot o_j)\cdot (1-sigmoid(\sum_jw_{j,k}\cdot o_j))\cdot {\frac{\partial \sum_jw_{j,k}\cdot o_j}{\partial w_{j,k}}}\\ &=-2(t_k - o_k) \cdot sigmoid(\sum_jw_{j,k}\cdot o_j)\cdot (1-sigmoid(\sum_jw_{j,k}\cdot o_j))\cdot o_j \end{aligned} wj,kE=2(tkok)jwj,kojsigmoid(jwj,koj)wj,kjwj,koj=2(tkok)sigmoid(jwj,koj)(1sigmoid(jwj,koj))wj,kjwj,koj=2(tkok)sigmoid(jwj,koj)(1sigmoid(jwj,koj))oj
去掉倍数2。我们只对误差函数的斜率方向感兴趣, 这样我们就可以使用梯度下降的方法, 因此可以去掉2。
∂ E ∂ w j , k = − ( t k − o k ) ⋅ s i g m o i d ( ∑ j w j , k ⋅ o j ) ( 1 − s i g m o i d ( ∑ j w j , k ⋅ o j ) ) ⋅ o j \frac{\partial E}{\partial w_{j,k}}=-(t_k - o_k) \cdot sigmoid(\sum_jw_{j,k}\cdot o_j)(1-sigmoid(\sum_jw_{j,k}\cdot o_j))\cdot o_j wj,kE=(tkok)sigmoid(jwj,koj)(1sigmoid(jwj,koj))oj
第一部分, 非常简单, 就是(目标值-实际值),我们对此已经很清楚了。 第二部分,在sigmoid中的求和表达式也很简单, 就是进入最后一层节点的信号,我们可以称之为 ik , 这样它看起来比较简单。 这是应用激活函数之前, 进入节点的信号。 最后一部分是前一隐藏层节点j的输出。

我们所得到的这个表达式, 是为了优化隐藏层和输出层之间的权重。 现在, 我们需要完成工作, 为输入层和隐藏层之间的权重找到类似的误差斜率
∂ E ∂ w i , j = − ( e j ) ⋅ s i g m o i d ( ∑ i w i , j ⋅ o i ) ( 1 − s i g m o i d ( ∑ i w i , j ⋅ o i ) ) ⋅ o i \frac{\partial E}{\partial w_{i,j}}=-(e_j) \cdot sigmoid(\sum_iw_{i,j}\cdot o_i)(1-sigmoid(\sum_iw_{i,j}\cdot o_i))\cdot o_i wi,jE=(ej)sigmoid(iwi,joi)(1sigmoid(iwi,joi))oi
第一部分的(目标值-实际值)误差,现在变成了隐藏层节点中重组的向后传播误差,正如在前面所看到的那样, 我们称之为 ej 。sigmoid部分可以保持不变, 但是内部的求和表达式指的是前一层, 因此求和的范围是所有由权重调节的进入隐藏层节点j的输入。 我们可以称之为 ij 。现在,最后一部分是第一层节点的输出 oi , 这碰巧是输入信号。

我们使用学习因子调节变化, 我们可以根据特定的问题, 调整这个学习因子。 当我们建立线性分类器,它作为避免被错误的训练样本拉得太远的一种方式, 同时也为了保证权重不会由于持续的超调而在最小值附近来回摆动。
new w j , k = old w j , k − α ⋅ ∂ E ∂ w j , k {\text{new}w_{j,k}}={\text{old}}w_{j,k}-\alpha \cdot {\frac{\partial E}{\partial w_{j,k}}} newwj,k=oldwj,kαwj,kE
更新后的权重 wj,k 是由刚刚得到误差斜率取反来调整旧的权重而得到的。正如我们先前所看到的,如果斜率为正,我们希望减小权重,如果斜率为负,我们希望增加权重,因此,我们要对斜率取反。

通过矩阵计算:

image-20230826161832815

权重改变矩阵中包含的值, 这些值可以调整链接权重 wj,k ,这个权重链接了当前层节点j与下一层节点k。你可以发现,表达式中的第一项使用下一层(节点k)的值,最后一项使用前一层(节点j)的值

权重更新矩阵有如下的矩阵形式, 这种形式可以让我们通过计算机编程语言高效地实现矩阵运算。

image-20230826162327765


S激活函数,如果输入变大,函数会变得平坦,由于我们使用梯度学习新的权重, 因此一个平坦的激活函数会出问题。

权重的改变取决于激活函数的梯度,小梯度意味着限制神经网络学习的能力,这就是所谓的饱和神经网络。 这意味着,我们应该尽量保持小的输入。同时还取决于输入信号 oj ,因此,我们也不应
该让输入信号太小。当计算机处理非常小或非常大的数字时,可能会丧失精度,因此,使用非常小的值也会出现问题。

重新调整输入值,将其范围控制在0.0到1.0。输入0会将 oj 设置为0,这样权重更新表达式就会等于0,从而造成学习能力的丧失, 因此在某些情况下, 我们会将此输入加上一个小小的偏移, 如0.01,避免输入0带来麻烦。


S激活函数的输出不可能大于1.0、小于0。如果我们将目标值设置在这些不可能达到的范围, 训练网络将会驱使更大的权重, 以获得越来越大的输出, 而这些输出实际上是不可能由激活函数生成的。 这使得网络饱和, 因此我们知道这种情况是很糟糕的。

因此, 我们应该重新调整目标值, 匹配激活函数的可能输出, 注意避开激活函数不可能达到的值。虽然, 常见的使用范围为0.0~1.0, 但是由于0.0和1.0这两个数也不可能是目标值, 并且有驱动产生过大的权重的风险, 因此一些人也使用0.01~0.99的范围。


内部链接的权重应该是随机的, 值较小, 但要避免零值。 如果节点的传入链接较多, 有一些人会使用相对复杂的规则, 如减小这些权重的大小。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/93555.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Java实现excel表数据的批量存储(结合easyexcel插件)

场景:加哥最近在做项目时,苦于系统自身并未提供数据批量导入的功能还不能自行添加上该功能,且自身不想手动一条一条将数据录入系统。随后,自己使用JDBC连接数据库、使用EasyExcel插件读取表格并将数据按照业务逻辑批量插入数据库完…

LeetCode-455-分发饼干-贪心算法

题目描述: 假设你是一位很棒的家长,想要给你的孩子们一些小饼干。但是,每个孩子最多只能给一块饼干。 对每个孩子 i,都有一个胃口值 g[i],这是能让孩子们满足胃口的饼干的最小尺寸;并且每块饼干 j&#xff…

AM62x GPMC并口如何实现“小数据-低时延,大数据-高带宽”—ARM+FPGA低成本通信方案

GPMC并口简介 GPMC(General Purpose Memory Controller)是TI处理器特有的通用存储器控制器接口,支持8/16bit数据位宽,支持128MB访问空间,最高时钟速率133MHz。GPMC是AM62x、AM64x、AM437x、AM335x、AM57x等处理器专用于与外部存储器设备的接口…

Hive/Spark 整库导出/导入脚本

博主历时三年精心创作的《大数据平台架构与原型实现:数据中台建设实战》一书现已由知名IT图书品牌电子工业出版社博文视点出版发行,点击《重磅推荐:建大数据平台太难了!给我发个工程原型吧!》了解图书详情,…

mysql57、mysql80 目录结构 之 Windows

查看mysql 数据存储的位置 /bin:存储可执行文件,主要包含客户端和服务端启动程序,如mysql.exe、mysqld.exe等 /docs:存放一些文档 /include:用于放置一些头文件,如:mysql.h、mysqld_error.h 等 …

taro react/vue h5 中的上传input onchange 值得区别

<inputclassNamebase-input-file-h5typefileacceptimage/*capturecameraonChange{onChangeInput} />1、taro3react 2、taro3vue3

古典加密的C++实现——凯撒密码、单表代换密码

&#x1f64c;秋名山码民的主页 &#x1f602;一个打过一年半的oier&#xff0c;写过一年多的Java&#xff0c;啥都会干一点的普通本科生 &#x1f389;欢迎关注&#x1f50e;点赞&#x1f44d;收藏⭐️留言&#x1f4dd; &#x1f64f;作者水平有限&#xff0c;如发现错误&…

Android 中SettingsActivity(PreferenceFragmentCompat)的简单使用

如果你需要一个简单的APP设置&#xff0c;可以使用sharedPreferences进行存储&#xff0c;我们可以借助AndroidStudio快速创建一个用于设置的Activity&#xff0c;其实它是继承PreferenceFragmentCompat&#xff0c;存储方式用的就是sharedPreferences&#xff0c;只是帮我们节…

vue使用vant中的popup层,在popup层中加搜索功能后,input框获取焦点 ios机型的软键盘不会将popup顶起来的问题

1.使用vant的popup弹出层做了一个piker的选择器,用户需要在此基础上增加筛选功能。也就是输入框 2.可是在ios机型中,input框在获取焦点以后,ios的软键盘弹起会遮盖住我们的popup层,导致体验不是很好 3.在大佬的解答及帮助下,采用窗口滚动的方式解决此方法 <Popupv-model&q…

docker的安装以及基本操作

一.认识docker Docker是一种用于构建、打包和运行应用程序的开源平台。它基于操作系统级虚拟化技术&#xff0c;可以将应用程序和其依赖的库、环境等资源打包到一个可移植的容器中&#xff0c;形成一个轻量级、独立的可执行单元。 开发者在本地编译测试通过的容器可以批量地在…

主流深度学习框架及神经网络模型汇总

目录 主流深度学习框架及神经网络模型汇总 一、人工智能的研究领域和分支 二、主流深度学习框架​编辑 1.TensorFlow 2.PyTorch 3.PaddlePaddle 4.Keras 5.Caffe/Caffe2 6.MXNet 7.Theano 8.Torch 9.CNTK 10.ONNX 三、深度学习移动端推理框架 1.TensorRT 2.TF-…

前端将file文件传给后台,后台将文件传给前台(包含上传下载)

前端将file文件传给后台&#xff0c;后台将文件传给前台&#xff08;包含上传下载&#xff09; 在开发过程中&#xff0c;经常会遇见对文件的处理。 例如&#xff1a;在上传、下载文件时&#xff0c;需要在前端选完文件传到后台传到服务器&#xff1b;或者文件从后台&#xf…

Mybatis缓存

缓存(cache&#xff09;的作用是为了减去数据库的压力&#xff0c;提高查询性能。缓存实现的原理 是从数据库中查询出来的对象在使用完后不要销毁&#xff0c;而是存储在内存&#xff08;缓存&#xff09;中&#xff0c; 当再次需要获取该对象时&#xff0c;直接从内存&#xf…

Docker部署项目

相关系列文章&#xff1a; 1、DockerHarbor私有仓库快速搭建 2、DockerJenkinsHarbor 3、Docker安装Mysql、Redis、nginx、nacos等环境 1、jenkins构建前端并上传服务器 在这篇文章中(DockerJenkinsHarbor)未完成前端的远程部署&#xff0c;这里对前端vue工程进行编译打包并上…

学习ts(十)装饰器

定义 装饰器是一种特殊类型的声明&#xff0c;它能够被附加到类声明&#xff0c;方法&#xff0c;访问符&#xff0c;属性或参数上&#xff0c;是一种在不改变原类和使用继承的情况下&#xff0c;动态的扩展对象功能。 装饰器使用expression形式&#xff0c;其中expression必须…

【C++】—— C++11新特性之 “右值引用和移动语义”

前言&#xff1a; 本期&#xff0c;我们将要的介绍有关 C右值引用 的相关知识。对于本期知识内容&#xff0c;大家是必须要能够掌握的&#xff0c;在面试中是属于重点考察对象。 目录 &#xff08;一&#xff09;左值引用和右值引用 1、什么是左值&#xff1f;什么是左值引用…

政务大厅人员睡岗离岗玩手机识别算法

人员睡岗离岗玩手机识别算法通过pythonyolo系列网络框架算法模型&#xff0c;人员睡岗离岗玩手机识别算法利用图像识别和行为分析&#xff0c;识别出睡岗、离岗和玩手机等不符合规定的行为&#xff0c;并发出告警信号以提醒相关人员。Python是一种由Guido van Rossum开发的通用…

Linux————LNMT搭建

一、原理 搭建一个基于Linux系统的Web服务器&#xff0c;使用Nginx作为反向代理服务器&#xff0c;Tomcat作为应用服务器&#xff0c;MySQL作为数据库服务器。 Linux操作系统 基于Linux的操作系统 Nginx Nginx是一款高性能的Web服务器和反向代理服务器&#xff0…

基于Java+SpringBoot+Vue前后端分离图书管理系统设计和实现

博主介绍&#xff1a;✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专…

svn软连接和文件忽略

软连接 1)TortoiseSVN->Properties->New->Externals->New 2)填入软连接信息 Local path: 写下软连接后的文件夹的名字 URL: 想要软连接的牡蛎->TortoiseSVN->Repo-browser 复制下填入 文件忽略 以空格隔开就行