ImageNetは大規模な画像データベースで、現在2万クラス1,400万枚を超える画像があります。クラスにはWordNetの単語を用いています。CNNがブレークしたILSVRCというコンペで用いられたりと、ベンチマークとして有名なデータセットです。
画像のダウンロードは、非営利で研究/教育目的に限られるので、それ以外の人は、画像のURLリストを使って自分でダウンロードしなければなりません。
URLリスト作成のための事前準備
今回は、ILSVRC2012で指定された1,000クラスをダウンロードしてみます。1,000クラスのみのURLリストはないので、自分でつくります。作成に必要なものは以下の3つです。
- すべての画像のURLリスト
- 1,000クラスのリスト
- WordNet IDとクラス名の紐付けリスト
すべての画像のURLリスト
http://image-net.org/download-imageurls からダウンロードできます。今回はFall 2011 Releaseをダウンロードしました。容量は334MBで、14,197,122行ありました。
URLリストは、画像IDとURLの2カラムが書かれています。
$ head -n 3 fall11_ulrs.txt n00004475_6590 http://farm4.static.flickr.com/3175/2737866473_7958dc8760.jpg n00004475_15899 http://farm4.static.flickr.com/3276/2875184020_9944005d0d.jpg n00004475_32312 http://farm3.static.flickr.com/2531/4094333885_e8462a8338.jpg
画像IDはユニークなIDで、xxx_yyy
のような形式です。xxx
はWordNetのIDです。
1,000クラスのリスト
ファイルとしてはダウンロードできないので、 http://image-net.org/challenges/LSVRC/2012/browse-synsets からつくります。つくったリストは https://git.io/ILSVRC2012 においています。
$ head -n 3 ILSVRC2012_ClassList.txt kit fox, Vulpes macrotis English setter Australian terrier
1行が1クラスです。
WordNet IDとクラス名の紐付けリスト
http://image-net.org/archive/words.txt からダウンロードできます 。WordNetIDとクラス名の2カラムが書かれています。
$ head -n 3 words.txt n00001740 entity n00001930 physical entity n00002137 abstraction, abstract entity
ダウンロードする画像のURLリストをつくる
1,000クラスからWordNet IDを算出
紐付けリスト(words.txt
)をつかって1,000クラスリスト(ILSVRC2012_ClassList.txt
)のWordNet IDを求めます。それぞれpandas
で読み込んでクラス名でマージします。
import pandas as pd words = pd.read_csv('words.txt', header=None, delimiter='\t') words.columns = ['id', 'name'] ILSVRC2012 = pd.read_csv('ILSVRC2012_ClassList.txt', header=None, delimiter='\t') ILSVRC2012.columns = ['name'] df = pd.merge(words, ILSVRC2012, on='name') w_ids = list(df['id'])
ここで、ついでに0~999のラベルをつくっておくと、学習に使うときに便利です。
label = pd.DataFrame(df['name'].unique()) label.columns = ['name'] label['label'] = label.index df = pd.merge(df, label, on='name')
1,000クラスのWordNet IDに含まれるものを抽出
すべての画像のURLリスト(fall11_urls.txt
)から、さきほどのWordNet IDに含まれるID(w_ids
)だけを抽出します。utf-8でない文字が含まれるようなので、無視するようにします。
import codecs urls = [] with codecs.open('fall11_urls.txt', 'r', 'utf-8', 'ignore') as f: for line in f: image_id, url, *tmp = line.strip().split('\t') w_id, _ = image_id.split('_') if w_id not in w_ids: continue urls.append({'name': image_id + '.jpg', 'url': url}) pd.DataFrame(urls).to_csv( 'urllist.txt', index=False, columns=['name', 'url'], header=False, sep=' ')
つくったURLリストには1,341,431ありました。
URLリストをつかって画像をダウンロード
いろいろ試した結果*1、wget
でダウンロードしました。
wget
の-b
オプションでバックグラウンド実行できるので、並列にダウンロードできます。-nc
オプションですでにあるファイルはダウンロードしないので、途中からやり直すのも楽です。
タイムアウト(-T
)は1秒、リトライ回数(-t
)は5回にしていますが、適当です。バックグラウンドで実行するときはログファイルができるので、ファイルを-a
オプションで指定しないと、1画像1ファイルできるので、大変なことになります。
$ cat urllist.txt | xargs -n 2 ./download.sh
# download.sh if [ $# -ne 2 ]; then exit 1 fi wget $2 -O $1 -T 1 -t 5 -nc -b -a wget.log
130万画像のダウンロードに3時間くらいかかりました。ファイルの容量は全部で100GBくらいでした。
コードは以下にまとめています。