Practical Deep Learning For Coders, Part 1をやっと終えた

fast.ai のMOOC講座、Practical Deep Learning For Coders, Part 1をやっていて 一通り学習できたので Part 2 へ進む前にまとめてみます。

どんな講座?

7個のレッスンがありディープラーニングのBest practicesを学べます。 講座の中でKaggleの実際のコンペ(Dogs vs. Cats Redux: Kernels EditionState Farm Distracted Driver DetectionThe Nature Conservancy Fisheries Monitoring)にも挑戦し、上位に入れるテクニックを教えてもらえます。

これが無料。すごい世の中になりました。ƪ(•◡•ƪ)"

レッスンあたり10時間、you should plan to spend around 10 hours a week for 7 weeks to complete the material と書いてありましたが3倍ぐらいは必要な印象です。

私は3周ぐらいリピートしたので相当に時間がかかってしまいました。。

学べる内容

  • Image Classification (Lesson1,2,3,4,7)
    • 転移学習 (VGG16)
    • Overfitting対策
      • (Dropout)
      • Data Augmentation
      • Batch Normalization
    • Semi-Supervised Learning (Pseudo labelling)
    • いろいろなアーキテクチャ
      • Multi-Input (メタデータの利用)
      • Multi-Output (Bounding Box出力)
      • Fully Convolution Network (Global Average Pooling)
      • Larger size input (640x360)
      • Inception model
      • Resnet
  • NLP (Lesson 4,5,6)
    • Embedding
    • Collaborative filtering
    • Pre-trained word embedding (Glove)
    • Sentiment Analysis
      • Multi-size CNN, LSTM
    • Text generation (character-level language model)
      • Sequential RNN, Stateful RNN, GRU

学習環境

Python2 + Keras 1.x系を使い、KerasのバックエンドはTheanoです。ただ、Theanoは開発が止まることが決定したのでちょっとアレな感じになっちゃいました。。

基本的にバックエンドに依存しないKerasの高レベルAPIだけで使うのでTheanoの開発が終わったあとに学習を始めても無駄にならないはず。Part 2では TensorFlowとPyTourchになるようです

TensorFlowをバックエンドしても動きますが、学習済みの重みファイルを変換しないとちゃんとした精度がでないので要注意です。 (「fast.aiでTensorFlowをバックエンドとして使う」)

非力な自宅PC(メモリ8GB、GPUメモリ2GB)ではLesson2ぐらいまでしか通用せず、基本的にはAWSやAzureのGPUインスタンスが必要です。

中間出力ファイルのサイズが大きいので全部のレッスンをファイルを消さずに進めるとディスクは70GB以上使います。

なので、ディスク容量への課金を節約するためにインスタンスのディスクサイズをミニマムにするといちいちファイルを消さないといけなくちょっと面倒かもしれません。

感想

日本語のブログ記事は

あたりしか見つかりませんでした。(調べ方がよくないのだろうか??)

惜しい点

  • 提供されているnotebookをその通りに実行しても講師のjeremyの結果をなぜか再現できないことが所々ある
  • keras 1.1.0(提供されているAWSのイメージでのkerasバージョン)とkeras 1.2.2(Azure用の環境構築スクリプトでインストールしたときのkerasバージョン)で挙動が違っていてkeras1.2.2だと所々動かなかったりする

ここでハマるとかなり時間のロスになります。。

あと、公開からそこそこ時間も経っているせいか今、フォーラムで質問してもレスがない場合が多い印象です。

