本文主要参考CNN入门+猫狗大战(Dogs vs. Cats)+PyTorch入门,原文作者给出了代码,并且讲解的十分详细,大家可以先去看原文,然后再通过阅读本文了解具体怎么跑起来此代码。本文主要是将数据集添加到了项目中,并且对修改了一点测试的代码。
一、下载代码和数据集
本文最上方的资源是上面那个链接的作者的代码,我只是将数据集添加到了里面,如果需要的话直接下载即可。
二、运行步骤
2.1 将代码上传到服务器上
2.2 运行train.py
源代码的readme文件中写的是先将代码中各个文件夹路径进行修改,我经过实践发现这步是不需要的,可以直接运行train.py就能训练模型了。
2.3 创建目录
创建目录test_imgs
,注意层级关系,是和data
同级的。关于为什么创建请接着看2.4
2.4 修改test.py
因为我运行原作者的new version
时是跑不通的,但是运行原作者old version
是可以跑的通的,但是它每次只能测试一张图片,并且在服务器中使用plt显示图片并没有任何的效果,所以我直接将代码修改为:
- 预测测试集中所有的图片
- 将预测的图片保存到
./test_imgs/
目录(./
指的是test.py
的当前目录)下,并且将图片命名为{index+1}_cat/dog.jpg
,其中index+1
表示当前图片是测试集中的第几张图片,cat/dog
表示如果model预测当前图片中是小猫的话,就存为cat
,如果预测结果为小狗的话就存为dog
from getdata import DogsVSCatsDataset as DVCD
from network import Net
import torch
from torch.autograd import Variable
import numpy as np
import torch.nn.functional as F
import torch.nn as nn
import matplotlib.pyplot as plt
from PIL import Image
import random
import os
import getdata
dataset_dir = './data/' # 数据集路径
model_file = './model/model.pth' # 模型保存路径
N = 1
# my version
def test():
model = Net() # 实例化一个网络
model.cuda() # 送入GPU,利用GPU计算
model = nn.DataParallel(model)
model.load_state_dict(torch.load(model_file)) # 加载训练好的模型参数
model.eval() # 设定为评估模式,即计算过程中不要dropout
datafile = DVCD('test', dataset_dir) # 实例化一个数据集
print('Dataset loaded! length of train set is {0}'.format(len(datafile)))
# index = np.random.randint(0, datafile.data_size, 1)[0] # 获取一个随机数,即随机从数据集中获取一个测试图片
# 将测试集中所有的图片都测试一遍
for index in range(datafile.data_size):
print(f"第{index+1}图片开始测试")
img = datafile.__getitem__(index) # 获取一个图像
img = img.unsqueeze(0) # 因为网络的输入是一个4维Tensor,3维数据,1维样本大小,所以直接获取的图像数据需要增加1个维度
img = Variable(img).cuda() # 将数据放置在PyTorch的Variable节点中,并送入GPU中作为网络计算起点
# print(img)
out = model(img) # 网路前向计算,输出图片属于猫或狗的概率,第一列维猫的概率,第二列为狗的概率
out = F.softmax(out, dim=1) # 采用SoftMax方法将输出的2个输出值调整至[0.0, 1.0],两者和为1
print(f"概率为:{out}") # 输出该图像属于猫或狗的概率
img = Image.open(datafile.list_img[index]) # 打开测试的图片
if out[0, 0] > out[0, 1]: # 猫的概率大于狗
print('the image is a cat')
img.save(f"./test_imgs/{index+1}_cat.jpg") # 服务器好像不能plt显示,所以我们保存下来
else: # 猫的概率小于狗
print('the image is a dog')
img.save(f"./test_imgs/{index+1}_dog.jpg") # 服务器好像不能plt显示,所以我们保存下来
# new version
# def test():
# # setting model
# model = Net() # 实例化一个网络
# model.cuda() # 送入GPU,利用GPU计算
# model = nn.DataParallel(model)
# model.load_state_dict(torch.load(model_file)) # 加载训练好的模型参数
# model.eval() # 设定为评估模式,即计算过程中不要dropout
# # get data
# files = random.sample(os.listdir(dataset_dir), N) # 随机获取N个测试图像
# imgs = [] # img
# imgs_data = [] # img data
# for file in files:
# img = Image.open(dataset_dir + file) # 打开图像
# img_data = getdata.dataTransform(img) # 转换成torch tensor数据
# imgs.append(img) # 图像list
# imgs_data.append(img_data) # tensor list
# imgs_data = torch.stack(imgs_data) # tensor list合成一个4D tensor
# # calculation
# out = model(imgs_data) # 对每个图像进行网络计算
# out = F.softmax(out, dim=1) # 输出概率化
# out = out.data.cpu().numpy() # 转成numpy数据
# # pring results 显示结果
# for idx in range(N):
# plt.figure()
# if out[idx, 0] > out[idx, 1]:
# plt.suptitle('cat:{:.1%},dog:{:.1%}'.format(out[idx, 0], out[idx, 1]))
# else:
# plt.suptitle('dog:{:.1%},cat:{:.1%}'.format(out[idx, 1], out[idx, 0]))
# plt.imshow(imgs[idx])
# plt.show()
# # old version
# def test():
# model = Net() # 实例化一个网络
# model.cuda() # 送入GPU,利用GPU计算
# model = nn.DataParallel(model)
# model.load_state_dict(torch.load(model_file)) # 加载训练好的模型参数
# model.eval() # 设定为评估模式,即计算过程中不要dropout
# datafile = DVCD('test', dataset_dir) # 实例化一个数据集
# print('Dataset loaded! length of train set is {0}'.format(len(datafile)))
# index = np.random.randint(0, datafile.data_size, 1)[0] # 获取一个随机数,即随机从数据集中获取一个测试图片
# print(f"idx={index}")
# img = datafile.__getitem__(index) # 获取一个图像
# img = img.unsqueeze(0) # 因为网络的输入是一个4维Tensor,3维数据,1维样本大小,所以直接获取的图像数据需要增加1个维度
# img = Variable(img).cuda() # 将数据放置在PyTorch的Variable节点中,并送入GPU中作为网络计算起点
# print(img)
# out = model(img) # 网路前向计算,输出图片属于猫或狗的概率,第一列维猫的概率,第二列为狗的概率
# out = F.softmax(out, dim=1) # 采用SoftMax方法将输出的2个输出值调整至[0.0, 1.0],两者和为1
# print(out) # 输出该图像属于猫或狗的概率
# if out[0, 0] > out[0, 1]: # 猫的概率大于狗
# print('the image is a cat')
# else: # 猫的概率小于狗
# print('the image is a dog')
# img = Image.open(datafile.list_img[index]) # 打开测试的图片
# plt.figure('image') # 利用matplotlib库显示图片
# plt.imshow(img)
# plt.show()
if __name__ == '__main__':
test()
# n = 10
# for i in range(n):
# print(i)
2.5 运行test.py
终端显示结果为:
test_imgs
目录下的结果为:
-
预测正确的
-
预测错误的
三、问题
- 运行train.py的时候,总是显示找不到训练集的文件路径,但是我一直点运行,总会有一次是可以运行成功的
- 运行test.py的时候,总是显示找不到模型的文件路径,但是我一直点运行,总会有一次是可以运行成功的
我感觉是不是因为服务器响应太慢了?不然怎么可能会有时候可以,有时候不可以呢?不是代码的问题,而是服务器的问题。如果有人知道的话,希望可以在评论区为我解答一下,拜托了!