2019年11月28日木曜日

マザーボードのBIOSアップデート


私の家のデスクトップPCは自作パソコンでほぼ10年前につくりました。
Deep Learningを試してみようと思い、グラフィックボードは最近買い替えましたがそれ以外はそのままです。
Win10になって、アップデートしてもうまく行かないこともしばしばですが、ま~問題なく動いているのでそのまま使っています。

【パソコン構成】
●マザーボード:ASUSteK SABERTOOTH X79
●CPU:Intel Core(TM)i7-3930K @3.20GHz --- Deep learning中はほぼ3.5GHzで稼働
●グラフィックボード:MSIのGeForce GTX 180Ti --- RTXが出て値下がりしたときに買いました
●メモリ-:Corsair DDR3 1600MHz 32.0GB


昔一度BIOSのアップデートを行ったのですが、今行おうとすると方法が変わっていたのでメモしておきます。
以前BOISのファイルは拡張子が「.ROM」のファイルでしたが、今ASUSからBIOSのファイルをダウンロードすると拡張子が「.CAP」のファイルになっています。

昔のBIOSセットアップツールでは、拡張子が「.CAP」のファイルは取り扱えないので、まず「★-CAP-Converter」を使って、拡張子が「.CAP」のファイルが扱えるBIOSセットアップツールにアップデートしておきます。
私の場合「SABERTOOTH-X79-CAP-Converter」ですが、ASUSホームページの製品情報ページからは見つからなかったので、googleで「SABERTOOTH-X79-CAP-Converter」で検索してここで見つかりました。

その後、ASUSホームページから最新のBIOSをダウンロードし、最新のBIOSにセットアップします。

【手順】

  1. ダウンロードしたzipファイルの「SABERTOOTH-X79-CAP-Converter」を解凍すると「SABERTOOTH-X79-CAP-Converter.ROM」ファイルがあります。このファイルをFAT32でフォーマットしたUSBにコピーするのですが、FAT32ではファイル名の文字数制限(8文字?)があるので、とりあえず「SABERX79.ROM」に変更しました。
  2. このUSBをマザーボード上のUSB端子に接続します。ここでもUSB3端子ではなく~USB2が良いと書いてあるものもありました。
  3. パソコンを再起動し(起動中にDeleteキーを押し続けて)、「UEFI BIOS Utility」を開きます。
  4. 右上の「終了/アドバンス」を押してアドバンスモードにします。
  5. 「Tool」メニューを選び「EZ Flash 2ユーティリティ」をクリック、以下指示に従って保存した「SABERX79.ROM」を選択してアップデートを行います。ここまで来ると「UEFI BIOS Utility」で「.CAP」ファイルが扱えるようになりますし、BIOSもある程度アップデートされたものに更新されています。
  6. 最後に最新のBIOSへのアップデートです。ASUSホームページからダウンロードした最新のBIOSの「.CAP」ファイルをUSBにコピーし、上と同じように「UEFI BIOS Utility」からBIOSの更新を行えば出来上がりです。SABERTOOTH-X79の場合、最新のBIOSでも2014/07/28のバージョン 4801 ベータバージョンが最新でした。もうこれ以上更新されることは無いでしょう。







2019年11月20日水曜日

Transfer learningでpretrained=True or Faleの違いについて


2019年11月11日と13日の投稿で、Transfer Learningを使った例をいきなり行いました。 私達が独自の画像データを集めて画像分類などのDeep learningを試そうとする場合、十分な数のデータを集められることは稀です。このような場合、ゼロからConvolutional Networkを組みトレーニングしても思うような結果が得られません。 そこで、Transfer Learningです。十分大きなデータセット、例えばImagNetのような1000カテゴリーで140万の画像でトレーニングされたモデルを使って、そこで事前トレーニングされたパラメーターのweightsを目的とするタスクの初期値として利用します。 fast.ai(PyTorch)には、たとえば分類(Classification)の分野で実績のある下記のモデルが実装されています。
  • AlexNet
  • VGG
  • ResNet
  • SqueezeNet
  • DenseNet
  • Inception v3
  • GoogLeNet
  • ShuffleNet v2
  • MobileNet v2
  • ResNeXt
  • Wide ResNet
  • MNASNet

