深度學習 (一)計算機如何處理和識別圖片揭祕

前言

       先來一張美景圖,欣賞一下大自然,順便大家猜猜這是哪裏?
這裏寫圖片描述
       有時候真感嘆大自然的雄偉壯闊,自然形成了無數的山和風景不需要任何點綴,有時候在想爲什麼親近自然界我們會有親近的感覺,可能那是我們的來源,我們人類在經過了無數代的繁衍生息,發展到了現在的文明,這些都是前輩們智慧的結晶,就比如我們每天看的電視、電腦,它們把彩色的世界呈現在我們眼前,提高了我們的生活品味和視覺享受,那麼你是否想過它是怎麼形成的嗎?下面就讓我們來說說它的原理。

三原色原理

百度百科

人眼對(Red Green Blue)紅、綠、藍最爲敏感,人的眼睛像一個三色接收器的體系,大多數的顏色可以通過紅、綠、藍三色按照不同的比例合成產生。同樣,絕大多數單色光也可以分解成紅、綠、藍三種色光,這是色度學的最基本的原理,也稱三原色原理。

       說道這裏難免會有些好奇、有些疑問了,爲什麼是三原色?爲什麼不是四原色、五元色呢?

       通過蒐集相關資料又發現了牛頓這個耳熟能詳的人物,驚訝於這又和他有關係,他這一生爲人類得做了多少貢獻,牛頓通過三菱鏡首先發明瞭自然光可以分解爲不同顏色的七彩色光,偉人的思想往往是與衆不同的,他們往往不會止步不前,繼續思考 他在想既然自然光可以分解,那麼七彩色光是不是也可以被分解或者合成呢?
順着這個思路他又經過了無數個晝夜不停的實驗和計算,(至於怎麼實驗的感興趣的可以自己搜索)終於真理又讓他發明了,在七彩色光中只有紅、綠、藍三種顏色不能夠再繼續分解,不能分解也就是原子的 這點和事務的特性一樣,所以稱其爲三原色,其它的光可以通過這三種光來組合疊加和相減算出來。

三原色我們達成的共識是這樣的:
(1)自然界的任何光色都可以由3種光色按不同的比例混合而成。
(2)三原色之間是相互獨立的,任何一種光色都不能由其餘的兩種光色來組成。
(3)混合色的飽和度由3種光色的比例來決定。混合色的亮度爲3種光色的亮度之和。

       三原色在應用於實際生活中時既可以相加,也可以相減,採用相加的方式成爲RGB顏色模型和CMY模式(品紅、青色、淡黃),也是用的最多的一種,相減爲CMYK模型,他們分別用於繪圖和印刷領域。
       三原色之所以可以代表最基礎的色彩,還有另外一個原理即正交,任何事物如果想研究他們 讓他們正交是最好的組織方式,因爲他們互不影響,如通笛卡爾座標系一樣,在座標系中可以表示任何點一樣,三原色猶如三個座標系,由三個顏色座標系可以表示出來很多種顏色,即三原色代表了世界這麼多顏色,反過來也可以看做是這麼多色彩的抽象,從而又論證了科學、科研是一個不段抽象、不斷總結昇華的過程,所以 學會總結 抽象非常重要。
        軟件或屏幕顯示圖片的時候是利用電子光照射屏幕上的發光材料產生的色彩,多個色彩相加,而印刷是墨的反光相減,可以說三原色的應用大大提高了我們認識世界和觀察世界的途徑,而不是活在非黑即白的世界裏面。

       通過三原色可以組合出來自然界的各種各樣的色彩,每種顏色值可以通過數值來表示大小強弱等,以目前計算機中8位來保存顏色值,每種顏色值的範圍是0-255個值來表示,根據組合原理三種色組合起來有255255255種色彩,對於我們肉眼的分辨能力已經夠用了。

顯示器爲什麼有顏色?

       理解了三原色再來看這個問題會比較簡單,在電子屏幕上有可以發光的三種材料熒光材料,在經過電子槍照射時會組合成不同顏色,電子槍的強弱即可以表示三種原色的色值大小,組合出來的顏色也就各不相同,有些特別相似的顏色也不是我們肉眼就能看出來的,即滿足了在我們視力範圍內的色彩。

圖像識別-計算

       一張圖片在屏幕上面如果無限縮小會看到是由無數個點組成的,其實任何事物都是由無限到有限來組成,無數個點會組成一個平面,當點和點之間的間距足夠小時我們的肉眼是分不出來的,我們看到的就是一個圖像,當無限個圖像從我們眼前閃過就會形成視頻電影,他們都是一個道理,好比幾何中的點組成線、線組成面、面組成立體空間,當分析到這一層次圖像識別就顯着處理簡單了,只要讓計算機計算組成圖片的無數個點的特徵就可以識別出來相似圖片,當然這也依賴於強大的運算能力,因爲像素高的大圖是非常大的,如常見筆記本電腦像素,有1366*768個像素點,數量級別在百萬級,況且以RGB模式來說有三個通道顏色 將會更大。

PC如何存儲圖片?

       圖片在計算機中是一個三維矩陣,讓我們通過一個圖片直觀感受一下,如下圖是訓練集中第一個類型裏面第一張圖片
這裏寫圖片描述
我們取該圖中第一個通道矩陣,並打印出來如下:

# 打印red 通道圖片矩陣
img_df = pd.DataFrame(X_train[0][:,:,0])
img_df.to_csv('X_train0101.csv')
plt.imshow(X_train[0])
plt.show()

