[TOC]
安裝,配置和測(cè)試
安裝
keras需要依賴多個(gè)python庫(kù),包括numpy桩引,scipy,pyyaml收夸,HDF5, h5py,如果使用CNN的推薦安裝cuDNN坑匠。
keras可以用TensorFlow,Theano卧惜,CNTK當(dāng)后端厘灼,這邊選的是tf夹纫。
安裝環(huán)境建議選擇Linux,配好python環(huán)境设凹,windows上也可以裝舰讹,據(jù)說(shuō)坑比較多
命令如下:
conda install numpy scipy pyyaml h5py
安裝tf
pip install --ignore-installed --upgrade https://storage.googleapis.com/tensorflow/linux/cpu/tensorflow-0.8.0rc0-cp27-none-linux_x86_64.whl
需要注意下,我這邊用的conda闪朱,后面編碼的時(shí)候月匣,也要用conda里的python,具體配置根據(jù)編譯器的不同而不同奋姿。
配置
keras的建議配置是
主板:X299型號(hào)或Z270型號(hào)
CPU: i7-6950X或i7-7700K 及其以上高級(jí)型號(hào)
內(nèi)存:品牌內(nèi)存锄开,總?cè)萘?2G以上,根據(jù)主板組成4通道或8通道
SSD: 品牌固態(tài)硬盤称诗,容量256G以上
顯卡:NVIDIA GTX TITAN(XP) NVIDIA GTX 1080ti萍悴、NVIDIA GTX TITAN、NVIDIA GTX 1080寓免、NVIDIA GTX 1070癣诱、NVIDIA GTX 1060 (順序?yàn)閮?yōu)先建議,并且建議同一顯卡再榄,可以根據(jù)主板插槽數(shù)量購(gòu)買多塊狡刘,例如X299型號(hào)主板最多可以采用×4的顯卡)
電源:由主機(jī)機(jī)容量的確定,一般有顯卡總?cè)萘亢笤偌?00W即可
最低配置
CPU:Intel第三代i5和i7以上系列產(chǎn)品或同性能AMD公司產(chǎn)品
內(nèi)存:總?cè)萘?G以上
有條件還是建議上顯卡困鸥,畢竟深度學(xué)習(xí)涉及大量矩陣運(yùn)算嗅蔬,cpu沒(méi)有顯卡來(lái)的方便。我這邊條件不夠疾就,沒(méi)用顯卡澜术,CUDA安裝跳過(guò)。
下面就是配tf和keras猬腰,代碼如下:
sudo pip install -U --pre pip setuptools wheel
sudo pip install -U --pre numpy scipy matplotlib scikit-learn scikit-image
sudo pip install -U --pre tensorflow-gpu
sudo pip install -U --pre keras
測(cè)試
安裝好之后鸟废,需要測(cè)試一下,常用的是一個(gè)手寫識(shí)別的程序姑荷,也就是mnist盒延,代碼如下
>>> git clone https://github.com/fchollet/keras.git
>>> cd keras/examples/
>>> python mnist_mlp.py
參考文檔 https://keras.io/
模型
keras里有兩種模型,分別是Sequential和Functional,下面分別論述鼠冕,對(duì)于詳細(xì)的api文檔添寺,參見(jiàn)參考文檔3
Sequential
Sequential是多個(gè)網(wǎng)絡(luò)層的線性堆疊,這邊是一個(gè)模型定義和優(yōu)化的例子懈费,優(yōu)化器暫時(shí)不用管计露,后面會(huì)提到
model = Sequential()
model.add(Dense(32, input_dim=784))
model.compile(optimizer='rmsprop',
loss='categorical_crossentropy',
metrics=['accuracy'])
這邊就是先import一個(gè)model,然后制定數(shù)據(jù)的shape,并指定優(yōu)化器和相關(guān)參數(shù)票罐,接著就是數(shù)據(jù)的訓(xùn)練叉趣。
我們以lstm為例,做訓(xùn)練數(shù)據(jù)
from keras.models import Sequential
from keras.layers import Dense, Dropout
from keras.layers import Embedding
from keras.layers import LSTM
model = Sequential()
model.add(Embedding(max_features, output_dim=256))
model.add(LSTM(128))
model.add(Dropout(0.5))
model.add(Dense(1, activation='sigmoid'))
model.compile(loss='binary_crossentropy',
optimizer='rmsprop',
metrics=['accuracy'])
model.fit(x_train, y_train, batch_size=16, epochs=10)
score = model.evaluate(x_test, y_test, batch_size=16)
訓(xùn)練的結(jié)果集可以用hdf5保存
Functional
Functional是一個(gè)能表達(dá)任意張量映射的model该押,Keras中Functional模型接口是用戶定義多輸出模型疗杉、非循環(huán)有向模型或具有共享層的模型等復(fù)雜模型的途徑。
利用函數(shù)式模型的接口蚕礼,我們可以很容易的重用已經(jīng)訓(xùn)練好的模型:你可以把模型當(dāng)作一個(gè)層一樣乡数,通過(guò)提供一個(gè)tensor來(lái)調(diào)用它。注意當(dāng)你調(diào)用一個(gè)模型時(shí)闻牡,你不僅僅重用了它的結(jié)構(gòu),也重用了它的權(quán)重绳矩。
x = Input(shape=(784,))
# This works, and returns the 10-way softmax we defined above.
y = model(x)
這種方式可以允許你快速的創(chuàng)建能處理序列信號(hào)的模型罩润,你可以很快將一個(gè)圖像分類的模型變?yōu)橐粋€(gè)對(duì)視頻分類的模型,只需要一行代碼:
from keras.layers import TimeDistributed
# Input tensor for sequences of 20 timesteps,
# each containing a 784-dimensional vector
input_sequences = Input(shape=(20, 784))
# This applies our previous model to every timestep in the input sequences.
# the output of the previous model was a 10-way softmax,
# so the output of the layer below will be a sequence of 20 vectors of size 10.
processed_sequences = TimeDistributed(model)(input_sequences)
另一個(gè)使用函數(shù)式模型的場(chǎng)合是使用共享層的時(shí)候翼馆。
考慮微博數(shù)據(jù)割以,我們希望建立模型來(lái)判別兩條微博是否是來(lái)自同一個(gè)用戶,這個(gè)需求同樣可以用來(lái)判斷一個(gè)用戶的兩條微博的相似性应媚。
訓(xùn)練
這邊選擇了一個(gè)視覺(jué)問(wèn)答的例子严沥,讓機(jī)器看一副圖片,然后問(wèn)問(wèn)題并回答中姜,這種工作消玄,在有深度學(xué)習(xí)之前,可能需要一個(gè)team的人才能完成丢胚,現(xiàn)在也就十來(lái)行代碼的工作量翩瓜。
from keras.layers import Conv2D, MaxPooling2D, Flatten
from keras.layers import Input, LSTM, Embedding, Dense
from keras.models import Model, Sequential
# First, let's define a vision model using a Sequential model.
# This model will encode an image into a vector.
vision_model = Sequential()
vision_model.add(Conv2D(64, (3, 3) activation='relu', padding='same', input_shape=(3, 224, 224)))
vision_model.add(Conv2D(64, (3, 3), activation='relu'))
vision_model.add(MaxPooling2D((2, 2)))
vision_model.add(Conv2D(128, (3, 3), activation='relu', padding='same'))
vision_model.add(Conv2D(128, (3, 3), activation='relu'))
vision_model.add(MaxPooling2D((2, 2)))
vision_model.add(Conv2D(256, (3, 3), activation='relu', padding='same'))
vision_model.add(Conv2D(256, (3, 3), activation='relu'))
vision_model.add(Conv2D(256, (3, 3), activation='relu'))
vision_model.add(MaxPooling2D((2, 2)))
vision_model.add(Flatten())
# Now let's get a tensor with the output of our vision model:
image_input = Input(shape=(3, 224, 224))
encoded_image = vision_model(image_input)
# Next, let's define a language model to encode the question into a vector.
# Each question will be at most 100 word long,
# and we will index words as integers from 1 to 9999.
question_input = Input(shape=(100,), dtype='int32')
embedded_question = Embedding(input_dim=10000, output_dim=256, input_length=100)(question_input)
encoded_question = LSTM(256)(embedded_question)
# Let's concatenate the question vector and the image vector:
merged = keras.layers.concatenate([encoded_question, encoded_image])
# And let's train a logistic regression over 1000 words on top:
output = Dense(1000, activation='softmax')(merged)
# This is our final model:
vqa_model = Model(inputs=[image_input, question_input], outputs=output)
# The next stage would be training this model on actual data.
參考文檔 http://arxiv.org/abs/1409.4842
http://arxiv.org/abs/1512.03385
https://keras.io/models/model/
優(yōu)化器
優(yōu)化器是編譯Keras模型必要的兩個(gè)參數(shù)之一
先看一個(gè)例子
from keras import optimizers
model = Sequential()
model.add(Dense(64, init='uniform', input_shape=(10,)))
model.add(Activation('tanh'))
model.add(Activation('softmax'))
sgd = optimizers.SGD(lr=0.01, decay=1e-6, momentum=0.9, nesterov=True)
model.compile(loss='mean_squared_error', optimizer=sgd)
可以在調(diào)用model.compile()之前初始化一個(gè)優(yōu)化器對(duì)象,然后傳入該函數(shù)(如上所示)携龟,也可以在調(diào)用model.compile()時(shí)傳遞一個(gè)預(yù)定義優(yōu)化器名兔跌。在后者情形下,優(yōu)化器的參數(shù)將使用默認(rèn)值峡蟋。
參數(shù)clipnorm和clipvalue是所有優(yōu)化器都可以使用的參數(shù),用于對(duì)梯度進(jìn)行裁剪坟桅。
常用的優(yōu)化器有SGD,Adam蕊蝗,Adadelta等仅乓。
SGD是隨機(jī)梯度下降法,支持動(dòng)量參數(shù)匿又,支持學(xué)習(xí)衰減率方灾,支持Nesterov動(dòng)量
參數(shù)如下
lr:大于0的浮點(diǎn)數(shù),學(xué)習(xí)率
momentum:大于0的浮點(diǎn)數(shù),動(dòng)量參數(shù)
decay:大于0的浮點(diǎn)數(shù)裕偿,每次更新后的學(xué)習(xí)率衰減值
nesterov:布爾值洞慎,確定是否使用Nesterov動(dòng)量
Adam
Adam(Adaptive Moment Estimation)本質(zhì)上是帶有動(dòng)量項(xiàng)的RMSprop,它利用梯度的一階矩估計(jì)和二階矩估計(jì)動(dòng)態(tài)調(diào)整每個(gè)參數(shù)的學(xué)習(xí)率嘿棘。Adam的優(yōu)點(diǎn)主要在于經(jīng)過(guò)偏置校正后劲腿,每一次迭代學(xué)習(xí)率都有個(gè)確定范圍,使得參數(shù)比較平穩(wěn)鸟妙。
參數(shù)如下
lr:大于0的浮點(diǎn)數(shù)焦人,學(xué)習(xí)率
beta_1/beta_2:浮點(diǎn)數(shù), 0<beta<1重父,通常很接近1
epsilon:大于0的小浮點(diǎn)數(shù)花椭,防止除0錯(cuò)誤
Adadelta
Adadelta是對(duì)Adagrad的擴(kuò)展,最初方案依然是對(duì)學(xué)習(xí)率進(jìn)行自適應(yīng)約束房午,但是進(jìn)行了計(jì)算上的簡(jiǎn)化矿辽。 Adagrad會(huì)累加之前所有的梯度平方,而Adadelta只累加固定大小的項(xiàng)郭厌,并且也不直接存儲(chǔ)這些項(xiàng)袋倔,僅僅是近似計(jì)算對(duì)應(yīng)的平均值。
參數(shù)如下
lr:大于0的浮點(diǎn)數(shù)折柠,學(xué)習(xí)率
rho:大于0的浮點(diǎn)數(shù)
epsilon:大于0的小浮點(diǎn)數(shù)宾娜,防止除0錯(cuò)誤
參考文檔 http://cs229.stanford.edu/proj2015/054_report.pdf
http://www.cs.toronto.edu/~fritz/absps/momentum.pdf
http://arxiv.org/abs/1212.5701
目標(biāo)函數(shù)
目標(biāo)函數(shù),或稱損失函數(shù)扇售,是編譯一個(gè)模型必須的兩個(gè)參數(shù)之一
可以通過(guò)傳遞預(yù)定義目標(biāo)函數(shù)名字指定目標(biāo)函數(shù)前塔,也可以傳遞一個(gè)Theano/TensroFlow的符號(hào)函數(shù)作為目標(biāo)函數(shù),該函數(shù)對(duì)每個(gè)數(shù)據(jù)點(diǎn)應(yīng)該只返回一個(gè)標(biāo)量值缘眶,并以下列兩個(gè)參數(shù)為參數(shù):
- y_true:真實(shí)的數(shù)據(jù)標(biāo)簽嘱根,Theano/TensorFlow張量
- y_pred:預(yù)測(cè)值,與y_true相同shape的Theano/TensorFlow張量
真實(shí)的優(yōu)化目標(biāo)函數(shù)是在各個(gè)數(shù)據(jù)點(diǎn)得到的損失函數(shù)值之和的均值