stMind

You'll never blog alone

MacとLinuxでディレクトリ内ファイルリストを取得する時の挙動が違う?

以前作ったDeep Learningを使ったブランドロゴ認識だけど、ありがたいことに使ってくれる方がいて、githubにissueが来ました。

github.com

27クラスのロゴ画像をそれぞれ学習用、テスト用に分けてpickle化するスクリプトでエラーになるということらしい。Issueにあがってるエラーログを見ると、Macで実行したときと、ファイルリストを取得した結果が違っている。OSXで実行した時は、各ロゴのtestとtrainが交互で、かつソートされているので、パスのリストであるtrain_test_dirsっていう変数から、train_test_dirs[0::2]でtestのリストだけをpickleにして、train_test_dirs[1::2]でtrainのリストだけをpickleにするような処理をしていた。要は各フォルダがtest→trainという順番になっていることを想定していた。(フォルダパスをリストにするだけなのに、実際のフォルダ構成を調べて処理しなくてもよいのだけど)

train_datasets = maybe_pickle(train_test_dirs[1::2])  # trainをpickle化
test_datasets = maybe_pickle(train_test_dirs[0::2])  # testをpickle化

OSXでのリストはこんな感じ。

Adidas/test
Adidas/train
Apple/test
Apple/train
BMW/test
BMW/train
(以下略)

一方で、どのDistributionかはわからないけど、Linuxで実行したらしき結果はこんな感じ。

Texaco/train
Texaco/test
Starbucks/train
Starbucks/test
Mini/train
Mini/test
(以下略)

ソートされてないし、trainとtestの順序が逆になっている。とりあえず、リストをスライスするときに、最初がtrainで次がtestになるように、

train_datasets = maybe_pickle(train_test_dirs[0::2])  # 最初(0)がtrain
test_datasets = maybe_pickle(train_test_dirs[1::2])  # 次(1)がtest

と変更してもらったら、エラーは出なくなったようだ。ちなみに、centosだとエラーだったけど、debianにしたら動いた、という方もいた。

結局

StackOverflowに回答あるみたいだけど、MacLinuxというか、FileSystemによって順番は違っていて、順番を固定した処理がしたければos.listdirでリストを取得した後に明示的にソートしておくということか。stackoverflow.com