これらの多くはILSVRC(ImagNet Large Scale Visual Recognition Challenge)という画像認識のコンペティションで優秀な成績を収めたモデルです。 2012年のこのコンペでDeep learningの手法を用いたAlexNetの登場が、今日のDeep learningの隆盛の先駆けだったようです。 事前トレーニングされたパラメーターのweightsがどれほど効果的なのか、確認してみたいと思います。 fast.aiでは、分類(Classification)にResNet34をよく使っているようなので、以降もモデルとしてResNet34を使います。 モデルを読み込むとき、pretrained=True(デフォルト設定)とすると、事前トレーニングされたパラメーターのweightsも読み込み、pretrained=Falseではパラメーターのweightsは読み込まれません。 これを使って、下記プログラムで両者を比べてみま見た。それにしてもfast.aiを使うと本当に簡単に書けますネ(^o^)。



%reload_ext autoreload
%autoreload 2
%matplotlib inline



from fastai.vision import *
from fastai.metrics import accuracy



dataset_dir='F:/DataSet/cifar10/cifar10_png'

データは同じくcifar10を使います。



tfms = get_transforms(do_flip=False)



path = dataset_dir
data=ImageDataBunch.from_folder(path,'train','val',ds_tfms=tfms, size=224,bs=16)
data.normalize(imagenet_stats)



# pretrain=True
learn_t = cnn_learner(data, models.resnet34, metrics=accuracy,callback_fns=ShowGraph)

# pretrain=False
learn_f = cnn_learner(data, models.resnet34, pretrained=False, metrics=accuracy,callback_fns=ShowGraph)



learn_t.model




ResNetモデルの構造を見てみます。

