概念和组成

  概念:我们在机器学习中谈论神经网络时,指的是神经网络学,或者说,是机器学习与神经网络这两个学科领域的交叉部分。我们在这里构建类似于神经模型的分类器,实则回到了分类的问题上。在训练过程中,神经网络的复杂性也体现了其分类的准确和可靠性很高的优点。

神经元模型

  生物的知识用起来哦!你想一个最简单的神经要怎么兴奋,其过程大致分为,感受刺激 --> 钾离子外流,钠离子内流 --> 达到兴奋所需要的电位差立刻兴奋 --> 传导…
那么在机器学习中,我们的神经元长成啥样呢?肯定和我们自己的神经元有区别,至少不会流血。

  这个神经元 x 端是其他神经元传递过来的信号,w 表示权重。什么意思?就是你传过来的东西我要消化处理一下才传递给下一层级。比如吃饭时,把食物送进空腔,没牙的老奶奶也知道用牙床磨两下食物后再送进胃里。

  我们求学也要有自己的理解不是吗?这个 w 就是两个神经元“通道的带权值”。当前神经元里面有一个阈值,将这个神经元的总输入值和阈值比较,然后通过“激活函数”产生神经元的输出。

激活函数

  理想中的激活函数便是阶跃函数(左图),输出值只有0,1。0代表抑制,1代表兴奋,但是它不连续,不光滑,因此我们实际上用的是sigmoid函数(右图)作为激活函数。它把可能在较大范围内变化的输入值挤压到 (0 1) 输出值范围内,因此有 时也称为 “挤压函数”。
  事实上,从计算机科学的角度看,我们可以先不考虑神经网络是否真的模拟了生物神经网络,只需将一个神经网络视为包含了许多参数的数学模型,这个模型是若干个函数相互(嵌套)带入而得.有效的神经网络学习算法大多以数学证明为支撑的。知道小时候为啥需要学数学乐吧,你只要学深一点除了文科领域哪儿都逃不过数学。

感知机和神经网络

  感知机由两层神经元组成,输入层接收外界输入信号后传递给输出层,输出层是M-P神经元,亦称"阔值逻辑单元".
  可是它太简单了,就跟膝跳反射似的不用动脑子。所以我们得增加它的层数实现更为精准理性的功能。在此之前我们还是得从这个简单的模型说起,万丈高楼平地起,好好看,好好学。
  更一般的,在给定的训练集中,权重Wi(i=01,2…,n)和θ都是通过学习得到。域值θ可以看做固定输入的亚结点所对应的连接权重Wn+1。**这样权重和域值的学习可以统一为权重的学习。**感知机学习的规则,对于训练集(x,y),若对感知机的输出为y`,则感知机的权重将这样调整:

  其中η∈(0,1),称为学习效率,从第一个式子可以看出,当y`=y时,预测全部正确△Wi = 0,不调整,不相等就会根据二式调整。
  需要注意的是感知机只有输出层神经元进行激活函数处理,即只拥有一层功能神经元,其学习能力非常有限。与或非问题都是线性可分的,若两个模式线性可分则存在一个线性超平面把他们分开如图。则感知机学习过程一定会收敛求得权向量Wi.否则感知机学习过程将发生动荡不稳定,就不能解决d图的非线性可分问题。

  要解决非线性可分问题,需要多层功能神经元。如下a图这个两层的感知机,输入层和输出层之间的一层,叫做隐层或隐含层。隐含层和输出层都具有激活函数的功能。
  更一般地,常见的神经网络如下两图所示层级结构,每层神经元与下一层神经元全互联。神经元之间不存在同级连接也不存在跨级连接。这样的神经网络称为”多层前馈神经网络”。

  其中传入层神经元接收外界输入,隐层和输出层神经元对信号进行加工,最终结果有输出层神经元输出。强调输入层神经元只是接收输入,隐层和输出层包含功能神经元。图a叫做“两层网络”也叫作“单隐层网络”。在机器学习过程中,通过训练集来调整神经元之间的“连接权”以及每个功能神经元的域值。也就是说:神经元学的东西蕴含在连接权和域值里面

误差逆传播算法(标准BP)

介绍

  多层网络的学习能力比单层感知机强得多,想要训练多层网络,简单的感知机学习规则显然不够。需要更强大的算法,误差逆传播算法(Error BackPropagation ,简称 BP)就是最杰出的算法代表。

