pytorch的 model.eval()和model.train()作用
pytorch中model.train()和model.eval()的区别主要在于Batch Normalization和Dropout两层。
model.eval():认为停止Batch Normalization的均值和方差统计,否则,即使不训练,因为有输入数据,BN的均值和方差也会改变。Dropout关闭,所有神经元都参与计算。
model.train():Batch Normalization的均值和方差统计开启,使得网络用到每一批数据的均值和方差,Dropout功能开启,定义好模型后,默认是model.train()模式。
torch.no_grad()用于停止autograd模块的工作,以起到加速和节省显存的作用,也就是不保存计算图,默认是保存的。
pytorch的模型搭建与训练流程
step1, 创建模型类,初始化模型的网络结构,在这里给出模型有哪几个模块的定义。
def forward()是pytorch模型类必有函数,用来定义模型的数据流,数据的输出从这里进入,逐级到最后一层,返回模型的输出。
# 搭建神经网络
class myModel(nn.Module):
def __init__(self) -> None:
super().__init__()
self.model = nn.Sequential(
nn.Conv2d(3, 32, 5, 1, 2),
nn.Dropout(p=0.6),
nn.MaxPool2d(2),
nn.Conv2d(32, 32, 5, 1, 2),
nn.Dropout(p=0.6),
nn.MaxPool2d(2),
nn.Conv2d(32, 64, 5, 1, 2),
nn.Dropout(p=0.6),
nn.MaxPool2d(2),
nn.Flatten(),
nn.Linear(64*4*4, 64),
nn.Linear(64, 10)
)
def forward(self, input):
input = self.model(input)
return input
step2, 模型的训练,训练优化器的选择
模型结构已经构建好了,接下来需要给出训练优化的一些设定,
创建损失函数
定义优化器,包括不同优化器对应的参数设置,如torch.optim.SGD随机梯度下降优化器的学习率设置。
# 创建网络模型
model = myModel().to(device)
# 创建损失函数
loss_fn = nn.CrossEntropyLoss()
# 优化器
learning_rate = 1e-2 # 1e-2 = 1 * (10)^(-2) = 1 / 100 = 0.01
optimizer = torch.optim.SGD(model.parameters(), lr = learning_rate)
step3, 训练时候数据流的定义,反向传播函数的连接定义
for i in range(epoch):
print("------第 {} 轮训练开始------".format(i+1))
# 训练步骤开始
total_train_accuracy=0
model.train()
for data in train_dataloader:
imgs, targets = data
outputs = model(imgs) # 将训练的数据放入
loss = loss_fn(outputs, targets) # 得到损失值
optimizer.zero_grad() # 优化过程中首先要使用优化器进行梯度清零
loss.backward() # 调用得到的损失,利用反向传播,得到每一个参数节点的梯度
optimizer.step() # 对参数进行优化
total_train_step += 1 # 上面就是进行了一次训练,训练次数 +1
accuracy_train = (outputs.argmax(1) == targets).sum()
total_train_accuracy += accuracy_train
# 只有训练步骤是100 倍数的时候才打印数据,可以减少一些没有用的数据,方便我们找到其他数据
if total_train_step % 100 == 0:
print("训练次数: {}, Loss: {}".format(total_train_step, loss))
step4,模型验证集的数据流程
model.eval()
with torch.no_grad():
for data in test_dataloader:
imgs, targets = data
outputs = model(imgs)
loss = loss_fn(outputs, targets) # 这里的 loss 只是一部分数据(data) 在网络模型上的损失
total_test_loss = total_test_loss + loss # 整个测试集的loss
accuracy=(outputs.argmax(1)==targets).sum()
total_accuracy+=accuracy
print("整体测试集上的loss: {}, test accuracy is: {}".format(total_test_loss,total_accuracy.cpu().numpy()/test_data_size))
setp5,单张图像的测试
注意,如果训练时候用了cuda, 测试时候的输入也要转换为.cuda(),否则报错,tensor的float或者int类型也必须要一致。
如果保存的模型是基于cuda的,测试时候想要改成cpu,则在load模型后,加一行代码model.to('cpu')即可切换为cpu格式的。
model=torch.load('model_9.pth')#之前保存了整个的模型,所以直接load模型了
model.eval()
fpath='./dataset/test/0_125.jpg'
img=Image.open(fpath)
img=np.array(img).transpose(2,0,1)
img=np.expand_dims(img,axis=0) #(N,Ci, Hi, Wi)
img=torch.tensor(img,dtype=torch.float32).cuda()
out=model(img)
print(out.argmax())
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)