Sequential(
  (0): Sequential(
    (0): Conv2d(3, 64, kernel_size=(7, 7), stride=(2, 2), padding=(3, 3), bias=False)
    (1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
    (2): ReLU(inplace=True)
    (3): MaxPool2d(kernel_size=3, stride=2, padding=1, dilation=1, ceil_mode=False)
    (4): Sequential(
      (0): BasicBlock(
        (conv1): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
        (bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
        (relu): ReLU(inplace=True)
        (conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
        (bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      )
      (1): BasicBlock(
        (conv1): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
        (bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
        (relu): ReLU(inplace=True)
        (conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
        (bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      )
      (2): BasicBlock(
        (conv1): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
        (bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
        (relu): ReLU(inplace=True)
        (conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
        (bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      )
    )
    (5): Sequential(
      (0): BasicBlock(
        (conv1): Conv2d(64, 128, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)
        (bn1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
        (relu): ReLU(inplace=True)
        (conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
        (bn2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
        (downsample): Sequential(
          (0): Conv2d(64, 128, kernel_size=(1, 1), stride=(2, 2), bias=False)
          (1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
        )
      )
      (1): BasicBlock(
        (conv1): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
        (bn1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
        (relu): ReLU(inplace=True)
        (conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
        (bn2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      )
      (2): BasicBlock(
        (conv1): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
        (bn1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
        (relu): ReLU(inplace=True)
        (conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
        (bn2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      )
      (3): BasicBlock(
        (conv1): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
        (bn1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
        (relu): ReLU(inplace=True)
        (conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
        (bn2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      )
    )
    (6): Sequential(
      (0): BasicBlock(
        (conv1): Conv2d(128, 256, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)
        (bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
        (relu): ReLU(inplace=True)
        (conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
        (bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
        (downsample): Sequential(
          (0): Conv2d(128, 256, kernel_size=(1, 1), stride=(2, 2), bias=False)
          (1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
        )
      )
      (1): BasicBlock(
        (conv1): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
        (bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
        (relu): ReLU(inplace=True)
        (conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
        (bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      )
      (2): BasicBlock(
        (conv1): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
        (bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
        (relu): ReLU(inplace=True)
        (conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
        (bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      )
      (3): BasicBlock(
        (conv1): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
        (bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
        (relu): ReLU(inplace=True)
        (conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
        (bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      )
      (4): BasicBlock(
        (conv1): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
        (bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
        (relu): ReLU(inplace=True)
        (conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
        (bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      )
      (5): BasicBlock(
        (conv1): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
        (bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
        (relu): ReLU(inplace=True)
        (conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
        (bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      )
    )
    (7): Sequential(
      (0): BasicBlock(
        (conv1): Conv2d(256, 512, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)
        (bn1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
        (relu): ReLU(inplace=True)
        (conv2): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
        (bn2): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
        (downsample): Sequential(
          (0): Conv2d(256, 512, kernel_size=(1, 1), stride=(2, 2), bias=False)
          (1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
        )
      )
      (1): BasicBlock(
        (conv1): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
        (bn1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
        (relu): ReLU(inplace=True)
        (conv2): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
        (bn2): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      )
      (2): BasicBlock(
        (conv1): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
        (bn1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
        (relu): ReLU(inplace=True)
        (conv2): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
        (bn2): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
      )
    )
  )
  (1): Sequential(
    (0): AdaptiveConcatPool2d(
      (ap): AdaptiveAvgPool2d(output_size=1)
      (mp): AdaptiveMaxPool2d(output_size=1)
    )
    (1): Flatten()
    (2): BatchNorm1d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
    (3): Dropout(p=0.25, inplace=False)
    (4): Linear(in_features=1024, out_features=512, bias=True)
    (5): ReLU(inplace=True)
    (6): BatchNorm1d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
    (7): Dropout(p=0.5, inplace=False)
    (8): Linear(in_features=512, out_features=10, bias=True)
  )
)

2019年11月11日のPyTorchのプログラムでは、最後の行

Linear(in_features=512, out_features=10, bias=True)

の赤字の10を、当初の1000から手作業でプログラムを組んで10に書換えていたのですが、fast.aiなら自動で書換えを行ってくれます。


# pretrained=Trueでトレーニング
learn_t.fit_one_cycle(4)

epoch    train_loss valid_loss accuracy time
0 0.546411 0.288624 0.904300 07:55
1 0.379403    0.204893 0.930500 07:52
2 0.307759 0.164119 0.943500 07:54
3 0.233057 0.156459    0.947800   07:52




# pretrained=Falseでトレーニング
learn_f.fit_one_cycle(4)

epoch train_loss    valid_loss    accuracy time
0          1.570276    1.356783 0.500200 09:28
1 1.037542 0.792953 0.722100 09:28
2 0.740422 0.555599 0.814100 09:28
3 0.578225 0.480209 0.840300 09:30



予想されたように、事前学習したweightsを初期値として利用できないpretrained=Falseでトレーニングした場合の精度は、pretrained=Trueに比べて明らかに下回りました。
でもepoch=4で精度0.840300は良い、良すぎるような気がします。

2019年11月11日投稿のPtTorchのプログラムで同じようにpretrained=Falseで試してみました。

Epoch 0/3
----------
train Loss: 1.8815 Acc: 0.3081
val Loss: 1.4405 Acc: 0.4643

Epoch 1/3
----------
train Loss: 1.5991 Acc: 0.4250
val Loss: 1.2646 Acc: 0.5476

Epoch 2/3
----------
train Loss: 1.3999 Acc: 0.5015
val Loss: 1.0513 Acc: 0.6295

Epoch 3/3
----------
train Loss: 1.2554 Acc: 0.5591
val Loss: 0.8255 Acc: 0.7179

Training complete in 20m 41s
Best val Acc: 0.717900





fast.aiで0.840300、0.717900との違いはよく分かりません。学習率の違いか何かデフォルトパラメータの違いだと思いますが、勉強不足で分かりません。また何時か検証したいと思います。