【TensorFlow2.x 實(shí)踐】服裝分類
前言
基于TensorFlow2.x的框架,使用PYthon編程語言,實(shí)現(xiàn)對服裝圖像進(jìn)行分類。
思路流程:
導(dǎo)入 Fashion MNIST數(shù)據(jù)1. 集探索數(shù)據(jù)1. 預(yù)處理數(shù)據(jù)1. 建立模型(搭建神經(jīng)網(wǎng)絡(luò)結(jié)構(gòu)、編譯模型)1. 訓(xùn)練模型(把數(shù)據(jù)輸入模型、評估準(zhǔn)確性、作出預(yù)測、驗(yàn)證預(yù)測) ?1. 使用訓(xùn)練有素的模型
一、Fashion MNIST數(shù)據(jù)集
Fashion MNIST數(shù)據(jù)集包括一些運(yùn)動鞋和襯衫等衣物;我們從下圖中先看一下:

給不同類別的?運(yùn)動鞋和襯衫等衣物,進(jìn)行索引分類;每個(gè)圖像都映射到一個(gè)標(biāo)簽。

不同的類別,對應(yīng)其索引,先把它們存儲在此處以供以后在繪制圖像時(shí)使用:
class_names?=?['T-shirt/top',?'Trouser',?'Pullover',?'Dress',?'Coat',
???????????????'Sandal',?'Shirt',?'Sneaker',?'Bag',?'Ankle?boot']
二、探索數(shù)據(jù)
在訓(xùn)練模型之前,我們可以探索數(shù)據(jù)集的格式。比如:訓(xùn)練集中有60,000張圖像,每個(gè)圖像表示為28 x 28像素。訓(xùn)練集中有60,000個(gè)標(biāo)簽;每個(gè)標(biāo)簽都是0到9之間的整數(shù)。
測試集中有10,000張圖像。同樣,每個(gè)圖像都表示為28 x 28像素。測試集包含10,000個(gè)圖像標(biāo)簽。
探索數(shù)據(jù)代碼:

運(yùn)行結(jié)果:

3、預(yù)處理數(shù)據(jù)
在訓(xùn)練網(wǎng)絡(luò)之前,必須對數(shù)據(jù)進(jìn)行預(yù)處理。如果檢查訓(xùn)練集中的第一張圖像,將看到像素值落在0到255的范圍內(nèi):
plt.figure()
plt.imshow(train_images[0])
plt.colorbar()
plt.grid(False)
plt.show()
查看第一張圖像(像素值落在0到255),運(yùn)行結(jié)果:

將這些值縮放到0到1的范圍,然后再將其輸入神經(jīng)網(wǎng)絡(luò)模型。為此,將值除以255。以相同的方式預(yù)處理訓(xùn)練集和測試集非常重要:
train_images?=?train_images?/?255.0
test_images?=?test_images?/?255.0
為了驗(yàn)證數(shù)據(jù)的格式正確,并且已經(jīng)準(zhǔn)備好構(gòu)建和訓(xùn)練網(wǎng)絡(luò),讓我們顯示訓(xùn)練集中的前25張圖像,并在每張圖像下方顯示類別名稱。
plt.figure(figsize=(10,10))
for?i?in?range(25):
????plt.subplot(5,5,i+1)
????plt.xticks([])
????plt.yticks([])
????plt.grid(False)
????plt.imshow(train_images[i],?cmap=plt.cm.binary)
????plt.xlabel(class_names[train_labels[i]])
plt.show()
運(yùn)行結(jié)果:可以看到?訓(xùn)練集中的前25張圖像

