如何解决如何使用我自己的数据在PyTorch上测试该卷积神经网络?
所以最近我一直在关注来自senddex的卷积神经网络教程,并且我一直在尝试实现他的代码来用我自己的图像测试经过训练的神经网络(在这种情况下,我只是从使用的数据集中选择随机图片在他的程序中)。因此,我的目的是训练神经网络,对其进行测试,最后将其保存,以便以后将其加载到单独的python文件中,以在单个图像上使用已经训练的NN。
他使用的数据集是“ Microsoft的狗与猫”。这是我编写神经网络程序(“ main.py”)的代码。
import cv2
import numpy as np
from tqdm import tqdm
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
REBUILD_DATA = False # set to true to one once,then back to false unless you want to change something in your training data.
class DogsVSCats():
IMG_SIZE = 100
CATS = "PetImages/Cat"
DOGS = "PetImages/Dog"
TESTING = "PetImages/Testing"
LABELS = {CATS: 0,DOGS: 1}
training_data = []
catcount = 0
dogcount = 0
def make_training_data(self):
for label in self.LABELS:
print(label)
for f in tqdm(os.listdir(label)):
if "jpg" in f:
try:
path = os.path.join(label,f)
img = cv2.imread(path,cv2.IMREAD_GRAYSCALE)
img = cv2.resize(img,(self.IMG_SIZE,self.IMG_SIZE))
self.training_data.append([np.array(img),np.eye(2)[self.LABELS[label]]]) # do something like print(np.eye(2)[1]),just makes one_hot
#print(np.eye(2)[self.LABELS[label]])
if label == self.CATS:
self.catcount += 1
elif label == self.DOGS:
self.dogcount += 1
except Exception as e:
pass
#print(label,f,str(e))
np.random.shuffle(self.training_data)
np.save("training_data.npy",self.training_data)
print('Cats:',dogsvcats.catcount)
print('Dogs:',dogsvcats.dogcount)
class Net(nn.Module):
def __init__(self):
super().__init__() # just run the init of parent class (nn.Module)
self.conv1 = nn.Conv2d(1,32,5) # input is 1 image,32 output channels,5x5 kernel / window
self.conv2 = nn.Conv2d(32,64,5) # input is 32,bc the first layer output 32. Then we say the output will be 64 channels,5x5 kernel / window
self.conv3 = nn.Conv2d(64,128,5)
x = torch.randn(50,50).view(-1,1,50,50)
self._to_linear = None
self.convs(x)
self.fc1 = nn.Linear(self._to_linear,512) #flattening.
self.fc2 = nn.Linear(512,2) # 512 in,2 out bc we're doing 2 classes (dog vs cat).
def convs(self,x):
# max pooling over 2x2
x = F.max_pool2d(F.relu(self.conv1(x)),(2,2))
x = F.max_pool2d(F.relu(self.conv2(x)),2))
x = F.max_pool2d(F.relu(self.conv3(x)),2))
if self._to_linear is None:
self._to_linear = x[0].shape[0]*x[0].shape[1]*x[0].shape[2]
return x
def forward(self,x):
x = self.convs(x)
x = x.view(-1,self._to_linear) # .view is reshape ... this flattens X before
x = F.relu(self.fc1(x))
x = self.fc2(x) # bc this is our output layer. No activation here.
return F.softmax(x,dim=1)
net = Net()
print(net)
if REBUILD_DATA:
dogsvcats = DogsVSCats()
dogsvcats.make_training_data()
training_data = np.load("training_data.npy",allow_pickle=True)
print(len(training_data))
optimizer = optim.Adam(net.parameters(),lr=0.001)
loss_function = nn.MSELoss()
X = torch.Tensor([i[0] for i in training_data]).view(-1,50)
X = X/255.0
y = torch.Tensor([i[1] for i in training_data])
VAL_PCT = 0.1 # lets reserve 10% of our data for validation
val_size = int(len(X)*VAL_PCT)
train_X = X[:-val_size]
train_y = y[:-val_size]
test_X = X[-val_size:]
test_y = y[-val_size:]
BATCH_SIZE = 100
EPOCHS = 1
def train(net):
for epoch in range(EPOCHS):
for i in tqdm(range(0,len(train_X),BATCH_SIZE)): # from 0,to the len of x,stepping BATCH_SIZE at a time. [:50] ..for now just to dev
#print(f"{i}:{i+BATCH_SIZE}")
batch_X = train_X[i:i+BATCH_SIZE].view(-1,50)
batch_y = train_y[i:i+BATCH_SIZE]
net.zero_grad()
outputs = net(batch_X)
loss = loss_function(outputs,batch_y)
loss.backward()
optimizer.step() # Does the update
print(f"Epoch: {epoch}. Loss: {loss}")
def test(net):
correct = 0
total = 0
with torch.no_grad():
for i in tqdm(range(len(test_X))):
real_class = torch.argmax(test_y[i])
net_out = net(test_X[i].view(-1,50))[0] # returns a list,predicted_class = torch.argmax(net_out)
if predicted_class == real_class:
correct += 1
total += 1
print("Accuracy: ",round(correct/total,3))
train(net)
test(net)
PATH = './object_detection.pth'
torch.save(net.state_dict(),PATH)
训练完神经网络后,我想在下一个程序中加载它,然后简单地在NN上测试图像。但是,每次我运行该程序时,都会再次对神经网络进行训练和测试,这会使该过程变得更长且烦人。而且,我认为当我运行该程序然后将图像输入到NN中时,整个“ main.py”都在运行。
请,有人可以帮我吗?真是太神奇了,因为我将其作为我学士学位论文的基础。潜在地,我还想修改此代码以通过它运行我自己的整个数据集,如果我是pytorch的新手,那么如果有人能帮助我做到这一点将令人难以置信。
import cv2
from main import Net,train,test
import numpy as np
classes = ('cat','dog')
imsize = 50
net = Net()
net.load_state_dict(torch.load('./object_detection.pth'))
def image_loader(image_name):
image = cv2.imread(image_name,cv2.IMREAD_GRAYSCALE)
image = cv2.resize(image,(imsize,imsize))
image = np.array(image)
image = torch.Tensor(image)/255
image = image.view(-1,50)
return image
test_image = image_loader("./PetImages/Cat/1021.jpg")
result = net(test_image)
_,predicted = torch.max(result,1)
print(result)
print(classes[predicted[0]])
解决方法
您面临的问题与NN无关,而是导入部分。
在第二个代码段中,导入类和函数,第一个代码段。同时,这些语句还将在其中执行所有代码,这不是我们想要的。
解决问题的最简单方法是在if情况下收集代码,以避免在导入过程中执行代码。
结果可能看起来像这样:
import cv2
import numpy as np
from tqdm import tqdm
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
class DogsVSCats():
IMG_SIZE = 100
CATS = "PetImages/Cat"
DOGS = "PetImages/Dog"
TESTING = "PetImages/Testing"
LABELS = {CATS: 0,DOGS: 1}
training_data = []
catcount = 0
dogcount = 0
def make_training_data(self):
for label in self.LABELS:
print(label)
for f in tqdm(os.listdir(label)):
if "jpg" in f:
try:
path = os.path.join(label,f)
img = cv2.imread(path,cv2.IMREAD_GRAYSCALE)
img = cv2.resize(img,(self.IMG_SIZE,self.IMG_SIZE))
self.training_data.append([np.array(img),np.eye(2)[self.LABELS[label]]]) # do something like print(np.eye(2)[1]),just makes one_hot
#print(np.eye(2)[self.LABELS[label]])
if label == self.CATS:
self.catcount += 1
elif label == self.DOGS:
self.dogcount += 1
except Exception as e:
pass
#print(label,f,str(e))
np.random.shuffle(self.training_data)
np.save("training_data.npy",self.training_data)
print('Cats:',dogsvcats.catcount)
print('Dogs:',dogsvcats.dogcount)
class Net(nn.Module):
def __init__(self):
super().__init__() # just run the init of parent class (nn.Module)
self.conv1 = nn.Conv2d(1,32,5) # input is 1 image,32 output channels,5x5 kernel / window
self.conv2 = nn.Conv2d(32,64,5) # input is 32,bc the first layer output 32. Then we say the output will be 64 channels,5x5 kernel / window
self.conv3 = nn.Conv2d(64,128,5)
x = torch.randn(50,50).view(-1,1,50,50)
self._to_linear = None
self.convs(x)
self.fc1 = nn.Linear(self._to_linear,512) #flattening.
self.fc2 = nn.Linear(512,2) # 512 in,2 out bc we're doing 2 classes (dog vs cat).
def convs(self,x):
# max pooling over 2x2
x = F.max_pool2d(F.relu(self.conv1(x)),(2,2))
x = F.max_pool2d(F.relu(self.conv2(x)),2))
x = F.max_pool2d(F.relu(self.conv3(x)),2))
if self._to_linear is None:
self._to_linear = x[0].shape[0]*x[0].shape[1]*x[0].shape[2]
return x
def forward(self,x):
x = self.convs(x)
x = x.view(-1,self._to_linear) # .view is reshape ... this flattens X before
x = F.relu(self.fc1(x))
x = self.fc2(x) # bc this is our output layer. No activation here.
return F.softmax(x,dim=1)
def train(net):
for epoch in range(EPOCHS):
for i in tqdm(range(0,len(train_X),BATCH_SIZE)): # from 0,to the len of x,stepping BATCH_SIZE at a time. [:50] ..for now just to dev
#print(f"{i}:{i+BATCH_SIZE}")
batch_X = train_X[i:i+BATCH_SIZE].view(-1,50)
batch_y = train_y[i:i+BATCH_SIZE]
net.zero_grad()
outputs = net(batch_X)
loss = loss_function(outputs,batch_y)
loss.backward()
optimizer.step() # Does the update
print(f"Epoch: {epoch}. Loss: {loss}")
def test(net):
correct = 0
total = 0
with torch.no_grad():
for i in tqdm(range(len(test_X))):
real_class = torch.argmax(test_y[i])
net_out = net(test_X[i].view(-1,50))[0] # returns a list,predicted_class = torch.argmax(net_out)
if predicted_class == real_class:
correct += 1
total += 1
print("Accuracy: ",round(correct/total,3))
if __name__ == "__main__":
REBUILD_DATA = False # set to true to one once,then back to false unless you want to change something in your training data.
net = Net()
print(net)
if REBUILD_DATA:
dogsvcats = DogsVSCats()
dogsvcats.make_training_data()
training_data = np.load("training_data.npy",allow_pickle=True)
print(len(training_data))
optimizer = optim.Adam(net.parameters(),lr=0.001)
loss_function = nn.MSELoss()
X = torch.Tensor([i[0] for i in training_data]).view(-1,50)
X = X/255.0
y = torch.Tensor([i[1] for i in training_data])
VAL_PCT = 0.1 # lets reserve 10% of our data for validation
val_size = int(len(X)*VAL_PCT)
train_X = X[:-val_size]
train_y = y[:-val_size]
test_X = X[-val_size:]
test_y = y[-val_size:]
BATCH_SIZE = 100
EPOCHS = 1
train(net)
test(net)
PATH = './object_detection.pth'
torch.save(net.state_dict(),PATH)
,
您可以使用torch.save和torch.load将模型另存为pickle文件并加载以供其他程序使用。因此,当您看到损失减少时,可以致电
torch.save(net.state_dict(),<save_path>) # to save
net.load_state_dict(torch.load(<save_path>)) # to load again
尽管在火车功能中,您仍需要跟踪最小损失
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。