當前位置:
首頁 > 知識 > 圖像分類任務中,Tensorflow與Keras 到底哪個更厲害?

圖像分類任務中,Tensorflow與Keras 到底哪個更厲害?

本文為 AI 研習社編譯的技術博客,原標題 Tensorflow Vs Keras? — Comparison by building a model for image classification,作者為DataTurks: Data Annotations Made Super Easy。

翻譯 | shunshun 整理 | 凡江

是的,標題中的問題在數據科學家之間的談話中是很常見。有人說TensorFlow更好,有人說Keras更好。讓我們看看這個問題在圖像分類的實際應用中的答案。

在此之前,先介紹Keras和Tensorflow這兩個術語,幫助你在10分鐘內構建強大的圖像分類器。


Tensorflow:

Tensorflow是開發深度學習模型最常用的庫。它是有史以來最好的庫,在日常實驗中被許多極客選擇。如果我說Google已經將Tensor Processing Units(TPU)用於處理張量,你能想像嗎?是的,他們已經這樣做了。他們提出了一個名為TPU的獨立實例,它具有最強大的功率驅動計算能力來處理tensorflow的深度學習模型。

是時候做一個了!

我現在將幫助你使用tensorflow創建一個功能強大的圖像分類器。等等!什麼是分類器?這只是一個簡單的問題,你向你的tensorflow代碼詢問,給定的圖像是玫瑰還是鬱金香。所以,首先的首先,讓我們在機器上安裝tensorflow。官方文檔有兩個版本,即CPU和GPU版本。對於CPU版本:

請注意,我是在GPU上而非CPU上進行實驗後才寫的這篇博客。這裡給出了詳細的GPU安裝。

現在,讓我們採用Google的Tensorflow進行實驗來訓練模型。谷歌的這個倉庫有許多令人驚嘆的處理圖像的簡單實驗的腳本。它非常簡潔,足以滿足我們的目的。還記得前面我用過「強大」這個詞嗎?是的,當我們使用稱為遷移學習的方法時,這個詞就會生效。遷移學習是一種有效的方式,它使用預訓練模型,這些模型已經訓練了幾天或幾周,然後改變最後一層以適應我們自己的類別。

