技術かなり間を空けてしまいましたが第3回です。CNTK自体が刻々とバージョンアップが続けられているため本連載の内容も陳腐化しているところがありますが、今回で終わりとなるので書ききってしまいます。前回の記事ではCNTKで多層パーセプトロン(MLP)のモデル実装とMNISTデータセットの学習を実施しました。今回は畳み込みニューラルネットワーク(CNN)を実装し、総括を行って終わりとしたいと思います。入力データは前回同様MNISTデータセットを使用します。データ準備の手順は前回に記載済みのため省略しますが、不明な人は前回を参照してください。はじめる機械学習(1)なお、畳み込みニューラルネットワークの基礎知識についてここで述べることはしません。私自身それほど詳しいわけではないですが、まったくわからないという方がいましたら「畳み込みニューラルネットワーク」で検索すると解説している文献はたくさん見つかりますので、調べてみると良いでしょう。CNNの実装さっそくCNNのモデルを実装しましょう。前回作成したmodels.pyに以下のコードを追加します。])見て頂ければわかると思いますが、MLPと比べても実装量はほんの少し増えているくらいで、それほど差がありません。このようにモデルの実装が簡単に行えるのはライブラリを使用する大きな利点になります。これらを中心に説明します。pad=pad_default_or_False)Convolutionはニューラルネットワークの畳み込み層を表す機能です。rf_shapeにフィルタの形状、num_filtersに出力フィルタ数を指定します。initは前回のDenseと同様、heの初期値を指定しています。padは出力のzero-paddingを行うか否かを表すフラグです。今回はdefault_optionsを使用しています。これは任意で使うことが可能で、withキーワードとともに使用することでネストの内部でdefault_optionsで指定した値がデフォルト値となります。今回はactivation=reluが記述されているため、Convolutionの活性化関数はReLU関数となっています。注意点として、フィルタの形状rf_shapeはConvolutionの入力パラメータと次元数を合わせなければいけません。MLPのときはMNISTデータセットの画像データを1次元に変換して全結合層で扱っていましたが、今回は画像の縦×横に合わせた2次元のデータを入力とします。することによってピクセル間の縦横の位置関係を考慮した学習が可能となります。pad=False)MaxPoolingはニューラルネットワークのプーリング層を表す機能です。Maxとあるとおり、最大値プーリングを実現します。存在しますので、用途に応じて使い分けましょう。rf_shapeとpadはConvolutionと同じです。stridesはプーリング処理のフィルタの移動量となります。今回はMaxPoolingにもdefault_optionsで記述したpad=Falseの指定が適用されています。DropoutDropout(prob)Dropoutはニューラルネットワークのドロップアウト層を表す機能です。probに0~1の範囲で有効とするパラメータの割合を指定します。1を指定するとすべてのパラメータを有効とし、ゼロを指定した場合はすべてのパラメータが無効となります。CNNで画像認識を実装するCNNのモデルを使用し、画像認識の実装を行ないます。前回のMLPと全体の流れは同じになるので、解説は変更のあるところに留めます。28)に変更しています。MLPでは1次元のデータを入力としていましたが、今回は縦×横の形状のままデータを入力するため、このように定義を変更します。create_readerに渡す入力データのサイズは前回同様、784を指定したいので、input_dataにサイズを確保しています。次に、モデルの作成部です。nn.layers(scaled_input)ここは前項で作成したCNNのモデルを作るようにしているだけですね。同じインターフェースで作るようにしているので、生成部の差し替えでOKです。次にTrainerの生成です。momentum=mm_schedule))少し変更量が多いですが、これは学習関数をsgdからadam_sgdへ変更したことが原因です。sgdのままであればMLPのときと全く同じコードでOKです。adam_sgdを使用せずともそれほど問題無いと思いますが、学習関数を変更する例として記載しておきます。学習期間max_epochsも40週に変更しています。これはモデルの複雑度が向上したことから学習に必要な期間が伸びた結果を考慮しています。最後に全体のコードを記載します。教師データとラベルを対応付けるハッシュ配列。テストデータとラベルを対応付けるハッシュ配列。error)スクリプトを実行してみましょう、と言いたいところですが前回と異なりかなりの処理時間が必要です。PCの処理性能によりますが数時間~もしかすると1日ほどかかるかもしれません。その間はPCが使い物にならなくなるため、実行するときは注意してください。誤って実行してしまったなどの理由で中断したいときは、コンソールでCtrl+Cを押せばキャンセルできると思います。処理時間についてなぜ今回のモデルがこれほど遅くなるのか疑問に思われるかもしれませんが、全結合層(Dense)と畳み込み層(Convolution)では計算量が違いますし、単純に層の深さも増加しています。この例を見てもわかるように機会学習には十分な処理性能を持ったマシンと時間が必須です。28×28という非常に小さなサイズの画像データでさえそうなのですから、データの大きさや量、モデルの複雑さが向上すればその時間は加速度的に増加していきます。このような処理時間の問題についてCNTKは特に力を入れて取り組んでおり、GPUコンピューティングのサポートや複数PCによる並列処理、また1bit-SGDといった高速化のための機能を利用するように呼びかけています。上記のグラフはあくまでMicrosoftが公表したデータですが、GPUおよび複数PC使用時の処理性能は他のライブラリを大きく引き離しています。私自身は試していませんが、クラウドサービスのAzureにCNTK構築済みの環境も用意されているそうです。性能向上を図るときはこういった機能を活用していきましょう。おわり3回に渡ってCNTKのインストールからMLP、CNNのモデルおよびMNISTデータセットの学習について記載してきました。私自身まだまだ勉強しているところですが、近年の機械学習分野の発展は目覚ましいものがあります。自分で実装してみると実感できると思うのですが、利用する側から見ると機械学習は難しい数式やネットワークモデルの理論よりも、むしろ学習データの準備やどのようにネットワークモデルにデータを入力するかという方法が大きな問題となります。(改善を続けてきた研究者の方たちの地道な努力があるからこそ言えるのですが)インターネット上にはMNISTデータセット以外にも学習用途に使うためのデータを提供してくれているものや、ネットワークモデルの学習パラメータを公開しているものもあります。いったものを上手く利用して機械学習による開発を行っていきたいですね。長くなりましたが、ここまでお付き合いいただいた方はありがとうございました。羅針では一緒に働いてくれる技術者を募集しています。機械学習...の仕事はまだ無いですが、われこそは!という方やともに技術を高めあっていきたいという方がいらっしゃれば、応募お待ちしております。