這裏寫圖片描述
       從圖片可以看到每個像素點的值都在0-255之間,三個這樣的顏色矩陣就可以組裝出來一個彩色圖片,矩陣越大像素點越多,會越清晰當然佔用內存也就越大,在實際預測時有時會對矩陣進行變化,變爲一個長的向量,方便計算距離,下面我們將這名變化來就是那距離。

knn圖片識別

如下先上代碼,思路是將三維的圖片矩陣 轉化爲一個長的n*1的向量,然後計算測試集每個圖片到訓集每個圖片的歐式距離,也就是兩個向量的距離,區最近的來作爲判別分類標準。

import os
import sys
import numpy as np
import cPickle as pickle  
from scipy.misc import imsave
import matplotlib.pyplot as plt

# 加載cifar-10圖片文件
def load_CIFAR_batch(filename):
    with open(filename, 'rb') as f:
        datadict=pickle.load(f)
        # 查看字典變量的key值情況
        print datadict.keys()
        X=datadict['data']
        Y=datadict['labels']
        # 默認顏色通道爲 3 32 32 形式,需要變爲32 32 3的形式
        X=X.reshape(10000, 3, 32, 32).transpose(0,2,3,1).astype("float")
        Y=np.array(Y)
        return X, Y

# 多個文件時組裝加載的數據
def load_CIFAR10(ROOT):

    xs=[]
    ys=[]

    for b in range(1,6):
        f=os.path.join(ROOT, "data_batch_%d" % (b, ))
        X, Y=load_CIFAR_batch(f)
        xs.append(X)
        ys.append(Y)

    X_train=np.concatenate(xs)
    Y_train=np.concatenate(ys)

    del X, Y
    X_test, Y_test=load_CIFAR_batch(os.path.join(ROOT, "test_batch"))
    return X_train, Y_train, X_test, Y_test

# 載入訓練和測試數據集
X_train, Y_train, X_test, Y_test = load_CIFAR10('cifar-10-batches-py/') 

# 把32*32*3的多維數組展平
Xtr_rows = X_train.reshape(X_train.shape[0], 32 * 32 * 3) # Xtr_rows : 50000 x 3072
Xtr_rows2000 = Xtr_rows[0:5000,:]
Y_train2000 = Y_train[0:5000]

# print type(Xtr_rows)
# print Y_train[0:2000]

Xte_rows = X_test.reshape(X_test.shape[0], 32 * 32 * 3) # Xte_rows : 10000 x 3072
Xte_rows2000 = Xte_rows[0:5000,:]


class NearestNeighbor:
  def __init__(self):
    pass

  def train(self, X, y):
    """ 
    這個地方的訓練其實就是把所有的已有圖片讀取進來 -_-||
    """
    # the nearest neighbor classifier simply remembers all the training data
    self.Xtr = X
    self.ytr = y

  def predict(self, X):
    """ 
    所謂的預測過程其實就是掃描所有訓練集中的圖片,計算距離,取最小的距離對應圖片的類目
    """
    num_test = X.shape[0]
    # 要保證維度一致哦
    Ypred = np.zeros(num_test, dtype = self.ytr.dtype)

    # 把訓練集掃一遍 -_-||
    for i in xrange(num_test):
      # 計算l1距離,並找到最近的圖片
      distances = np.sum(np.abs(self.Xtr - X[i,:]), axis = 1)
      min_index = np.argmin(distances) # 取最近圖片的下標
      Ypred[i] = self.ytr[min_index] # 記錄下label

    return Ypred

nn = NearestNeighbor() # 初始化一個最近鄰對象
nn.train(Xtr_rows2000, Y_train2000) # 訓練...其實就是讀取訓練集
print "開始訓練"
Yte_predict = nn.predict(Xte_rows2000) # 預測
print Yte_predict
print "結束訓練"
# 比對標準答案,計算準確率
print 'accuracy: %f' % ( np.mean(Yte_predict == Y_test) )

發現這個訓練很耗時間,一時半會出不來結果參考網上結果爲30%+,可見效果並不是特別好。

總結

這只是一個圖像識別的思路,除此之外還有很多高校的識別方法,以後會探索更搞笑的算法,對於圖像識別越快速、準確率、召回率越高,越是我們希望看到的。

題外思考

創造平等的機會 與 平等的結果 誰更好?
       我們先舉一個簡單的例子,比如很厲害的清華大學要像全社會招生,由於社會各個地區教育資源、師資力量不平等造成了他們最終考試的水平也不平等,好的地方很可能分數比較高,造成大學招進來的人都是資源好的地方的學生,教育本來就欠缺的地方永遠也沒有進去好大學的資格,如何改變這種狀況呢?
       可以提高基礎教育條件對於條件不好的地方加大投資力度,幫助教育落後的地方改改教育狀況,即創造平等的參與機會,另一種做法是大學按地區名額來招生,每年給教育落後地區也分配一定名額,那麼他們也可以進度好大學,如此也可能帶來大學整體水平下降,各有利弊,我是覺得創造平等機會其實是更好的,有助於提高升大學的綜合水平,爲社會培養出來更多的精英。
        法國高等教育分爲了兩類,一類是共同大學 另一類是精英大學,共同大學注重公平性屬於普及綜合教育、基礎教育一類,精英大學是培養高端人才的,每年招收不如3%,歷史上法國大部分科學家、高管都出自它的精英大學,比如巴黎綜合工科學院 ,我們熟悉的泊松既出自這個學校,泊松的二項式定理,邏輯迴歸方程推導時即假設了樣本是服從泊松分佈的,大家也可以思考思考哪個更重要!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章