“几分钟建立一个深度学习模型?训练要花几个小时!我甚至没有一台足够好的机器。”无数从事数据科学研究的人都这样说,他们总是试图回避在自己的机器上构建深度学习模型。
其实,你不需要为谷歌或其他大型科技公司工作就可以使用深度学习数据集,在几分钟内从零开始建立起你自己的神经网络,而不需要租用谷歌的服务器也不再只是一个梦。Fast.ai的学生在Imagenet数据集上仅用18分钟就设计出了一个模型,本文将展示与其类似的模型构建过程。
深度学习是一个很广泛的领域,因此本文我们将把重点主要放在解决图像分类项目上。此外,我们将使用一个非常简单的深度学习体系结构来提高准确度。
你可以考虑将本文中看到的python代码作为构建图像分类模型的参考。一旦你对这个概念有了很好的理解,就可以试着参加比赛了!
什么是图像分类?
观察下面这张图:
你会立刻意识到这是一辆(豪华的)汽车。后退一步,分析你是如何得出这个结论的——你看到了一张图片并对它的所属类别进行了分类(本例中是一辆车)。简言之,这就是关于图像分类的一切。
对给定的图像进行分类,图像中可能有n个类别。手动检查和分类图像是一个非常繁琐的过程。当我们面对大量的图片,比如10000张甚至100000张时,这个任务几乎不可能完成。如果整个过程能够实现自动化,并根据相应的类快速标记图像,这将有多大的用处?
自动驾驶汽车是一个理解图像分类在现实世界中的应用的很好的例子。为了实现自动驾驶,我们可以建立一个图像分类模型来识别道路上的各种物体,例如汽车、人、移动物体等。在本文后面我们将会看到几个用例,周围还有更多的应用。
既然我们已经掌握了主题,那么让我们深入研究一下如何构建图像分类模型,它的先决条件是什么以及其如何在Python中实现。
设置图像数据的结构
为了解决图像分类问题,我们的数据需要采用特定的格式。我们将在几个部分中看到这一点,但在这之前,请记住这些指示。
你需要两个文件夹,一个用于训练集,另一个用于测试集。训练集文件夹中又包含一个.csv文件和一个图像文件夹:
- csv文件包含所有训练图像的名称及其相应的标签
- 图像文件夹包含所有的训练图像
测试集中的.csv文件与训练集中的不同。测试集中的.csv文件包含所有测试图像的名称,但不包含其相应的标签。你能猜到为什么吗?我们的模型将在训练集中的图像上进行训练,标签预测将在测试集中的图像上进行。
如果你的数据不是上面描述的格式,你需要相应地对其进行转换(否则预测将会是错误的、无用的)。
分解模型构建过程
在深入研究Python代码之前,让我们花点时间了解一下图像分类模型通常是如何设计的。我们可以把这个过程大致分为4个阶段。每个阶段都需要一定的时间来执行:
- 加载和预处理数据——30%的时间
- 定义模型架构——10%的时间
- 训练模型——50%的时间
- 性能评估——10%的时间
现在我们更详细地解释一下上面的每一个步骤。这一部分非常重要,因为并非所有模型都是一下子构建起来的。你需要在每次迭代之后返回,对步骤进行微调,然后再次运行。对基础概念有一个扎实的理解,对于加速整个过程将有很大的帮助。
阶段1:数据的加载和预处理
就深度学习模型而言,数据就是黄金。如果训练集中有大量的图像,你的图像分类模型将更有可能表现良好。此外,数据的形状根据我们使用的体系结构/框架而变化。
因此,强烈建议你学习“Python中图像处理的基础知识”,以进一步了解预处理如何处理图像数据。但我们目前还不用这么深入。为了了解我们的模型如何处理未见过的数据(以及在将其公开给测试集之前),我们需要创建一个验证集。这是通过划分训练集数据来完成的。
简言之,在训练集上训练模型,并在验证数据上加以验证。一旦我们对模型在验证集上的性能感到满意,就可以用其对测试数据进行预测。
此步骤所需时间:大约2-3分钟。
阶段2:定义模型架构
这是我们深度学习模型构建过程中的另一个关键步骤。我们必须定义模型的外观,这需要回答以下问题:
- 需要多少卷积层?
- 每层的激活功能是什么?
- 每层有多少隐藏单元?
还有很多问题,在此不再一一列举。这些本质上是模型的超参数,它们在决定预测有多准确方面起着重要作用。
我们如何决定这些值?好问题!一个好想法是根据现有的研究选择这些值。另一个想法是不断尝试这些值直到找到最佳匹配,但这可能是一个非常耗时的过程。
此步骤所需时间:大约1分钟。
阶段3:训练模型
为了训练数据,我们需要:
- 训练图像及其相应的正确标签
- 验证图像及其相应的正确标签(我们仅使用这些标签来验证模型,而不在训练阶段使用)
我们还明确了这个步骤中的时期数。首先,我们将运行10个时期的模型(你可以稍后更改时期的数量)。
此步骤所需时间:由于训练需要模型学习结构,我们需要大约5分钟来完成此步骤。
是时候做预测了!
阶段4:评估模型的性能
最后,我们加载测试数据(图像)并在此完成预处理步骤。然后我们使用训练模型为这些图像预测类。
此步骤所需时间:不超过1分钟。
建立问题陈述并理解数据
我们将接受一个非常酷的挑战来理解图像分类。建立一个模型,根据服装(衬衫、裤子、鞋子、袜子等)对给定的一组图像进行分类。这实际上是许多电子商务零售商面临的一个问题,这使其成为一个更有趣的计算机视觉问题。
这个挑战被称为“识别服装”,是DataHack平台上遇到的实践问题之一。
我们总共有70000张图像(28 x 28维),其中60000张来自训练集,10000张来自测试集。根据服装类型预先标记训练图像,共10个类别。当然,测试图像没有标签。挑战在于识别所有测试图像中的服装类型。
我们将在Google Colab上构建模型,因为其可为我们训练模型提供免费的GPU。
建立图像分类模型的步骤
是时候激发Python技能了。最终到达了动手实践部分了!
- 安装Google Colab
- 导入库
- 加载和预处理数据(3分钟)
- 创建验证集
- 定义模型结构(1分钟)
- 训练模型(5分钟)
- 预测(1分钟)
让我们一步一步来:
步骤 1:安装Google Colab
因为要从Google Drive链接导入数据,所以我们需要在Google Colabnotebook中添加几行代码。创建新的python 3notebook并编写以下代码块:
!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
接下来我们将创建一个驱动器变量来访问GoogleDrive:
auth.authenticate_user()
gauth = GoogleAuth()
gauth.credentials = GoogleCredentials.get_application_default()
drive = GoogleDrive(gauth)
为了下载数据集,我们将使用Google Drive上上传文件的ID:
download = drive.CreateFile({'id': '1BZOv422XJvxFUnGh-0xVeSvgFgqVY45q'})
将上述代码中的“id”替换为文件的id。现在,我们将下载此文件并解压缩:
download.GetContentFile('train_LbELtWX.zip')
!unzip train_LbELtWX.zip
每次启动notebook时都必须运行这些代码块。
步骤 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:定义模型结构
将创建一个具有两个卷积层、一个隐藏层和一个输出层的简单架构。
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)
下载此样本_cnn.csv文件,并将其上传到竞赛页面,已生成成绩并检查在排行榜上的排名。这将为你提供一个开始处理任何图像分类问题的参考解决方案!
你可以尝试超参数调整和正则化技术来进一步提高模型的性能。
接受另一个挑战
让我们在不同的数据集上测试学习效果。我们将在本节中解决“识别数字”练习问题,下载数据集。在继续之前,试着自己解决这个问题。你已经有了解决问题的工具——你只需要应用它们就行了!回来检查一下你的结果,或者如果你在某个时刻被卡住了。
在这个挑战中,我们需要识别给定图像中的数字。总共有70000张图片–在训练集中有49000张贴有标签的图片,在测试集中有21000张(测试图片没有标签)。我们需要识别/预测这些未标记图像的类别。
准备好开始了吗?棒极了!创建新的python 3 notebook并运行以下代码:
# 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)
在练习题页面上提交这个文件,得到一个相当不错的准确数字。这是一个好的开端,但总有改进的余地。继续调整超参数值,看看你是否可以改进基本模型。
本文转自公众号 读芯术,原文地址