四、建立模型
建立神經(jīng)網(wǎng)絡(luò)需要配置模型的各層(圖層),然后編譯模型。
1)搭建神經(jīng)網(wǎng)絡(luò)結(jié)構(gòu)
神經(jīng)網(wǎng)絡(luò)的基本組成部分是圖層?。圖層(神經(jīng)網(wǎng)絡(luò)的結(jié)構(gòu))將輸入到圖層中的數(shù)據(jù)進(jìn)行提取特征。
深度學(xué)習(xí)的大部分內(nèi)容是將簡單的層鏈接在一起。大多數(shù)層(例如?)具有在訓(xùn)練期間學(xué)習(xí)的參數(shù)。
model?=?keras.Sequential([
????keras.layers.Flatten(input_shape=(28,?28)),
????keras.layers.Dense(128,?activation='relu'),
????keras.layers.Dense(10)
])
此網(wǎng)絡(luò)的第一層將圖像的格式從二維數(shù)組(28 x 28像素)轉(zhuǎn)換為一維數(shù)組(28 * 28 = 784像素)。可以將這一層看作是堆疊圖像中的像素行并將它們排成一行。該層沒有學(xué)習(xí)參數(shù)。它只會重新格式化數(shù)據(jù)。
像素展平后,網(wǎng)絡(luò)由兩個(gè)層序列組成。這些是緊密連接或完全連接的神經(jīng)層。第一Dense層具有128個(gè)節(jié)點(diǎn)(或神經(jīng)元)。第二層(也是最后一層)返回長度為10的logits數(shù)組。每個(gè)節(jié)點(diǎn)包含一個(gè)得分,該得分指示當(dāng)前圖像屬于10個(gè)類之一。
2)編譯模型
在準(zhǔn)備訓(xùn)練模型之前,需要進(jìn)行一些其他設(shè)置。這些是在模型的編譯步驟中添加的:
損失函數(shù)?-衡量訓(xùn)練期間模型的準(zhǔn)確性。希望最小化此功能,以在正確的方向上“引導(dǎo)”模型。- 優(yōu)化器?-這是基于模型看到的數(shù)據(jù)及其損失函數(shù)來更新模型的方式。- 指標(biāo)?-用于監(jiān)視培訓(xùn)和測試步驟。以下示例使用precision?,即正確分類的圖像比例。
model.compile(optimizer='adam',
??????????????loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
??????????????metrics=['accuracy'])
五、訓(xùn)練模型
訓(xùn)練神經(jīng)網(wǎng)絡(luò)模型需要執(zhí)行以下步驟:
將訓(xùn)練數(shù)據(jù)輸入模型。在此示例中,訓(xùn)練數(shù)據(jù)在 train_images和train_labels數(shù)組中。1. 訓(xùn)練過程中該模型會學(xué)習(xí)關(guān)聯(lián)圖像和標(biāo)簽。(找到正確的對應(yīng)關(guān)系,比如a圖片,對應(yīng)a標(biāo)簽,而不是對應(yīng)c標(biāo)簽)1. 使用訓(xùn)練好后的模型對測試集進(jìn)行預(yù)測。(在本示例中為test_images數(shù)組)1. 驗(yàn)證預(yù)測是否與test_labels數(shù)組中的標(biāo)簽匹配。
1)把數(shù)據(jù)輸入模型進(jìn)行訓(xùn)練
要開始訓(xùn)練,請調(diào)用model.fit方法:
model.fit(train_images,?train_labels,?epochs=10)
這里訓(xùn)練過程中會迭代10次;
第1次訓(xùn)練:

第2次訓(xùn)練:

..........................3、4、5、6、7、8、9...................訓(xùn)練
第10次訓(xùn)練:

模型訓(xùn)練時(shí),會顯示損失和準(zhǔn)確性指標(biāo)。該模型在訓(xùn)練數(shù)據(jù)上達(dá)到約0.91(或91%)的精度。

2)評估準(zhǔn)確性
比較模型在測試數(shù)據(jù)集上的表現(xiàn):
test_loss,?test_acc?=?model.evaluate(test_images,??test_labels,?verbose=2)
print('\nTest?accuracy:',?test_acc)
運(yùn)行結(jié)果:

測試數(shù)據(jù)集的準(zhǔn)確性略低于訓(xùn)練數(shù)據(jù)集的準(zhǔn)確性。訓(xùn)練準(zhǔn)確性和測試準(zhǔn)確性之間的差距代表過度擬合?。當(dāng)機(jī)器學(xué)習(xí)模型在新的,以前看不見的輸入上的表現(xiàn)比訓(xùn)練數(shù)據(jù)上的表現(xiàn)差時(shí),就會發(fā)生過度擬合。過度擬合的模型“記憶”訓(xùn)練數(shù)據(jù)集中的噪聲和細(xì)節(jié),從而對新數(shù)據(jù)的模型性能產(chǎn)生負(fù)面影響。
解決方案:請參見以下內(nèi)容:(有興趣可以看一下)
3)作出預(yù)測
通過訓(xùn)練模型,可以使用它來預(yù)測某些圖像。模型的線性輸出?。附加一個(gè)softmax層,以將logit轉(zhuǎn)換為更容易解釋的概率。
probability_model?=?tf.keras.Sequential([model,??tf.keras.layers.Softmax()])
predictions?=?probability_model.predict(test_images)
在這里,模型已經(jīng)預(yù)測了測試集中每個(gè)圖像的標(biāo)簽。讓我們看一下第一個(gè)預(yù)測:
predictions[0]
運(yùn)行結(jié)果:

