3
本文作者: 晟煒 | 2017-01-16 11:45 |
如果你覺得這是一篇簡單介紹人工智能、機器學習和深度學習的文章,那就錯啦。你可以在網(wǎng)上搜羅到一大堆相關(guān)話題的文章,而這篇文章也并不是討論人工智能是否會奴役人類或搶走人們飯碗之類的話題,畢竟相關(guān)的各種推論和謠言已經(jīng)滿天飛了。
這只是一篇詳細描述如何開始搭建一個機器學習系統(tǒng),并讓它可以識別所看到圖像的文章。
作者Wolfgang Beyer目前現(xiàn)在正在學習人工智能和機器學習的內(nèi)容。他認為最好的學習方式不是僅僅閱讀各類材料,而是要真正地去動手搭建一個系統(tǒng)。這就是雷鋒網(wǎng)翻譯本文的目的,也是作者要向你介紹的。在這篇文章中Beyer將向你展示如何搭建一個系統(tǒng),去完成一項簡單的計算機視覺任務:識別圖像內(nèi)容。
Beyer強調(diào),他并不是一個專家?!拔艺趯W習,而且還有很多東西需要學習。我只是簡單介紹我正在做的事情。如果這對你能有所幫助,或者你也覺得很有趣,就已經(jīng)很好了。如果你發(fā)現(xiàn)了錯誤或有什么改進建議也請告訴我,你的回復對我也很重要?!?/p>
閱讀本文前你并不需要具備機器學習的相關(guān)經(jīng)驗。示例代碼是使用Python寫的,如果你有Python的基礎(chǔ)知識是最好的。但如果你只是掌握其他的編程語言,那也已經(jīng)足夠了。由于篇幅限制,本系列將分四篇文章發(fā)布,雷鋒網(wǎng)編譯,未經(jīng)許可不得轉(zhuǎn)載。
為什么讓機器學會圖像識別?
圖像識別是開發(fā)和測試機器學習的一項重要任務,因為視覺可能是最重要的一項感知能力。雖然對于人類來說,它是與生俱來的。但它是怎么實現(xiàn)的?大腦是怎樣將視網(wǎng)膜上的圖像轉(zhuǎn)化成我們對周圍環(huán)境的心智模式的?我想沒人能對此一清二楚。關(guān)鍵是,對我們來說這看起來如此簡單——我們不需要有意識地去做這件事,而對于計算機來說卻困難重重(事實上,對我們來說也并不是看上去那么簡單。只是我們并沒有意識到進行了多少工作。有超過一半的大腦區(qū)域直接或間接參與了視覺活動)。
在我們甚至都不知道自己怎么看到東西的情況下,怎么讓計算機去做到這樣的事情呢?這就是機器學習要研究的事情。我們采取的方法是讓計算機自己去完成這樣的過程,而不是手把手地一步步教會計算機如何解釋圖像并翻譯成計算機程序。我們給計算機提供總體結(jié)構(gòu),讓計算機從經(jīng)驗中學習,就像我們?nèi)祟愖龅哪菢印?/p>
但是,在我們開始構(gòu)想計算機視覺的整體方案之前,讓我們把這個任務簡化為一個容易掌握的小目標。
我們嘗試解決一個盡可能小而簡單的問題,另外也不要期望它能瞬間讓我們成為機器學習大師。我們希望計算機能做的包括以下方面:當我們向計算機展示一幅圖片(特定尺寸)時,它能夠?qū)D片進行分析并打上標簽。他可以從固定數(shù)量的標簽中進行選擇,每一類的標簽描述了一種圖像的內(nèi)容。我們的目標就是這個模型能夠盡可能地挑選出正確的標簽。這個任務被稱作圖像分類。
我們將使用標準的CIFAR-10數(shù)據(jù)集。CIFAR-10包含了60000幅圖片。它有10個不同的分類,每類包含6000幅圖片。每幅圖片的規(guī)格是32x32像素。這么小尺寸的圖片對我們?nèi)祟悂碚f有時很難進行正確的分類,但它卻簡化了計算機模型的任務,并降低了分析圖片的計算負載。
CIFAR-10數(shù)據(jù)集中10個分類中的隨機圖片。由于分辨率低,人類很難進行正確的標簽。
我們將圖片轉(zhuǎn)化為一連串的數(shù)字輸送給計算模型。每個像素由代表紅色,綠色和藍色的三個浮點數(shù)來表示。其結(jié)果就是32x32x3=3072個值。
除了CIFAR-10,還有很多其他的圖像數(shù)據(jù)集可以用于計算機視覺的研究。之所以使用標準數(shù)據(jù)集,有兩個目的:
第一,要收集這么多的圖片是一項巨大的工作。你需要有大量的圖片資源,并根據(jù)需要對他們進行分別標簽。
第二,使用相同的數(shù)據(jù)集,可以讓我們有目的地比較不同方法的優(yōu)劣。
另外,使用標準數(shù)據(jù)集,可以相互比較,在競賽中排出名次。最有名的比賽是Image-Net圖像識別大賽,它需要對1000個不同的種類進行識別。2012年的勝者是來自多倫多大學(University of Toronto)的亞力克斯?克利則夫斯基(Alex Krizhevsky),伊利亞·蘇特斯科娃(Ilya Sutskever)和杰夫·辛頓(Geoffrey Hinton)設(shè)計的算法(雷鋒網(wǎng)注:可點擊論文鏈接查看)。這個系統(tǒng)領(lǐng)跑整個比賽并且以巨大的優(yōu)勢獲勝。
這次比賽對整個研究領(lǐng)域產(chǎn)生了巨大的沖擊,因為這是第一次使用卷積神經(jīng)網(wǎng)絡的方法獲得勝利。卷積神經(jīng)網(wǎng)絡是一種人工神經(jīng)網(wǎng)絡,它大致模擬了動物視覺的皮質(zhì)行為。這一技術(shù)的應用已經(jīng)有一段時間,但它的潛力還沒被多數(shù)人認識到。2012 Image-Net競賽后,這種情況出現(xiàn)了改變。人們突然對神經(jīng)網(wǎng)絡和深度學習(深度學習是使用多層神經(jīng)網(wǎng)絡的方法解決機器學習的問題)產(chǎn)生了巨大興趣,而這次賽事也極大地推動了以后幾年深度學習的快速發(fā)展。
我們怎么使用圖像數(shù)據(jù)集讓計算機自己學習呢?即使計算機自己能夠?qū)W習,我們也需要告訴它學習什么和怎樣學習。所以,我們需要通過制定一個大致的流程讓計算機能夠?qū)D像進行評估。
我們定義一個通用的數(shù)學模型,將輸入圖像轉(zhuǎn)換為輸出標簽。這個模型的實際輸出不僅僅依賴于圖像本身,還依賴模型內(nèi)建的參數(shù)。這些參數(shù)并不是由我們提供,而是由計算機通過學習獲得。
這樣一來,這個過程可以被理解為一個優(yōu)化問題。我們初始定義一個模型并提供初始的參數(shù)值。然后再向模型輸入圖像數(shù)據(jù)集和已知的正確標簽。這就是訓練的過程。在這個階段模型重復校驗,訓練數(shù)據(jù),持續(xù)調(diào)整參數(shù)值。目標是找到合適的參數(shù)使模型輸出盡可能多的正確結(jié)果。這種同時使用輸入數(shù)據(jù)和正確結(jié)果的訓練方法叫做監(jiān)督學習。還有一種叫做非監(jiān)督學習,這種學習中只使用了輸入數(shù)據(jù)而沒有標簽,但在這篇文章中我們不做討論。
當訓練完成,模型參數(shù)被固定下來,并可以被用于圖像集以外的圖像分類。
在訓練期間,模型的預測結(jié)果與真實值進行比較。這些信息被用于更新參數(shù)值。在測試過程中就不再有反饋,模型只是產(chǎn)生標簽。
TensorFlow是機器學習的開源軟件庫,它由Google在2015年發(fā)布并很快成為全世界的研究者和學習者中最流行的機器學習庫之一。它在圖像分類模型中承擔重要作用。
接下來,我們就要開始學習如何用TensorFlow搭建一個合適的模型。
Github支持這個模型的完整代碼。在使用之前,你需要安裝以下軟件:
· Python(代碼經(jīng)過了Python2.7測試,Python3.3+也應該可以工作,安裝鏈接)
· TensorFlow(安裝指導鏈接)
· CIFAR-10數(shù)據(jù)集:下載Python版本的數(shù)據(jù)集
從https://www.cs.toronto.edu/~kriz/cifar.html下載或者使用鏈接中的壓縮文檔。請把 cifar-10-batches-py解壓到python源代碼的目錄下,這樣圖像的路徑應該為/path-to-your-python-source-code-files/cifar-10-batches-py/。
好了,現(xiàn)在我們可以開始了。讓我們先來看看試驗的主文件softmax.py,一行一行地來分析:
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import numpy as np
import tensorflow as tf
import time
import data_helpers
根據(jù)TensorFlow代碼規(guī)范,在所有TensorFlow Python文件中為了Python2和3的兼容性,都應該添加future語句。然后導入TensorFlow,numpy用于數(shù)值計算和時間模塊。data_helper.py包括加載和準備數(shù)據(jù)集的函數(shù)。
beginTime = time.time()
# Parameter definitions
batch_size = 100
learning_rate = 0.005
max_steps = 1000
# Prepare data
data_sets = data_helpers.load_data()
我們啟動一個計時器測量運行時間和定義一些參數(shù)。稍后在實際使用它們時再進行討論。然后加載CIFAR-10數(shù)據(jù)集。因為讀取數(shù)據(jù)并不是我們要做的核心,我把這部分的函數(shù)單獨放在data_helper.py文件中。它只是負責讀取包含數(shù)據(jù)集的文件,并把數(shù)據(jù)放入一個方便我們操作的數(shù)據(jù)結(jié)構(gòu)中。
需要提到的重要的一點是,load_data()是將60000幅圖像分為兩部分。大的一部分包含50000幅圖像。這些數(shù)據(jù)集用于訓練我們的模型。另外的10000幅圖像被稱作測試集。在訓練結(jié)束之前,我們的模型將不會看到這些圖像。直到模型中的參數(shù)不再變換,我們使用測試集作為模型輸入來檢驗模型的性能。
將數(shù)據(jù)分為訓練集和測試集非常重要。我們并不知道我們的模型在遇到訓練數(shù)據(jù)集或測試數(shù)據(jù)集的時候是否有相同的表現(xiàn)。最糟的情況在于,模型記錄下了它看過的所有圖像。如果我們使用相同的訓練集進行測試,模型通過查找存儲下來的正確答案,可能表現(xiàn)得非常完美。但是如果使用它從未見過的圖像則原形畢露。這在模型學習中有個專門的概念叫做過度擬合,就是說特定的訓練數(shù)據(jù)可能掩蓋一些更為通常的特征。在機器學習中避免過度擬合是一項重大的課題。關(guān)于過度擬合和為什么建議將數(shù)據(jù)分成2個或者3個數(shù)據(jù)集,可以參考Coursera上吳恩達(Andrew Ng)機器學習課程的節(jié)選視頻。
回到我們的代碼,load_data()返回一個dictionary類型數(shù)據(jù):
images_train:訓練集轉(zhuǎn)換為50000x3072(32像素x32像素x3個顏色通道)的數(shù)組
labels_train:訓練集的50000個標簽(每個數(shù)字從0到9代表圖像訓練集的10個分類)
images_test:測試集(10000x3072)
labels_test:測試集的10000個標簽
classes:10個文本標簽,將數(shù)字轉(zhuǎn)換成文字(0代表“飛機”,1代表“車”,等等)
# Define input placeholders
images_placeholder = tf.placeholder(tf.float32, shape=[None, 3072])
labels_placeholder = tf.placeholder(tf.int64, shape=[None])
做好了這些工作后,雷鋒網(wǎng)在下篇將帶大家開始建立這個模型。
via wolfib
雷峰網(wǎng)版權(quán)文章,未經(jīng)授權(quán)禁止轉(zhuǎn)載。詳情見轉(zhuǎn)載須知。