介绍图像分类是计算机视觉最重要的应用之一。它的应用范围从自动驾驶汽车中的物体分类到医疗行业中的血细胞识别,从制造业中的缺陷物品识别到构建可以对是否戴口罩的人进行分类的系统。在所有这些行业中,图像分类都以这样或那样的方式使用。他们是如何做到的呢?他们使用哪个框架?关于TensorFlow、PyTorch、Keras等不同深度学习框架之间的差异,你一定已经读过很多了。TensorFlow和PyTorch无疑是业界最流行的框架。我相信您会找到无穷无尽的资源来了解这些深度学习框架之间的异同。在本文中,我们将了解如何在PyTorch和TensorFlow中构建基本的图像分类模型。我们将从PyTorch和TensorFlow的简要概述开始。然后,我们将使用MNIST手写数字分类数据集,并使用PyTorch和TensorFlow中的CNN(卷积神经网络)构建图像分类模型。这将是您的起点,然后您可以选择您喜欢的任何框架,或开始构建其他计算机视觉模型。目录PyTorch概述TensorFlow概述理解问题陈述:MNIST在PyTorch中实现卷积神经网络(CNN)另外,张量是多维数组,就像NumPy的ndarrays一样也可以在GPU上运行。PyTorch的一个独特之处在于它使用动态计算图。PyTorch的Autograd包从张量生成计算图并自动计算梯度。而不是具有特定功能的预定义图形。PyTorch为我们提供了一个框架,可以随时随地构建计算图,甚至可以在运行时更改它们。特别是,这对于我们不知道创建神经网络需要多少内存的情况很有用。您可以使用PyTorch应对各种深度学习挑战。以下是一些挑战:图像(检测、分类等)文本(分类、生成等)强化学习TensorFlow概述TensorFlow由GoogleBrain团队的研究人员和工程师开发。它远不是深度学习中最常用的软件库(尽管其他人正在迅速赶上)。TensorFlow如此受欢迎的最大原因之一是它支持多种语言创建深度学习模型,例如Python、C++和R。它提供了详细的文档和指南。TensorFlow由许多组件组成。这里有两个突出的地方:TensorBoard:使用数据流图帮助有效地可视化数据TensorFlow:对于快速部署新算法/实验非常有用TensorFlow目前正在运行2.0版本,该版本于2019年9月正式发布。我们还将在2.0版本中实现CNN.我希望您现在对PyTorch和TensorFlow有了基本的了解。现在,让我们尝试使用这两个框架构建深度学习模型并了解其内部工作原理。在此之前,让我们先了解一下我们将在本文中解决的问题陈述。理解问题陈述:MNIST在我们开始之前,让我们理解数据集。在本文中,我们将解决流行的MNIST问题。这是一项数字识别任务,我们必须将手写数字的图像分类为从0到9的10个类别之一。在MNIST数据集中,我们对从各种扫描文档中获取的图像进行了数字化处理,并进行了尺寸归一化和居中处理。随后,每个图像都是一个28x28像素的正方形(总共784个像素)。数据集的标准拆分用于评估和比较模型,其中60,000张图像用于训练模型,另一组10,000张图像用于测试模型。现在,我们还了解了数据集。因此,让我们在PyTorch和TensorFlow中使用CNN构建一个图像分类模型。我们将从PyTorch中的实现开始。我们将在googlecolab中实现这些模型,它提供免费的GPU来运行这些深度学习模型。在PyTorch中实现卷积神经网络(CNN)让我们首先导入所有库:#importingthelibrariesimportnumpyasnpimporttorchiimporttorchvisionimportmatplotlib.pyplotaspltfromtimeimporttimefromtorchvisionimportdatasets,transformsfromtorchimportnn,optim我们还在Googlecolab上检查PyTorch的版本:#versionofpytorchprint(torch.__version__)VersionofPy5.5.1如果您使用任何其他版本,您可能会收到一些警告或错误,因此您可以更新到此版本的PyTorch。我们将对图像执行一些转换,例如归一化像素值,所以让我们也定义这些转换:#transformationstobeappliedonimagestransform=transforms.Compose([transforms.ToTensor(),transforms.Normalize((0.5,),(0.5,)),])现在,让我们加载MNIST数据集的训练和测试集:#definingthetrainingandtestingsettrainset=datasets.MNIST('./data',download=True,train=True,transform=transform)testset=datasets。MNIST('./',download=True,train=False,transform=transform)接下来,我定义训练和测试加载器,这将帮助我们批量加载训练和测试集。我将批量大小定义为64:#definingtrainloaderandtestloadertrainloader=torch.utils.data.DataLoader(trainset,batch_size=64,shuffle=True)testloader=torch.utils.data.DataLoader(testset,batch_size=64,shuffle=True)首先让我们看一下训练集的摘要:#shapeoftrainingdatadataiter=iter(trainloader)images,labels=dataiter.next()print(images.shape)print(labels.shape)所以在每批中我们有64张图像,每张图像都是大小为28,28,对于每张图片我们都有一个对应的标签。让我们可视化训练图像,看看它长什么样:#visualizingthetrainingimagesplt.imshow(images[0].numpy().squeeze(),cmap='gray')它是数字0的图像。同样,让我们??可视化测试集图像:#shapeofvalidationdatadataiter=iter(testloader)images,labels=dataiter.next()print(images.shape)print(labels.shape)在测试集中,我们还有大小为64的批次。现在让我们定义架构定义模型架构我们将在这里使用CNN模型。所以让我们定义和训练模型:#definingthemodelarchitectureclassNet(nn.Module):def__init__(self):super(Net,self).__init__()self.cnn_layers=nn.Sequential(#Defininga2Dconvolutionlayernn.Conv2d(1,4,kernel_size=3、stride=1,padding=1),nn.BatchNorm2d(4),nn.ReLU(inplace=True),nn.MaxPool2d(kernel_size=2,stride=2),#Defininganother2Dconvolutionlayernn.Conv2d(4,4,kernel_size=3,stride=1,padding=1),nn.BatchNorm2d(4),nn.ReLU(inplace=True),nn.MaxPool2d(kernel_size=2,stride=2),)self.linear_layers=nn。Sequential(nn.Linear(4*7*7,10))#Definingtheforwardpassdefforward(self,x):x=self.cnn_layers(x)x=x.view(x.size(0),-1)x=self.linear_layers(x)returnx我们还定义了优化器和损失函数,然后我们将看一下模型的摘要:#definingthemodelmodel=Net()#definingtheoptimizeroptimizer=optim.Adam(model.parameters(),lr=0.01)#definingthelossfunctioncriterion=nn.CrossEntropyLoss()#checkingifGPUisavailableiftorch.cuda.is_available():model=model.cuda()criterion=criterion.cuda()print(model)所以我们有2个卷积层,这将有助于提取特征。来自这些卷积层的特征被传递到完全连接的层,这些层将图像分类到它们各自的类别中。现在我们的模型架构已经准备就绪,让我们训练这个模型十个时期:foriinrange(10):running_loss=0forimages,labelsintrainloader:iftorch.cuda.is_available():images=images.cuda()labels=labels.cuda()#Trainingpassoptimizer.zero_grad()output=model(images)loss=criterion(output,labels)#Thisiswherethemodellearnsbybackpropagatingloss.backward()#Andoptimizesitsweightshereoptimizer.step()running_loss+=loss.item()else:print("Epoch{}-训练损失:{}".format(i+1,running_loss/len(trainloader)))并且你会看到训练随着时代的增加而减少。这意味着我们的模型正在从训练集中学习模式。让我们检查这个模型在测试集上的性能:#gettingpredictionsontestsetandmeasuringtheperformancecorrect_count,all_count=0,0forimages,labelsintestloader:foriinrange(len(labels)):iftorch.cuda.is_available():images=images.cuda()labels=labels.cuda()img=images[i].view(1,1,28,28)withtorch.no_grad():logps=model(img)ps=torch.exp(logps)probab=list(ps.cpu()[0])pred_label=probab.index(max(probab))true_label=labels.cpu()[i]if(true_label==pred_label):correct_count+=1all_count+=1print("NumberOfImagesTested=",all_count)print("\nModelAccuracy=",(correct_count/all_count))因此我们总共测试了10,000张图像,模型在预测测试图像的标签方面的准确率约为96%。这就是如何在PyTorch中构建卷积神经网络。在下一节中,我们将研究如何在TensorFlow中实现相同的架构。在TensorFlow中实现卷积神经网络(CNN)现在,让我们在TensorFlow中使用卷积神经网络解决相同的MNIST问题。像往常一样,我们将从导入库开始:#importingthelibrariesimporttensorflowastffromtensorflow.kerasimportdatasets,layers,modelsfromtensorflow.keras.utilsimportto_categoricalimportmatplotlib.pyplotasplt检查我们使用的TensorFlow版本:#versionoftensorflowprint(tf.__version__)所以我们使用2。TensorFlow的2.__version__.0版本。现在让我们使用tensorflow.keras的数据集类加载MNIST数据集:(train_images,train_labels),(test_images,test_labels)=datasets.mnist.load_data(path='mnist.npz')#Normalizepixelvaluestobebetween0and1train_images,test_images=train_images/255.0,test_images/255.0这里我们加载了MNIST数据集的训练集和测试集。此外,我们对训练和测试图像的像素值进行了归一化处理。接下来,让我们可视化数据集中的一些图像:#visualizingafewimagesplt.figure(figsize=(10,10))foriinrange(9):plt.subplot(3,3,i+1)plt.xticks([])plt.yticks([])plt.grid(False)plt.imshow(train_images[i],cmap='gray')plt.show()这就是我们的数据集的样子。我们有手写数字的图像。让我们再看看训练集和测试集的形状:#shapeofthetrainingandtestset(train_images.shape,train_labels.shape),(test_images.shape,test_labels.shape)所以我们在训练集中有60,000张28x28的图像,在测试集有10,000张相同形状的图像。接下来,我们将调整图像大小并对目标变量进行一次性编码:#reshapingtheimagestrain_images=train_images.reshape((60000,28,28,1))test_images=test_images.reshape((10000,28,28,1))#onehotencodingthetargetvariabletrain_labels=to_categorical(train_labels)test_labels=to_categorical(test_labels)定义模型架构现在,我们将定义模型的架构。我们将使用Pytorch中定义的相同架构。因此,我们的模型将是2个卷积层和一个最大池化层的组合,然后我们将有一个Flatten层,最后是一个具有10个神经元的全连接层,因为我们有10个类。#definingthemodelarchitecturemodel=models.Sequential()model.add(layers.Conv2D(4,(3,3),activation='relu',input_shape=(28,28,1)))model.add(layers.MaxPooling2D((2,2),strides=2))model.add(layers.Conv2D(4,(3,3),activation='relu'))model.add(layers.MaxPooling2D((2,2),strides=2))model.add(layers.Flatten())model.add(layers.Dense(10,activation='softmax'))让我们快速看一下模型的总结:#summaryofthemodelmodel.summary()所以总结我们有2个卷积层、2个最大池化层、一个展平层和一个全连接层。模型中的参数总数为1198。现在我们的模型准备好了,我们将编译它:#compilingthemodelmodel.compile(optimizer='adam',loss='categorical_crossentropy',metrics=['accuracy'])我们使用的是Adam优化器,你也可以修改它使变化。损失函数设置为分类交叉熵,因为我们正在解决多类分类问题并且度量是“准确性”。现在让我们训练模型10个epochs#trainingthemodelhistory=model.fit(train_images,train_labels,epochs=10,validation_data=(test_images,test_labels))总之,最初,训练损失约为0.46,在10个epoch之后,训练损失下降到0.08。10个epoch后的训练和验证准确率分别为97.31%和97.48%。所以,这就是我们如何在TensorFlow中训练CNN。尾注总而言之,在本文中,我们首先对PyTorch和TensorFlow进行了简要概述。然后我们了解了MNIST手写数字分类挑战,最后,在PyTorch和TensorFlow中使用CNN(卷积神经网络)构建了图像分类模型。到目前为止,我希望您熟悉这两个框架。接下来,接受另一个图像分类挑战并尝试使用PyTorch和TensorFlow解决它。