ハマったところ

  • lesson2.ipynb

    keras 1.2.2 では Iteratorのメソッドが N ではなく n に変わっている...

      model.evaluate_generator(get_batches(path+'valid', gen, False, batch_size*2), val_batches.n) # keras 1.2.2
      #model.evaluate_generator(get_batches(path+'valid', gen, False, batch_size*2), val_batches.N) # keras 1.1.0
    
  • dogs_cats_redux.ipynb

    sklearnのバージョンが0.19.1だと log_lossでエラーになる...

      # y = [log_loss([1],[[i*.0001,1-(i*.0001)]],eps=1e-15) for i in range(1,10000,1)] # this raise error...
      # http://forums.fast.ai/t/dogs-cats-redux-error-y-true-contains-only-one-label/6137/4
      y = [log_loss([1,0],[i*.0001,1-(i*.0001)],eps=1e-15) for i in range(1,10000,1)]
    
  • lesson3.ipynb

    notebook通りのlearning rateではJeremyの結果が再現できない...

      # We won't reproduce Jeremy's results with parameters (p=0.6, lr=0.001)
      # http://forums.fast.ai/t/bn-loss-scores-increasing-during-bn-model-fit-training-in-l3/4617
      p=0.3
    
  • lesson4.ipynb

    notebook通りのパラメータではJeremyの結果が再現できない...

      # u = Embedding(n_users, n_factors, input_length=1, W_regularizer=l2(1e-4))(user_in)
      u = Embedding(n_users, n_factors, input_length=1, W_regularizer=l2(1e-6))(user_in) # http://forums.fast.ai/t/lesson-4-discussion/210/51
    
  • statefarm.ipynb

    5倍にするとどうやってもメモリエラーになってしまう...

      # da_conv_feat = conv_model.predict_generator(da_batches, da_batches.nb_sample*5)
      da_conv_feat = conv_model.predict_generator(da_batches, da_batches.nb_sample*1) # use 1 time instead of 5 times to avoid Memory Error...
    
  • wordvectors.ipynb

    Jupyter notebookを開くとNotJSONErrorになる...

    NotJSONError in wordvectors.ipynb · Issue #152 · fastai/courses · GitHub

  • lesson5.ipynb

    notebook通りではJeremyの結果を再現できない...

      # http://forums.fast.ai/t/lesson-5-discussion/233/23
      # try starting the embedding layer as being trainable, and then set it to non-trainable after a couple of epochs. 
      # It improved my accuracy from 0.83 to 0.9. Nothing else did.
      model.layers[0].trainable=True
    
  • lesson6.ipynb

    notebook通りだと' 'が出力される...

      #model.optimizer.lr=0.000001 
    
      # http://forums.fast.ai/t/lesson-6-discussion/245/26
      model.optimizer.lr = 0.001 # Adam's default learning rate will be fine.
    

    notebook通りだとエラーになる...

      #model.optimizer.lr.set_value(0.000001) # This causes AttributeError: 'float' object has no attribute 'set_value' !
      # http://forums.fast.ai/t/python-and-keras-questions-and-tips/224/18
      model.optimizer.lr = 0.000001
    
  • lesson7

    keras 1.2.2 だと gen.flow でエラーが出る...

      # In keras 1.2.2, you'll encounter 'ValueError: NumpyArrayIterator is set to use the dimension ordering convention "th" (channels on axis 1), i.e. expected either 1, 3 or 4 channels on axis 1'.
      # http://forums.fast.ai/t/pseudo-labeling-section-in-lesson-7-throwing-a-valueerror/1746/4
    
      if keras.__version__ == '1.2.2':
          import image # override NumpyArrayIterator in keras 1.1.0.
    

    utils.pyのMixIteratorをそのまま使うとうまくいかない

      # Change the method in utils.py a bit so that it can work
      class MixIterator(object):
          def __init__(self, iters):
              self.iters = iters
              self.multi = type(iters) is list
          if self.multi:
              # self.N = sum([it[0].N for it in self.iters])
              self.N = sum([it.N for it in self.iters])
          else:
              self.N = sum([it.N for it in self.iters])
    
          def reset(self):
              for it in self.iters: it.reset()
    
          def __iter__(self):
              return self
    
          def next(self, *args, **kwargs):
              if self.multi:
                  #nexts = [[next(it) for it in o] for o in self.iters]
                  nexts = [next(it) for it in self.iters]
                  n0 = np.concatenate([n[0] for n in nexts])
                  n1 = np.concatenate([n[1] for n in nexts])
                  return (n0, n1)
              else:
                  nexts = [next(it) for it in self.iters]
                  n0 = np.concatenate([n[0] for n in nexts])
                  n1 = np.concatenate([n[1] for n in nexts])
                  return (n0, n1)
    

これらの修正を含めた私のnotebookはこちらにあります。 github.com

追記

Part1のv2がリリースされるようです

Unofficial release of part 1 v2 - Part 1 - Deep Learning Course Forums

BTW, if you’re in the middle of v1 of the course, I’d strongly encourage you to switch to the new v2. It’s a huge step up from v1 in terms of the quality of models that you’ll learn and the amount you’ll be able to do. If you’ve already completed v1, you’ll find most of v2 is new, so it’s worth doing as well (especially lessons 2-4).

とあるのでPart2の前にPart1のv2をやったほうがいいのかなあ