在最后一部分中, 我们实现了神经网络或创建了对手写数字进行分类的模型。现在, 我们通过从网络上获取图像来测试模型。我们使用以下图像:
http://calstormbasketball.com/wp-content/uploads/2018/08/5020657994731_01c.jpeg
当你将此链接粘贴到浏览器上时, 你将看到数字5的图像:
文章图片
看到这一点之后, 我们将意识到它是数字5。现在, 我们将尝试使我们的网络对其进行预测。
我们可以按照以下步骤对数字图像进行预测:
步骤1:
第一步, 我们将执行GET请求以检索图像数据。要发出GET请求, 我们需要将请求导入为:
import requests
现在, 我们设置一个变量URL并将链接分配为字符串。
url=' http://calstormbasketball.com/wp-content/uploads/2018/08/5020657994731_01c.jpeg '
第2步:
在下一步中, 我们设置一个变量响应, 其值将从请求的get()方法获得。 get()方法将包含两个参数, 即URL和stream, stream将等于true。
response=requests.get(url, stream=True)
第三步:
我们将使用响应的原始内容来获取图像。为此, 我们首先必须从PIL(Python图像库)中导入图像。
from PIL import Image
我们使用image的open()方法, 并将响应的原始内容作为参数传递。从该方法返回的值将分配给名为img的变量, 如下所示:
img=Image.open(response.raw)
现在, 我们绘制图像以确保一切正常。
plt.imshow(img)plt.show()
【PyTorch如何测试卷积神经网络模型((实例图解))】当我们运行它时, 它将由于PIL产生错误。我们必须先安装枕头才能运行此代码。我们必须在anaconda命令提示符下运行conda install -c anaconda pillow命令以安装枕头。
运行代码时, 它将提供预期的输出。
文章图片
步骤4:
我们需要确保图像与训练后的神经网络学习的图像相对应。我们的图像是1000 * 1000像素, 因此我们需要像训练数据中那样将其变成28 * 28灰度图像。在我们训练有素的图像数据集中, 图像具有黑色背景和白色前景, 而在上面的图像中, 具有白色背景和黑色前景。现在, 我们的首要任务是对该图像进行预处理。
我们将使用PIL.ImageOps的invert()方法并将图像作为参数传递。此方法将反转我们图像的颜色。
img=PIL.ImageOps.invert(img)
该图像是具有三个通道的像素强度值的RGB格式, 由于许多原因, 这将带来问题。为此, 我们必须将该图像转换为二进制黑白图像, 并将其转换为:
img=img.convert('1')
我们将以与转换所有其他训练图像相同的方式来转换此图像。我们必须将图像转换为28 * 28像素, 因此我们必须在转换后的链组成中添加一个参数调整大小, 如下所示:
transform1=transforms.Compose([transforms.Resize((28, 28)), transforms.ToTensor(), transforms.Normalize((0.5, ), (0.5, ))])img=transform1(img)
现在, 我们的图像采用张量的形式, 因此我们必须将其更改为numpy数组。在绘制图像之前, 我们必须导入PIL.ImageOps, 然后将图像绘制为:
import PIL.ImageOpsplt.imshow(im_convert(img))
文章图片
步骤5:
现在, 我们将该图像输入到神经网络中进行预测。我们将图像添加到设备中, 并确保对四维权重进行四维输入。我们将取消压缩图像, 并将其分配给新的可变图像, 如下所示:
image=img.to(device)image=image[0].unsqueeze().unsqueeze(0)
这将返回一个尺寸为1的新张量, 该张量将插入到指定的零位置。
output=model(image)_, pred=torch.max(output, 1)print(pred.item())
它将为我们带来预期的预测:
文章图片
步骤6:
在下一步中, 我们包装验证加载程序。它将创建一个对象, 该对象使我们一次可以通过可变验证加载程序一个元素。我们通过在dataiter上调用next来一次访问一个元素。 next()函数将获取第一批验证数据, 该验证数据将被拆分为图像和标签, 如下所示:
dataiter=iter(validation_loader)images, labels=dataiter.next()
无需重塑图像。我们将图像和标签添加到设备中, 并且还将需要所有图像和预测的输出。
images_=images.to(device)labels=labels.to(device)output=model(images_)_, preds=torch.max(output, 1)
步骤7:
现在, 我们将批量绘制图像及其相应的标签。这将借助于plt的图形功能来完成, 并且将无花果的大小设置为等于整数25 * 4的元组, 这将指定图形的宽度和高度。
fig=plt.figure(figsize=(25, 4))
现在, 我们从批次中绘制20个MNIST图像。我们使用add_subplot()方法向当前图形添加一个子图, 并将2、10和idx作为函数的参数传递。这里有两个没有行, 十个没有列, idx是索引。
ax=fig.add_subplot(2, 10, idx+1)
现在, 我们将在im_show()函数的帮助下显示图像, 并为每个图像绘图指定一个标题:
plt.imshow(im_convert(images[idx])) ax.set_title("{}({})".format(str(preds[idx].item()), str(labels[idx].item())), color=("green" if preds[idx]==labels[idx] else "red"))
最后调用plt.show(), 它将给我们一个错误。此错误将是im_convert()函数的, 即无法将CUDA张量转换为numpy。所以我们必须使用tensor.cpu()作为:
image=tensor.cpu().clone().detach().numpy()
现在, 我们将重新调用我们的plt.show(), 它将为我们提供预期的输出:
文章图片
完整的代码
import torchimport matplotlib.pyplot as pltimport numpy as npimport torch.nn.functional as funcimport PIL.ImageOpsfrom torch import nnfrom torchvision import datasets, transforms import requestsfrom PIL import Imagetransform1=transforms.Compose([transforms.Resize((28, 28)), transforms.ToTensor(), transforms.Normalize((0.5, ), (0.5, ))])training_dataset=datasets.MNIST(root='./data', train=True, download=True, transform=transform1)validation_dataset=datasets.MNIST(root='./data', train=False, download=True, transform=transform1)training_loader=torch.utils.data.DataLoader(dataset=training_dataset, batch_size=100, shuffle=True)validation_loader=torch.utils.data.DataLoader(dataset=validation_dataset, batch_size=100, shuffle=False)def im_convert(tensor):image=tensor.cpu().clone().detach().numpy()image=image.transpose(1, 2, 0)print(image.shape)image=image*(np.array((0.5, 0.5, 0.5))+np.array((0.5, 0.5, 0.5)))image=image.clip(0, 1)return imagedataiter=iter(training_loader)images, labels=dataiter.next()fig=plt.figure(figsize=(25, 4))for idx in np.arange(20):ax=fig.add_subplot(2, 10, idx+1)plt.imshow(im_convert(images[idx]))ax.set_title([labels[idx].item()])class classification1(nn.Module):def __init__(self, input_layer, hidden_layer1, hidden_layer2, output_layer):super().__init__()self.linear1=nn.Linear(input_layer, hidden_layer1)self.linear2=nn.Linear(hidden_layer1, hidden_layer2)self.linear3=nn.Linear(hidden_layer2, output_layer)def forward(self, x):x=func.relu(self.linear1(x))x=func.relu(self.linear2(x))x=self.linear3(x)return xmodel=classification1(784, 125, 65, 10)criteron=nn.CrossEntropyLoss()optimizer=torch.optim.Adam(model.parameters(), lr=0.0001)epochs=12loss_history=[]correct_history=[]val_loss_history=[]val_correct_history=[]for e in range(epochs):loss=0.0correct=0.0val_loss=0.0val_correct=0.0for input, labels in training_loader:inputs=input.view(input.shape[0], -1)outputs=model(inputs)loss1=criteron(outputs, labels)optimizer.zero_grad()loss1.backward()optimizer.step()_, preds=torch.max(outputs, 1)loss+=loss1.item()correct+=torch.sum(preds==labels.data)else:with torch.no_grad():for val_input, val_labels in validation_loader:val_inputs=val_input.view(val_input.shape[0], -1)val_outputs=model(val_inputs)val_loss1=criteron(val_outputs, val_labels) _, val_preds=torch.max(val_outputs, 1)val_loss+=val_loss1.item()val_correct+=torch.sum(val_preds==val_labels.data)epoch_loss=loss/len(training_loader.dataset)epoch_acc=correct.float()/len(training_dataset)loss_history.append(epoch_loss)correct_history.append(epoch_acc)val_epoch_loss=val_loss/len(validation_loader.dataset)val_epoch_acc=val_correct.float()/len(validation_dataset)val_loss_history.append(val_epoch_loss)val_correct_history.append(val_epoch_acc)print('training_loss:{:.4f}, {:.4f}'.format(epoch_loss, epoch_acc.item()))print('validation_loss:{:.4f}, {:.4f}'.format(val_epoch_loss, val_epoch_acc.item()))url='http://calstormbasketball.com/wp-content/uploads/2018/08/5020657994731_01c.jpeg'response=requests.get(url, stream=True)img=Image.open(response.raw)img=PIL.ImageOps.invert(img)img=img.convert('1')img=transform1(img) plt.imshow(im_convert(img))images=img.to(device)images=images[0].unsqueeze(0).unsqueeze(0)output=model(images)_, pred=torch.max(output, 1)print(pred.item())dataiter=iter(validation_loader)images, labels=dataiter.next()images_=images.to(device)labels=labels.to(device)output=model(images_)_, preds=torch.max(output, 1)fig=plt.figure(figsize=(25, 4))for idx in np.arange(20):ax=fig.add_subplot(2, 10, idx+1, xticks=[], yticks=[])plt.imshow(im_convert(images[idx]))ax.set_title("{}({})".format(str(preds[idx].item()), str(labels[idx].item())), color=("green" if preds[idx]==labels[idx] else "red"))plt.show()
文章图片
文章图片
因此, 很明显, 与深度神经网络相比, CNN以最佳方式对图像进行分类。这就是为什么我们更喜欢卷积神经网络而不是深度神经网络的原因。
推荐阅读
- 在PyTorch中测试深层神经网络(图解)
- PyTorch张量介绍和用法
- PyTorch预测和线性分类使用图解
- PyTorch神经网络(感知器图解)
- PyTorch一维张量用法图解
- PyTorch软件包介绍
- Python教程(几个常用的内置函数)
- 什么是爬虫(Python爬虫框架有哪些?)
- 用 Python 提取 PDF 文本的简单方法