Pytorch是torch的python版本,是一款开源的神经网络框架,专门针对 GPU 加速的深度神经网络(DNN)编程。
在安装之前需先确定电脑是否含有Nvidia(英伟达显卡),以便安装正确的版本。打开任务管理器:

只有带NVIDIA的英伟达显卡的电脑才能安装GPU版本,否则其他的就只能安装CPU版本。
Anaconda是一个强大的开源数据科学平台,它将很多好的工具整合在一起,极大地简化了使用者的工作流程,并能够帮助使用者解决一系列数据科学难题。官方网站:Anaconda官网。

完成安装后需要手动配置环境变量,在系统环境变量Path中新建值(根据安装路径不同应自行调整,需注意最后一条路径以\结尾):
E:\anaconda3
E:\anaconda3\Library\bin
E:\anaconda3\Library\mingw-w64\bin
E:\anaconda3\Scripts\
在完成安装后使用命令行查看是否完成安装:
conda --version
python

此时可通过Anaconda Navifator进行打开:

使用conda安装python包时使用官方服务器位于国外,故可使用国内的清华镜像源,在Anaconda Prompt进行操作:
conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/
conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main/
//设置搜索时显示通道地址
conda config --set show_channel_urls yes
安装好的Anaconda会自带一个基础环境。但是我们后续的项目每一个需要的安装包不同,为了避免冲突,所以我们可以为每一个项目配置一个虚拟环境,这样就不相互打扰了。使用Anaconda Prompt创建虚拟环境:
conda env list
conda create –n torchProject python=3.8
conda env list:查看当前虚拟环境列表。conda create –n 虚拟环境名字 python=版本:创建指定Python版本的虚拟环境。查看已创建的虚拟环境:

使用任务管理器查看自己电脑GPU的型号:

进入官网安装最新的显卡驱动(可直接使用命令查看是否已安装驱动程序):

安装完后即可通过命令行查看电脑驱动的版本:
nvidia-smi

CUDA Driver版本就是12.0,表示的是驱动所能支持的最大运行API版本就是12.0。若要安装CUDA Runtime Version(运行版本),要保证CUDA Driver 版本 >= CUDA Runtime 版本,也就是12.0及以前的。
进入Pytorch官网:官网,若官网给出的版本符合电脑配置,复制指令到conda环境中运行即可 ,否则需自行寻找符合的版本:


激活虚拟环境并进行安装:
Pycharm官网: Pycharm官网
本机中安装路径为:E:\Pycharm,完成安装后即可新建项目编写代码:
回归问题:预测数值型的目标值,本质是寻找自变量和因变量之间的关系,以便能够预测新的、未知的数据点的输出值。例如,根据房屋的面积、位置等特征预测其价格(房价预测、股票价价格预测、温度预测等)。

其中,
x
x
x表示特征向量,而
y
y
y表示某一标签,即,通过特征对标签进行预测。
下图是小明每天学习的时间和最后考试的分数的数据。数据如下表所示,同时想知道小明假设学习4个小时最后考试会得多少分?

这是预测一个具体的数值的回归任务,将每日学习的时间和考试的得分用图画出来,大致可得出随着学习时间的增长,那么最后的考试的得分就会越高:

数据的输入只有一个,即为小明的学习时间,输出是考试的得分。因此可使用单特征线性模型进行预测,模型为:
f
(
x
)
=
w
x
+
b
f(x)=wx+b
f(x)=wx+b
此时的目的变为,求出最优的
w
、
b
w、b
w、b来表示输入与输出之间的关系,而最优指的即是输出的考试得分和真实的考试得分(也可以称为真实值或者标签)之间的差值越小越好,最好是0(显示生活中获取的数据存在噪声影响,数据之间的关系也存在一定误差,故而只能逼近0)。线性回归模型使用的损失函数即为上文中的均方误差函数:

此时问题转化为求出最优的
w
、
b
w、b
w、b来使得均方误差函数值最小。
此处采用最为原始的穷举法,即穷举
w
、
b
w、b
w、b的值并不断计算损失函数,使之最小:

可得出,当
w
=
2
、
b
=
0
w=2、b=0
w=2、b=0时,误差函数为零,此时最优。而在现实生活中,处理问题是很复杂的,往往输入的特征也是多个的,那么就意味着有多个
w
、
b
w、b
w、b来表达输入和输出之间的关系,利用穷举法找到最优的
w
w
w是不现实的,此时可使用最小二乘法、梯度下降法。
这里将梯度下降法运用到上例当中以求解参数
w
w
w的最优解,设置初始值
w
0
=
4
w_0=4
w0=4,超参数学习率为0.01,对损失函数进行求导:

更新参数的值:

经过100轮的梯度更新,
w
w
w逼近最优值2,画出梯度下降过程中损失函数的变化趋势:

因此梯度下降法可通过不断的计算梯度找到使损失最小的参数,而当数据的特征有多个时,就需要对损失函数求偏导并重复上述过程,即不断对参数进行迭代更新,直到损失函数趋于平稳不再下降。二维的损失函数变化趋势:

数据:

# 定义数据集
x_data = [1, 2, 3] # type:每日学习时间
y_data = [2, 4, 6] # type:考试得分
# 初始化参数w
w = 4 #type:初始化模型参数
#定义线性回归模型
def forword(x):
return x * w #返回预测值
#定义损失函数:使用均方误差函数
def loss(x_data, y_data):
costValue = 0 # type:损失误差
for x, y in zip(x_data, y_data):
y_pred = forword(x) #type:预测值
costValue += (y_pred - y) ** 2
return costValue / (len(x_data))
#定义梯度计算公式
def gradient(x_data, y_data):
grad = 0 #type:初始化梯度
for x, y in zip(x_data, y_data):
#(wx-y)^2对w求导后得:2x(wx-y)
grad += 2 * x * (w * x - y)
#除以len(x_data)后得到损失函数梯度值
return grad / len(x_data)
#使用梯度下降法更新参数
for epoch in range(100): #训练100轮
#计算损失函数
loss_value = loss(x_data, y_data)
#获取损失函数梯度
grad_value = gradient(x_data, y_data)
#利用梯度更新参数w,设置学习率为0.01
w = w - 0.01 * grad_value #初始w一般设大些才符合梯度下降法
print("学习轮次:", epoch, ",参数值:", w, ",损失函数:", loss_value)
print("100轮时得到w:", w, ",预测学习时间为4时,得分为:", forword(4))


逻辑回归模型一般用于二分类任务当中,事实上,逻辑回归其实是用回归的方法来做分类,其输出是一个在0-1之间的连续值,但人为设定一个阈值来使输出的值映射为一个类别。
s
i
g
m
o
i
d
sigmoid
sigmoid函数的定义如下:

其中,
e
e
e为欧拉常数,自变量
z
z
z可取任意值,函数值域为
(
0
,
1
)
(0,1)
(0,1),相当于将输入的自变量映射到了
0
1
0~1
0 1之间。正是由于
s
i
g
m
o
i
d
sigmoid
sigmoid函数的映射特性,使得可将其输出值作为事件发生的概率。设输入的数据特征为向量
x
x
x,不同特征有着对应的权重参数表示该数据特征的重要程度,使用向量
w
w
w表示,同时还有偏置参数
b
b
b,令:
z
=
w
0
x
0
+
w
1
x
1
+
.
.
.
+
w
n
x
n
+
b
等价于:
z
=
w
T
x
+
b
z=w_0 x_0+w_1x_1+...+w_nx_n+b\\ 等价于:z=w^Tx+b
z=w0x0+w1x1+...+wnxn+b等价于:z=wTx+b
将
z
z
z输入到逻辑回归模型中后,就可计算出该事件为正例的概率。因此,一个二分类问题预测结果为正例的表达式为:
p
(
y
=
1
∣
X
)
=
1
1
+
e
−
w
T
X
+
b
p(y=1|X)=\frac{ 1 }{ 1+e^{-w^TX+b} }
p(y=1∣X)=1+e−wTX+b1
即,二分类问题的最终结果只能为0或1,将特征数据输入逻辑回归模型预测结果为
y
ˉ
=
0.8
\bar{y}=0.8
yˉ=0.8(处于0~1),表示在输入特征数据的情况下,预测真实值为
y
=
1
y=1
y=1的概率为0.8,之后可通过设置相应阈值,当概率在某一范围内时就认为真实值为
y
=
1
y=1
y=1。
相应的,预测结果为反例的表达式为:

在计算过程中,需要考虑
y
=
1
、
y
=
0
y=1、y=0
y=1、y=0两种情况,使得计算变得复杂。此时可将上述两个公式合并在一起:

这就是逻辑回归模型公式。注意到,若真实值
y
=
1
y=1
y=1,则此时
P
(
y
=
1
∣
X
)
P(y=1|X)
P(y=1∣X)越接近1,就代表模型预测越准确,即希望上式值越大;而若真实值
y
=
0
y=0
y=0,则此时希望
P
(
y
=
0
∣
X
)
P(y=0|X)
P(y=0∣X)接近0,即
1
−
P
(
y
=
0
∣
X
)
1-P(y=0|X)
1−P(y=0∣X)越大代表模型预测越准确。综上,不管真实值为何值,都希望
P
(
y
∣
X
)
P(y|X)
P(y∣X)越大越好。
&emps; 利用逻辑回归模型可对输入的数据特征进行判断,并得出二分类的结果。但模型性能的好坏仍取决于模型中的参数向量
w
、
b
w、b
w、b,与线性回归思想一致,需要从提供的数据样本中不断学习(反向传播)来更新参数,使得预测结果与真实值接近。在上文中可知,希望
P
(
y
∣
X
)
P(y|X)
P(y∣X)越大越好,故将所有样本数据下概率的乘积作为逻辑回归损失函数:

其中:
p
(
1
∣
x
i
)
=
1
1
+
e
−
w
T
X
i
+
b
p(1|x_i)=\frac{ 1 }{ 1+e^{-w^TX_i+b} }
p(1∣xi)=1+e−wTXi+b1
一般将其写为以下形式:
p
(
1
∣
x
i
)
=
1
1
+
e
−
w
T
X
i
+
b
=
σ
(
w
T
X
i
+
b
)
p(1|x_i)=\frac{ 1 }{ 1+e^{-w^TX_i+b} }=σ(w^TX_i+b)
p(1∣xi)=1+e−wTXi+b1=σ(wTXi+b)
此时损失函数为:

连乘运算不便于求导,故通过对数函数将其转化为求和运算:

为便于理解(损失函数值越小一般代表误差越小),且与梯度下降法相结合,给原函数加上符号并取均值,得到了逻辑回归模型的损失函数——交叉熵损失函数:

与线性回归利用梯度下降法更新参数思路一致,设定求出损失函数梯度公式、设置参数初值、更新参数、计算损失函数,并重复该过程,直到满足迭代轮次或损失阈值。找到最合适的模型参数后,利用训练出来的参数就可以利用逻辑回归模型进行分类。
参数
w
w
w偏导数求解:

参数
b
b
b偏导数求解:



准确率(Accuracy):准确率,即,判断正确的概率,可作为评价模型性能的指标。计算模型的准确率:
A
C
C
=
T
P
+
T
N
T
P
+
T
N
+
F
P
+
F
N
=
90
%
ACC=\frac{TP+TN}{TP+TN+FP+FN}=90\%
ACC=TP+TN+FP+FNTP+TN=90%
模型准确率为
90
%
90\%
90%,但并不代表模型优秀,换一个角度看,共有10个肿瘤患者,但只有5个被成功预测,说明模型效果并不优秀。事实上,导致这一结果的原因是因为样本不均衡,因为正类和反类的数量相差太大,这使得即使认定所有样本都是正类,准确率也有
90
%
90\%
90%。此时就需要使用更多的指标评价模型性能。通俗来说,准确率就是:预测正确的结果占总样本的百分比。
精确率(Precision):精确率,又称查准率,指预测为正类的样本中有多少是真的正类样本,计算上述模型的精确率:
P
=
T
P
T
P
+
F
P
=
50
%
P=\frac{TP}{TP+FP}=50\%
P=TP+FPTP=50%
预测为正类的样本中只有
50
%
50\%
50%预测正确,可见模型对患有癌症的识别并不准确。
召回率(Recall):召回率,又称查全率,指样本中的正类有多少被正确预测,计算上述模型的召回率:
R
=
T
P
T
P
+
F
N
=
50
%
R=\frac{TP}{TP+FN}=50\%
R=TP+FNTP=50%
召回率分母与精确率不同。
F1分数
精确率与召回率仅分母不同,二者关系可使用P-R图表示:

评估模型时自然希望P、R越高越好,但在一些情况下二者是矛盾的。比如极端情况下,有100个正类样本,模型只预测了一个正类样本且预测正确,则此时
P
=
100
%
,
R
=
1
%
P=100\%,R=1\%
P=100%,R=1%,同样,有1个正类样本,模型预测了100个正类样本(其中只有一个预测正确),则此时
P
=
1
%
,
R
=
100
%
P=1\%,R=100\%
P=1%,R=100%。此时就需要综合考虑,最常见的方法就是使用
F
F
F分数:
F
=
(
α
2
+
1
)
P
∗
R
α
2
(
P
+
R
)
F=\frac{(α^2+1)P*R}{α^2(P+R)}
F=α2(P+R)(α2+1)P∗R
F分数是二者的加权调和平均,能同时综合进行考虑,通常取
α
=
1
α=1
α=1,即
F
1
F1
F1分数:
F
1
=
2
P
R
P
+
R
F1=\frac{2PR}{P+R}
F1=P+R2PR




神经网络(Neural Network,NN),是一种模仿生物神经网络的结构和功能的数学模型,用于对函数进行估计或近似。人脑可以看做是一个生物神经网络,由众多的神经元连接而成。当神经元“兴奋”时,就会向相连的神经元发送化学物质,从而改变这些神经元内的电位;如果某神经元的电位超过了一个“阈值”,那么它就会被激活,即“兴奋”起来,向其他神经元发送化学物质。
全连接神经网络,是指第 N 层的每个神经元和第 N-1 层的所有神经元相连,第 N-1 层神经元的输出就是第 N 层神经元的输入。整体结构由三部分组成:

通过输入层激活信号,再通过隐藏层提取特征,不同隐藏层神经单元对应不同输入层的神经单元权重和自身偏置均可能不同,输入层兴奋传递到隐藏层兴奋,最后输出层根据不同的隐藏层权重和自身偏置输出结果。举一个例子,目标是识别一个 4x3 的图像,下例中采用了12 神经节点来对应 4x3 个像素点(神经点属于隐藏层),在隐藏层中使用另外三个神经单元进行特征提取,最后输出层再使用两个神经节点标记识别结果是 0 或 1:


总之,模型的意义就在于找到最为合适的参数w、b,使得预测结果与真实情况最为接近。
神经网络本质是由多个神经单元组合而成,因此只要搞清楚神经元的本质就可以搞清楚全连接神经网络了。例如,一个全连接神经网络神经元的模型图:

x:各个输入的分量。b:偏置,用于控制神经元被激活的容易程度。w:各个信号的权重的参数,用于控制各个信号的重要性,可以是一个数、向量、矩阵等。h:激活函数。a:神经元的输出。可简写为:
a
=
h
(
w
T
x
+
b
)
a=h(w^{T}x+b)
a=h(wTx+b)
即,一个神经元的功能是求得输入向量与权向量的内积后,经一个非线性传递函数得到一个标量结果。
观察上述数学表达式发现,该式子只是将线性模型的输出结果经过一个激活函数的计算再输出,激活函数的种类有很多,但有着一定是非线性函数的共同特征。而若使用线性函数作为激活函数,则不管如何加深神经网络的层数,隐藏层再怎么多,总是存在与之等效的“无隐藏层的神经网络”。
激活函数有助于将神经元输出的值限制在我们要求的某个限制内。 因为激活函数的输入是W * x + b,其中W是单元的权重(Weight),x是输入,然后在其上加上b偏差(Bias)。 如果不限制在某个值上,则此值的变动范围会非常大,此时可使用激活函数将输出值限定在一个范围(常用0~1),来表示神经元的兴奋程度(0表静默,1表活跃)。并且,激活函数为神经网络引入了非线性的能力,其本身是有非线性性。
上文中提到,激活函数必须是非线性(即,不仅仅只有加法、数量乘法的运算)的,否则不管如何加深神经网络的层数,隐藏层再怎么多,总是存在与之等效的“无隐藏层的神经网络”。借鉴博客:机器学习-神经网络为什么需要非线性(激活函数)。
由上文可知,每一层的参数操作对应的函数表达式为
a
1
=
w
1
∗
x
+
b
1
a_1=w_1*x+b_1
a1=w1∗x+b1。将x用向量表示,而w相当于一个矩阵,此时二者乘积相当于是矩阵x列向量的线性组合:

此时对应神经网络仅含一层隐藏层,若将输出结果作为下一隐藏层的输入,并继续使用线性(仅含有加法、数量乘法运算)的激活函数,即
a
2
=
w
2
∗
a
1
+
b
2
a_2=w_2*a_1+b_2
a2=w2∗a1+b2,进行数学推导:

此时
a
2
a_2
a2相当于是一组新参数
w
′
、
b
′
w'、b'
w′、b′与输入向量
x
x
x运算得到,神经网络只含有一层隐藏层,即多层线性操作等价于一层线性操作。但真实世界有些原始数据本身就是线性不可分的,必须要对原始空间进行一定的非线性操作,比如上文中提及的限制输出范围,故而激活函数必须是非线性的,否则没有意义。
常见非线性函数有二次函数、分段函数、指数函数。
Sigmoid函数往往用于作为二分类问题输出层激活函数,输出值作为分类的概率,如,是种类A的概率为0.99,不是的概率为0.01。

梯度,是指某一函数在该点处的方向导数沿着该方向取得最大值,对于一维函数指的就是某一点处的导数。Sigmoid函数存在梯度消失(梯度变小并不断接近0,但不为0)、梯度爆炸(梯度快速变为极大值)的情况,但在实际中,梯度值期望是一个平稳值,即不大不小,此时方便求出对应的参数值。
注意,导数往往由于求出参数w、b,而参数即用于使输出结果最接近于真实情况。
Tanh函数的输出结果在(-1~1)之间,是一个对称的值域。

Tanh函数更容易收敛,是指相对于sigmoid函数,Tanh函数求出最佳参数所需的训练轮次更少,因为Tanh函数的导数在-1到1之间变化,具有较高的梯度(sigmoid函数最大梯度为0.25,而Tanh函数为1),有利于网络的快速训练。

ReLU函数解决了梯度消失的问题,因为当输入值小于0时导数值等于0,此时神经元死亡,以后面内容可知,在计算参数时会利用损失函数来反向传播优化参数w、b,而激活函数ReLU直接使得输出为0,此时不再出现损失,不会再优化参数w、b(神经元死亡指的即是,神经元的参数再也不会更新),也就解决了梯度消失问题。

无法为正负输入值提供一致的关系预测是指,正、负区间函数运算并不对称,使得对正负输入值的预测方式不同。
前向传播,是指将数据特征作为输入,输入到隐藏层,将数据特征和对应的权重相乘同时再和偏置进行求和,将计算的结果通过激活函数进行激活,将经过激活函数激活的函数输出值作为下一层神经网络层的输入再和对应的权重相乘同时和对应的偏置求和,再将计算的结果通过激活函数进行激活,不断重复上述的过程直到神经网络的输出层,最终得到神经网络的输出值。
简单来说,输入数据输入到神经网络并通过隐藏层进行运算,最后输出结果的过程,就是神经网络的前向传播。一个简单的神经网络:

隐藏层两个神经元的计算:
a
11
=
s
i
g
m
o
i
d
(
w
11
x
1
+
w
13
x
2
+
b
1
)
a
12
=
s
i
g
m
o
i
d
(
w
12
x
1
+
w
14
x
2
+
b
2
)
a_{11}=sigmoid(w_{11}x_1+w_{13}x_2+b_1)\\ a_{12}=sigmoid(w_{12}x_1+w_{14}x_2+b_2)
a11=sigmoid(w11x1+w13x2+b1)a12=sigmoid(w12x1+w14x2+b2)
传输层神经元的计算:
a
21
=
r
e
l
u
(
w
21
a
11
+
w
22
a
12
+
b
3
)
a_{21}=relu(w_{21}a_{11}+w_{22}a_{12}+b_3)
a21=relu(w21a11+w22a12+b3)
其中,
w
11
、
w
13
、
b
1
、
w
12
、
w
14
、
b
2
、
w
21
、
w
22
、
b
3
w_{11}、w_{13}、b_1、w_{12}、w_{14}、b_2、w_{21}、w_{22}、b_3
w11、w13、b1、w12、w14、b2、w21、w22、b3隐藏层对应输入的权重和偏置,训练模型的目的在于,找到一种方法可以求出准确的w和b,使得前向传播计算出来的y无限接近于真实情况。常见方法,如,梯度下降法,反向传播法就是梯度下降法在深度神经网络上的具体实现方式。
在模型确定后(本质是确定了一组参数),就希望训练结果接近于真实值,此时可设置损失函数来计算前向传播的输出值和真实的label值之间的损失误差,来对模型性能进行评估。目前常见的损失函数有均方误差、交叉熵误差。对于不同类型的问题,如:
对于不同类型的问题就有着不同的常用损失函数。
1.均方误差函数
&emsp在回归问题中使用较多的是均方误差函数:

其中,
f
(
x
i
)
、
y
i
f(x_i)、y_i
f(xi)、yi分别表示输入数据对应的前向传播输出值、真实值,均方误差函数求出所有误差的平方和,并除以
2
m
2m
2m,
m
m
m是输入数据的个数。事实上,是所有误差的平方和的平均值并除以2,除以2目的在于更好计算
J
(
x
)
J(x)
J(x)的导数,2的有无对模型性能的评估并无影响。

以上图为例(tain_loss,训练集损失函数图),在初始训练时(训练轮次较低),误差往往较大,而随着训练轮次的增加,模型参数的不断迭代使得误差不断降低(指针对训练集的误差),在
e
p
o
c
h
=
75
epoch=75
epoch=75左右时,误差接近0。
2.交叉熵函数
在分类问题中使用较多的是交叉熵函数:

事实上,模型训练的流程为,将数据输入模型并通过前向传播得到输出数据,利用损失函数计算输出数据与真实数据之间的误差,并利用反向传播更新参数(这一过程需使用梯度)使损失函数变低(神经网络的输出和真实值更加逼近),最后不断重复这一过程,直到损失函数接近于0。
但是实际项目中,由于数据中存在噪声,因此损失值在参数不断的更新下会不断接近0,但是不可能等于0,所以我们往常将模型的训练轮次和损失值变化画图显示出来,如果损失值在一定的轮次后趋于平缓不再下降,那么就认为模型的训练已经收敛了。例如:

上文中的反向传播,正是基于梯度下降法实现的。

梯度下降法正是基于此思想,只是从追求不同方向上最陡的山体梯度,变为追求如何修改参数可使损失函数值下降最快。反之,就是梯度上升法。需要注意的是,梯度下降法只是一种局部搜索优化算法,即它无法保证得到全局最优解。因此,有时需要运用其他优化算法来搜索全局最优解。

1.一元函数:模型仅有一个参数

函数
J
(
w
)
J(w)
J(w)即为损失函数,横坐标
w
w
w表示模型参数,问题转化为如何求出函数极小值处参数
w
w
w的值。
思路:在当前位置求偏导,即梯度,负梯度不断增大接近零的方向(
w
w
w的变化方向),就是不断逼近函数极小值的方向。有时得到的是函数最小值的局部最优解,如果损失函数是凸函数,梯度下降法得到的解就是全局最优解。
一元函数的梯度(导数)公式:

假设损失函数为
J
(
θ
)
J(θ)
J(θ),其中
θ
θ
θ是模型参数,从一个初始点
θ
0
θ_0
θ0开始迭代,每次迭代更新
θ
θ
θ的值,直至损失函数值下降到一定程度,或者达到固定次数的迭代次数。每次迭代的更新公式:

其中,
α
α
α是学习率,控制每一步迭代的步长。学习率太小会导致收敛速度慢,而学习率太大会导致算法发散。因此,学习率是梯度下降法中需要调整的一个超参数。
注意,超参数是指算法运行之前手动设置的参数,用于控制模型的行为和性能。这些超参数的选择会影响到模型的训练速度、收敛性、容量和泛化能力等方面,常见的超参数如学习率、迭代次数、正则化参数、隐藏层的神经元数量等。
2. 多元函数:模型含多个参数
对于不同参数
θ
i
θ_i
θi,其梯度定义为:

其中,函数
J
(
θ
)
J(θ)
J(θ)即为损失函数,此时每次迭代的更新公式为:

直至损失函数值下降到一定程度,或者达到固定次数的迭代次数时,算法终止。

初始误差(使用均方误差函数):
J
(
x
1
)
=
(
2
−
1.731
)
2
/
2
J(x_1)=(2-1.731)^2/2
J(x1)=(2−1.731)2/2




完成一轮更新后,损失函数的值更加逼近0,代表预测结果更加接近真实情况。
在完成上文的学习后,可大致梳理出模型训练的大致流程:
计算机视觉中深度学习算法几乎都用到了卷积神经网络来作为图像的特征提取。
1.灰度图
灰度图就是常见的黑白图像,以下是一个24*16的灰度图:

其中,每一个像素都有对应的像素值表示像素的强度,像素值大小范围为0~255,其中0表黑色,255表白色,因此在计算机中可使用数字矩阵表示该图像:

彩色图
在表示图像时有多种不同的颜色模型,最常见的是RGB模型。该模型是一种加法颜色模型,由三个数字矩阵表示三种原色(三原色模型中原色分别为红、绿、蓝),将三种原色混合在一起后就可用于表示广泛的颜色范围。例:


图像通道,指的是构成图像的多个单独的成分或层。每个通道代表图像的一种颜色或特定的信息,这些信息可以组合在一起形成完整的图像(可见通道理解为图像的特征)。当图像的形状加载到计算机中时,像素矩阵为H×W×3。其中H是整个高度上的像素数量,W是整个宽度上的像素数,3表示通道数。常见图像通道类型:

与全连接神经网络相比,卷积神经网络多了卷积层、池化层,输入卷积神经网络中的数据特征图通过卷积运算和池化运算,将其中的有效特征提取出来输入到全连接层,并对数据进行分类或者预测。其中,卷积层会改变输入特征图的通道数,如上图中输入单通道卷积运算后得到三通道图像(三通道图像指图像由三种特征进行表达,并非RGB图像),也可改变图像的大小,如从30x30x1变为24x24x3等其他功能。池化层则不会改变图像的通道数,但会改变图像的大小。
上图中利用卷积层、池化层不断改变通道数、图像大小后,将从图像提取的特征信息输入到全连接层,相当于输入到全连接神经网络当中,最后将结果通过输出层输出。之所以使用卷积神经网络,而不直接使用全连接神经网络处理图像,是因为直接顺序输入图像像素值(将像素数据拉平为一维),就失去了像素之间的空间信息,如下图中狗耳朵与狗头,直接输入像素值,就会丢失狗耳朵长在狗头上的空间特征:

事实上,像图像这样的3维形状的数据中应该含有重要的空间信息。比如,空间上相邻的地方像素值应该是相似的值、RGB通道之间分别有着密切的关联性,但是相距比较远的像素之间的关联性比较低。但是全连接层会忽视形状,将全部的信息作为相同的神经元处理,因此无法利用与形状相关的信息。而卷积神经网络中的卷积层可以保持形状不变,当输入的数据是图像的时候,卷积层会以3维的数据形式接受数据,同样以3维的形式输出到下一层,因此相对于全连接神经网络,卷积神经网络可以比较好的理解空间形状的数据。
卷积神经网络的核心就是存在卷积运算的卷积层,卷积运算相当于图像处理中的滤波运算,因此卷积核又被称之为滤波器。计算过程如下,其中卷积核的数值可理解为 w i w_i wi:

在全连接神经网络中,神经网络有两种参数,一种是权重参数、一种是偏置参数。在卷积神经网络中,卷积核就是卷积神经网络网络的权重参数,当然卷积神经网络中也是存在偏置参数的。如图所示,偏置参数的形状通常是一个1x1的卷积核,这个偏置的参数值会被加到通过卷积运算的所有元素上。具体如图所示:

可注意到,卷积神经网络与全连接神经网络不同,前者实现了权重共享,即卷积核中的参数并不会只针对某一像素值,而是在卷积核移动过程中与所有像素值进行运算。权重共享使得卷积神经网络参数量远少于全连接神经网络,减少过拟合的发生(参数越多,越容易引入噪声特征,越容易发生过拟合)。
在应用多层卷积时,我们常常丢失边缘像素。由于我们通常使用小卷积核,因此对于任何单个卷积,我们可能只会丢失几个像素。但随着我们应用许多连续卷积层,累积丢失的像素数就多了。解决这个问题的简单方法即为填充(padding):在输入图像的边界填充元素(通常填充元素是
0
0
0)。

使用填充的主要目的是调整输出数据的大小。比如,输入的数据大小为(3,3),卷积核的大小为(2,2),进行卷积运算得出的输出数据大小为(2,2);当对输入数据进行幅度为1的填充,此时输入的数据的大小为(5,5),经过卷积运算输出的数据大小就为(4,4)。如果不填充数据的话,输入数据大小为(3,3),输出数据大小为(2,2),相当于输出数据比输入数据大小缩小了1个元素,如果在一个卷积神经网络中有多个卷积层,需要进行多次的卷积运算,如果每次进行卷积运算都会缩小空间,那么在某个时刻可能输出的大小为(1,1),这时候就无法进行卷积运算了。因此为了避免这样的情况,利用填充操作可以解决上述出现的问题,保持输出数据的空间大小不变或者变大。
利用卷积核在输入数据上进行滑动的间隔称为步幅。上述的所有例子中的步幅都是1,这里的步幅是可以设置的,和填充的幅度一样,可以设置为大于1的整数。如下图,当步幅为2的时候进行的卷积运算的运算结果如图所示:

如上图所示,输入数据大小为(4,4),卷积核的大小为(2,2),数据填充为0,步幅的大小为2。设置步幅大小可用于高效计算或是缩减采样次数(如高分别率图像中往往存在过多冗余的像素),卷积窗口可以跳过中间位置,每次滑动多个元素。假设输入大小为(H,W),卷积核大小为(FH,FW),输出数据的大小为(OH,OW),填充为P,步幅S,则有如下公式:

上图中案例即为:

在上文的一通道图像中,往往可设置多个卷积核进行卷积操作,从而提取图像的不同特征信息。对于多通道图像,仍然可以设置多通道的卷积核进行特征提取,原理是利用多个卷积核分别对输入数据的各个通道进行卷积操作,然后将各个通道的卷积结果相加得到最终的输出。这样就可以同时提取输入数据各个通道的特征,并将它们有效地组合起来。以三通道图为例:

与单通道卷积运算相比,此处多了将不同通道的卷积运算结果进行相加,因此最终输出的特征图通道大小为1,形状为(2,2),即,经过卷积层操作后,特征图的通道数发生改变。
池化层是缩小特征图空间的运算,池化层和卷积层的不同是,特征图是需要和卷积核进行卷积运算,因此卷积层是有需要进行参数的学习的,通过前向传播确定误差,再通过反向传播进行参数的更新,从而确定最佳的卷积核与偏置值。但是池化层只是从目标区域中提取最大值或者平均值,所以是没有需要学习的参数的。
池化层一般用于在目标区域中提取像素的最大值,或者计算平均值,分别对应最大池化和平均池化两种操作。其中,最大池化是将输入的图像划分为若干个矩形区域,对每个子区域输出最大值。直觉上,这种机制能够有效地原因在于,在发现一个特征之后,它的精确位置远不及它和其他特征的相对位置的关系重要。池化层会不断地减小数据的空间大小,因此参数的数量和计算量也会下降,这在一定程度上也控制了过拟合。通常来说,CNN的卷积层之间都会周期性地插入池化层。

池化层的步幅大小一般和池化的窗口大小一样,比如该样例中的池化窗口大小为(2,2),那么此时的步幅就设定为2,通过不断的计算一个(4,4)大小的特征图最终转变成(2,2)的计算图。当然池化层的输入特征图和输出特征图之间的关系也可以利用上述的卷积层的输入输出计算公式来计算,只不过卷积核大小变成池化窗口大小而已。