功能

  • 大多数现实中任务中使用的神经网络,都使用BP训练算法
  • BP算法不仅可用于多层前馈神经网络,还可用于其他类型的神经网络。如:训练递归神经网络,一般我们指的BP网络都是训练的多层前馈网络。

公式推导

  给定训练集D={(x1x_1x1​,y1y_1y1​),(x2x_2x2​,y2y_2y2​)…(xmx_mxm​,ymy_mym​)}xix_ixi​∈RdR^dRd,yiy_iyi​∈RlR^lRl,输入事例由d个属性描述,输出l个实维向量。我们来看图:d个输入神经元,q个隐层神经元,l个输出神经元构成的多层前馈网络结构。第j个输出层神经元的域值用θjθ_jθj​表示,隐层第h个神经元用γh表示。输入层第i个神经元和隐层第h个神经元之间的连接权记vihv_{ih}vih​,隐层第h个神经元和输出层第j个神经元之间的连接权ωhjω_{hj}ωhj​,记第h个神经元接收的输入为αhα_hαh​=∑di=1vihxi\sum_{d_i=1}v_{ih}x_i∑di​=1​vih​xi​输出层第j个神经元接收的输入为βj=∑qh=1ωhjbhβ_j=∑_{q_h=1}ω_{hj}b_hβj​=∑qh​=1​ωhj​bh​,其中bh为第h个隐层神经元的输出。
  假设隐层和输出层的神经元都使用sigmoid函数,对训练例(xk,yk)(x_k,y_k)(xk​,yk​),假定神经网络的输出为y^k=(y1,y2...y^lk)\hat y_k=(y_1,y_2...\hat y^{k}_l)y^​k​=(y1​,y2​...y^​lk​)
那么有:y^jk=f(βj−θj)1\hat y^{k}_j=f(\beta_j-\theta_j)\qquad 1y^​jk​=f(βj​−θj​)1

  根据算法名字我们知道从结果逆向更新权重值,我们用这个绿色的结点。注意强调:yjy_jyj​是用sigmoid函数处理而来,βj,θj\beta_j,\theta_jβj​,θj​分别表示yjy_jyj​的输入和域值。输入是所有隐层都参与了,累计求和而来。
输出的y^\hat yy^​和实际的yyy有一个误差,我们就要借助它来更新权重和阈值,这里我们采用均方误差:
Ek=12∑i=1l(y^j−yj)22E_k=\frac{1}{2}\sum_{i=1}^l(\hat y_j-y_j)^2\qquad2Ek​=21​i=1∑l​(y^​j​−yj​)22
  这里的EkE_kEk​是输出层所有结点的误差处理,1/2是方便后面的求导。
我们更新估计式:
v=v+Δv3v=v+\Delta v\qquad3v=v+Δv3
Δv=η(y−y^)xi4\Delta v=\eta(y-\hat y)x_i\qquad4Δv=η(y−y^​)xi​4
  现在我们来推导whjw_{hj}whj​的链接权。BP算法基于梯度下降策略以目标的负梯度方向来调整,由输出层的误差E_k和给定的学习率η\etaη:
Δwhj=−η∂Ek∂whj5\Delta w_{hj}=-\eta\frac{\partial E_k}{\partial w_{hj}}\qquad5Δwhj​=−η∂whj​∂Ek​​5
  注意whjw_{hj}whj​先影响到第j个输出层神经元的输入值βj,再影响到输出y^jk\hat y_{j}^ky^​jk​最后影响到EkE_kEk​,那么就类似于我们的符合函数,进行链式求导。
