import os
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from torch.utils.data import Dataset
import torchvision
import torchvision.transforms as transforms
from torchvision.models.inception import inception_v3
from torchvision.models.resnet import resnet18
from torchvision.models.vgg import vgg19
import shutil
import pandas as pd
from scipy import interp
from utils import *
import argparse
from glob import glob
from PIL import Image
from tensorboardX import SummaryWriter
import pdb
parser = argparse.ArgumentParser(description='This is a script to training something!')
parser.add_argument('-td', '--train_data_dir', help="训练数据地址", type=str, required=True)
parser.add_argument('-ted', '--test_data_dir', help="测试数据地址", type=str, required=True)
parser.add_argument('-b', '--batch_size', type=int, help="网络batch size大小,默认为32", default=32)
parser.add_argument('-nt', '--net_type', help="网络类型,默认为'resnet-18',可选'vgg19','inception-v3'", type=str,
default='resnet-18')
parser.add_argument('-e', '--epoch_num', type=int, help="训练次数,默认为10", default=10)
parser.add_argument('-s', '--image_size', type=int, help="图片大小,默认为224", default=224)
parser.add_argument('-de', '--device', help="计算驱动使用cpu还是gpu", type=str, default='cpu',choices=['cpu','gpu'])
args = parser.parse_args()
class My_ImageFolder(Dataset):
def init(self, data_path, transform=None):
data_ls = []
class_ls = []
# 获取图片路径及类别
train_image_dir_list = os.listdir(data_path)
train_image_dir_list = np.array(train_image_dir_list)
train_image_dir_list.sort()
for class_id, class_dir in enumerate(train_image_dir_list):
Image_examples = glob(os.path.join(data_path, class_dir, '*.jpg'))
Image_examples += glob(os.path.join(data_path, class_dir, '*.bmp'))
Image_examples += glob(os.path.join(data_path, class_dir, '*.png'))
Image_examples += glob(os.path.join(data_path, class_dir, '*.Jpeg'))
Image_examples.sort()
# data_ls += Image_examples
# class_ls += (np.zeros(len(Image_examples), dtype=np.int) + class_id).tolist()
data_ls += Image_examples
class_ls += (np.zeros(len(Image_examples), dtype=np.int) + class_id).tolist()
self.data_ls = data_ls
self.class_ls = class_ls
self.transform = transform
def __len__(self):
return len(self.data_ls)
def __getitem__(self, index):
"""
Args:
index (int): Index
Returns:
tuple: (sample, target) where target is class_index of the target class.
"""
image_path = self.data_ls[index]
target = self.class_ls[index]
sample = Image.open(image_path)
sample = sample.convert('RGB')
if self.transform is not None:
sample = self.transform(sample)
return sample, target, image_path
def train(train_dataset, train_loader, test_dataset, test_loader, network, epoch_num, tb_log_dir):
writer = SummaryWriter(log_dir=tb_log_dir)
for epoch in range(epoch_num):
# 训练数据集
network.train()
total_correct = 0
total_loss = []
for batch in tqdm(train_loader): # Get Batch
images, labels, _ = batch
images = images.to(device)
labels = labels.to(device)
preds = network(images) # Pass Batch
loss = F.cross_entropy(preds, labels) # Calculate loss
optimizer.zero_grad() # 梯度清零,否则会累加
loss.backward() # Calculate Gradients
optimizer.step() # Update Weights
total_loss.append(loss.item())
total_correct += get_num_correct(preds, labels)
print('train epoch', epoch, "total_correct", total_correct, "loss", np.mean(total_loss), "accuracy",
total_correct / len(train_dataset))
writer.add_scalar('loss/train', np.mean(total_loss), epoch)
writer.add_scalar('acc/train', total_correct / len(train_dataset), epoch)
# 测试数据集
network.eval()
total_correct = 0
total_loss = []
with torch.no_grad():
for batch in tqdm(test_loader): # Get Batch
images, labels, _ = batch
images = images.to(device)
labels = labels.to(device)
preds = network(images) # Pass Batch
loss = F.cross_entropy(preds, labels) # Calculate loss
total_loss.append(loss.item())
total_correct += get_num_correct(preds, labels)
print('test epoch', epoch, "total_correct", total_correct, "loss", np.mean(total_loss), "accuracy",
total_correct / len(test_dataset))
writer.add_scalar('loss/test', np.mean(total_loss), epoch)
writer.add_scalar('acc/test', total_correct / len(test_dataset), epoch)
writer.close()
if name == 'main':
train_data_dir = args.train_data_dir
test_data_dir = args.test_data_dir
batch_size = args.batch_size
input_size = args.image_size
epoch_num = args.epoch_num
network_type = args.net_type
tb_log_dir = './classfy_result'
if args.device=='gpu':
device = 'cuda'
elif args.device=='cpu':
device = 'cpu'
class_list = os.listdir(train_data_dir)
n_classes = len(class_list)
#结果保存文件
result_dir = './classfy_result'
if not os.path.exists(result_dir):
os.makedirs(result_dir)
# 建立训练数据集
train_dataset = My_ImageFolder(train_data_dir,
transforms.Compose([
transforms.RandomResizedCrop(input_size), # 把每张图片变成需要输入的维度
# transforms.Resize(input_size),
transforms.ToTensor(),
transforms.Normalize(mean=[0.485, 0.456, 0.406],
std=[0.229, 0.224, 0.225])
]))
train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=batch_size, shuffle=True)
# 建立测试数据集
# 读取测试图片
test_dataset = My_ImageFolder(test_data_dir,
transforms.Compose([
# transforms.RandomResizedCrop(input_size),
# transforms.RandomHorizontalFlip(),
transforms.Resize((input_size,input_size)),
transforms.ToTensor(),
transforms.Normalize(mean=[0.485, 0.456, 0.406],
std=[0.229, 0.224, 0.225])
]))
# 重新设置一个loader
test_loader = torch.utils.data.DataLoader(test_dataset, batch_size=batch_size, shuffle=False)
# 创建resnet18网络
if network_type == 'resnet-18':
network = resnet18(pretrained=False, num_classes=n_classes).to(device)
elif network_type == 'inception-v3':
network = inception_v3(pretrained=False, num_classes=n_classes, aux_logits=False).to(device)
elif network_type == 'vgg19':
network = vgg19(pretrained=False, num_classes=n_classes).to(device)
else:
print('you selected network type is not in the list')
optimizer = optim.Adam(network.parameters(), lr=0.01)
train(train_dataset, train_loader, test_dataset, test_loader, network, epoch_num, tb_log_dir)
# 得到所有数据的预测值
test_preds = get_all_preds(network, test_loader, device) # 开始对图片做预测
# In[*]
test_preds = torch.Tensor(test_preds) # 再次将numpy转为tensor
test_labels = torch.Tensor(test_dataset.class_ls).long()
test_preds.argmax(dim=1) # 测试结果,用于和test_labels对比
# pdb.set_trace()
# In[*]
# 预测正确的数目
pre_correct = get_num_correct(test_preds, test_labels)
accuracy = pre_correct / len(test_dataset)
print("pre_correct", pre_correct)
print("accuracy", accuracy)
# In[*]
cm = confusion_matrix(test_labels, test_preds.argmax(dim=1)) # 横向相加为真实标签值,竖向相加为预测值
# 直接画出矩阵表和矩阵图
plt.figure(figsize=(10, 10))
plot_confusion_matrix(cm, class_list)
plt.savefig("./classfy_result/matrix.jpg")
# plt.show()
plt.close()
# In[*]
# 把标签哑变量处理
labels_num = test_dataset.class_ls
labels_dummy = np.array(pd.get_dummies(labels_num))
# In[*]
# 得到预测的概率值
test_preds_tensor = torch.tensor(test_preds)
test_preds_softmax = F.softmax(test_preds_tensor, dim=1).numpy()
# 计算每一类的ROC
save_ROC(labels_dummy, test_preds_softmax, n_classes)
# 保存预测结果分数
save_pre_score(test_data_dir, test_preds_softmax, labels_num)
# 计算每一类PR
show_PR(labels_dummy, test_preds_softmax, n_classes)
# 保存图片分类结果
results = test_preds.argmax(dim=1)
for r, path in zip(results, test_dataset.data_ls):
dst_path = os.path.join(result_dir, class_list[r], os.path.basename(path))
if not os.path.exists(os.path.dirname(dst_path)):
os.makedirs(os.path.dirname(dst_path))
shutil.copy(path, dst_path)
以上是代码
改为CPU可以运行,改为GPU就跑不动
这是在等待用户输入内容吗
要不就是程序有错误,程序陷入死循环了
把你代码贴出来看下啊