Keras 中 list_pictures 函式的原始碼分析及改進
1. list_pictures 的原始碼分析及改進
1.1 list_pictures 的原始碼分析
首先來看一下 list_pictures 的原始碼,具體如下
def list_pictures(directory, ext='jpg|jpeg|bmp|png|ppm'):
return [os.path.join(root, f)
for root, _, files in os.walk(directory) for f in files
if re.match(r'([\w]+\.(?:' + ext + '))', f) ]
不是很熟悉 python 的小夥伴可能會覺得上面的程式碼寫的有點迷,這實際上列表推導式,它等價於下面的這段程式碼
def list_pictures(directory, ext='jpg|jpeg|bmp|png|ppm'):
res = []
for root, _, files in os.walk(directory):
for f in files:
if re.match(r'([\w]+\.(?:' + ext + '))', f):
res.append(os.path.join(root,f ))
return res
我們可以看到使用列表推導式只需要 4 行程式碼即可,但是使用了雙層 for
迴圈加上 if
條件判斷需要 7 行程式碼。所以列表推導式是一種高效簡潔的寫法。
python 中 os.walk
是一個簡單易用的檔案、目錄遍歷器,用這種方式來遍歷出文件夾中的所有路徑,並返回一個包含所有路徑的迭代器。這個函式的好處是,在我們使用 Keras 中的 predict_generator
的批量地預測資料中的結果時,我們並不知道返回的預測的結果對應的什麼樣的輸入順序,這個時候使用 list_pictures
便可以給出資料的輸入順序。
1.2 list_pictures 的原始碼改進
但是由於正則表示式的問題,會導致其無法讀取檔名中帶有 - 的檔案,比如無法讀取名為 ‘asd-123.jpg’ 這樣的圖片。考慮到我們在實際使用中,在一個檔案中應該是都是圖片,所以完全可以拋棄正則表示式,而使用檔案遍歷的方式,下面是我改進的 list_pictures
函式
def my_list_pictures(path):
"""return the img path in a list
# Arguments
path: the path which is stored pintures
# Return
list
"""
pictures_list = []
for (root, dirs, files) in os.walk(path):
for file in files:
pictures_list.append(os.path.join(root, file))
return pictures_list
2. 如何正確 import list_pictures
在一年之前 Keras 的版本大概是 2.1.X,現在安裝的版本大多都是 2.2.X。在這兩個版本中,list_pictures 函式所在的資料夾發生了改變,我們可以從下面的 import
看出,在這裡我們分別以 Keras 2.2.4 和 Keras 2.1.5 為例進行說明
首先我們需要檢視自己安裝 keras 的版本,在Ubuntu終端中執行
python
>>> import keras
>>> keras.__version__
將會看到對應的結果,然後我們根據自己 Keras 的版本正確的 import
即可
# Keras 2.2.4
from keras_preprocessing.image import list_pictures
# Keras 2.1.5
from keras.preprocessing.image import list_pictures
所以在 Keras 2.1.5 中 list_pictures
位於 keras -> preprocessing -> image.py
,而在 Keras 2.2.4 中 list_pictures
位於 keras_preprocessing -> image.py
,相當於將 image.py
從 keras 的檔案中搬離了出來