∂Ek∂whj=∂Ek∂y^jk⋅∂y^jk∂βj⋅∂βj∂whj6\frac{\partial E_k}{\partial w_{hj}}=\frac{\partial E_k}{\partial \hat y_{j}^k}\cdot\frac{\partial \hat y_{j}^k}{\partial \beta_{j}}\cdot\frac{\partial \beta_{j}}{\partial w_{hj}}\qquad6∂whj​∂Ek​​=∂y^​jk​∂Ek​​⋅∂βj​∂y^​jk​​⋅∂whj​∂βj​​6
我们有βj的定义:βj=∑h=1qwhjbh7\beta _j=\sum_{h=1}^qw_{hj}b_h\qquad7βj​=h=1∑q​whj​bh​7
有:∂βj∂whj=bh\frac{\partial \beta_j}{\partial w_{hj}}=b_h∂whj​∂βj​​=bh​
sigmoid函数有一个非常好的导数性质:
f′(x)=f(x)(1−f(x))f'(x)=f(x)(1-f(x))f′(x)=f(x)(1−f(x))
由公式 1 和 2 我们设一个gig_igi​
gi=−∂Ek∂y^jk⋅∂y^jk∂βjg_i=-\frac{\partial E_k}{\partial \hat y_{j}^k}\cdot\frac{\partial \hat y_{j}^k}{\partial \beta_{j}}gi​=−∂y^​jk​∂Ek​​⋅∂βj​∂y^​jk​​
=−(y^jk−yjk)f′(βj−θj)\qquad=-(\hat y_{j}^k-y_{j}^k)f'(\beta_j-\theta_j)=−(y^​jk​−yjk​)f′(βj​−θj​)
=y^jk(1−y^jk)(yjk−y^jk)=\hat y_{j}^k(1-\hat y_{j}^k)(y_{j}^k-\hat y_{j}^k)=y^​jk​(1−y^​jk​)(yjk​−y^​jk​)
带入 5 公式:
Δwhj=ηgjbh\Delta w_{hj}=\eta g_jb_hΔwhj​=ηgj​bh​
类似可得:Δθj=−ηgj\Delta \theta_j=-\eta g_jΔθj​=−ηgj​
我们求下一层的权重变化 ΔVih,如法炮制一遍:
Δvih=−η∂Ek∂vih\Delta v_{ih}=-\eta \frac{\partial E_k}{\partial v_{ih}}Δvih​=−η∂vih​∂Ek​​
链式求导找关系,在上述的关系上要新增whjw_{hj}whj​->bhb_hbh​->vihv_{ih}vih​ :
∂Ek∂vih=∂Ek∂y^jk⋅∂y^jk∂βj⋅∂βj∂whj⋅∂whj∂bh⋅∂bh∂αh⋅∂αh∂vih\frac{\partial E_k}{\partial v_{ih}}=\frac{\partial E_k}{\partial \hat y_{j}^k}\cdot\frac{\partial \hat y_{j}^k}{\partial \beta_{j}}\cdot\frac{\partial \beta_j}{\partial w_{hj}}\cdot\frac{\partial w_{hj}}{\partial b_h}\cdot\frac{\partial b_h}{\partial \alpha_h}\cdot\frac{\partial \alpha_{h}}{\partial v_{ih}}∂vih​∂Ek​​=∂y^​jk​∂Ek​​⋅∂βj​∂y^​jk​​⋅∂whj​∂βj​​⋅∂bh​∂whj​​⋅∂αh​∂bh​​⋅∂vih​∂αh​​

同时我们引入ehe_heh​:eh=−∂Ek∂bh⋅∂bh∂αhe_h=-\frac{\partial E_k}{\partial b_h}\cdot\frac{\partial b_h}{\partial \alpha_h}eh​=−∂bh​∂Ek​​⋅∂αh​∂bh​​
=−∑j=1l∂Ek∂βj⋅∂βj∂bhf′(αh−γh)=-\sum_{j=1}^l\frac{\partial E_k}{\partial \beta_j}\cdot\frac{\partial \beta_j}{\partial b_h}f'(\alpha_h-\gamma _h)=−j=1∑l​∂βj​∂Ek​​⋅∂bh​∂βj​​f′(αh​−γh​)
=∑j=1lgiwhjf′(αh−γh)=\sum_{j=1}^lg_iw_{hj}f'(\alpha_h-\gamma_h)=j=1∑l​gi​whj​f′(αh​−γh​)
=bh(1−bh)∑j=1lgiwhj=b_h(1-b_h)\sum_{j=1}^lg_iw_{hj}=bh​(1−bh​)j=1∑l​gi​whj​
从而对隐层的更新:
Δvih=ηehxi\Delta v_{ih}=\eta e_hx_iΔvih​=ηeh​xi​
Δγh=−ηeh\Delta\gamma _h=-\eta e_hΔγh​=−ηeh​
  学习率η∈(0,1)控制着算法每一轮的迭代中更新步长,η太大容易振荡,太小收敛太慢了(就是y^=y\hat y=yy^​=y这个过程)。我们要做到精细可以是每一层的η都不一样,比如此处我们不妨设输出层η1,隐层η2。

工作流程

累计BP算法

  我们需要注意BP算法的目标是要最小化训练集D上的累计误差:
E=1m∑k=1mEkE=\frac{1}{m}\sum_{k=1}^mE_kE=m1​k=1∑m​Ek​
  我们上面说的是标准BP算法,每一次仅对一个训练样例更新连接权和阈值,其更新规则是根据单个的Ek而言。如果类似的推导基于累积误差最小化的更新规则,就得到了累积误差逆传播算法。这两个算法都很常用,标准BP算法往往需要进行更多次的迭代,而累积BP算法读取整个训练集D一遍后才对参数进行更新,其更新频率低很多。但是在很多任务中,累计误差Ek下降到一定程度后,进一步下降会非常缓慢,这是标准BP往往会更快获得较好的解。数据多更新次数越多标准BP较好

新问题拟合

  现在任然未解决的问题:隐层的神经元到底需要几个?我们无法通过数据样例准确给出,只能通过试错法来确定隐层神经元的个数。

拟合问题

  正是由于神经网络强大的表示能力,BP神经网络经常曹禺拟合:其训练误差逐渐降低,但是测试误差可能持续升高。

解决之道

  1.早停:将数据分成训练集和验证集,训练集用来计算梯度、更新连接权和阈值,验证集用来估计误差。如果训练集误差降低,验证集的误差反而升高,立刻终止训练,同时返回最小误差的连接权和阈值。
  2.正则化:在误差目标中增加一个用于描述网络复杂的部分,例如连接权和阈值的平方和.E=λ1m∑k=1mEk+(1−λ)∑iwi2E=\lambda \frac{1}{m}\sum_{k=1}^mE_k+(1-\lambda)\sum_{i}w_i^2E=λm1​k=1∑m​Ek​+(1−λ)i∑​wi2​
  其中λ∈(0,1)用于验证经验误差与网络复杂度这两项进行折中,常通过交叉验证法来估计。增加连接权与阈值平方和这一项后,训练过程将会偏向比较好的链接权和阈值,使网络输出更加平滑,从而对拟合有所缓解。

全局最小和局部最小

知识理解

  我们神经网络的训练过程可以看做一个参数的寻优过程,即在参数空间中,寻找一组最优的链接权w,阈值参数θ使得误差E最小。
  高数中我们知道参数最优在两个位置:局部极小、全局最小。直观来看,局部极小值是参数空间中的某个点,其邻域点的误差值均不小于该点的函数值;全局最小解便是参数空间中所欲点的误差值均不小于该点的误差函数值。
显然参数空间梯度为零的点,其误差函数就是局部极小值。想一想这个图,可能有多个极小值,最小值就藏在其中,我们就要把它找出来。

  基于梯度的搜索是使用最广泛的参数寻优方法。我们每次进行迭代,计算误差函数在当前点的梯度,然后根据梯度确定搜索方向。这里我们负梯度方向为函数下降最快的方向,因此我们沿着这个方向寻找最优解,当梯度为零就是达到了局部极小值,既可以停止搜索了。可是多个极值点的情况我们只能找到一个极值点就停止了,就好比说我要去找西瓜,你看见路边的芝麻就停止了寻找,显然不能这样。

跳出局部极小

我们通常采用以下策略:

  • 用多组不同的参数初始化神经网络,按标椎方法训练后,取其中误差最小的解作为最终参数。这相当于从多个不同的初始点开始搜索,这样就可能陷入不同的局部极小,从其中选择最接近全局最小的哪个参数组作为结果。
  • 使用“模拟退火”技术,每一步都有一定的概率接受比当前解更差的结果,从而有助于。在每次迭代中选择次优解要随着时间的推移而逐渐降低,从而保证算法的稳定。
  • 使用随机梯度下降,与标准梯度下降精确计算梯度不同,随机梯度下降在算法中添加了随机因素。那么即使陷入了局部极小,但是梯度不为零啊,继续更新,这样有机会跳出局部最小继续搜索。
      这些解决之道都是启发式,在理论上还缺乏保证。也就是你可以靠一定的概率接近或者取到全局最小,但是也有风险取不到。

BP算法举例

  多说无益,我们来看最直观的数据运行过程,放松一下头脑,马上发车。
这里我们输出层 2 个神经元,隐层 3 个神经元,输出层 2 个神经元。
初始权重值:

连接权 w1 w2 w3 w4 w5 w6 w7 w8 w9 w10 w11 w12
权值 0.1 0.15 0.2 0.25 0.3 0.35 0.4 0.45 0.5 0.55 0.6 0.65

偏执项b1=0.35 b2=0.65
  我们先进行前向传播。(我都用手写了,你们也试一下吧,抄一遍也可以)


  **接下来算输出层的输入值和输出值。**如法炮制一遍。

  我们得到了第一轮的均方误差E,现在我们以更新 w7 权重为例来更新权值。

