KelpNetをOpenCL・GPUで動かす
今回は、KelpNetをOpenCL・GPUで動かす方法を紹介します。OpenCLは、CPU・GPU・FPGAなどで並列処理を行うためのAPIです。KelpNetはCUDAではなくOpenCLを用いるため、GPUを用いる場合でも環境構築がとても簡単に出来ます。また、Nvidia製のGPUだけでなく、AMD製のRadeon系のGPUなどにも対応しています。
この記事でははじめにOpenCLの導入について説明し、次にコードをGPUに対応させる方法について説明します。
OpenCLの導入
OpenCLは、MacやNvidia製のGPUの最新のドライバなどはデフォルトでサポートされているため、特に導入の作業が増えることはありません。GPUのドライバを長い間アップデートしていないなという方は、こちらからデバイスにあったバージョンをダウンロード出来ます。また、AMD製のCPU・GPUもこちらからダウンロードできます。
以下では、少し手順が必要なIntel製のCPUを用いる場合のOpenCLのドライバのインストール方法について説明します。はじめに、こちらのサイトを開きます。次に、右側のメニューからWindowsもしくはLinuxの内自分のOSに合ったものを選択し、FREE Downloadをクリックしてください。
すると次のようなページに飛びますので、チェックボックスにチェックを入れ、氏名などの情報を入力し、Submitをクリックしてください。
Submitをクリックすると、製品名・ライセンスタイプ・シリアル番号などの情報をIntel側に送信してもよいかどうかを尋ねられるので、チェックボックスにチェックを入れます。
チェックボックスにチェックを入れると、以下のようなダウンロード用のリンクが出現しますので、こちらをクリックしてOpenCLのインストーラーをダウンロードします。
ダウンロードが終わったら、インストーラーを起動してください(注:インストールはVisual Studioを閉じてから行ってください)。インストーラーの起動後は基本的にNext連打 & Installで大丈夫です。最後に再起動(Reboot)するかどうかを聞かれますので、再起動してOpenCLのインストールは終了です。
また、以下のようにWeaverを初期化することで、KelpNetをOpenCLで動かすことが可能になります。Weaverとは、CPU・GPU関連の処理を担うマネージャーのようなものです。CPUが2台以上ある場合は、CPUのインデックスを指定することが出来ます。
// Weaverを初期化 Weaver.Initialize(ComputeDeviceTypes.Cpu); // CPUが2台以上ある場合はインデックスを指定 // Weaver.Initialize(ComputeDeviceTypes.Cpu, 0);
KelpNetのコードをGPUに対応させる
GPUを用いる場合は、まずWeaverのDeviceTypeにGPUを指定して初期化します。CPUの際と同様に、GPUが2台以上ある場合は、GPUのインデックスを指定することができます。次に、ネットワークを定義する際に全結合層(Linear)や畳み込み層(Convolution2D)のGPUフラグ(gpuEnable)をtrueにします。これだけでKelpNetをGPUで動かすことが出来ます。
(2018/09/01 追記)
CPU & GPUなど、複数のプラットフォームにOpenCLをインストールしている場合、Weaverを初期化する際に使用したいplatformIdを指定する必要があります。どのプラットフォームにどのIDが割り当てられているかは、以下のコードによって確認することが出来ます。ここで、ClooとKelpNetは同じ名前のクラスを持つため、コンフリクト(衝突)が発生する可能性があります。そのため、using Cloo;
は学習を行う際にはコメントアウトしてください。
// ComputePlatformを呼び出すために、Clooを用意 using Cloo; // Main関数で以下のfor文を実行 for (int i = 0; i < ComputePlatform.Platforms.Count; i++) Console.WriteLine("platformId: " + i + " " + ComputePlatform.Platforms[i].Name);
すると、出力が以下のようになります。この際は、CPUを用いる場合はplatformIdに0を、GPUを用いる場合はplatformIdに1を指定してください。
platformId 0 Intel (R) OpenCL platformId 1 NVIDIA CUDA
// Weaverを初期化 platformIdは上記の方法で確認し, 指定する Weaver.Initialize(ComputeDeviceTypes.Gpu, platformId: 1); // デバイスが2台以上ある場合はインデックスを指定可能 // Weaver.Initialize(ComputeDeviceTypes.Gpu, platformId: 1, deviceIndex: 1); // CPU FunctionStack model = new FunctionStack( new Convolution2D(3, 32, 5, pad: 2, name: "l1 Conv2D"), new BatchNormalization(32, name: "l1 BatchNorm"), new ReLU(name: "l1 ReLU"), new Linear(5 * 5 * 64, 256, name: "l2 Linear"), new BatchNormalization(256, name: "l2 BatchNorm"), new ReLU(name: "l2 ReLU"), new Linear(256, 3, name: "l3 Linear"), new Softmax(name: "l3 Softmax") ); // GPU FunctionStack model = new FunctionStack( new Convolution2D(3, 32, 5, pad: 2, name: "l1 Conv2D", gpuEnable: true), new BatchNormalization(32, name: "l1 BatchNorm"), new ReLU(name: "l1 ReLU"), new Linear(5 * 5 * 64, 256, name: "l2 Linear", gpuEnable: true), new BatchNormalization(256, name: "l2 BatchNorm"), new ReLU(name: "l2 ReLU"), new Linear(256, 3, name: "l3 Linear", gpuEnable: true), new Softmax(name: "l3 Softmax") );