一 网络矿建搭建,
#第一部分数据读取,数据预处理,将标签处理
#第二部分模型搭建。可自行选择模型
#第三阶段定义训练,验证,预测函数
# 第四部分模型训练
# -*- coding: utf-8 -*-
import os, sys, glob, argparse
import pandas as pd
import numpy as np
from tqdm import tqdm
import time, datetime
import pdb, traceback
import cv2
# import imagehash
from PIL import Image
from sklearn.model_selection import train_test_split, StratifiedKFold, KFold
from efficientnet_pytorch import EfficientNet
# model = EfficientNet.from_pretrained('efficientnet-b4') #加载预训练EfficientNet
import torch
torch.manual_seed(0) #随机初始化神经网络参数种子
torch.backends.cudnn.deterministic = False #优化运行效率
torch.backends.cudnn.benchmark = True #优化运行效率
import torchvision.models as models
import torchvision.transforms as transforms
import torchvision.datasets as datasets
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from torch.autograd import Variable
from torch.utils.data.dataset import Dataset
class QRDataset(Dataset):
def __init__(self, img_path, transform=None):
self.img_path = img_path
if transform is not None:
self.transform = transform
else:
self.transform = None
def __getitem__(self, index):
start_time = time.time()
img = Image.open(self.img_path[index]).convert('RGB')
if self.transform is not None:
img = self.transform(img)
print(img.shape)
return img,torch.from_numpy(np.array(int('PNEUMONIA' in self.img_path[index])))
def __len__(self):
return len(self.img_path)
#模型搭建
class VisitNet(nn.Module):
def __init__(self):
super(VisitNet, self).__init__()
model = models.resnet18(True)
model.avgpool = nn.AdaptiveAvgPool2d(1)
model.fc = nn.Linear(512, 2)
self.resnet = model
def forward(self, img): #模型训练时,不需要使用forward,只要在实例化一个对象中传入对应的参数就可以自动调用 forward 函数
out = self.resnet(img)
return out
def train(train_iter, model, criterion, optimizer, scheduler,device):
# 保存训练一个epoch的Loss值与准确率
train_loss = 0.0
train_acc = 0.0
# 指定模型训练
model.train()
for i, (inputs, targets) in enumerate(train_iter):
inputs = inputs.to(device)
targets =targets.to(device)
# 模型前向运行
outputs = model(inputs)
# 计算Loss值
loss = criterion(outputs, targets)
# 计算预测结果
pred = outputs.argmax(dim=1)
# 清除梯度
optimizer.zero_grad()
# 反传loss
loss.backward()
# 更新模型权重
optimizer.step()
# 更新学习率
scheduler.step()
# 统计Loss,Acc值
train_loss += loss.item() * inputs.size(0)
train_acc += (preds == targets.data).float().sum().item()
epoch_loss = train_loss / train_iter.size(0)
epoch_acc = train_acc / train_iter.size(0)
print('{} Loss: {:.4f} Acc: {:.4f}'.format('train', epoch_loss, epoch_acc))
return model
# 定义验证阶段
def val(valid_iter, model, criterion):
# 模型验证
model.eval()
# 指定不保存梯度
with torch.no_grad():
# 统计Loss值与准确率
valid_loss = 0.0
valid_acc = 0.0
for i, (inputs, targets) in enumerate(valid_iter):
inputs = inputs.to(device)
targets =targets.to(device)
# 模型前向运行
outputs = model(inputs)
# 计算Loss值
loss = criterion(outputs, targets)
# 计算预测结果
pred = outputs.argmax(dim=1)
# 统计Loss,Acc值
valid_loss += loss.item() * inputs.size(0)
valid_acc += (preds == targets.data).float().sum().item()
epoch_loss = valid_loss / dataset_sizes[phase]
epoch_acc = float(running_corrects) / dataset_sizes[phase]
print('{} Loss: {:.4f} Acc: {:.4f}'.format('valid', epoch_loss, epoch_acc))
return epoch_acc
def predict(test_loader, model):
# switch to evaluate mode
model.eval() #设置模型在预测模式
test_pred = []
with torch.no_grad(): #with torch.no_grad()或者@torch.no_grad()中的数据不需要计算梯度,也不会进行反向传播
end = time.time()
for i, (inputs, _) in enumerate(test_loader):
inputs = inputs.t