用卷积神经网络模型辨认不同时尚服装,四种方法对比

2018 年 11 月 6 日 论智
来源:Medium
编译:Bing

在实体店买衣服的过程中,我们会被眼花缭乱的信息轰炸。要兼顾某件衣服的款式、价格、商场优惠还不够,商场的灯光、拥挤的过道,无时无刻不在考验着人们分辨信息的能力。

那么,电脑能自动检测衬衫、裤子、连衣裙或运动鞋的照片吗?事实证明,如果有高质量的训练数据,准确地对时尚单品图片进行分类是很很容易做到的。在本文中,我们将讲解如何用Fashion-MNIST数据集搭建一个用于辨认时尚单品的机器学习模型。我们会提到如何训练模型、针对类别分类设计输入和输出以及每个模型的最终结果。

图像分类

这一任务中涉及到的问题包括视角的变化、尺度变化、同类的多种变化、照片形变、照片遮挡、光线条件、背景等问题。如何写出一套可以区分图片类型的算法呢?计算机视觉研究人员提出了一种数据驱动的方法来解决。过去,人们会了解每一图片类别的代码,从而进行分类。现在,研究人员从每类图像中都选出一些样本,训练深度学习算法学习每种类别的特点。换句话说,他们首先收集带标签的训练数据集,然后输入到计算机中,让计算机熟悉这些数据。

主要步骤如下:

  • 输入的是一个含有N张图片的数据集,每张图片都带有类别标签,数据集中共有K个不同的类别。

  • 之后,我们用训练集去训练一个分类器,学习每种类别的样式。

  • 最后,让分类器对陌生图片进行标签预测,从而对分类器质量进行评估。之后我们会比较真实标签和分类器的预测标签。

Fashion MNIST数据集

去年八月份,德国研究机构Zalando Research在GitHub上推出了一个全新的数据集,其中训练集包含60000个样例,测试集包含10000个样例,分为10类,其中的样本都来自日常穿着的衣裤鞋包,每个都是28×28的灰度图像,其中总共有10类标签,每张图像都有各自的标签。

10种标签包括:

  • 0:T-shirt/上衣

  • 1:裤子

  • 2:套头衫

  • 3:连衣裙

  • 4:大衣

  • 5:凉鞋

  • 6:衬衣

  • 7:运动鞋

  • 8:包

  • 9:高帮鞋

Fashion MNIST的可视化嵌入

嵌入是一种将分散目标(图像、文字等等)映射到高维向量中的方法。这些向量中的每个维度通常都没有内在意义,机器学习运用的是想两件的距离和总体的模式。在这里,我打算用TensorBoard表示高维的Fashion MNIST数据。阅读了数据并创建测试标签后,我用以下代码创建了TensorBoard的嵌入投射器:

  
  
    
  1. from tensorflow.contrib.tensorboard.plugins import projector

  2. logdir = 'fashionMNIST-logs'

  3. # Creating the embedding variable with all the images defined above under X_test

  4. embedding_var = tf.Variable(X_test, name='fmnist_embedding')

  5. # Format: tensorflow/contrib/tensorboard/plugins/projector/projector_config.proto

  6. config = projector.ProjectorConfig()

  7. # You can add multiple embeddings. Here I add only one.

  8. embedding = config.embeddings.add()

  9. embedding.tensor_name = embedding_var.name

  10. # Link this tensor to its metadata file (e.g. labels).

  11. embedding.metadata_path = os.path.join(logdir, 'metadata.tsv')

  12. # Use this logdir to create a summary writer

  13. summary_writer = tf.summary.FileWriter(logdir)

  14. # The next line writes a projector_config.pbtxt in the logdir. TensorBoard will read this file during startup.

  15. projector.visualize_embeddings(summary_writer,config)

  16. # Periodically save the model variables in a checkpoint in logdir.

  17. with tf.Session() as sesh:

  18.    sesh.run(tf.global_variables_initializer())

  19.    saver = tf.train.Saver()

  20.    saver.save(sesh, os.path.join(logdir, 'model.ckpt'))

  21. # Create the sprite image

  22. rows = 28

  23. cols = 28

  24. label = ['T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat', 'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot']

  25. sprite_dim = int(np.sqrt(X_test.shape[0]))

  26. sprite_image = np.ones((cols * sprite_dim, rows * sprite_dim))

  27. index = 0

  28. labels = []

  29. for i in range(sprite_dim):

  30.    for j in range(sprite_dim):

  31.        labels.append(label[int(Y_test[index])])

  32.        sprite_image[

  33.            i * cols: (i + 1) * cols,

  34.            j * rows: (j + 1) * rows

  35.        ] = X_test[index].reshape(28, 28) * -1 + 1

  36.        index += 1

  37. # After constructing the sprite, I need to tell the Embedding Projector where to find it

  38. embedding.sprite.image_path = os.path.join(logdir, 'sprite.png')

  39. embedding.sprite.single_image_dim.extend([28, 28])

  40. # Create the metadata (labels) file

  41. with open(embedding.metadata_path, 'w') as meta:

  42.    meta.write('Index\tLabel\n')

  43.    for index, label in enumerate(labels):

  44.        meta.write('{}\t{}\n'.format(index, label))