我们根据公式:
Δw7=−η∂Etotal∂w7\Delta w_{7}=-\eta\frac{\partial E_{total}}{\partial w_7}Δw7​=−η∂w7​∂Etotal​​

请我们已经求出了∂Etotal∂w7\frac{\partial E_{total}}{\partial w_7}∂w7​∂Etotal​​,加入我们初始化η=0.5
那么根据 w7 的更新公式:
w7+=w7+Δw7w_7^+=w7+\Delta w_7w7+​=w7+Δw7​
w7+=0.4−0.5∗0.078064=0.360968w_7^+=0.4-0.5*0.078064=0.360968w7+​=0.4−0.5∗0.078064=0.360968
同理我们可以求出:
w8+=0.453383w_8^+=0.453383w8+​=0.453383w9+=0.458137\qquad w_9^+=0.458137w9+​=0.458137
w10+=0.553629w_{10}^+=0.553629w10+​=0.553629w11+=0.557448\qquad w_{11}^+=0.557448w11+​=0.557448
w12+=0.653688w_{12}^+=0.653688w12+​=0.653688

结合初始值这张表:w7~w12

连接权 w1 w2 w3 w4 w5 w6 w7 w8 w9 w10 w11 w12
权值 0.1 0.15 0.2 0.25 0.3 0.35 0.4 0.45 0.5 0.55 0.6 0.65
  我们发现 w7w_{7}w7​的值0.4更新为 w7+w_{7}^+w7+​ = 0.360968 它变小了,w9+w_{9}^+w9+​, w11+w_{11}^+w11+​也变小了.另外 w8+w_{8}^+w8+​ ,w10+w_{10}^+w10+​ ,w12+w_{12}^+w12+​变大了。

  接下来我们来进行w1w_1w1​的更新,看看关系图找出求导的关系链
用笔推一下,流程大致这样:

特别注意:这里的 w7w_7w7​ 已经更新过了
类似的:
∂Eo2∂bh1=∂Eo2∂y^2⋅∂y^2∂β2⋅∂β2∂bh1=(y^2−y2)y^2(1−y^2)w8\frac{\partial \,E_{o2}}{\partial\, b_{h1}}=\frac{\partial \,E_{o2}}{\partial\, \hat y_{2}}\cdot\frac{\partial \,\hat y_{2}}{\partial\, \beta _{2}}\cdot\frac{\partial \,\beta_{2}}{\partial\, b_{h1}}=(\hat y_2-y_2)\hat y_2(1-\hat y_2)w_8∂bh1​∂Eo2​​=∂y^​2​∂Eo2​​⋅∂β2​∂y^​2​​⋅∂bh1​∂β2​​=(y^​2​−y2​)y^​2​(1−y^​2​)w8​
  计算出∂Eo2∂bh1\frac{\partial \,E_{o2}}{\partial\, b_{h1}}∂bh1​∂Eo2​​=-0.453383,然后计算出∂Etotal∂w1=0.011204\frac{\partial \,E_{total}}{\partial\, w_{1}}=0.011204∂w1​∂Etotal​​=0.011204.进而:w1+=w1+Δw1=0.1−η∂Etotal∂w1=0.1−0.5∗0.011204=0.094534w_1^+=w1+\Delta w_1=0.1-\eta \frac{\partial \,E_{total}}{\partial\, w_{1}}=0.1-0.5*0.011204=0.094534w1+​=w1+Δw1​=0.1−η∂w1​∂Etotal​​=0.1−0.5∗0.011204=0.094534
  类似的更新出其他连接权值:
  越往前面更新权值,它的计算复杂度会更高,消耗也更大。更新次数越多,就越接近真实值。

代码实现

这里我采用我老师的代码,里面附加详解。我老师的代码

