「pytorchとfastaiではじめるディープラーニング」を読む

15 11月

「pytorchとfastaiではじめるディープラーニング」を読んでいく上での注意点を記録します。

作成したソフトを最終的にはローカルのパソコンで実行することになるので,google colab ではなくて,ローカルのパソコンで実行できるように環境を作っていきたいと思います。

コードなどのサイト

最初に,ubuntu のインストールです。最小限のインストールを選択します。その場合には numpy がインストールされていません。ビデオカードのドライバーを入れないようにしました。

次に,CUDA のインストールです。手順はこのサイトに従います。CUDA をインストールして,そのあとサイトに従ってビデオカードのドライバーをインストールしました。

nvidia-smi の出力です。


~$ nvidia-smi
Thu Nov 16 15:11:52 2023
+---------------------------------------------------------------------------------------+
| NVIDIA-SMI 545.23.06 Driver Version: 545.23.06 CUDA Version: 12.3 |
|-----------------------------------------+----------------------+----------------------+
| GPU Name Persistence-M | Bus-Id Disp.A | Volatile Uncorr. ECC |
| Fan Temp Perf Pwr:Usage/Cap | Memory-Usage | GPU-Util Compute M. |
| | | MIG M. |
|=========================================+======================+======================|
| 0 NVIDIA RTX A4000 On | 00000000:17:00.0 Off | Off |
| 41% 33C P8 18W / 140W | 3569MiB / 16376MiB | 0% Default |
| | | N/A |
+-----------------------------------------+----------------------+----------------------+

+---------------------------------------------------------------------------------------+
| Processes: |
| GPU GI CI PID Type Process name GPU Memory |
| ID ID Usage |
|=======================================================================================|
| 0 N/A N/A 17151 G /usr/lib/xorg/Xorg 94MiB |
| 0 N/A N/A 17274 G /usr/bin/gnome-shell 7MiB |
| 0 N/A N/A 24586 C /usr/bin/python3 3454MiB |
+---------------------------------------------------------------------------------------+

このあと、Python 関連のものを入れます。synaptic でjupyter-notebook、python3-pip のインストール。そのあとで、下記で cupy を入れる。

$ sudo python3 -m pip install -U setuptools pip
$ sudo pip3 install cupy-cuda12x

1行目のコマンドが効いているのかどうか分からない。sudo でやる必要はあると思う。12x は本当に x を書いた。pandas、matplotlib は後でインストールする予定です。numpy は関連するソフトとして,同時にインストールされた模様です。以下,いろいろとバージョンを見てみました。scipy,sympy も知らぬ間に入りました。numpy のバージョンが新しすぎるような気が?最初と異なるようなきがするが?

サンプルコードを試している環境ですが、上記であげたリンク先のページには(例えばここ)に「ドライブへのコピー」があります。

これをクリックしてダウンロードします。Ubuntu22 なのですが、ファイルは自分のホームディレクトリーのダウンロードフォルダーの中にあります。そのファイルを端末から起動したローカルで動いている jypyter-notebook から利用します。途中途中でコードを実行した際に、データなどがダウンロードされるのですが、それはホームの隠れフォルダー、「.fastai」の中に収められるようです。

以下,本を読みながらの色々を記録していきます。

p16あたり

#hide
! [ -e /content ] && pip install -Uqq fastbook
import fastbook
fastbook.setup_book()

本の方にはないが,サンプルコードに上記のようなものがある。colab ではこのまま動く。ローカルで実行するなら,fastbook は普通にインストールした方が良い。2行目はコメントアウトしておいて,端末で下記を実行した。

    sudo pip3 install -Uqq fastbook

これで,fastbook をインポート可能となった。

p16

#id first_training
#caption Results from the first training
# CLICK ME
from fastai.vision.all import *
path = untar_data(URLs.PETS)/'images'

def is_cat(x): return x[0].isupper()
dls = ImageDataLoaders.from_name_func(
    path, get_image_files(path), valid_pct=0.2, seed=42,
    label_func=is_cat, item_tfms=Resize(224))

learn = vision_learner(dls, resnet34, metrics=error_rate)
learn.fine_tune(1)