该投射器有三种对数据集降维的方法,两种线性方法,一种非线性方法。每种方法都能用于创建二维或三维场景。

PCA:PCA是一种用于直接降维的技术,嵌入投射器计算前十位的主要成分,通过菜单,我们可以将那些成分投射成任意两种或三种的结合上。PCA是一个线性工具,通常在检查全局几何结构上非常高效。

t-SNE:这是一种流行的非线性降维方法,嵌入投射器会同时提供二维和三维的t-SNE视图。在客户端可以看到平面图,能展示出每一步算法。由于t-SNE通常会保留一些局部结构,这在探索局部近邻、找寻聚类中是很有用的。

Custom:我还可以基于文本搜索创建特殊的线性投射器,用于在空间中寻找有意义的方向。程序可以计算这些点集的中心点,他们的标签可以与搜索匹配,利用向量之间的不同作为投射器的轴。

查看完成的可视化步骤代码,可点击此网址:github.com/khanhnamle1994/fashion-mnist/blob/master/TensorBoard-Visualization.ipynb

在Fashion MNIST上训练CNN模型

接下来,我会创建多个基于CNN的分类模型,在Fashion MNIST上评估模型性能。我会用Keras框架搭建模型,想了解框架的更多信息,可以点击此网址:keras.io/。下面是我想要比较的四种模型:

  • 有一层卷积层的CNN

  • 有三层卷积层的CNN

  • 有四层卷积层的CNN

  • 经过与训练的VGG-19模型

除了预训练模型,我的实验方法如下:

  • 将原始训练数据(共60000张图片)分成训练集和验证集两部分,80%是训练集,20%是验证集,另外还有10000张测试图片,用于最终测试模型在陌生图像上的表现。这可以研究模型是否在训练数据上过度拟合,以及是否应该降低学习速率。

  • 用256的batch size训练模型10个epoch,同时用categorical_crossentropy损失函数和Adam优化器共同编译。

  • 之后进行数据增强,可以通过旋转、变化、缩放生成新的训练样本,再通过50个epoch对模型进行训练。

以下是下载数据并分离数据的代码:

  
  
    
  1. # Import libraries

  2. from keras.utils import to_categorical

  3. from sklearn.model_selection import train_test_split

  4. # Load training and test data into dataframes

  5. data_train = pd.read_csv('data/fashion-mnist_train.csv')

  6. data_test = pd.read_csv('data/fashion-mnist_test.csv')

  7. # X forms the training images, and y forms the training labels

  8. X = np.array(data_train.iloc[:, 1:])

  9. y = to_categorical(np.array(data_train.iloc[:, 0]))

  10. # Here I split original training data to sub-training (80%) and validation data (20%)

  11. X_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.2, random_state=13)

  12. # X_test forms the test images, and y_test forms the test labels

  13. X_test = np.array(data_test.iloc[:, 1:])

  14. y_test = to_categorical(np.array(data_test.iloc[:, 0]))