預(yù)測是由10個(gè)數(shù)字組成的數(shù)組。它們代表模型對圖像對應(yīng)于10種不同服裝中的每一種的“置信度”。可以看到哪個(gè)標(biāo)簽的置信度最高:np.argmax(predictions[0])
輸出是 9
因此,模型最有把握認(rèn)為該圖像是短靴/腳踝靴(class_names[9]?);檢查測試標(biāo)簽表明此分類是正確的:test_labels[0]
輸出也是 9
4)驗(yàn)證預(yù)測
通過訓(xùn)練模型,可以使用它來預(yù)測某些圖像。讓我們看一下第0張圖像,預(yù)測和預(yù)測數(shù)組。正確的預(yù)測標(biāo)簽為藍(lán)色,錯(cuò)誤的預(yù)測標(biāo)簽為紅色。該數(shù)字給出了預(yù)測標(biāo)簽的百分比(滿分為100)。
正確的預(yù)測標(biāo)簽為藍(lán)色:
i?=?0
plt.figure(figsize=(6,3))
plt.subplot(1,2,1)
plot_image(i,?predictions[i],?test_labels,?test_images)
plt.subplot(1,2,2)
plot_value_array(i,?predictions[i],??test_labels)
plt.show()
運(yùn)行結(jié)果:

錯(cuò)誤的預(yù)測標(biāo)簽為紅色:
i?=?12
plt.figure(figsize=(6,3))
plt.subplot(1,2,1)
plot_image(i,?predictions[i],?test_labels,?test_images)
plt.subplot(1,2,2)
plot_value_array(i,?predictions[i],??test_labels)
plt.show()
運(yùn)行結(jié)果:

繪制一些帶有預(yù)測的圖像:
#?繪制一些帶有預(yù)測的圖像
#?繪制前X張測試圖像,它們的預(yù)測標(biāo)簽和真實(shí)標(biāo)簽。
#?將正確的預(yù)測顏色設(shè)置為藍(lán)色,將不正確的預(yù)測顏色設(shè)置為紅色。
num_rows?=?5
num_cols?=?3
num_images?=?num_rows*num_cols
plt.figure(figsize=(2*2*num_cols,?2*num_rows))
for?i?in?range(num_images):
??plt.subplot(num_rows,?2*num_cols,?2*i+1)
??plot_image(i,?predictions[i],?test_labels,?test_images)
??plt.subplot(num_rows,?2*num_cols,?2*i+2)
??plot_value_array(i,?predictions[i],?test_labels)
plt.tight_layout()
plt.show()

六、使用訓(xùn)練有素的模型
使用經(jīng)過訓(xùn)練的模型對單個(gè)圖像進(jìn)行預(yù)測;先挑一張圖片,比如test_images[0],它是這樣的:

它是短靴/腳踝靴,對應(yīng)標(biāo)簽是9。下面使用模型進(jìn)行預(yù)測:
#?【6?使用訓(xùn)練有素的模型】
#?使用經(jīng)過訓(xùn)練的模型對單個(gè)圖像進(jìn)行預(yù)測。
#?從測試數(shù)據(jù)集中獲取圖像。
img?=?test_images[0]
#?將圖像添加到唯一的批處理
img?=?(np.expand_dims(img,0))
#?為該圖像預(yù)測正確的標(biāo)簽:
predictions_single?=?probability_model.predict(img)
print("輸出每一個(gè)標(biāo)簽的把握:",?predictions_single)??#?一共10個(gè)標(biāo)簽,索引從0,1,2到9
plot_value_array(1,?predictions_single[0],?test_labels)
_?=?plt.xticks(range(10),?class_names,?rotation=45)
# keras.Model.predict返回一個(gè)列表列表-數(shù)據(jù)批次中每個(gè)圖像的一個(gè)列表。批量獲取我們(僅)圖像的預(yù)測
print("模型預(yù)測的結(jié)果:",?np.argmax(predictions_single[0]))
運(yùn)行結(jié)果:

我們可以看到有99.6%的把握認(rèn)為是標(biāo)簽9,預(yù)測正確了,能分辨出是短靴/腳踝靴(標(biāo)簽是9)。
七、源代碼:
#?本程序基于TensorFlow訓(xùn)練了一個(gè)神經(jīng)網(wǎng)絡(luò)模型來對運(yùn)動鞋和襯衫等衣物的圖像進(jìn)行分類。
#?使用tf.keras (高級API)在TensorFlow中構(gòu)建和訓(xùn)練模型。
#?TensorFlow?and?tf.keras
import?tensorflow?as?tf
from?tensorflow?import?keras
#?Helper?libraries
import?numpy?as?np
import?matplotlib.pyplot?as?plt
#?查看當(dāng)前tensorflow版本
print("當(dāng)前tensorflow版本",?tf.__version__)
#?【1?導(dǎo)入Fashion?MNIST數(shù)據(jù)集】
'''
加載數(shù)據(jù)集將返回四個(gè)NumPy數(shù)組:
train_images和train_labels數(shù)組是訓(xùn)練集?,即模型用來學(xué)習(xí)的數(shù)據(jù)。
針對測試集?,?test_images和test_labels數(shù)組對模型進(jìn)行測試?
'''
'''
圖像是28x28 NumPy數(shù)組,像素值范圍是0到255。?標(biāo)簽是整數(shù)數(shù)組,范圍是0到9。這些對應(yīng)于圖像表示的衣服類別?:
標(biāo)簽?????類
0?????T恤
1?????褲子
2?????套衫/衛(wèi)衣
3?????連衣裙
4?????外衣/外套
5?????涼鞋
6?????襯衫
7?????運(yùn)動鞋
8?????袋子
9?????短靴/腳踝靴
'''
fashion_mnist?=?keras.datasets.fashion_mnist
(train_images,?train_labels),?(test_images,?test_labels)?=?fashion_mnist.load_data()
#?每個(gè)圖像都映射到一個(gè)標(biāo)簽
class_names?=?['T-shirt/top',?'Trouser',?'Pullover',?'Dress',?'Coat',
???????????????'Sandal',?'Shirt',?'Sneaker',?'Bag',?'Ankle?boot']
#?【2?探索數(shù)據(jù)】
#?在訓(xùn)練模型之前,讓我們探索數(shù)據(jù)集的格式。下圖顯示了訓(xùn)練集中有60,000張圖像,每個(gè)圖像表示為28 x 28像素
print("訓(xùn)練集總圖片數(shù):",?train_images.shape)
#?訓(xùn)練集中有60,000個(gè)標(biāo)簽
print("訓(xùn)練集中標(biāo)簽數(shù):",?len(train_labels))
#?每個(gè)標(biāo)簽都是0到9之間的整數(shù)
print("標(biāo)簽取值:",?train_labels)
#?測試集中有10,000張圖像。同樣,每個(gè)圖像都表示為28 x 28像素
print("測試集總圖片數(shù):",?test_images.shape)
#?測試集包含10,000個(gè)圖像標(biāo)簽
print("測試集標(biāo)簽數(shù):",?len(test_labels))
#?【3?預(yù)處理數(shù)據(jù)】
#?在訓(xùn)練網(wǎng)絡(luò)之前,必須對數(shù)據(jù)進(jìn)行預(yù)處理。如果檢查訓(xùn)練集中的第一張圖像,將看到像素值落在0到255的范圍內(nèi)
plt.figure()
plt.imshow(train_images[0])
plt.colorbar()
plt.grid(False)
plt.show()
#?將這些值縮放到0到1的范圍,然后再將其輸入神經(jīng)網(wǎng)絡(luò)模型。為此,將值除以255。以相同的方式預(yù)處理訓(xùn)練集和測試集非常重要:
train_images?=?train_images?/?255.0
test_images?=?test_images?/?255.0
#為了驗(yàn)證數(shù)據(jù)的格式正確,并且已經(jīng)準(zhǔn)備好構(gòu)建和訓(xùn)練網(wǎng)絡(luò),讓我們顯示訓(xùn)練集中的前25張圖像,并在每張圖像下方顯示班級名稱。
plt.figure(figsize=(10,10))
for?i?in?range(25):
????plt.subplot(5,5,i+1)
????plt.xticks([])
????plt.yticks([])
????plt.grid(False)
????plt.imshow(train_images[i],?cmap=plt.cm.binary)
????plt.xlabel(class_names[train_labels[i]])
plt.show()
#?【4?建立模型】
#?建立神經(jīng)網(wǎng)絡(luò)需要配置模型的各層,然后編譯模型
#?搭建神經(jīng)網(wǎng)絡(luò)結(jié)構(gòu)?神經(jīng)網(wǎng)絡(luò)的基本組成部分是層?。圖層(神經(jīng)網(wǎng)絡(luò)結(jié)構(gòu))從輸入到其中的數(shù)據(jù)中提取表示
#?深度學(xué)習(xí)的大部分內(nèi)容是將簡單的層鏈接在一起。大多數(shù)層(例如tf.keras.layers.Dense )具有在訓(xùn)練期間學(xué)習(xí)的參數(shù)。
model?=?keras.Sequential([
????keras.layers.Flatten(input_shape=(28,?28)),
????keras.layers.Dense(128,?activation='relu'),
????keras.layers.Dense(10)
])
'''
編譯模型
在準(zhǔn)備訓(xùn)練模型之前,需要進(jìn)行一些其他設(shè)置。這些是在模型的編譯步驟中添加的:
損失函數(shù)?-衡量訓(xùn)練期間模型的準(zhǔn)確性。您希望最小化此功能,以在正確的方向上“引導(dǎo)”模型。
優(yōu)化器?-這是基于模型看到的數(shù)據(jù)及其損失函數(shù)來更新模型的方式。
指標(biāo)?-用于監(jiān)視培訓(xùn)和測試步驟。以下示例使用precision ,即正確分類的圖像比例。
'''
model.compile(optimizer='adam',
??????????????loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
??????????????metrics=['accuracy'])
#?【5?訓(xùn)練模型】
'''
訓(xùn)練神經(jīng)網(wǎng)絡(luò)模型需要執(zhí)行以下步驟:
1.將訓(xùn)練數(shù)據(jù)輸入模型。在此示例中,訓(xùn)練數(shù)據(jù)在train_images和train_labels數(shù)組中。
2.該模型學(xué)習(xí)關(guān)聯(lián)圖像和標(biāo)簽。
3.要求模型對測試集進(jìn)行預(yù)測(在本示例中為test_images數(shù)組)。
4.驗(yàn)證預(yù)測是否與test_labels數(shù)組中的標(biāo)簽匹配。
'''
#?要開始訓(xùn)練,請調(diào)用model.fit方法,之所以這么稱呼是因?yàn)樗鼓P汀斑m合”訓(xùn)練數(shù)據(jù):
model.fit(train_images,?train_labels,?epochs=10)
#?比較模型在測試數(shù)據(jù)集上的表現(xiàn)
test_loss,?test_acc?=?model.evaluate(test_images,??test_labels,?verbose=2)
print('\nTest?accuracy:',?test_acc)
#?作出預(yù)測?通過訓(xùn)練模型,您可以使用它來預(yù)測某些圖像。模型的線性輸出logits 。附加一個(gè)softmax層,以將logit轉(zhuǎn)換為更容易解釋的概率。
probability_model?=?tf.keras.Sequential([model,??tf.keras.layers.Softmax()])
predictions?=?probability_model.predict(test_images)
print(predictions[0])
print(np.argmax(predictions[0]))
print(test_labels[0])
#?以圖形方式查看完整的10個(gè)類預(yù)測。
def?plot_image(i,?predictions_array,?true_label,?img):
??true_label,?img?=?true_label[i],?img[i]
??plt.grid(False)
??plt.xticks([])
??plt.yticks([])
??plt.imshow(img,?cmap=plt.cm.binary)
??predicted_label?=?np.argmax(predictions_array)
??if?predicted_label?==?true_label:
????color?=?'blue'
??else:
????color?=?'red'
??plt.xlabel("{}?{:2.0f}%?({})".format(class_names[predicted_label],
????????????????????????????????100*np.max(predictions_array),
????????????????????????????????class_names[true_label]),
????????????????????????????????color=color)
def?plot_value_array(i,?predictions_array,?true_label):
??true_label?=?true_label[i]
??plt.grid(False)
??plt.xticks(range(10))
??plt.yticks([])
??thisplot?=?plt.bar(range(10),?predictions_array,?color="#777777")
??plt.ylim([0,?1])
??predicted_label?=?np.argmax(predictions_array)
??thisplot[predicted_label].set_color('red')
??thisplot[true_label].set_color('blue')
'''驗(yàn)證預(yù)測
通過訓(xùn)練模型,您可以使用它來預(yù)測某些圖像。
讓我們看一下第0張圖像,預(yù)測和預(yù)測數(shù)組。正確的預(yù)測標(biāo)簽為藍(lán)色,錯(cuò)誤的預(yù)測標(biāo)簽為紅色。該數(shù)字給出了預(yù)測標(biāo)簽的百分比(滿分為100)。'''
i?=?0
plt.figure(figsize=(6,3))
plt.subplot(1,2,1)
plot_image(i,?predictions[i],?test_labels,?test_images)
plt.subplot(1,2,2)
plot_value_array(i,?predictions[i],??test_labels)
plt.show()
i?=?12
plt.figure(figsize=(6,3))
plt.subplot(1,2,1)
plot_image(i,?predictions[i],?test_labels,?test_images)
plt.subplot(1,2,2)
plot_value_array(i,?predictions[i],??test_labels)
plt.show()
#?繪制一些帶有預(yù)測的圖像
#?繪制前X張測試圖像,它們的預(yù)測標(biāo)簽和真實(shí)標(biāo)簽。
#?將正確的預(yù)測顏色設(shè)置為藍(lán)色,將不正確的預(yù)測顏色設(shè)置為紅色。
num_rows?=?5
num_cols?=?3
num_images?=?num_rows*num_cols
plt.figure(figsize=(2*2*num_cols,?2*num_rows))
for?i?in?range(num_images):
??plt.subplot(num_rows,?2*num_cols,?2*i+1)
??plot_image(i,?predictions[i],?test_labels,?test_images)
??plt.subplot(num_rows,?2*num_cols,?2*i+2)
??plot_value_array(i,?predictions[i],?test_labels)
plt.tight_layout()
plt.show()
#?【6?使用訓(xùn)練有素的模型】
#?使用經(jīng)過訓(xùn)練的模型對單個(gè)圖像進(jìn)行預(yù)測。
#?從測試數(shù)據(jù)集中獲取圖像。
img?=?test_images[0]
#?將圖像添加到唯一的批處理
img?=?(np.expand_dims(img,0))
#?為該圖像預(yù)測正確的標(biāo)簽:
predictions_single?=?probability_model.predict(img)
print("輸出每一個(gè)標(biāo)簽的把握:",?predictions_single)??#?一共10個(gè)標(biāo)簽,索引從0,1,2到9
plot_value_array(1,?predictions_single[0],?test_labels)
_?=?plt.xticks(range(10),?class_names,?rotation=45)
# keras.Model.predict返回一個(gè)列表列表-數(shù)據(jù)批次中每個(gè)圖像的一個(gè)列表。批量獲取我們(僅)圖像的預(yù)測
print("模型預(yù)測的結(jié)果:",?np.argmax(predictions_single[0]))
希望對你有幫助;


Python“寶藏級”公眾號【Python之王】專注于Python領(lǐng)域,會爬蟲,數(shù)分,C++,tensorflow和Pytorch等等。
近 2年共原創(chuàng) 100+ 篇技術(shù)文章。創(chuàng)作的精品文章系列有:
日常收集整理了一批不錯(cuò)的?Python?學(xué)習(xí)資料,有需要的小伙可以自行免費(fèi)領(lǐng)取。
獲取方式如下:公眾號回復(fù)資料。領(lǐng)取Python等系列筆記,項(xiàng)目,書籍,直接套上模板就可以用了。資料包含算法、python、算法小抄、力扣刷題手冊和 C++ 等學(xué)習(xí)資料!