このコードは,ビデオメモリが 2GB のカードでは,メモリ不足でエラーとなった。6GB は大丈夫だった。

p17

#hide_output
uploader = widgets.FileUpload()
uploader

module ‘ipywidgets.widgets’ has no attribute ‘FileUpload’ というエラーがでる。ここのサイトによれば、ipywidgets のバージョンを7.5以上にしろとある。

    sudo pip3 install ipywidgets==7.5

sudo pip3 のところは、すべてのユーザーで有効にするかどうかによって異なるだろう。これによって,ボタンは表示されたが,上手く機能しなかった。それで,その下のコードを実行した。

#hide
# For the book, we can't actually click an upload button, so we fake it
uploader = SimpleNamespace(data = ['images/chapter1_cat_example.jpg'])

ファイルへのパスは適当に編集する。これは機能して,下記のように上手くいった。

1.000000 という驚きの判定結果だった。犬の写真では,ちゃんと false になったので,大丈夫ではないかと思う。

2章

サンプルコードの最初の所で,numpy に関して,バージョンの警告が出た。前も出たように思う。

numpy のバージョンを下げてみようと思う。

sudo pip3 uninstall numpy
sudo pip3 install numpy==1.24.4

pip3 list で確認すると、変更されていた。

$ pip3 list
Package                  Version
------------------------ ----------------
aiohttp                  3.8.6
aiosignal                1.3.1
annotated-types          0.6.0

途中省略

numpy                    1.24.4

p61あたり

azure を上手く利用できない。ImageNet の画像で同じことができないか検討してみる。以下は参照サイトなど。

ImageNet の2012年のデータをダウンロードした。トレーニング用のファイル ILSVRC2012_img_train の中にあるファイルを利用する。先に上げたサイトによれば、02132136-n がグリズリー(brown bear)で、02133161-n が American black bear、04399382-n が teddy である。それぞれ画像は1500個ある。これを2章のコードと同じ位置に配置する。フォルダー構成はコードと同じ位置に bears フォルダーを作りその中に grizzly, black, teddy フォルダーを作る。画像はすべてではなくて、それぞれ150個ほどの画像を置いた。画像のラベルはフォルダー名から取得するようで、これで2章のコードを動かすことができた。下記は、p71 の混同行列の結果である。教科書の結果と比べて、多少間違いが多くなっている。

p77 あたりの VBox も上手く行きました。ここの Upload ボタンは機能する。何が違うのだろうか?

voila のインストール。これは端末でやりました。しかし色々と上手くいかなかったので、インストールはしないほうがいいかも。

sudo pip3 install voila
sudo jupyter serverextension enable --sys-prefix voila

voila のインストールの後、jupyter-notebook が起動しなくなった。下記のようなエラーがでる。

Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/notebook/traittypes.py", line 232, in _resolve_classes
    klass = self._resolve_string(klass)
  File "/usr/local/lib/python3.10/dist-packages/traitlets/traitlets.py", line 2018, in _resolve_string
    return import_item(string)
  File "/usr/local/lib/python3.10/dist-packages/traitlets/utils/importstring.py", line 31, in import_item
    module = __import__(package, fromlist=[obj])
ModuleNotFoundError: No module named 'jupyter_server.contents'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/bin/jupyter-notebook", line 33, in 
    sys.exit(load_entry_point('notebook==6.4.8', 'console_scripts', 'jupyter-notebook')())
  File "/usr/local/lib/python3.10/dist-packages/jupyter_core/application.py", line 281, in launch_instance
    super().launch_instance(argv=argv, **kwargs)
  File "/usr/local/lib/python3.10/dist-packages/traitlets/config/application.py", line 1075, in launch_instance
    app = cls.instance(**kwargs)
  File "/usr/local/lib/python3.10/dist-packages/traitlets/config/configurable.py", line 583, in instance
    inst = cls(*args, **kwargs)
  File "/usr/local/lib/python3.10/dist-packages/traitlets/traitlets.py", line 1294, in __new__
    inst.setup_instance(*args, **kwargs)
  File "/usr/local/lib/python3.10/dist-packages/traitlets/traitlets.py", line 1337, in setup_instance
    super(HasTraits, self).setup_instance(*args, **kwargs)
  File "/usr/local/lib/python3.10/dist-packages/traitlets/traitlets.py", line 1313, in setup_instance
    init(self)
  File "/usr/lib/python3/dist-packages/notebook/traittypes.py", line 223, in instance_init
    self._resolve_classes()
  File "/usr/lib/python3/dist-packages/notebook/traittypes.py", line 235, in _resolve_classes
    warn(f"{klass} is not importable. Is it installed?", ImportWarning)