下载数据后,我会重新处理它们,让它们的值处于0到1之间。此前,训练数据都被存储在一个(60000,28,28)的数组中,其中的值在0到255之间。

  
  
    
  1. # Each image's dimension is 28 x 28

  2. img_rows, img_cols = 28, 28

  3. input_shape = (img_rows, img_cols, 1)

  4. # Prepare the training images

  5. X_train = X_train.reshape(X_train.shape[0], img_rows, img_cols, 1)

  6. X_train = X_train.astype('float32')

  7. X_train /= 255

  8. # Prepare the test images

  9. X_test = X_test.reshape(X_test.shape[0], img_rows, img_cols, 1)

  10. X_test = X_test.astype('float32')

  11. X_test /= 255

  12. # Prepare the validation images

  13. X_val = X_val.reshape(X_val.shape[0], img_rows, img_cols, 1)

  14. X_val = X_val.astype('float32')

  15. X_val /= 255

一层卷积层CNN

下面是只有一层卷积层的CNN代码:

  
  
    
  1. from keras.models import Sequential

  2. from keras.layers import Dense, Dropout, Flatten

  3. from keras.layers import Conv2D, MaxPooling2D

  4. cnn1 = Sequential()

  5. cnn1.add(Conv2D(32, kernel_size=(3, 3), activation='relu', input_shape=input_shape))

  6. cnn1.add(MaxPooling2D(pool_size=(2, 2)))

  7. cnn1.add(Dropout(0.2))

  8. cnn1.add(Flatten())

  9. cnn1.add(Dense(128, activation='relu'))

  10. cnn1.add(Dense(10, activation='softmax'))

  11. cnn1.compile(loss=keras.losses.categorical_crossentropy,

  12.              optimizer=keras.optimizers.Adam(),

  13.              metrics=['accuracy'])

训练完模型后,下面是测试损失和测试精确度:

进行数据增强后的测试损失和测试精确度:

训练和验证精确度和损失的可视化:

完整代码请点击:github.com/khanhnamle1994/fashion-mnist/blob/master/CNN-1Conv.ipynb

三层卷积层CNN

有三层卷积层的CNN代码:

  
  
    
  1. from keras.models import Sequential

  2. from keras.layers import Dense, Dropout, Flatten

  3. from keras.layers import Conv2D, MaxPooling2D

  4. cnn3 = Sequential()

  5. cnn3.add(Conv2D(32, kernel_size=(3, 3), activation='relu', input_shape=input_shape))

  6. cnn3.add(MaxPooling2D((2, 2)))

  7. cnn3.add(Dropout(0.25))

  8. cnn3.add(Conv2D(64, kernel_size=(3, 3), activation='relu'))

  9. cnn3.add(MaxPooling2D(pool_size=(2, 2)))

  10. cnn3.add(Dropout(0.25))

  11. cnn3.add(Conv2D(128, kernel_size=(3, 3), activation='relu'))

  12. cnn3.add(Dropout(0.4))

  13. cnn3.add(Flatten())

  14. cnn3.add(Dense(128, activation='relu'))

  15. cnn3.add(Dropout(0.3))

  16. cnn3.add(Dense(10, activation='softmax'))

  17. cnn3.compile(loss=keras.losses.categorical_crossentropy,

  18.              optimizer=keras.optimizers.Adam(),

  19.              metrics=['accuracy'])

训练模型后,测试损失和测试精确度:

数据增强后的测试损失和精确度:

训练和验证的精确度和损失:

完整代码请点击:github.com/khanhnamle1994/fashion-mnist/blob/master/CNN-3Conv.ipynb