机器学习——神经网络相关推荐

  1. 常用激活函数--小白角度 TensorFlow 机器学习 神经网络 选取

    常用激活函数--小白角度TensorFlow 机器学习 神经网络 选取 先简单介绍一下激活函数 常用激活函数review 1.阶跃函数 2.Sigmoid函数(logistic函数) 3.Hyperb ...

  2. 深度学习 2 机器学习 神经网络 卷积神经网络

    机器学习 无监督学习 监督学习 半监督学习 强化学习 经验中总结提升 遗传算法 适者生存不是者淘汰 什么是神经网络 Neural Network 人工神经元 数学模型 计算机模型 人工神经网络在外界信 ...

  3. Educoder 机器学习 神经网络 第三关:反向传播算法

    任务描述 相关知识 数据集介绍 神经网络是如何训练 前向传播 交叉熵 反向传播 sklearn中的神经网络 编程要求 测试说明 任务描述 本关任务:用sklearn构建神经网络模型,并通过鸢尾花数据集 ...

  4. 吴恩达机器学习神经网络 8-1非线性假设

    Non-linear hypotheses 非线性假设 神经网络实际上是一个相对古老的算法,但是后来沉寂了一段时间,不过现在,它又成为许多机器学习问题的首选技术. 为什么要研究神经网络? 这是一个监督 ...

  5. 机器学习-神经网络(Neural Network)算法

    学习彭亮<深度学习基础介绍:机器学习>课程 背景 以人脑中的神经网络为启发,最著名的算法是1980年的backpropagation 多层向前神经网络(Multilayer Feed-Fo ...

  6. 机器学习-神经网络为什么需要非线性(激活函数)

    引言 在学习机器学习的时候,我就一直有着一个疑惑.为什么神经网络需要激活函数(Activation Function)?可能有的人会说,引入激活函数是为了给网络引进非线性.但是有没有仔细思考过,引入非 ...

  7. 大数据----机器学习---神经网络

    1.神经网络与深度学习的发展历程: 2.神经网络与大脑神经元 神经网络的起源.结构.个体间的信息交互方式是以我们大脑神经元为模板的,我们的大脑神经元如下所示: 3.神经网络源头--M-P神经元模型 M ...

  8. 机器学习——神经网络(Neural Network)

    1.MP模型 Mp模型是最基础,最原始的神经网络模型.MP模型是1943年心理学家W.S.McCulloch和数理逻辑学家W.Pitts建立的.它的主要结构如图1所示. 图1 (来源于浙江大学胡浩基老 ...

  9. 深度学习-机器学习(神经网络的应用 上)

    1.用Python来实现神经网络: ************具体直接看代码**************** #神经网络算法(Neural Network) import numpy as npdef ...

  10. 吴恩达机器学习 -- 神经网络学习

    9.1 非线性假设 无论是线性回归还是逻辑回归都有这样一个缺点,即:当特征太多时,计算的负荷会非常大. 吴恩达老师举了一个例子: 当我们使用 的多次项式进行预测时,我们可以应用的很好. 之前课程学习过 ...

最新文章

  1. 实现一个悬浮在软键盘上的输入栏
  2. mysql外键_mysql系列之存储引擎
  3. RabbitMQ播放模块! 构架
  4. windows 下cmd命令行的替换工具cmder
  5. 扩展云存储边界,阿里云推出全球首个云定义存储产品
  6. GMaps.js:让你快速集成 Google Maps 服务的 jQuery 插件
  7. inno setup打包的安装包如何在卸载完程序后可以继续安装_这两个方法就够了!快速制作Python程序Windows安装包...
  8. 齿轮箱常见故障数据_齿轮箱故障分析和维护使用
  9. 修改tomcat服务器图标,如何更改tomcat图标
  10. Oracle在SQL语句中对时间操作、运算
  11. 常见的oracle面试题及答案,Oracle精选面试题(附答案及分析)
  12. 浅谈HTTP接口性能测试脚本的编写
  13. 系统规划与管理师历年论文
  14. python-qbittorrent+爬虫第二弹:爬取国内某bt站内容、分析页面,批量导入qbittorrent并下载归档
  15. ♥️Javascript之DOM♥️
  16. 1.文件字符流:什么是文件字符流???
  17. 使用随机文件流类RandomAccessFile将一个文本文件倒置读出
  18. idea 中ctrl+shift+数字的作用
  19. xwiki功能-皮肤
  20. 比程序员更好的职业_立即成为更好的程序员的20条技巧

热门文章

  1. 程序员应该坚持写博客
  2. 最速下降法matlab全局最小值_最速下降法+Matlab代码
  3. android 触摸屏 驱动 win10,win10系统触摸驱动安装方法教程
  4. 谷歌云服务器的ip是什么ip,看到有人在问谷歌云的IP段问题,我推荐几个自用觉得不错的...
  5. linux系统如何解压rar文件
  6. 小米笔记本适合计算机专业吗,真Pro还是假专业?细说小米新笔记本电脑五宗罪...
  7. aspectjweaver.jar包下载
  8. M5311连接HTTPS服务器下载bin文件(干货)
  9. matlab sbus,WIRIS Pro Sc科研级机载双摄热红外成像仪
  10. Awesome Mac :好用的Mac软件和教程