TypeError: warn() missing 1 required keyword-only argument: 'stacklevel'

このサイトなどを見て、traitlets を削除してみた。pip3 list などで見ると、traitlets は 5.14.0 が入っていたようだ。

sudo pip3 uninstall traitlets

起動するようにはなった。voila はアンインストールした。これ以降の2章のコードは実行を諦める。

p73

モデルを下記で保存している。

learn.export()

保存した pkl ファイルを利用すれば、下記のようなコードで、推論が可能である。

訓練はGPU を使っている。推論は別のパソコンで実施することになる。その場合、GPU を利用しないかもしれない。ただ、上記のコードを、GPU を利用しない VirtualBox 上の ubuntu22 で実行すると下記のような警告が来た。fastbook のインストール方法にも問題があったのかもしれない。

$ python3 ./test.py 
/usr/local/lib/python3.10/dist-packages/fastai/torch_core.py:263: UserWarning: 'has_mps' is deprecated, please use 'torch.backends.mps.is_built()'
  return getattr(torch, 'has_mps', False)
('teddy', tensor(2), tensor([1.1100e-05, 2.4582e-05, 9.9996e-01]))

mps は GPU 関連らしい。それと学習済みのモデルの取り扱いに関して、記事がいくつかある。同じようなことをみなさんやろうとしている。

当面は、推論の方にも GPU を用意することで対応しようと思う。ただ、リクエストがたくさん来て時間的に重なり、いくつかパラレルに処理するような場合、CPU 処理の方が安全な気がする。

p70 あたり、i5-3000番台で実行した場合の話

学習環境を変えて、古い core i5-3570, GeForce GTX 1060 6GB でコードを実行してみると警告があった。

抜き出すとこんな警告。 実行が止まるわけではない。

[W NNPACK.cpp:64] Could not initialize NNPACK! Reason: Unsupported hardware.

確信はないが、こんな記事があった。CPU が AVX2 命令に対応していないという警告だとのこと。確かにこの命令は4000番台から採用されている。実際に i5-4000 番台の CPU では警告が出ない。

p188

本にはコードの記述がないが、サンプルコードには下記のようなコードがある。

#hide_input
from IPython.display import HTML
df = pd.DataFrame(sm_acts, columns=["3","7"])
df['targ'] = targ
df['idx'] = idx
df['result'] = sm_acts[range(6), targ]
#t = df.style.hide_index()
t = df.style.hide()
#To have html code compatible with our script
html = t._repr_html_().split('</style>')[1]
html = re.sub(r'<table id="([^"]+)"\s*>', r'<table >', html)
display(HTML(html))

jinja2 のバージョンに関するエラーが生じていたので、jinja2 のバージョンを 3.1.2 に変更した。この他、'Styler' object has no attribute 'hide_index' というエラーもあった。これは、このサイトにあるように書き換えた。

#t = df.style.hide_index()
t = df.style.hide()

p214あたり

確定的ではないが、記録する。下記のコードに関して、

loss_func = nn.BCEWithLogitsLoss()
loss = loss_func(activs, y)

エラーが生じる。

TypeError: no implementation found for 'torch.nn.functional.binary_cross_entropy_with_logits' on types that implement __torch_function__: [, ]

まったく同じ内容というわけではないが、このサイトの記事を参考にして下記のように変更してみた。

loss_func = nn.BCEWithLogitsLoss()
#loss = loss_func(activs, y)
loss = loss_func(TensorBase(activs), TensorBase(y))
loss

出力は下記。

TensorBase(1.0535, grad_fn=<AliasBackward0>)

本とは異なる出力である。これで良いかどうかは分からない。

p261

dtreeviz をインストールする必要があった。

sudo pip install dtreeviz