四层卷积层的CNN

下面是四层卷积层的CNN代码:

  
  
    
  1. from keras.models import Sequential

  2. from keras.layers import Dense, Dropout, Flatten

  3. from keras.layers import Conv2D, MaxPooling2D, BatchNormalization

  4. cnn4 = Sequential()

  5. cnn4.add(Conv2D(32, kernel_size=(3, 3), activation='relu', input_shape=input_shape))

  6. cnn4.add(BatchNormalization())

  7. cnn4.add(Conv2D(32, kernel_size=(3, 3), activation='relu'))

  8. cnn4.add(BatchNormalization())

  9. cnn4.add(MaxPooling2D(pool_size=(2, 2)))

  10. cnn4.add(Dropout(0.25))

  11. cnn4.add(Conv2D(64, kernel_size=(3, 3), activation='relu'))

  12. cnn4.add(BatchNormalization())

  13. cnn4.add(Dropout(0.25))

  14. cnn4.add(Conv2D(128, kernel_size=(3, 3), activation='relu'))

  15. cnn4.add(BatchNormalization())

  16. cnn4.add(MaxPooling2D(pool_size=(2, 2)))

  17. cnn4.add(Dropout(0.25))

  18. cnn4.add(Flatten())

  19. cnn4.add(Dense(512, activation='relu'))

  20. cnn4.add(BatchNormalization())

  21. cnn4.add(Dropout(0.5))

  22. cnn4.add(Dense(128, activation='relu'))

  23. cnn4.add(BatchNormalization())

  24. cnn4.add(Dropout(0.5))

  25. cnn4.add(Dense(10, activation='softmax'))

  26. cnn4.compile(loss=keras.losses.categorical_crossentropy,

  27.              optimizer=keras.optimizers.Adam(),

  28.              metrics=['accuracy'])

训练模型后的测试损失和精确度:

数据增强后的测试损失和精确度:

训练和验证的精确度和损失:

完整代码请点击:github.com/khanhnamle1994/fashion-mnist/blob/master/CNN-4Conv.ipynb

迁移学习

在小数据集上常用的一种高效深度学习方法就是使用预训练网络。一种预训练网络是此前在大型数据集上训练过的网络,通常处理过大型图像分类任务。如果这样的原始数据集足够大并且足够通用,那么预训练网络学习到的特征空间分层可以用于视觉世界的普通模型,它的特征可以解决很多不同的计算机视觉问题。

我尝试使用VGG19预训练模型,这在ImageNet中广泛使用的ConvNets架构。以下是所用的代码:

  
  
    
  1. import keras

  2. from keras.applications import VGG19

  3. from keras.applications.vgg19 import preprocess_input

  4. from keras.layers import Dense, Dropout

  5. from keras.models import Model

  6. from keras import models

  7. from keras import layers

  8. from keras import optimizers

  9. # Create the base model of VGG19

  10. vgg19 = VGG19(weights='imagenet', include_top=False, input_shape = (150, 150, 3), classes = 10)

  11. # Preprocessing the input

  12. X_train = preprocess_input(X_train)

  13. X_val = preprocess_input(X_val)

  14. X_test = preprocess_input(X_test)

  15. # Extracting features

  16. train_features = vgg19.predict(np.array(X_train), batch_size=256, verbose=1)

  17. test_features = vgg19.predict(np.array(X_test), batch_size=256, verbose=1)

  18. val_features = vgg19.predict(np.array(X_val), batch_size=256, verbose=1)

  19. # Flatten extracted features

  20. train_features = np.reshape(train_features, (48000, 4*4*512))

  21. test_features = np.reshape(test_features, (10000, 4*4*512))

  22. val_features = np.reshape(val_features, (12000, 4*4*512))

  23. # Add Dense and Dropout layers on top of VGG19 pre-trained

  24. model = models.Sequential()

  25. model.add(layers.Dense(512, activation='relu', input_dim=4 * 4 * 512))

  26. model.add(layers.Dropout(0.5))

  27. model.add(layers.Dense(10, activation="softmax"))

  28. # Compile the model

  29. model.compile(loss=keras.losses.categorical_crossentropy,

  30.              optimizer=keras.optimizers.Adam(),

  31.              metrics=['accuracy'])