Inception V3是一個非常好的模型,在[2015 ImageNet Challenge](//image-net.org/challenges/LSVRC/2015/results)圖像分類競賽中排名第二。當數據集的每個類別具有較少圖像數量時,它被提及為遷移學習的最佳網路。

Inception V3

現在克隆git倉庫:

現在,你可以選擇圖像。你所要做的就是以下面的方式存儲數據集文件夾。

FLOWER DATA

它看起來應該像上面圖那樣(忽略image.py)。通過下面代碼獲得flower_photos文件夾:

創建數據

你可以使用任何你喜歡的圖像。越多越好(目標是幾千)。向上面文件夾格式那樣以類別將它們分開,並確保它們在一個名為tf_files的文件夾中。

你可以下載已經存在的有多種任務使用的數據集,如癌症檢測,權力的遊戲中的人物分類。這裡有各種圖像分類數據集。

或者,如果你有自己獨特的用例,則可以為其創建自己的數據集。你可以從網上下載圖像並立即製作大型數據集,使用像Dataturks這樣的注釋工具,你可以手動上傳圖像並標記圖像。更好的是,Dataturks的輸出可以很容易地用於構建tf_files。

使用Dataturks創建數據

我發現了一個很棒的插件,可以在Google Chrome上批量下載圖像。這個和Dataturks將使構建訓練數據變得輕而易舉。鏈接在這裡。

您可以嘗試使用dataturks的image_classification工具執行此操作。這裡該工具提供的最佳功能是,如果我們有一個非結構化數據集,其中所有圖像都在一個文件夾中。通過手動標記圖像的類別,你可以下載一個json文件,該文件包含嵌入其中的類的圖像的所有詳細信息。然後使用下面給出的keras和tensorflow腳本:

訓練

現在是時候訓練模型了。在tensorflow-for-poets-2文件夾中,有一個名為scripts的文件夾,它包含重新訓練模型所需的一切。retrain.py有一種特殊的裁剪和縮放圖像的方式,非常酷。

然後使用以下命令訓練,選項名稱本身描述所需的訓練路徑的位置。

這將下載inception模型並使用training文件夾和給定的參數訓練最後一層。我使用12GB Nvidia Tesla k80和7GB Vram在GCP實例上訓練了4000步。

訓練時80%數據集用作訓練,20%用作測試,我們可以看到,它給出了91%的test_accuracy。現在是時候測試了!我們在`tf_files/`中有一個.pb文件,可用於測試。`label_image.py`中添加了以下更改:

上面的代碼將幫助我們繪製正在測試的圖像的準確性並保存它。對於rodom圖像的置信度百分比如下所示

下面顯示了幾個測試圖像的輸出

包含所有類別的少量輸出的拼貼畫

正如我們所看到的,結果對於所述任務來說真的很好了。


Keras

Keras是一個基於TensorFlow構建的高級API(也可以在Theano之上使用)。與Tensorflow相比,它更加用戶友好且易於使用。如果我們是所有這些深度學習的新手,並想從頭開始編寫一個新模型,那麼我會建議使用Keras,因為其易讀性和易寫性。可以通過下面指令安裝:

甚至這個東西都包含了tensorflow,所以CPU v/s GPU兼容性變化也將適用於此。

因為,我們必須執行使用inception模型的遷移學習對花進行分類的相同任務,我已經看到Keras以標準格式載入模型,如API編寫的那樣。

Keras有一種載入數據集的標準格式,即我們不是直接在數據集文件夾中提供文件夾,而是手動劃分訓練和測試數據,並按以下方式排列。我使用了我在tensorflow部分下載的相同數據集,並按照以下說明進行了一些更改。

它看起來應該如下所示:

TRAIN FOLDER

至於,我們現在已完成數據集的設置,是時候進行訓練了。我已經寫了一小段代碼來進行下面的訓練:

importos

importsys

importglob

importargparse

importmatplotlib.pyplotasplt

fromkerasimport__version__

fromkeras.applications.inception_v3importInceptionV3, preprocess_input

fromkeras.modelsimportModel

fromkeras.layersimportDense, GlobalAveragePooling2D

fromkeras.preprocessing.imageimportImageDataGenerator

fromkeras.optimizersimportSGD

IM_WIDTH, IM_HEIGHT =299,299#fixed size for InceptionV3

NB_EPOCHS =3

BAT_SIZE =32

FC_SIZE =1024

NB_IV3_LAYERS_TO_FREEZE =172

defget_nb_files(directory):

"""Get number of files by searching directory recursively"""

ifnotos.path.exists(directory):

return

cnt =

forr, dirs, filesinos.walk(directory):

fordrindirs:

cnt += len(glob.glob(os.path.join(r, dr +"/*")))

returncnt

defsetup_to_transfer_learn(model, base_model):

"""Freeze all layers and compile the model"""

forlayerinbase_model.layers:

layer.trainable =False

model.compile(optimizer="rmsprop", loss="categorical_crossentropy", metrics=["accuracy"])

defadd_new_last_layer(base_model, nb_classes):

"""Add last layer to the convnet

Args:

base_model: keras model excluding top

nb_classes: # of classes

Returns:

new keras model with last layer

"""

x = base_model.output

x = GlobalAveragePooling2D()(x)

x = Dense(FC_SIZE, activation="relu")(x)#new FC layer, random init

predictions = Dense(nb_classes, activation="softmax")(x)#new softmax layer

model = Model(input=base_model.input, output=predictions)

returnmodel

defsetup_to_finetune(model):

"""Freeze the bottom NB_IV3_LAYERS and retrain the remaining top layers.

note: NB_IV3_LAYERS corresponds to the top 2 inception blocks in the inceptionv3 arch

Args:

model: keras model

"""

forlayerinmodel.layers[:NB_IV3_LAYERS_TO_FREEZE]:

layer.trainable =False

forlayerinmodel.layers[NB_IV3_LAYERS_TO_FREEZE:]:

layer.trainable =True

model.compile(optimizer=SGD(lr=0.0001, momentum=0.9), loss="categorical_crossentropy", metrics=["accuracy"])

deftrain(args):

"""Use transfer learning and fine-tuning to train a network on a new dataset"""

nb_train_samples = get_nb_files(args.train_dir)

nb_classes = len(glob.glob(args.train_dir +"/*"))

nb_val_samples = get_nb_files(args.val_dir)

nb_epoch = int(args.nb_epoch)

batch_size = int(args.batch_size)

# data prep

train_datagen = ImageDataGenerator(

preprocessing_function=preprocess_input,

rotation_range=30,

width_shift_range=0.2,

height_shift_range=0.2,

shear_range=0.2,

zoom_range=0.2,

horizontal_flip=True

)

test_datagen = ImageDataGenerator(

preprocessing_function=preprocess_input,

rotation_range=30,

width_shift_range=0.2,

height_shift_range=0.2,

shear_range=0.2,

zoom_range=0.2,

horizontal_flip=True

)

train_generator = train_datagen.flow_from_directory(

args.train_dir,

target_size=(IM_WIDTH, IM_HEIGHT),

batch_size=batch_size,

)

validation_generator = test_datagen.flow_from_directory(

args.val_dir,

target_size=(IM_WIDTH, IM_HEIGHT),

batch_size=batch_size,

)

# setup model

base_model = InceptionV3(weights="imagenet", include_top=False)#include_top=False excludes final FC layer

model = add_new_last_layer(base_model, nb_classes)

# transfer learning

setup_to_transfer_learn(model, base_model)

history_tl = model.fit_generator(

train_generator,

nb_epoch=nb_epoch,

samples_per_epoch=nb_train_samples,

validation_data=validation_generator,

nb_val_samples=nb_val_samples,

class_weight="auto")

# fine-tuning

setup_to_finetune(model)

history_ft = model.fit_generator(

train_generator,

samples_per_epoch=nb_train_samples,

nb_epoch=nb_epoch,

validation_data=validation_generator,

nb_val_samples=nb_val_samples,

class_weight="auto")

model.save(args.output_model_file)

ifargs.plot:

plot_training(history_ft)

defplot_training(history):

acc = history.history["acc"]

val_acc = history.history["val_acc"]

loss = history.history["loss"]

val_loss = history.history["val_loss"]

epochs = range(len(acc))

plt.plot(epochs, acc,"r.")

plt.plot(epochs, val_acc,"r")

plt.title("Training and validation accuracy")

plt.figure()

plt.plot(epochs, loss,"r.")

plt.plot(epochs, val_loss,"r-")

plt.title("Training and validation loss")

plt.show()

if__name__=="__main__":

a = argparse.ArgumentParser()

a.add_argument(" - train_dir")

a.add_argument(" - val_dir")

a.add_argument(" - nb_epoch", default=NB_EPOCHS)

a.add_argument(" - batch_size", default=BAT_SIZE)

a.add_argument(" - output_model_file", default="inceptionv3-ft.model")

a.add_argument(" - plot", action="store_true")

args = a.parse_args()

ifargs.train_dirisNoneorargs.val_dirisNone:

a.print_help()

sys.exit(1)

if(notos.path.exists(args.train_dir))or(notos.path.exists(args.val_dir)):

print("directories do not exist")

sys.exit(1)

train(args)

這段代碼編寫得很整齊,可以通過傳遞給下面命令的參數輕鬆理解:

我的GPU上訓練一分鐘1 epoch,每個epoch 292步,並且訓練了50個epoch(這是非常多!),批量大小為10,數據分割為80%訓練集,20%測試集。

哇哦。我們完成了訓練並得到了約91%的測試準確率,損失為0.38。該模型已保存為一個inception.model文件,可以再次載入並測試。為此,編寫了另一個腳本,同時在圖像上繪製預測類別並保存它。測試腳本如下:

importsys

importargparse

importnumpyasnp

fromPILimportImage

importrequests

fromioimportBytesIO

importmatplotlib.pyplotasplt

fromPILimportImage,ImageDraw,ImageFont

fromkeras.preprocessingimportimage

fromkeras.modelsimportload_model

fromkeras.applications.inception_v3importpreprocess_input

target_size = (229,229)#fixed size for InceptionV3 architecture

defpredict(model, img, target_size):

"""Run model prediction on image

Args:

model: keras model

img: PIL format image

target_size: (w,h) tuple

Returns:

list of predicted labels and their probabilities

"""

ifimg.size != target_size:

img = img.resize(target_size)

x = image.img_to_array(img)

x = np.expand_dims(x, axis=)

x = preprocess_input(x)

preds = model.predict(x)

returnpreds[]

defplot_preds(image, preds):

"""Displays image and the top-n predicted probabilities in a bar graph

Args:

image: PIL image

preds: list of predicted labels and their probabilities

"""

plt.imshow(image)

plt.axis("off")

plt.figure()

labels = ("daisy","dandelion","roses","sunflower","tulips")

plt.barh([,1,2,3,4], preds, alpha=0.5)

plt.yticks([,1,2,3,4], labels)

plt.xlabel("Probability")

plt.xlim(,1.01)

plt.tight_layout()

plt.show()

if__name__=="__main__":

a = argparse.ArgumentParser()

a.add_argument(" - image", help="path to image")

a.add_argument(" - image_url", help="url to image")

a.add_argument(" - model")

args = a.parse_args()

ifargs.imageisNoneandargs.image_urlisNone:

a.print_help()

sys.exit(1)

model = load_model(args.model)

model.fit()

ifargs.imageisnotNone:

labels = ("daisy","dandelion","roses","sunflower","tulips")

image1 = Image.open(args.image)

preds = predict(model, image1, target_size)

print(preds)

preds = preds.tolist()

plot_preds(image1, preds)

fonttype = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf",18)

draw = ImageDraw.Draw(image1)

draw.text(xy=(5,5),text = str(labels[preds.index(max(preds))])+":"+str(max(preds)),fill = (255,255,255,128),font = fonttype)

image1.show()

image1.save((args.image).split(".")[]+"1"+".jpg")

inception_test.py

可以通過下面的命令進行測試

所有類別的預測置信度百分比輸出如下

[daisy,dandelion,roses,sunflower,tulip]

以下是帶圖表的少數輸出

帶有概率圖表的測試圖像

最後!您已經學會了如何使用Keras和tensorflow構建強大的分類器。但是,哪一個是最好的仍然是我們頭腦中的問題!因此,讓我們僅根據此分類任務進行比較研究。

keras的全部訓練和測試代碼以及tensorflow的更改的腳本都可以在我的github中找到。

原型:

如果你真的想快速編寫代碼並構建一個模型,那麼Keras就是一個很好的選擇。我們可以在幾分鐘內建立複雜模型!Model和Sequential API非常強大,因為它們易於使用,它們甚至不會讓你感覺自己是構建強大的模型。

model = Sequential()

model.add(Dense(32, activation="relu", input_dim=100))

model.add(Dense(1, activation="sigmoid"))

model.compile(optimizer="rmsprop",

loss="binary_crossentropy",

metrics=["accuracy"])

# Generate dummy data

importnumpyasnp

data = np.random.random((1000,100))

labels = np.random.randint(2, size=(1000,1))

# Train the model, iterating on the data in batches of 32 samples

model.fit(data, labels, epochs=10, batch_size=32)

就是這樣,一個模型就準備好了!甚至相對於tensorflow,遷移學習在Keras中更容易編碼實現。在你是一個非常厲害的程序員之前,Tensorflow從頭開始編碼都太難。

從0開始以及靈活性:

上述模型是在相同的數據集上訓練的,我們看到相比於tensorflow,Keras需要更多的時間進行訓練。Tensorflow在15分鐘內完成了4000步的訓練,而Keras在50個epoch內花了大約2個小時。可能是我們無法比較epoch與步長,但在這種情況下你看到了,相比之下兩者的測試準確度均為91%,因此我們可以描述keras訓練比tensorflow慢一點。除此之外,由於tensorflow是一個低級庫,因此它是有道理的。

訓練時間和處理能力:

上述模型是在相同的數據集上訓練的,我們看到相比於tensorflow,Keras需要更多的時間進行訓練。Tensorflow在15分鐘內完成了4000步的訓練,而Keras在50個epoch內花了大約2個小時。可能是我們無法比較epoch與步長,但在這種情況下你看到了,相比之下兩者的測試準確度均為91%,因此我們可以描述keras訓練比tensorflow慢一點。除此之外,由於tensorflow是一個低級庫,因此它是有道理的。

提供額外功能:

Tensorflow有一個內置的調試器,可以在訓練期間調試以及生成圖形。

TensorFlow調試器快照 (來源:TensorFlow文檔)

Tensorflow甚至支持線程和隊列來非同步訓練大型張量!這為TPU提供了更好,更快的處理速度。線程的示例代碼如下所示:

# Create the graph, etc.

init_op = tf.global_variables_initializer()

# Create a session for running operations in the Graph.

sess = tf.Session()

# Initialize the variables (like the epoch counter).

sess.run(init_op)

# Start input enqueue threads.

coord = tf.train.Coordinator()

threads = tf.train.start_queue_runners(sess=sess, coord=coord)

try:

whilenotcoord.should_stop():

# Run training steps or whatever

sess.run(train_op)

excepttf.errors.OutOfRangeError:

print("Done training -- epoch limit reached")

finally:

# When done, ask the threads to stop.

coord.request_stop()

# Wait for threads to finish.

coord.join(threads)

sess.close()

監測和控制:

根據我在深度學習方面的經驗,我認為tensorflow非常適合許多情況,儘管它有點難度。例如,我們可以非常輕鬆地監控每個和所有內容,例如控制網路的權重和梯度。我們可以選擇應該訓練哪個步驟,哪個不應該。這在Keras中是不可行的。下面給出就是魔法!


結論:

無論如何,Keras很快將被整合到tensorflow中!那麼,為什麼要去pythonic?(Keras是pythonic)。我的建議是花一些時間習慣tensorflow。上面的分類問題,如果您已經關注博客並相應地完成了相應的步驟,然後你會覺得相比於tensorflow,Keras在很多方面都little painful and patience killer。所以,嘗試使用其他類,並嘗試為應用程序訓練分類器,如假筆記檢測...

希望這篇博客能讓你更好地了解何時使用它們!


喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 AI研習社 的精彩文章:

Machine Can See 2018 圖像對抗攻擊大賽比賽心得
針對計算機視覺一些問題的分析

TAG:AI研習社 |