“在几分钟内建立一个深度学习模型?训练需要几个小时!我甚至没有一台足够好的机器。“我曾经无数次地听过数据科学家这样的抱怨,他们不愿在自己的机器上建立深度学习模型。
事实上,完全可以在几分钟内从头开始构建自己的神经网络,而无需租用大型服务器。 Fast.ai的学生在18分钟内在Imagenet数据集上设计了一个模型 – 我将在本文中展示类似的内容。
深度学习是一个广阔的领域,因此我们将缩小我们的注意力并聚焦在解决图像分类项目的挑战。此外,我们将使用一个非常简单的深度学习架构来获得令人印象深刻的准确度分数。
您可以将本文中看到的Python代码视为构建图像分类模型的基准。一旦掌握了这个概念,就可以继续使用代码,参加比赛并登上排行榜前列!
如果您刚接触深度学习并且对计算机视觉领域着迷(谁不是?!),请查看’使用深度学习的计算机视觉‘当然。
目录
- 什么是图像分类及其用例
- 设置图像数据的结构
- 打破模型构建过程
- 设置问题陈述和理解数据
- 构建图像分类模型的步骤
- 迎接另一个挑战
什么是图像分类?
考虑下面的图像:
你会立即认出它 – 它是一辆(时髦的)汽车。退后一步,分析你是如何得出这个结论的 – 你被展示了一个图像,你将它所属的类别分类(在这种情况下是一辆汽车)。简而言之,这就是图像分类的全部意义所在。
手动检查和分类图像是一个非常繁琐的过程。当我们面对大量的图像,比如10000张或甚至100,000张时,任务变得几乎不可能。如果我们能够自动完成整个过程并根据相应的类快速标记图像,那将会有多大用处?
自动驾驶汽车是了解现实世界中图像分类使用的一个很好的例子。为了实现自动驾驶,我们可以构建一种图像分类模型,用于识别道路上的各种物体,例如车辆,人,移动物体等。
接下来让我们深入探讨如何构建图像分类模型,它的先决条件是什么,以及如何在Python中实现它。
设置图像数据结构
我们的数据需要采用特定格式才能解决图像分类问题。
您应该有2个数据文件,一个用于训练,另一个用于测试集。在训练集中,您将拥有.csv文件和图像文件夹:
- .csv文件包含所有训练图像的名称及其对应的真实标签
- 图像文件夹包含所有训练图像。
我们的测试集中的.csv文件与训练集中的文件不同。此测试集.csv文件包含所有测试图像的名称,但它们不要有任何相应的标签。我们的模型将根据训练集中的图像进行训练,标签预测将在测试集图像上进行
如果您的数据不是上述格式,则需要相应地进行转换。
打破模型构建过程
在深入研究Python代码之前,让我们花点时间了解一下图像分类模型的设计方式。我们可以将这个过程大致分为4个阶段。每个阶段都需要一定的时间来执行:
- 加载数据和预处理数据 – 30%的时间
- 定义模型结构 – 10%的时间
- 训练模型 – 50%的时间
- 性能评估 – 10%时间
让我更详细地解释上述每个步骤。这部分是至关重要的,因为不是每个模型都是一步到位的。您需要在每次迭代后返回,调优您的步骤,然后再次运行它。深入了解基本概念将大大加快整个过程。
阶段1:加载和预处理数据
就深度学习模型而言,数据是黄金(数据挖的天花板上数据本省)。如果您在训练集中拥有大量图像,则您的图像分类模型将有更好的表现。此外,数据的形式根据我们使用的架构/框架而有所不同。
因此,关键数据预处理步骤(任何项目中永恒的重要步骤)。我强烈建议你去看看’Python中图像处理的基础知识‘了解更多有关预处理如何处理图像数据的信息。
为了了解我们的模型如何对看不见的数据的执行效果,我们需要创建一个验证集。这是通过划分训练集数据来完成的。
简而言之,我们在训练数据上训练模型并在验证数据上进行验证。一旦我们对模型在验证集上的性能感到满意,我们就可以使用它来对测试数据进行预测。
此步骤所需的时间:2-3分钟左右。
第2阶段:定义模型的结构
这是我们深度学习模型构建过程中的另一个关键步骤。我们必须定义我们的模型的结构,并且需要回答以下问题:
- 我们想要多少个卷积层?
- 每层的激活函数应该是什么?
- 每层应该有多少隐藏节点?
除此之外,还有很多需要考察的点。这些本质上是模型的超参数,它在决定预测的好坏方面起着很大的作用。
我们如何决定这些超参数值?好问题!一个好主意是根据现有的研究/调查选择这些值。另一个想法是不断尝试不同的值,直到找到最佳匹配,但这可能是一个非常耗时的过程。
此步骤所需的时间:需要1分钟定义模型的体系结构。
第3阶段:训练模型
为了训练模型,我们要求:
- 训练图像及其相应的真实标签
- 验证图像及其相应的真实标签(我们仅使用这些标签来验证模型,而不是在训练阶段)
我们还定义了此步骤中的epochs(将训练数据完整跑一遍成为一个epoch)。对于初学者,我们将运行模型10个epochs(您可以稍后更改epochs的数量)。
此步骤所需的时间:由于训练需要模型来学习结构,我们需要大约5分钟完成这一步。
接下来可以做预测了!
第4阶段:估计模型的性能
最后,我们加载测试数据(图像)并在此处完成预处理步骤。然后,我们使用训练模型预测这些图像的类别。
此步骤所需的时间:~1分钟。
设置问题和理解数据
我们将挑选一个非常酷的挑战来理解图像分类。我们要建立一个模型,可以根据服装(衬衫,裤子,鞋子,袜子等)对一组给定的图像进行分类。这实际上是许多电商零售商面临的问题,这使得它成为一个非常热门的计算机视觉问题。
这一挑战被称为’识别服装‘并且是我们对我们的DataHack平台实践问题之一。您必须从上面的链接注册并下载数据集。
我们总共有70,000张图像(28 x 28维),其中60,000张来自训练集,10,000张来自测试集。根据服装类型,训练图像已标记类别,总共10类。当然,测试图像没有标记。挑战在于确定所有测试图像中存在的服装类型。
我们将在谷歌Colab建立我们的模型,因为它提供了免费的GPU来训练我们的模型。
构建模型的步骤
是时候使用Python技能开始干活了!
- 设置Google Colab
- 导入库
- 加载和预处理数据 – (3分钟)
- 创建验证集
- 定义模型结构 – (1分钟)
- 训练模型 – (5分钟)
- 做出预测 – (1分钟)
让我们详细看一下每一步。
步骤1:设置Google Colab
由于我们从Google云端硬盘链接导入数据,因此我们需要在Google Colab笔记本中添加几行代码。创建一个新的Python 3笔记本并编写以下代码块:
!pip install PyDrive
这将安装PyDrive。现在我们将导入一些必需的库:
import os
from pydrive.auth import GoogleAuth
from pydrive.drive import GoogleDrive
from google.colab import auth
from oauth2client.client import GoogleCredentials
接下来,我们将创建一个驱动器变量来访问Google云端硬盘:
auth.authenticate_user()
gauth = GoogleAuth()
gauth.credentials = GoogleCredentials.get_application_default()
drive = GoogleDrive(gauth)
要下载数据集,我们将使用Google云端硬盘上传文件的ID:
download = drive.CreateFile({'id': '1BZOv422XJvxFUnGh-0xVeSvgFgqVY45q'})
将上述代码中的“id”替换为您的文件ID。现在我们将下载此文件并解压缩:
download.GetContentFile('train_LbELtWX.zip') !unzip train_LbELtWX.zip
每次启动笔记本时都必须运行这些代码块。
第2步:导入我们在模型构建阶段需要的库。
import keras
from keras.models import Sequential
from keras.layers import Dense, Dropout, Flatten
from keras.layers import Conv2D, MaxPooling2D
from keras.utils import to_categorical
from keras.preprocessing import image
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from keras.utils import to_categorical
from tqdm import tqdm
第3步:回想一下前面讨论过的预处理步骤。我们将在加载数据后在这里使用它们。
train = pd.read_csv('train.csv')
接下来,我们将读取所有训练图像,将它们存储在列表中,最后将该列表转换为numpy数组。
# We have grayscale images, so while loading the images we will keep grayscale=True, if you have RGB images, you should set grayscale as False
train_image = []
for i in tqdm(range(train.shape[0])):
img = image.load_img('train/'+train['id'][i].astype('str')+'.png', target_size=(28,28,1), grayscale=True)
img = image.img_to_array(img)
img = img/255
train_image.append(img)
X = np.array(train_image)
由于它是多类别分类问题(10个类),我们将使用one-hot编码目标变量。
y=train['label'].values
y = to_categorical(y)
第4步:从训练数据创建验证集。
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=42, test_size=0.2)
第5步:定义模型结构。
我们将创建一个具有2个卷积层,一个dense隐藏层和一个输出层的简单架构。
model = Sequential()
model.add(Conv2D(32, kernel_size=(3, 3),activation='relu',input_shape=(28,28,1)))
model.add(Conv2D(64, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(128, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(10, activation='softmax'))
接下来,我们将编译我们创建的模型。
model.compile(loss='categorical_crossentropy',optimizer='Adam',metrics=['accuracy'])
第6步:训练模型。
在这一步中,我们将在训练集图像上训练模型,并通过是否猜对了验证集来验证它。
model.fit(X_train, y_train, epochs=10, validation_data=(X_test, y_test))
第7步:做出预测!
我们最初将遵循我们在处理训练数据时执行的步骤。加载测试图像并使用。预测它们的类别,model.predict_classes()函数。
download = drive.CreateFile({'id': '1KuyWGFEpj7Fr2DgBsW8qsWvjqEzfoJBY'})
download.GetContentFile('test_ScVgIM0.zip')
!unzip test_ScVgIM0.zip
让我们导入测试文件:
test = pd.read_csv('test.csv')
现在,我们将读取并存储所有测试图像:
test_image = []
for i in tqdm(range(test.shape[0])):
img = image.load_img('test/'+test['id'][i].astype('str')+'.png', target_size=(28,28,1), grayscale=True)
img = image.img_to_array(img)
img = img/255
test_image.append(img)
test = np.array(test_image)
# making predictions
prediction = model.predict_classes(test)
我们还将创建一个提交文件,以便在DataHack平台页面上传(以查看我们的结果在排行榜上的表现)。
download = drive.CreateFile({'id': '1z4QXy7WravpSj-S4Cs9Fk8ZNaX-qh5HF'})
download.GetContentFile('sample_submission_I5njJSF.csv')
# creating submission file
sample = pd.read_csv('sample_submission_I5njJSF.csv')
sample['label'] = prediction
sample.to_csv('sample_cnn.csv', header=True, index=False)
下载这个sample_cnn.csv提交并上传到比赛页面以生成结果并检查排行榜上的排名。这将为您提供基准解决方案,帮助您开始解决任何图像分类问题!
您可以尝试使用超参数调整和正则化技术来进一步提高模型的性能。建议你查看这篇文章,以更详细地了解这个调优(fine-tuning)步骤 – ‘从头开始学习卷积神经网络的综合教程”。
挑选不同的挑战
让我们在不同的数据集上测试我们的学习效果。这里我们会实践破解’识别数字‘。继续下载数据集。在继续之前,请尝试自行解决此问题。你已经有了解决它的工具 – 你只需要应用它们!
在这个挑战中,我们需要识别给定图像中的数字。我们共有70,000张图像 – 训练集中49,000个标记图像,测试集中剩余21,000个图像(测试图像未标记)。我们需要识别/预测这些未标记图像的类别。
准备开始了吗?真棒!创建一个新的Python 3笔记本并运行以下代码:
# Setting up Colab
!pip install PyDrive
import os
from pydrive.auth import GoogleAuth
from pydrive.drive import GoogleDrive
from google.colab import auth
from oauth2client.client import GoogleCredentials
auth.authenticate_user()
gauth = GoogleAuth()
gauth.credentials = GoogleCredentials.get_application_default()
drive = GoogleDrive(gauth)
# Replace the id and filename in the below codes
download = drive.CreateFile({'id': '1ZCzHDAfwgLdQke_GNnHp_4OheRRtNPs-'})
download.GetContentFile('Train_UQcUa52.zip')
!unzip Train_UQcUa52.zip
# Importing libraries
import keras
from keras.models import Sequential
from keras.layers import Dense, Dropout, Flatten
from keras.layers import Conv2D, MaxPooling2D
from keras.utils import to_categorical
from keras.preprocessing import image
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from keras.utils import to_categorical
from tqdm import tqdm
train = pd.read_csv('train.csv')
# Reading the training images train_image = [] for i in tqdm(range(train.shape[0])): img = image.load_img('Images/train/'+train['filename'][i], target_size=(28,28,1), grayscale=True) img = image.img_to_array(img) img = img/255 train_image.append(img) X = np.array(train_image)
# Creating the target variable
y=train['label'].values
y = to_categorical(y)
# Creating validation set X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=42, test_size=0.2)
# Define the model structure
model = Sequential()
model.add(Conv2D(32, kernel_size=(3, 3),activation='relu',input_shape=(28,28,1)))
model.add(Conv2D(64, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(128, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(10, activation='softmax'))
# Compile the model model.compile(loss='categorical_crossentropy',optimizer='Adam',metrics=['accuracy'])
# Training the model
model.fit(X_train, y_train, epochs=10, validation_data=(X_test, y_test))
download = drive.CreateFile({'id': '1zHJR6yiI06ao-UAh_LXZQRIOzBO3sNDq'})
download.GetContentFile('Test_fCbTej3.csv')
test_file = pd.read_csv('Test_fCbTej3.csv')
test_image = []
for i in tqdm(range(test_file.shape[0])):
img = image.load_img('Images/test/'+test_file['filename'][i], target_size=(28,28,1), grayscale=True)
img = image.img_to_array(img)
img = img/255
test_image.append(img)
test = np.array(test_image)
prediction = model.predict_classes(test)
download = drive.CreateFile({'id': '1nRz5bD7ReGrdinpdFcHVIEyjqtPGPyHx'})
download.GetContentFile('Sample_Submission_lxuyBuB.csv')
sample = pd.read_csv('Sample_Submission_lxuyBuB.csv')
sample['filename'] = test_file['filename']
sample['label'] = prediction
sample.to_csv('sample.csv', header=True, index=False)
在练习题页面上提交此文件以获得相当不错的准确度数字。这是一个良好的开端,但总有改进的余地。继续调整超参数值,看看你是否可以改进我们的基本模型。
后记
谁说深度学习模型需要数小时或数天来训练。我的目标是展示你可以在短时间内搞定一个相当不错的深度学习模型。您应该接受类似的挑战,并尝试编码。没有什么比边学边做更有效了!