模型训练后,测试损失和精确度如下:

可视化:

结语

时尚领域是计算机视觉和机器学习应用的热门,由于其中的予以复杂性,导致问题难度增加。希望这篇文章能对你在图像分类任务上有所启发。

原文地址:towardsdatascience.com/the-4-convolutional-neural-network-models-that-can-classify-your-fashion-images-9fe7f3e5399d

星标论智,每天获取最新资讯

登录查看更多
1

相关内容

FashionMNIST 是一个替代 MNIST 手写数字集的图像数据集。 它是由 Zalando(一家德国的时尚科技公司)旗下的研究部门提供。其涵盖了来自 10 种类别的共 7 万个不同商品的正面图片。FashionMNIST 的大小、格式和训练集/测试集划分与原始的 MNIST 完全一致。60000/10000 的训练测试数据划分,28x28 的灰度图片。你可以直接用它来测试你的机器学习和深度学习算法性能,且不需要改动任何的代码。
【KDD2020-清华大学】图对比编码的图神经网络预训练
专知会员服务
43+阅读 · 2020年6月18日
专知会员服务
73+阅读 · 2020年5月21日
【Amazon】使用预先训练的Transformer模型进行数据增强
专知会员服务
56+阅读 · 2020年3月6日
【模型泛化教程】标签平滑与Keras, TensorFlow,和深度学习
专知会员服务
20+阅读 · 2019年12月31日
 图像内容自动描述技术综述
专知会员服务
84+阅读 · 2019年11月17日
零样本图像分类综述 : 十年进展
专知会员服务
123+阅读 · 2019年11月16日
基于TensorFlow和Keras的图像识别
Python程序员
16+阅读 · 2019年6月24日
手把手教你用Keras进行多标签分类(附代码)
数据派THU
11+阅读 · 2018年7月17日
一个小例子带你轻松Keras图像分类入门
云栖社区
4+阅读 · 2018年1月24日
Python实现对12500张猫狗图像的精准分类
机器学习算法与Python学习
3+阅读 · 2018年1月18日
我用Python实现了12500张猫狗图像的精准分类
51CTO博客
4+阅读 · 2018年1月12日
Arxiv
11+阅读 · 2018年5月13日
Arxiv
4+阅读 · 2016年12月29日
VIP会员
相关VIP内容
【KDD2020-清华大学】图对比编码的图神经网络预训练
专知会员服务
43+阅读 · 2020年6月18日
专知会员服务
73+阅读 · 2020年5月21日
【Amazon】使用预先训练的Transformer模型进行数据增强
专知会员服务
56+阅读 · 2020年3月6日
【模型泛化教程】标签平滑与Keras, TensorFlow,和深度学习
专知会员服务
20+阅读 · 2019年12月31日
 图像内容自动描述技术综述
专知会员服务
84+阅读 · 2019年11月17日
零样本图像分类综述 : 十年进展
专知会员服务
123+阅读 · 2019年11月16日
相关资讯
基于TensorFlow和Keras的图像识别
Python程序员
16+阅读 · 2019年6月24日
手把手教你用Keras进行多标签分类(附代码)
数据派THU
11+阅读 · 2018年7月17日
一个小例子带你轻松Keras图像分类入门
云栖社区
4+阅读 · 2018年1月24日
Python实现对12500张猫狗图像的精准分类
机器学习算法与Python学习
3+阅读 · 2018年1月18日
我用Python实现了12500张猫狗图像的精准分类
51CTO博客
4+阅读 · 2018年1月12日
Top
微信扫码咨询专知VIP会员