目录
- 一、神经网络
- 1.1、模型训练
- 1.2、损失函数
- 1.2.1、分类:hinge loss/合页损失/支持向量机损失
- 1.2.2、分类:交叉熵损失(softmax分类器)
- 1.2.2.1 二分类交叉熵损失
- 1.2.2.2 多分类交叉熵损失
- 1.2.3、回归:误差平方和(SSE)、均方误差 (MSE)
- 1.3、激活函数
- 1.3.1 Sigmoid函数
- 1.3.2.Tanh (双曲正切)
- 1.3.3 ReLu函数
- 1.3.4 Leaky ReLu
- 二、神经网络案例
一、神经网络
1.1、模型训练
模型训练的目标:求解一组最适合的权重向量w,令神经网络的输出结果与真实值尽量接近。
模型训练的流程:定义基本模型——定义损失函数——定义优化算法——以最小化损失函数为目标,求解权重
1.2、损失函数
在训练神经网络时,我们需要定义一个评估指标,用来衡量模型预测结果与真实结果之间的差异。这个指标通常称为“损失函数”。具体来说,损失函数的值越小,表示模型的预测结果越接近真实值,说明模型在当前数据集上的表现较好,权重参数也相对优秀;相反,如果损失函数的值较大,说明模型的预测结果与真实值之间存在较大偏差,模型的性能较差,权重参数也需要调整和优化。
在训练神经网络时,我们的目标是使得损失函数L(w)尽可能小,因此问题转化为求解损失函数L(w)最小值对应的自变量w,即寻找最优的权重参数w。为了方便求解,我们通常将损失函数L(w)转变成凸函数,因为在凸函数中,最小值是唯一的,且容易找到。在凸函数上寻找损失函数的最小值时,常用的优化算法是梯度下降算法。梯度下降通过迭代更新参数w,沿着损失函数的负梯度方向逐步找到最小值,从而实现模型参数的优化。梯度下降及其变种(如随机梯度下降、批量梯度下降)被广泛应用于深度学习模型的训练过程中。常见的损失函数如下:
1.2.1、分类:hinge loss/合页损失/支持向量机损失
Hinge Loss(合页损失)是一种常用的损失函数,主要用于支持向量机等模型中,特别是在二分类问题中。它的主要目的是确保正确类别的分数与错误类别的最高分之间的差异达到一个固定的边界,从而促使模型学会产生更大的间隔,提高模型的泛化能力。
对于训练集中的第 i 张图片数据
x
i
x_i
xi,在 w下会有一个得分结果向量
f
(
x
i
,
w
)
f(x_i,w)
f(xi,w),第 j 类的得分为我们记作
f
(
x
i
,
w
)
j
f(x_i,w)_j
f(xi,w)j,则在该样本上的损失我们由下列公式计算得到:
L
i
=
∑
j
≠
y
i
max
(
0
,
f
(
x
i
,
w
)
j
−
f
(
x
i
,
w
)
y
i
+
Δ
)
L_i = \sum_{j \neq y_i} \max(0, f(x_i, w)_j - f(x_i, w)_{y_i} + \Delta)
Li=j=yi∑max(0,f(xi,w)j−f(xi,w)yi+Δ)
假如现在有三个类别,而得分函数计算某张图片的得分为
f
(
i
,
w
)
f(i,w)
f(i,w)=[13,-7,11],而实际的结果是第一类(
y
i
y_i
yi= 0)。假设
Δ
\Delta
Δ= 10。遍历错误类别(
j
≠
y
j≠y
j=y),求值加和:
L
i
=
m
a
x
(
0
,
−
7
−
13
+
10
)
+
m
a
x
(
0
,
11
−
13
+
10
)
=
8
L_i=max(0,-7-13+10)+max(0,11-13+10)=8
Li=max(0,−7−13+10)+max(0,11−13+10)=8
加入正则项
求和的两个参数:
j
j
j表示非正确类别;
i
i
i表示样本,共
N
N
N个。
1.2.2、分类:交叉熵损失(softmax分类器)
1.2.2.1 二分类交叉熵损失
二分类交叉熵损失函数,也称为对数损失,是由极大似然估计推导而来的,常用于二分类任务中衡量模型预测与真实标签之间的差异。对于包含
m
m
m个样本的数据集,其在所有样本上的平均损失可以表示为:
L
(
w
)
=
−
∑
i
=
1
m
(
y
i
⋅
ln
(
σ
i
)
+
(
1
−
y
i
)
⋅
ln
(
1
−
σ
i
)
)
L(w) = -\sum_{i=1}^{m} \left( y_i \cdot \ln(\sigma_i) + (1 - y_i) \cdot \ln(1 - \sigma_i) \right)
L(w)=−i=1∑m(yi⋅ln(σi)+(1−yi)⋅ln(1−σi))
y
i
y_i
yi:第
i
i
i个样本的真实标签(0 或 1)
σ
i
\sigma_i
σi:第
i
i
i个样本的预测概率(模型输出的 sigmoid 值)
m
m
m:样本的总数
w
w
w:表示求解出来的一组权重(在等号的右侧,
w
w
w在
σ
\sigma
σ 里)
在单个样本的损失:
L
(
w
)
i
=
−
(
y
i
⋅
ln
(
σ
i
)
+
(
1
−
y
i
)
⋅
ln
(
1
−
σ
i
)
)
L(w)_i = -\left( y_i \cdot \ln(\sigma_i) + (1 - y_i) \cdot \ln(1 - \sigma_i) \right)
L(w)i=−(yi⋅ln(σi)+(1−yi)⋅ln(1−σi))
- 1、极大似然估计求解二分类交叉熵损失
(1)构建对数似然函数
二分类神经网络的标签是[0,1],此标签服从伯努利分布(即0-1分布),因此可得:样本 i i i在由特征向量 x i x_i xi和权重向量 w w w组成的预测函数中,样本标签被预测为1的概率为:
P 1 = P ( y ^ i = 1 ∣ x i , w ) = σ P_1 = P(\hat{y}_i = 1 \mid x_i, \boldsymbol{w}) = \sigma P1=P(y^i=1∣xi,w)=σ
对二分类而言, σ \sigma σ就是sigmoid函数的结果。
样本 i i i在由特征向量 x i x_i xi和权重向量 w w w组成的预测函数中,样本标签被预测为0的概率为:
P 0 = P ( y ^ i = 0 ∣ x i , w ) = 1 − σ P_0 = P(\hat{y}_i = 0 \mid x_i, \boldsymbol{w}) = 1- \sigma P0=P(y^i=0∣xi,w)=1−σ
将两种取值的概率整合,我们可以定义如下等式:
P ( y ^ i ∣ x i , w ) = P 1 y i ⋅ P 0 1 − y i P(\hat{y}_i \mid \boldsymbol{x}_i, \boldsymbol{w}) = P_1^{y_i} \cdot P_0^{1 - y_i} P(y^i∣xi,w)=P1yi⋅P01−yi
P ( y ^ i ∣ x i , w ) P(\hat{y}_i \mid \boldsymbol{x}_i, \boldsymbol{w}) P(y^i∣xi,w)是对单个样本i而言的函数,对一个训练集的m个样本来说,我们可以定义如下等式来表达所有样本在特征张量 x x x和权重向量 w w w组成的预测函数中,预测出所有可能的 y ^ \hat{y} y^的概率 p p p为:
p = ∏ i = 1 m ( σ i y i ⋅ ( 1 − σ i ) 1 − y i ) p=\prod_{i=1}^{m} \left( \sigma_i^{y_i} \cdot (1 - \sigma_i)^{1 - y_i} \right) p=i=1∏m(σiyi⋅(1−σi)1−yi)
这个函数就是逻辑回归的似然函数。对该概率P取以e为底的对数:
l n p = l n ∏ i = 1 m ( σ i y i ⋅ ( 1 − σ i ) 1 − y i ) = ∑ i = 1 m ( y i ⋅ ln ( σ i ) + ( 1 − y i ) ⋅ ln ( 1 − σ i ) ) lnp=ln \prod_{i=1}^{m} \left( \sigma_i^{y_i} \cdot (1 - \sigma_i)^{1 - y_i} \right) =\sum_{i=1}^{m} \left( y_i \cdot \ln(\sigma_i) + (1 - y_i) \cdot \ln(1 - \sigma_i) \right) lnp=lni=1∏m(σiyi⋅(1−σi)1−yi)=i=1∑m(yi⋅ln(σi)+(1−yi)⋅ln(1−σi))
这就是我们的二分类交叉熵函数。为了数学上的便利以及更好地定义”损失”的含义,我们希望将极大值问题转换为极小值问题,因此我们对 l n p lnp lnp取负,并且让权重 w w w作为函数的自变量,就得到了我们的损失函数 L ( w ) L(w) L(w) :
L ( w ) = − ∑ i = 1 m ( y i ⋅ ln ( σ i ) + ( 1 − y i ) ⋅ ln ( 1 − σ i ) ) L(w) = -\sum_{i=1}^{m} \left( y_i \cdot \ln(\sigma_i) + (1 - y_i) \cdot \ln(1 - \sigma_i) \right) L(w)=−i=1∑m(yi⋅ln(σi)+(1−yi)⋅ln(1−σi))
在极大似然估计中,我们只要在对数似然函数上对权重 w w w求导,再令导数为0,就可以求解出最合适的 w w w。
(2)用tensor实现二分类交叉熵损失
import torch
import time
N=3*pow(10,3)
torch.random.manual_seed(12)
X=torch.rand((N,4),dtype=torch.float32)
w=torch.rand((4,1),dtype=torch.float32,requires_grad=True)
y=torch.randint(low=0,high=2,size=(N,1),dtype=torch.float32)
zhat=torch.mm(X,w)
sigma=torch.sigmoid(zhat)
loss=-(1/N)*torch.sum((1-y)*torch.log(1-sigma)+y*torch.log(sigma))
loss #输出tensor(0.7403, grad_fn=<MulBackward0>)
#注意,在写损失函数这样的复杂函数时,除了普通的加减乘除以外的全部计算,都要使用torch中的函数,因为tensor的运算速度是远远超过普通Python代码
(3)用PyTorch中的类实现二分类交叉熵损失
对于二分类交叉熵损失,nn提供了两个类:BCEWithLogitsLoss以及BCELoss。BCEWithLogitsLoss内置了sigmoid函数与交叉熵函数,它会自动计算输入值的sigmoid值,因此需要输入zhat与真实标签,且顺序不能变化,zhat必须在前。BCELoss中只有交叉熵函数,没有sigmoid层,因此需要输入sigmoid与真实标签,且顺序不能变化。同时,这两个函数都要求预测值与真实标签的数据类型以及结构必须相同。
import torch.nn as nn
#调用nn模块下的类
criterion=nn.BCELoss() #实例化
loss=criterion(sigma,y)
# loss
criterion1=nn.BCEWithLogitsLoss() #实例化
loss1=criterion1(zhat,y)
loss1 #输出tensor(0.7403, grad_fn=<BinaryCrossEntropyWithLogitsBackward0>)
两个类的结果是一致的。根据PyTorch官方的公告,更推荐使用BCEWithLogitsLoss这个内置了sigmoid函数的类。内置的sigmoid函数可以让精度问题被缩小(因为将指数运算包含在了内部),以维持算法运行时的稳定性,即是说当数据量变大、数据本身也变大时,BCELoss类产生的结果可能有精度问题。所以,当我们的输出层使用sigmoid函数时,我们就可以使用BCEWithLogitsLoss作为损失函数。
criterion2 = nn.BCEWithLogitsLoss(reduction = "mean") #sum、none
loss = criterion2(zhat,y)
loss
与MSELoss相同,二分类交叉熵的类们也有参数reduction,默认是”mean“,表示求解所有样本平均的损失,也可换为”sum”,要求输出整体的损失。以及,还可以使用选项“none”,表示不对损失结果做任何聚合运算,直接输出每个样本对应的损失矩阵。
1.2.2.2 多分类交叉熵损失
交叉熵损失函数(Cross-Entropy Loss)是分类问题中常用的损失函数,主要用于衡量模型预测概率分布与真实概率分布之间的差异。在机器学习和深度学习中,交叉熵损失函数常用于多类别分类问题,其目标是最小化损失函数,从而优化模型预测的准确性。
对于训练集中的第
i
i
i张图片数据
x
i
x_i
xi,在
w
w
w下会有一个得分结果向量
f
y
i
f_{y_i}
fyi,则损失函数记作:
L
i
=
−
log
(
e
f
y
i
∑
j
e
f
j
)
L_i = -\log \left( \frac{e^{f_{y_i}}}{\sum_j e^{f_j}} \right)
Li=−log(∑jefjefyi)
假设实际的结果是第二类(
y
i
y_i
yi= 2),求出Hinge Loss损失为1.58,交叉熵损失为1.04。
调用logsoftmax和NLLLoss实现
import torch
import torch.nn as nn
N=3*pow(10,2)
torch.random.manual_seed(12)
X=torch.rand((N,4),dtype=torch.float32)
w=torch.rand((4,3),dtype=torch.float32,requires_grad=True)
y=torch.randint(low=0,high=3,size=(N,),dtype=torch.float32)
zhat=torch.mm(X,w)
#调用softmax和NLLLoss
logsm=nn.LogSoftmax(dim=1) #实例化
logsigma=logsm(zhat)
criterion=nn.NLLLoss() #实例化
#由于交叉熵损失需要将标签转化为独热形式,因此不接受浮点数作为标签的输入,对NLLLoss而言,需要输入logsigma
criterion(logsigma,y.long()) #输出tensor(1.1455, grad_fn=<NllLossBackward0>)
直接调用CrossEntropyLoss
import torch
import torch.nn as nn
N=3*pow(10,2)
torch.random.manual_seed(12)
X=torch.rand((N,4),dtype=torch.float32)
w=torch.rand((4,3),dtype=torch.float32,requires_grad=True)
y=torch.randint(low=0,high=3,size=(N,),dtype=torch.float32)
zhat=torch.mm(X,w)
criterion=nn.CrossEntropyLoss() #,CrossEntropyLoss也有参数reduction,可以设置为mean、sum以及None,
#对打包好的CrossEntropyLoss而言,只需要输入zhat
criterion(zhat,y.long()) #输出tensor(1.1455, grad_fn=<NllLossBackward0>)
无论是二分类还是多分类,PyTorch都提供了包含输出层激活函数和 不包含输出层激活函数的类两种选择。在实际神经网络建模中,类可以被放入定义好的Model类中去构建神经网络的结构,因此是否包含激活函数,就需要由用户来自行选择。
1.2.3、回归:误差平方和(SSE)、均方误差 (MSE)
对于回归类神经网络而言,最常见的损失函数是
S
S
E
SSE
SSE和
M
S
E
MSE
MSE:
S
S
E
=
∑
i
=
1
n
(
y
i
−
y
^
i
)
2
M
S
E
=
1
n
∑
i
=
1
n
(
y
i
−
y
^
i
)
2
SSE = \sum_{i=1}^{n} (y_i - \hat{y}_i)^2 \qquad MSE = \frac{1}{n} \sum_{i=1}^{n} (y_i - \hat{y}_i)^2
SSE=i=1∑n(yi−y^i)2MSE=n1i=1∑n(yi−y^i)2
y
i
y_i
yi:第
i
i
i个观测值的实际值
y
^
i
\hat{y}_i
y^i:第
i
i
i个观测值的预测值
n
n
n:观测值的总数
在PyTorch中,我们可以简单通过以下代码调用MSE:
import torch
from torch.nn import MSELoss #类
y = torch.randn(size=(50,),dtype=torch.float32)
yhat= torch.randn(size=(50,),dtype=torch.float32)
criterion=MSELoss()
loss=criterion(yhat,y)
loss
#在MSELoss中有重要的参数reduction,当reduction="mean"(默认也是mean),则输出MSE;reduction=‘sum’,则输出SSE
criterion=MSELoss(reduction="mean")
loss1=criterion(yhat,y)
criterion=MSELoss(reduction="sum")
loss2=criterion(yhat,y)
print(loss,loss1,loss2) #输出:tensor(2.5836) tensor(2.5836) tensor(129.1810)
1.3、激活函数
引入激活函数目的:如果没有激活函数,多层神经网络等价于单层线性变换(无论叠加多少层,输出都是输入的线性组合)。引入激活函数使网络能够拟合非线性关系,使特征得到更加丰富的表达。。
1.3.1 Sigmoid函数
函数输出范围在(0,1)。函数的导数=f(x)(1-f(x)),特性较好。
梯度消失问题:当输入值非常大或非常小时,梯度接近零,导致梯度下降过程中的学习变慢。
Sigmoid 函数的输出始终为((0, 1) 区间),这可能导致梯度下降过程中出现效率低下的情况。
应用场景:主要用于二分类问题(如逻辑回归模型中的输出层)。
1.3.2.Tanh (双曲正切)
输出范围 (-1, 1),因此它的均值接近零,这可以避免梯度消失问题(当输入的值过大或过小时,梯度会变得非常小,仍然存在梯度消失问题)。比 Sigmoid 更好,输出值在零点附近对称,通常在优化时表现得更好。
应用场景:常用于循环神经网络 (RNN) 和其他需要处理时间序列数据的任务中。
1.3.3 ReLu函数
最受欢迎的激活函数是修正线性单元(ReLU),因为它实现起来简单,同时在各种预测任务中表现良好。ReLU提供了一种非常简单的非线性变换。给定元素x,ReLU函数被定义为该元素与0中的最大值:
ReLU(x)=max(x,0)
通俗地说,ReLU函数通过将相应的激活值设为0,仅保留正元素并丢弃所有负元素。输出范围是 [0, ∞),当输入大于 0 时,ReLU 输出输入值本身;当输入小于 0 时,ReLU 输出 0。
由于 ReLU 激活函数的输出始终非负,它在反向传播时不会遇到梯度消失问题,通常能够加速训练过程。
稀疏激活:ReLU 会导致部分神经元的输出为 0,进而在某些情况下产生稀疏激活。
死神经元问题:对于负输入,ReLU 输出始终为 0,这意味着某些神经元可能永远不会被激活,从而导致“死神经元”问题。
应用场景:常用于卷积神经网络 CNN 和深度前馈网络 DNN中,是最常用的激活函数。
1.3.4 Leaky ReLu
Leaky ReLU 是对传统 ReLU 激活函数的一种改进,旨在解决 ReLU 激活函数的“死神经元”问题。
当输入值 x>0 时,Leaky ReLU 的输出和输入相同,保持线性。
当输入值x≤0 时,输出值是输入的负值部分按比例缩小,具体的比例由 α 控制(一般是一个小于 1 的值)。
避免死神经元:在传统的 ReLU 激活函数中,当输入为负时,ReLU 输出总是 0,这可能导致神经元永远不会被激活,无法参与训练,形成“死神经元”问题。而 Leaky ReLU 通过给负输入值一个小的负斜率(αx)来避免这个问题。
避免梯度消失:相对于 Sigmoid 和 Tanh,Leaky ReLU 在大部分区域都有稳定的梯度,尤其在正区间,梯度是恒定的,因此它能够有效避免梯度消失问题,并加速神经网络的训练。
计算效率高:Leaky ReLU 继承了 ReLU 的计算效率高的特点,因为它只包含简单的数学操作(加法、乘法),并且对计算资源的需求较低。
可能会引入一些不必要的负值:如果 α 过大,可能会导致网络训练不稳定,甚至影响模型的性能。因此,需要合适地选择 α 值。
没有解决全局最优问题:虽然 Leaky ReLU 在局部避免了死神经元问题,但并不能从根本上解决网络的全局优化问题,特别是在网络较深的情况下,可能仍然会遇到梯度爆炸或梯度消失的风险。
应用场景:深度神经网络: Leaky ReLU 被广泛应用于各种深度神经网络(DNN),因为它能够加速训练并防止死神经元问题,特别是在层数较深时尤为重要。卷积神经网络 (CNN): 在卷积神经网络中,Leaky ReLU 常常被用作卷积层和全连接层的激活函数,尤其在需要处理大量数据和复杂特征时。生成对抗网络 (GANs): 生成对抗网络中的生成器和判别器常常使用 Leaky ReLU 来避免死神经元现象,并提升训练效果。
二、神经网络案例
Fashion-MNIST 数据集是一个用于机器学习和计算机视觉任务的流行数据集,通常用于替代经典的 MNIST 手写数字数据集。包含 10 个类别的时尚单品图像,每个类别有 7,000 张灰度图像。10 个类别分别为:T-shirt/top(T恤/上衣)、Trouser(裤子)、Pullover(套头衫)、Dress(连衣裙)、Coat(外套)、Sandal(凉鞋)、Shirt(衬衫)、Sneaker(运动鞋)、Bag(包)、Ankle boot(短靴),每张图像为 28x28 像素的灰度图像。神经网络算法流程:
1 、初始化参数
设置步长lr,动量值gamma,迭代次数epochs,batch_size等信息,(如果需要)设置初始权重
w
0
w_0
w0
2、数据准备
导入数据,并进行预处理(如归一化、标准化);将数据切分成batches,以便分批处理
3、定义神经网络架构
设计网络结构,包括输入层、隐藏层和输出层。
选择激活函数(如 ReLU、Sigmoid、Tanh)。
4、定义损失函数
选择损失函数L(w),(如均方误差 MSE、交叉熵损失 Cross-Entropy Loss)。
(可选)调整损失函数为凸函数,以便求解最小值
5、定义优化算法
选择优化器(如 SGD、Adam、RMSprop)
配置优化器参数(如学习率、动量)。
6、训练模型
在epoches和batch上循环,执行以下步骤:
6.1)调整数据结构:确保数据格式与网络输入匹配。
6.2)前向传播:计算网络输出,并计算初始损失值,“正向传播”求损失。
6.3)反向传播:在损失函数L(w)对每个权重w的偏导数(梯度),“反向传播”回传误差,根据误差信号修正每层的权重。
6.4)更新权重:使用优化算法迭代更新权重。
6.5)清空梯度:将当前梯度清零,为下一轮计算做准备。
6.6)监控进度:记录并监控模型训练进度和效果(如损失值、准确率)。
7、输出结果
保存训练好的模型;评估模型性能(如测试集准确率、混淆矩阵);(可选)可视化训练过程(如损失曲线、准确率曲线)。
import torch
from torch import nn
from torch import optim
from torch.nn import functional as F
from torch.utils.data import DataLoader,TensorDataset
import torchvision
import torchvision.transforms as transforms
#1.1、确定数据、超参数
lr=0.15
gamma=0.8
epochs=10
bs=128
# 1.2实例化数据
mnist=torchvision.datasets.FashionMNIST(root='D:\MINST-FASHION数据集', #运行根目录
download=False,#是否下载数据
train=True, #训练数据集
transform=transforms.ToTensor()) #数据转换tensor
batchdata=DataLoader(mnist,
batch_size=bs,
shuffle=True)
input_=mnist.data[0].numel() #请问这个张量中总共有多少元素?28*28
output_=len(mnist.targets.unique())
#1.3 定义神经网络框架
class Model(nn.Module):
def __init__(self,in_features=10,out_features=2):
super().__init__()
self.linear1=nn.Linear(in_features,128,bias=False)
self.output=nn.Linear(128,out_features,bias=False)
def forward(self,x):
x=x.view(-1,28*28)#需要对数据结构进行一个改变-1作为占位符,表示请pytorch帮忙自动计算-1这个位置维度应该是多少
sigma1=torch.relu(self.linear1(x))
sigma2=F.log_softmax(self.output(sigma1),dim=1)
return sigma2
#1.4 定义训练函数(损失函数、优化算法)
def fit(net,bacthdata,lr=0.01, epochs=5, gamma = 0):
criterion = nn.NLLLoss()
opt = optim.SGD(net.parameters(),lr=lr,momentum = gamma)
correct = 0 #循环开始之前,预测正确的值为0
samples = 0 #循环开始之前,模型一个样本都没有见过
for epoch in range(epochs): #全数据被训练几次
for batch_idx,(x,y) in enumerate(batchdata):
y = y.view(x.shape[0]) #降维
sigma = net.forward(x) #正向传播
loss = criterion(sigma,y)
loss.backward()
opt.step()
opt.zero_grad()
#求解准确率,全部判断正确的样本数量/已经看过的总样本量
yhat = torch.max(sigma, 1)[1] #torch.max函数结果中的索引为1的部分
correct += torch.sum(yhat == y)
samples += x.shape[0]
#每训练一个batch的数据,模型见过的数据就会增加x.shape[0]
if (batch_idx + 1) % 125 == 0 or batch_idx == len(batchdata)-1: #每N个batch我就打印一次
print("Epoch{}:[{}/{}({:.0f}%)],Loss:{:.6f},Accuracy:{:.3f}".format(
epoch+1
,samples
,epochs*len(batchdata.dataset)
,100*samples/(epochs*len(batchdata.dataset))
,loss.data.item()
,float(100*correct/samples)
))
#分子代表:已经查看过的数据有多少
#分母代表:在现有的epochs设置,模型一共需要查看多少数据
#1.5 输出结果
torch.manual_seed(1412)
net = Model(in_features=input_, out_features=output_)
fit(net,batchdata,lr=lr,epochs=epochs,gamma=gamma)