• トップ
  • ブログ一覧
  • 【前編】「Keras」と「PyTorch」を徹底比較してみた!~MNIST編~
  • 【前編】「Keras」と「PyTorch」を徹底比較してみた!~MNIST編~

    広告メディア事業部広告メディア事業部
    2020.08.03

    IT技術

    【前編】Keras と PyTorch を比較したい!

    現在、Keras(ケラス)と PyTorch(パイトーチ)が、機械学習フレームワークの中で人気 No 1、2を争っています。

    今回は、この2つを「様々な角度」から徹底比較してみようと思います!

    SageMaker(セージメイカー)

    また、本記事では、「SageMaker」を使っていきたいと思います。

    SageMaker では、「Jupyter Notebook」でビルトインカーネルを切り替えるだけで、どちらのフレームワークも簡単に動かすことができます。

    インストールする手間もなく、おすすめです!

    MNIST で比較!(Kerasの場合)

    まずは、Keras について見ていきたいと思います。

    「Sequential モード」の場合を想定して、解説していきます。

    モデル定義パート

    Keras の MNIST のモデル定義の部分は、以下のような感じになります。

    1model = Sequential()
    2model.add(Conv2D(32, kernel_size=(3, 3),
    3                 activation='relu',
    4                 input_shape=input_shape))
    5model.add(Conv2D(64, (3, 3), activation='relu'))
    6model.add(MaxPooling2D(pool_size=(2, 2)))
    7model.add(Dropout(0.25))
    8model.add(Flatten())
    9model.add(Dense(128, activation='relu'))
    10model.add(Dropout(0.5))
    11model.add(Dense(num_classes, activation='softmax'))
    12
    13model.compile(loss=keras.losses.categorical_crossentropy,
    14              optimizer=keras.optimizers.Adadelta(),
    15              metrics=['accuracy'])

    Sequential を使ったモデル定義の場合だと、model.add() で、使いたいレイヤを必要なパラメータと共に付け加えていくだけで簡単に定義できてしまいます。

    また、一番最初のレイヤだけは input_shape=  の部分で画像サイズ(あるいはテンソルのサイズ)を入力していますが、そのあとのレイヤでは自動で計算してくれます。

    モデル定義の見やすさは、Keras が有利でしょう。

    トレーニングパート

    続いて、トレーニング部分を見ていきます!

    1model.compile(loss=keras.losses.categorical_crossentropy,
    2              optimizer=keras.optimizers.Adadelta(),
    3              metrics=['accuracy'])
    4
    5model.fit(x_train, y_train,
    6          batch_size=batch_size,
    7          epochs=epochs,
    8          verbose=1,
    9          validation_data=(x_test, y_test))

    model.compile() でオプティマイザと損失関数をセットしています。

    あとは model.fit()  をコールすれば、Epoch 回数分の学習が走ります。

    verbose=1 としているので、中間結果としての損失と Accuracy が表示されます。

    損失関数」と「オプティマイザ」は通常セットで変更するので、compile と fit パートを分けているのは、とても合理的な実装だと思います。

    とてもシンプルかつ簡単で、そういった面では Keras が断然優位です。

    MNISTで比較!(PyTorchの場合)

    続いて、PyTorch で同じ部分を見てみましょう!

    モデル定義パート

    モデル定義は、次のようにクラスを使って行います。

    1class Net(nn.Module):
    2    def __init__(self):
    3        super(Net, self).__init__()
    4        self.conv1 = nn.Conv2d(1, 32, 3, 1)
    5        self.conv2 = nn.Conv2d(32, 64, 3, 1)
    6        self.dropout1 = nn.Dropout2d(0.25)
    7        self.dropout2 = nn.Dropout2d(0.5)
    8        self.fc1 = nn.Linear(9216, 128)
    9        self.fc2 = nn.Linear(128, 10)
    10
    11    def forward(self, x):
    12        x = self.conv1(x)
    13        x = F.relu(x)
    14        x = self.conv2(x)
    15        x = F.relu(x)
    16        x = F.max_pool2d(x, 2)
    17        x = self.dropout1(x)
    18        x = torch.flatten(x, 1)
    19        x = self.fc1(x)
    20        x = F.relu(x)
    21        x = self.dropout2(x)
    22        x = self.fc2(x)
    23        output = F.log_softmax(x, dim=1)
    24        return output

    PyTorch では、クラスの初期化と Forward 関数を定義する必要があります。

    初期化では、使用する層についての定義を行い、Forward 関数でこれをつなげていきます。

    各層への「入力サイズ」と「出力サイズ」をきちんと書いていかなければならない事が、Keras と大きく違います。

    畳み込み計算などは、出力サイズを計算するのが少し面倒です。

    このあたりについては、Keras を使った方が余計なことを考えずにネットを組むことができて楽です。

    「全てが表示されていて、隠されたものがない」というあたりは、とても見通しが良い印象です。

    Keras だと「あれ?これだけでいいの?」と逆に考え込んでしまうようなら、PyTorch の方がいいかもしれません。

    トレーニングパート

    続いて、トレーニング部分を見ていきます!

    1 model.train()
    2    for batch_idx, (data, target) in enumerate(train_loader):
    3        data, target = data.to(device), target.to(device)
    4        optimizer.zero_grad()
    5        output = model(data)
    6        loss = F.nll_loss(output, target)
    7        loss.backward()
    8        optimizer.step()
    9        if batch_idx % log_interval == 0:
    10            print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(
    11                epoch, batch_idx * len(data), len(train_loader.dataset),
    12                100. * batch_idx / len(train_loader), loss.item()))

    Keras とは大きく異なり、Epoch ごとに入力テンソルを Loader より取り込み、オプティマイザを初期化した後、計算を実行します。

    計算が終わったら、

    1. 損失値を算出
    2. 微分
    3. オプティマイザをかける

    という一連の流れをすべて記述する必用があります。

    このあたりは、ほとんどが定型的なものなので、覚えてしまえば、それほど難しくはありません。

    ただ、それぞれ微妙に調整しなければいけないので、調整のやり方がよくわからない初心者の方には少しハードルが高いかもしれません。

    このやり方は、「Define by Run」と呼ばれるやり方ですが、「なんでこれが良いの?」と思う人もいるかもしれません。

    ですが、実際にデバッグをするときには、こちらの方が圧倒的にやりやすいのです。

    データの流れを追ってみる!

    せっかくデータの流れが追えるので、少しだけデータの流れを追ってみましょう。

    enumerate で「一回分のデータxバッチサイズ」の配列が datatarget に渡されます。

    (ここでの target とはラベルのことです。)

    次に、「CPU」か「GPU」に渡されたデータを送ります。

    データを渡したら、続いて、オプティマイザを初期化します。

    一回のネットワークでの epoch は output=model(data) で行われます。

    epoch が走ったら(もしくは実際のネットワークでの加乗算が走ったら)、損失を計算し、微分をして、ネットワーク内部の Weight を更新していきます。

    この流れは、どのニューラルネットでも同じ動きで、その動きが見える、データの流れが見えるというところは、PyTorch の素敵な部分の1つです。

    デバッグがやりやすい

    デバッグがやりやすいのも、特徴の1つです。

    たとえば Jupyter であれば、問題のあったところに「pdb」を埋め込めば、その場でテンソルの内容を確認することができます!

    1from IPython.core.debugger import Pdb; Pdb().set_trace()

    これがそのデバッグ文ですね。

    これをいれると、その場で pdb の入力ができるようになります。

    試した後は、「c」を入力すると元に戻るので、コマンドを知らないうちは「c」を入力してください。

    実際に output = model(data) のあとに、この行を挿入してみてください。

    入力側のネットワークのTensorと、一回の演算結果での出力側の Tensor について簡単に見ることができます。

    GPUへの切り替えが楽!

    また、次の行もポイントで、実際に「GPU」を使用するテンソルを決めて、GPU に転送することも簡単に書けます。

    1data, target = data.to(device), target.to(device)

    Keras で GPU を使う場合は、バックエンドをインストールしなおすことが必要となり、それに比べると PyTorch は非常に楽です。

    Keras の場合でも、SageMaker だとカーネルを切り替えるだけで済むので簡単ですが、そうでないない場合は断然、PyTorch が楽です。

    このあたりを難しく感じるような初心者のころや、中身ははあまり考えたくない、もしくは必要ないという場合は、Keras をオススメします。

    実際に自分でデータを持っていて、「アダプテーションを行うから、実際のデータをデバッグで見ないといけないんだ!」というような人には、PyTorch をオススメします。

    「実装状況」で比較

    世の中の実装状況を見ていると、感触では、PyTorch の方が実装が増えているように感じます。

    が、実際はどうでしょうか?

    実際に、本家のサンプルプログラム数を比較してみます。

    すると、Keras だと主要なものが「5つ」。

    それに対して、PyTorch の方は「12」もあります。

    よって、PyTorch の方が数は多いということが言えます。

    「ドキュメント」で比較

    PyTorch は、昔からとても良いドキュメントが公式サイトに展開されています。

    今回、2020年4月に1.5がリリースされてドキュメントが一新されましたが、さらに良くなっています。

    【PyTorch ドキュメント】
    https://pytorch.org/docs/stable/index.html

    特に、「PyTorch Hub」と言われるサイトには、最新のリサーチ(研究)レベルのネットが多く掲載されています。

    【PyTorch Hub】
    https://pytorch.org/hub/

    一方、Kerasでは…

    Keras の方は、ドキュメントは PyTorch に比べるとやや薄いという感じがします。

    ただ、一貫した思想に基づいて作られているので、こちらの方が好きな人もいるのではないかと感じます。

    【Keras ドキュメント】
    https://keras.io/about/

    「記述性」で比較

    記述性では、PyTorch と比較されがちな Keras。

    ただ、Keras には、「ファンクションモード」という上級向けの機能があります。

    これを使うと、ほぼ PyTorch と同じような記述性を持っています。

    また、Callback を使いこなすと、PyTorch の学習ループでやっているようなことも書くことが出来ます。

    kerasは、決して機能的に劣っているということはありません。

    「学習のしやすさ」で比較

    Keras は、初心者がとても学習しやすいものになっています。

    これは Keras が、レイヤ(層)中心の考え方で作られているためです。

    これは、層と層を繋げていくことで、「ニューラルネットが成り立っている」ということをよく理解できるからです。

    また、書籍類についても、Keras の方が、ニューラルネットの解説をしてある本で良書のものが多いです。

    PyTorch

    PyTorch は、どちらかというと実践向けが多いというイメージです。

    書籍類についても、実践的な上級者向けの内容が多いようです。

    後編につづく!

    今回は、人気の機械学習フレームワーク Keras と PyTorch を簡単に比較してみました。

    1. 初心者や情報系の大学院生などには、「Keras」
    2. 実際に実務でネットを組むような場合には、「PyTorch」

    という感じが良いのかなと思いました。

    機械学習に興味がある方は、ぜひ一度、Keras と PyTorch を試してみてください!

    後編に続く

    後編では、もうすこし深く、見ていきたいと思います!

    featureImg2020.08.04【後編】「Keras」と「PyTorch」を徹底比較してみた!~データローダ・転移学習編~【後編】Keras と PyTorch を比較したい!前回は、基本的な「Keras」と「PyTorch」の違いについて...

    こちらの記事もオススメ!

    featureImg2020.07.28機械学習 特集知識編人工知能・機械学習でよく使われるワード徹底まとめ!機械学習の元祖「パーセプトロン」とは?【人工知能】ニューラルネ...

    featureImg2020.07.17ライトコード的「やってみた!」シリーズ「やってみた!」を集めました!(株)ライトコードが今まで作ってきた「やってみた!」記事を集めてみました!※作成日が新し...

    ライトコードでは、エンジニアを積極採用中!

    ライトコードでは、エンジニアを積極採用しています!社長と一杯しながらお話しする機会もご用意しております。そのほかカジュアル面談等もございますので、くわしくは採用情報をご確認ください。

    採用情報へ

    広告メディア事業部

    広告メディア事業部

    おすすめ記事

    エンジニア大募集中!

    ライトコードでは、エンジニアを積極採用中です。

    特に、WEBエンジニアとモバイルエンジニアは是非ご応募お待ちしております!

    また、フリーランスエンジニア様も大募集中です。

    background