在實體店買衣服的過程中,我們會被眼花繚亂的信息轟炸。要兼顧某件衣服的款式、價格、商場優(yōu)惠還不夠,商場的燈光、擁擠的過道,無時無刻不在考驗著人們分辨信息的能力。
那么,電腦能自動檢測襯衫、褲子、連衣裙或運動鞋的照片嗎?事實證明,如果有高質(zhì)量的訓(xùn)練數(shù)據(jù),準(zhǔn)確地對時尚單品圖片進行分類是很很容易做到的。在本文中,我們將講解如何用Fashion-MNIST數(shù)據(jù)集搭建一個用于辨認時尚單品的機器學(xué)習(xí)模型。我們會提到如何訓(xùn)練模型、針對類別分類設(shè)計輸入和輸出以及每個模型的最終結(jié)果。
圖像分類
這一任務(wù)中涉及到的問題包括視角的變化、尺度變化、同類的多種變化、照片形變、照片遮擋、光線條件、背景等問題。如何寫出一套可以區(qū)分圖片類型的算法呢?計算機視覺研究人員提出了一種數(shù)據(jù)驅(qū)動的方法來解決。過去,人們會了解每一圖片類別的代碼,從而進行分類。現(xiàn)在,研究人員從每類圖像中都選出一些樣本,訓(xùn)練深度學(xué)習(xí)算法學(xué)習(xí)每種類別的特點。換句話說,他們首先收集帶標(biāo)簽的訓(xùn)練數(shù)據(jù)集,然后輸入到計算機中,讓計算機熟悉這些數(shù)據(jù)。
主要步驟如下:
輸入的是一個含有N張圖片的數(shù)據(jù)集,每張圖片都帶有類別標(biāo)簽,數(shù)據(jù)集中共有K個不同的類別。
之后,我們用訓(xùn)練集去訓(xùn)練一個分類器,學(xué)習(xí)每種類別的樣式。
最后,讓分類器對陌生圖片進行標(biāo)簽預(yù)測,從而對分類器質(zhì)量進行評估。之后我們會比較真實標(biāo)簽和分類器的預(yù)測標(biāo)簽。
Fashion MNIST數(shù)據(jù)集
去年八月份,德國研究機構(gòu)Zalando Research在GitHub上推出了一個全新的數(shù)據(jù)集,其中訓(xùn)練集包含60000個樣例,測試集包含10000個樣例,分為10類,其中的樣本都來自日常穿著的衣褲鞋包,每個都是28×28的灰度圖像,其中總共有10類標(biāo)簽,每張圖像都有各自的標(biāo)簽。
10種標(biāo)簽包括:
0:T-shirt/上衣
1:褲子
2:套頭衫
3:連衣裙
4:大衣
5:涼鞋
6:襯衣
7:運動鞋
8:包
9:高幫鞋
Fashion MNIST的可視化嵌入
嵌入是一種將分散目標(biāo)(圖像、文字等等)映射到高維向量中的方法。這些向量中的每個維度通常都沒有內(nèi)在意義,機器學(xué)習(xí)運用的是想兩件的距離和總體的模式。在這里,我打算用TensorBoard表示高維的Fashion MNIST數(shù)據(jù)。閱讀了數(shù)據(jù)并創(chuàng)建測試標(biāo)簽后,我用以下代碼創(chuàng)建了TensorBoard的嵌入投射器:
from tensorflow.contrib.tensorboard.plugins import projector
logdir = 'fashionMNIST-logs'
# Creating the embedding variable with all the images defined above under X_test
embedding_var = tf.Variable(X_test, name='fmnist_embedding')
# Format: tensorflow/contrib/tensorboard/plugins/projector/projector_config.proto
config = projector.ProjectorConfig()
# You can add multiple embeddings. Here I add only one.
embedding = config.embeddings.add()
embedding.tensor_name = embedding_var.name
# Link this tensor to its metadata file (e.g. labels).
embedding.metadata_path = os.path.join(logdir, 'metadata.tsv')
# Use this logdir to create a summary writer
summary_writer = tf.summary.FileWriter(logdir)
# The next line writes a projector_config.pbtxt in the logdir. TensorBoard will read this file during startup.
projector.visualize_embeddings(summary_writer,config)
# Periodically save the model variables in a checkpoint in logdir.
with tf.Session() as sesh:
sesh.run(tf.global_variables_initializer())
saver = tf.train.Saver()
saver.save(sesh, os.path.join(logdir, 'model.ckpt'))
# Create the sprite image
rows = 28
cols = 28
label = ['T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat', 'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot']
sprite_dim = int(np.sqrt(X_test.shape[0]))
sprite_image = np.ones((cols * sprite_dim, rows * sprite_dim))
index = 0
labels = []
for i in range(sprite_dim):
for j in range(sprite_dim):
labels.append(label[int(Y_test[index])])
sprite_image[
i * cols: (i + 1) * cols,
j * rows: (j + 1) * rows
] = X_test[index].reshape(28, 28) * -1 + 1
index += 1
# After constructing the sprite, I need to tell the Embedding Projector where to find it
embedding.sprite.image_path = os.path.join(logdir, 'sprite.png')
embedding.sprite.single_image_dim.extend([28, 28])
# Create the metadata (labels) file
with open(embedding.metadata_path, 'w') as meta:
meta.write('Index Label ')
for index, label in enumerate(labels):
meta.write('{} {} '.format(index, label))
該投射器有三種對數(shù)據(jù)集降維的方法,兩種線性方法,一種非線性方法。每種方法都能用于創(chuàng)建二維或三維場景。
PCA:PCA是一種用于直接降維的技術(shù),嵌入投射器計算前十位的主要成分,通過菜單,我們可以將那些成分投射成任意兩種或三種的結(jié)合上。PCA是一個線性工具,通常在檢查全局幾何結(jié)構(gòu)上非常高效。
t-SNE:這是一種流行的非線性降維方法,嵌入投射器會同時提供二維和三維的t-SNE視圖。在客戶端可以看到平面圖,能展示出每一步算法。由于t-SNE通常會保留一些局部結(jié)構(gòu),這在探索局部近鄰、找尋聚類中是很有用的。
Custom:我還可以基于文本搜索創(chuàng)建特殊的線性投射器,用于在空間中尋找有意義的方向。程序可以計算這些點集的中心點,他們的標(biāo)簽可以與搜索匹配,利用向量之間的不同作為投射器的軸。
查看完成的可視化步驟代碼,可點擊此網(wǎng)址:github.com/khanhnamle1994/fashion-mnist/blob/master/TensorBoard-Visualization.ipynb
在Fashion MNIST上訓(xùn)練CNN模型
接下來,我會創(chuàng)建多個基于CNN的分類模型,在Fashion MNIST上評估模型性能。我會用Keras框架搭建模型,想了解框架的更多信息,可以點擊此網(wǎng)址:keras.io/。下面是我想要比較的四種模型:
有一層卷積層的CNN
有三層卷積層的CNN
有四層卷積層的CNN
經(jīng)過與訓(xùn)練的VGG-19模型
除了預(yù)訓(xùn)練模型,我的實驗方法如下:
將原始訓(xùn)練數(shù)據(jù)(共60000張圖片)分成訓(xùn)練集和驗證集兩部分,80%是訓(xùn)練集,20%是驗證集,另外還有10000張測試圖片,用于最終測試模型在陌生圖像上的表現(xiàn)。這可以研究模型是否在訓(xùn)練數(shù)據(jù)上過度擬合,以及是否應(yīng)該降低學(xué)習(xí)速率。
用256的batch size訓(xùn)練模型10個epoch,同時用categorical_crossentropy損失函數(shù)和Adam優(yōu)化器共同編譯。
之后進行數(shù)據(jù)增強,可以通過旋轉(zhuǎn)、變化、縮放生成新的訓(xùn)練樣本,再通過50個epoch對模型進行訓(xùn)練。
以下是下載數(shù)據(jù)并分離數(shù)據(jù)的代碼:
# Import libraries
from keras.utils import to_categorical
from sklearn.model_selection import train_test_split
# Load training and test data into dataframes
data_train = pd.read_csv('data/fashion-mnist_train.csv')
data_test = pd.read_csv('data/fashion-mnist_test.csv')
# X forms the training images, and y forms the training labels
X = np.array(data_train.iloc[:, 1:])
y = to_categorical(np.array(data_train.iloc[:, 0]))
# Here I split original training data to sub-training (80%) and validation data (20%)
X_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.2, random_state=13)
# X_test forms the test images, and y_test forms the test labels
X_test = np.array(data_test.iloc[:, 1:])
y_test = to_categorical(np.array(data_test.iloc[:, 0]))
下載數(shù)據(jù)后,我會重新處理它們,讓它們的值處于0到1之間。此前,訓(xùn)練數(shù)據(jù)都被存儲在一個(60000,28,28)的數(shù)組中,其中的值在0到255之間。
# Each image's dimension is 28 x 28
img_rows, img_cols = 28, 28
input_shape = (img_rows, img_cols, 1)
# Prepare the training images
X_train = X_train.reshape(X_train.shape[0], img_rows, img_cols, 1)
X_train = X_train.astype('float32')
X_train /= 255
# Prepare the test images
X_test = X_test.reshape(X_test.shape[0], img_rows, img_cols, 1)
X_test = X_test.astype('float32')
X_test /= 255
# Prepare the validation images
X_val = X_val.reshape(X_val.shape[0], img_rows, img_cols, 1)
X_val = X_val.astype('float32')
X_val /= 255
一層卷積層CNN
下面是只有一層卷積層的CNN代碼:
from keras.models importSequential
from keras.layers importDense, Dropout, Flatten
from keras.layers importConv2D, MaxPooling2D
cnn1 = Sequential()
cnn1.add(Conv2D(32, kernel_size=(3, 3), activation='relu', input_shape=input_shape))
cnn1.add(MaxPooling2D(pool_size=(2, 2)))
cnn1.add(Dropout(0.2))
cnn1.add(Flatten())
cnn1.add(Dense(128, activation='relu'))
cnn1.add(Dense(10, activation='softmax'))
cnn1.compile(loss=keras.losses.categorical_crossentropy,
optimizer=keras.optimizers.Adam(),
metrics=['accuracy'])
訓(xùn)練完模型后,下面是測試損失和測試精確度:
進行數(shù)據(jù)增強后的測試損失和測試精確度:
訓(xùn)練和驗證精確度和損失的可視化:
完整代碼請點擊:github.com/khanhnamle1994/fashion-mnist/blob/master/CNN-1Conv.ipynb
三層卷積層CNN
有三層卷積層的CNN代碼:
from keras.models importSequential
from keras.layers importDense, Dropout, Flatten
from keras.layers importConv2D, MaxPooling2D
cnn3 = Sequential()
cnn3.add(Conv2D(32, kernel_size=(3, 3), activation='relu', input_shape=input_shape))
cnn3.add(MaxPooling2D((2, 2)))
cnn3.add(Dropout(0.25))
cnn3.add(Conv2D(64, kernel_size=(3, 3), activation='relu'))
cnn3.add(MaxPooling2D(pool_size=(2, 2)))
cnn3.add(Dropout(0.25))
cnn3.add(Conv2D(128, kernel_size=(3, 3), activation='relu'))
cnn3.add(Dropout(0.4))
cnn3.add(Flatten())
cnn3.add(Dense(128, activation='relu'))
cnn3.add(Dropout(0.3))
cnn3.add(Dense(10, activation='softmax'))
cnn3.compile(loss=keras.losses.categorical_crossentropy,
optimizer=keras.optimizers.Adam(),
metrics=['accuracy'])
訓(xùn)練模型后,測試損失和測試精確度:
數(shù)據(jù)增強后的測試損失和精確度:
訓(xùn)練和驗證的精確度和損失:
完整代碼請點擊:github.com/khanhnamle1994/fashion-mnist/blob/master/CNN-3Conv.ipynb
四層卷積層的CNN
下面是四層卷積層的CNN代碼:
from keras.models importSequential
from keras.layers importDense, Dropout, Flatten
from keras.layers importConv2D, MaxPooling2D, BatchNormalization
cnn4 = Sequential()
cnn4.add(Conv2D(32, kernel_size=(3, 3), activation='relu', input_shape=input_shape))
cnn4.add(BatchNormalization())
cnn4.add(Conv2D(32, kernel_size=(3, 3), activation='relu'))
cnn4.add(BatchNormalization())
cnn4.add(MaxPooling2D(pool_size=(2, 2)))
cnn4.add(Dropout(0.25))
cnn4.add(Conv2D(64, kernel_size=(3, 3), activation='relu'))
cnn4.add(BatchNormalization())
cnn4.add(Dropout(0.25))
cnn4.add(Conv2D(128, kernel_size=(3, 3), activation='relu'))
cnn4.add(BatchNormalization())
cnn4.add(MaxPooling2D(pool_size=(2, 2)))
cnn4.add(Dropout(0.25))
cnn4.add(Flatten())
cnn4.add(Dense(512, activation='relu'))
cnn4.add(BatchNormalization())
cnn4.add(Dropout(0.5))
cnn4.add(Dense(128, activation='relu'))
cnn4.add(BatchNormalization())
cnn4.add(Dropout(0.5))
cnn4.add(Dense(10, activation='softmax'))
cnn4.compile(loss=keras.losses.categorical_crossentropy,
optimizer=keras.optimizers.Adam(),
metrics=['accuracy'])
訓(xùn)練模型后的測試損失和精確度:
數(shù)據(jù)增強后的測試損失和精確度:
訓(xùn)練和驗證的精確度和損失:
完整代碼請點擊:github.com/khanhnamle1994/fashion-mnist/blob/master/CNN-4Conv.ipynb
遷移學(xué)習(xí)
在小數(shù)據(jù)集上常用的一種高效深度學(xué)習(xí)方法就是使用預(yù)訓(xùn)練網(wǎng)絡(luò)。一種預(yù)訓(xùn)練網(wǎng)絡(luò)是此前在大型數(shù)據(jù)集上訓(xùn)練過的網(wǎng)絡(luò),通常處理過大型圖像分類任務(wù)。如果這樣的原始數(shù)據(jù)集足夠大并且足夠通用,那么預(yù)訓(xùn)練網(wǎng)絡(luò)學(xué)習(xí)到的特征空間分層可以用于視覺世界的普通模型,它的特征可以解決很多不同的計算機視覺問題。
我嘗試使用VGG19預(yù)訓(xùn)練模型,這在ImageNet中廣泛使用的ConvNets架構(gòu)。以下是所用的代碼:
import keras
from keras.applications import VGG19
from keras.applications.vgg19 import preprocess_input
from keras.layers importDense, Dropout
from keras.models importModel
from keras import models
from keras import layers
from keras import optimizers
# Create the base model of VGG19
vgg19 = VGG19(weights='imagenet', include_top=False, input_shape = (150, 150, 3), classes = 10)
# Preprocessing the input
X_train = preprocess_input(X_train)
X_val = preprocess_input(X_val)
X_test = preprocess_input(X_test)
# Extracting features
train_features = vgg19.predict(np.array(X_train), batch_size=256, verbose=1)
test_features = vgg19.predict(np.array(X_test), batch_size=256, verbose=1)
val_features = vgg19.predict(np.array(X_val), batch_size=256, verbose=1)
# Flatten extracted features
train_features = np.reshape(train_features, (48000, 4*4*512))
test_features = np.reshape(test_features, (10000, 4*4*512))
val_features = np.reshape(val_features, (12000, 4*4*512))
# Add Dense and Dropout layers on top of VGG19 pre-trained
model = models.Sequential()
model.add(layers.Dense(512, activation='relu', input_dim=4 * 4 * 512))
model.add(layers.Dropout(0.5))
model.add(layers.Dense(10, activation="softmax"))
# Compile the model
model.compile(loss=keras.losses.categorical_crossentropy,
optimizer=keras.optimizers.Adam(),
metrics=['accuracy'])
模型訓(xùn)練后,測試損失和精確度如下:
可視化:
結(jié)語
時尚領(lǐng)域是計算機視覺和機器學(xué)習(xí)應(yīng)用的熱門,由于其中的予以復(fù)雜性,導(dǎo)致問題難度增加。希望這篇文章能對你在圖像分類任務(wù)上有所啟發(fā)。
-
神經(jīng)網(wǎng)絡(luò)
+關(guān)注
關(guān)注
42文章
4734瀏覽量
100420 -
機器學(xué)習(xí)
+關(guān)注
關(guān)注
66文章
8353瀏覽量
132315 -
數(shù)據(jù)集
+關(guān)注
關(guān)注
4文章
1200瀏覽量
24621
原文標(biāo)題:用卷積神經(jīng)網(wǎng)絡(luò)模型辨認不同時尚服裝,四種方法對比
文章出處:【微信號:jqr_AI,微信公眾號:論智】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
評論