首先来看一下 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
便可以给出数据的输入顺序。
但是由于正则表达式的问题,会导致其无法读取文件名中带有 - 的文件,比如无法读取名为 ‘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
另外有一点需要多加注意,需要在 flow_from_directory(directory)
将 shuffle
设置为 False
!要不然读入的图像是打乱顺序的,怎么可能还找出正确的顺序。
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 的文件中搬离了出来
[1] seriesc GitHub https://github.com/keras-team/keras/pull/10489#issuecomment-421888042