Python3とPyTorchを使用してニューラルスタイル転送を実行する方法

提供:Dev Guides
移動先:案内検索

序章

機械学習(ML)は、データからモデルを学習するアルゴリズムに焦点を当てたAIのサブフィールドです。

ニューラルスタイル転送と呼ばれるコンピュータビジョンの分野での機械学習の実用的なアプリケーションを見てみましょう。 2015年、研究者はディープラーニング技術を使用して、ある画像のコンテンツを別の画像の芸術的なスタイルと混合するアルゴリズムを作成しました。 この新しいアルゴリズムは独自の画像を生成しましたが、視覚システムが新しい芸術的概念をどのように推測するかについても独自の視点を提供しました。

その名前が示すように、ニューラルスタイルの転送はこのタスクを実行するためにニューラルネットワークに依存しています。 この実装の正確な詳細はこのチュートリアルの範囲を超えていますが、芸術的なスタイルの転送に関するこのブログ投稿または元の研究原稿から詳細を学ぶことができます。

このチュートリアルでは、Jupyter NotebookとLinuxコマンドラインを使用してニューラルスタイル転送を適用し、次のような画像を取得します。

フィンセントファンゴッホの「星月夜」の芸術的なスタイルを適用して変換し、次の画像を作成します。

前提条件

このチュートリアルを完了するには、次のものが必要です。

機械学習モデルの操作はメモリを大量に消費する可能性があるため、このチュートリアルの計算の一部を実行するには、マシンに少なくとも8GBのメモリが必要です。

ステップ1—依存関係のインストールとPyTorch-Style-TransferGitHubリポジトリのクローン作成

このチュートリアルでは、 HangZhangによって提供されるPyTorch-Style-Transferと呼ばれるニューラルスタイル転送のオープンソース実装を使用します。 この特定の実装では、PyTorchライブラリを使用します。

プログラミング環境をアクティブ化し、次のコマンドを使用してtorchvisionおよびtorchfileパッケージをインストールします。

pip install torchvision torchfile

Pipは自動的に依存関係を取得します。

OutputSuccessfully installed numpy-1.22.0 pillow-9.0.0 torch-1.10.1 torchfile-0.1.0 torchvision-0.11.2 typing-extensions-4.0.1

ホームディレクトリがファイルで乱雑にならないようにするには、style_transferという名前の新しいディレクトリを作成し、それを作業ディレクトリとして使用します。

mkdir style_transfer
cd style_transfer

次に、git cloneコマンドを使用して、PyTorch-Style-Transferリポジトリを作業ディレクトリに複製します。 Gitの詳細については、このGitチュートリアルシリーズをご覧ください。

git clone https://github.com/zhanghang1989/PyTorch-Style-Transfer.git

このリポジトリの作成者は、使用するコードをPyTorch-Style-Transferリポジトリのexperimentsフォルダーに配置したため、すべてのファイルのクローンが作成されたら、このディレクトリに切り替えます。

cd PyTorch-Style-Transfer/experiments

experimentsディレクトリの内容を見てください。

ls

次のディレクトリが表示されます。

Outputcamera_demo.py  dataset  images  main.py  models  net.py  option.py  utils.py

このチュートリアルでは、ストック画像を含むimages/ディレクトリと、画像にニューラルスタイル転送を適用するために使用されるmain.pyスクリプトを使用します。

次のセクションに進む前に、ニューラルスタイル転送を実行するために必要な事前トレーニング済みの深層学習モデルもダウンロードする必要があります。 これらのモデルは大きくなる可能性があるため、GitHubに保存するのには適していないため、作成者はファイルをダウンロードするための小さなスクリプトを提供します。 スクリプトはmodels/download_model.shにあります。

まず、スクリプトを実行可能にします。

chmod +x ./models/download_model.sh

次に、スクリプトを実行してモデルをダウンロードします。

./models/download_model.sh

すべてがダウンロードされたので、これらのツールを使用していくつかの画像を変換してみましょう。

ステップ2—最初のスタイルの転送実験を実行する

ニューラルスタイルの転送がどのように機能するかを説明するために、PyTorch-Style-Transferリポジトリの作成者によって提供された例を使用することから始めましょう。 画像を表示して表示する必要があるため、Jupyterノートブックを使用する方が便利です。

ターミナルからJupyterを起動します。

jupyter notebook

次に、提示された手順に従ってJupyterにアクセスします。

Jupyterが表示されたら、右上のプルダウンメニューから New> Python 3 を選択して、新しいノートブックを作成します。

これにより、コードを入力できる新しいノートブックが開きます。

ノートブックの上部に、次のコードを追加して、必要なライブラリをロードします。

ノート

import torch
import os
import subprocess
from IPython.display import Image
from IPython.display import display

torchに加えて、標準ライブラリosおよびsubprocessもインポートします。これらは、Jupyterノートブックから直接Pythonスクリプトを実行するために使用します。 また、Jupyterノートブック内に画像を表示できるIPython.displayライブラリも含まれています。

ALT+ENTER(またはmacOSではSHIFT+ENTER)と入力してコードを実行し、ノートブック内の新しいコードブロックに移動します。 このチュートリアルの各コードブロックの後にこれを実行して、結果を確認します。


PyTorch-Style-TransferリポジトリのREADMEファイルで提供されている例では、images/ディレクトリにあるストックイメージとmain.pyスクリプトを使用しています。 main.pyスクリプトを実行するには、少なくとも5つの引数を指定する必要があります。

  • コンテンツ画像へのパス(/images/contentにあります)。
  • スタイル画像へのパス(/images/21stylesにあります)。
  • スタイル転送の実行に使用される事前トレーニング済みのGAN(Generative Adversarial Network)モデルへのパス(/modelsにあります)。
  • 出力画像のパスと名前。
  • ディープラーニングモデルは、GPUではるかに高速に実行されます。 使用可能なパラメーターがある場合は、--cuda=1パラメーターを指定します。それ以外の場合は、--cuda=0を使用します。

ニューラルスタイルの転送コードを実行するには、必要な引数を指定し、subprocessライブラリを使用してシェルでコマンドを実行します。

まず、作業ディレクトリへのパスを定義しましょう。 workingdirという変数に格納します。

ノート

# define the path to the working directory
experiment_dir = 'style_transfer/PyTorch-Style-Transfer/experiments'
workingdir = '{}/{}'.format(os.environ['HOME'], experiment_dir)

画像やその他のファイルを指すときに、コード全体でこの変数を使用します。

次に、main.pyスクリプトへのパスと、このテスト実行の入力として使用する引数のリストを定義しましょう。 コンテンツ画像をvenice-boat.jpg、スタイル画像をstarry_night.jpgと指定し、ニューラルスタイル転送の出力をtest.jpgというファイルに保存します。

ノート

# specify the path to the main.py script
path2script = '{}/main.py'.format(workingdir)

# specify the list of arguments to be used as input to main.py
args = ['eval',
        '--content-image',
        '{}/images/content/venice-boat.jpg'.format(workingdir),
        '--style-image',
        '{}/images/21styles/starry_night.jpg'.format(workingdir),
        '--model',
        '{}/models/21styles.model'.format(workingdir),
        '--output-image',
        '{}/test.jpg'.format(workingdir),
        '--cuda=0']

テスト例を実行する前に、ノートブックで次のコードを実行することにより、この例で選択したコンテンツとスタイルの画像を簡単に確認できます。

ノート

content_image = Image('{}/images/content/venice-boat.jpg'.format(workingdir))
style_image = Image('{}/images/21styles/starry_night.jpg'.format(workingdir))
display(content_image)
display(style_image)

次の画像が出力に表示されます。

最後に、main.pyの呼び出しとその引数のリストを連結し、subprocess.check_output関数を使用してシェルで実行します。

ノート

# build subprocess command
cmd = ['python3', path2script] + args

# run the command
x = subprocess.check_output(cmd, universal_newlines=True)

マシンで使用可能なメモリの量によっては、実行に1〜2分かかる場合があります。 完了すると、作業ディレクトリにtest.jpgファイルが表示されます。 Jupyterノートブックから、 Ipythonマジックコマンドを使用して、Jupyterノートブック内の作業ディレクトリの内容を表示できます。

ノート

!ls $workingdir

または、端末でlsコマンドを使用することもできます。 どちらの方法でも、次の出力が表示されます。

Output__pycache__ dataset  main.py  myutils  option.py
camera_demo.py  images   models   net      test.jpg

test.jpgという新しいファイルが表示されます。このファイルには、入力コンテンツとスタイル画像を使用したニューラルスタイル転送の結果が含まれています。

Image機能を使用して、test.jpgの内容を表示します。

ノート

Image('{}/test.jpg'.format(workingdir))

ヴィンセントヴァンヴォーの星月夜のキャンバスの芸術的なスタイルは、ヴェネツィアのボートの画像のコンテンツにマッピングされています。 教科書の例でニューラルスタイルの転送を正常に適用したので、別の画像でこの演習を繰り返してみましょう。

ステップ3—独自の画像を変換する

これまで、使用しているライブラリの作成者から提供された画像を使用してきました。 代わりに私たち自身の画像を使用しましょう。 これを行うには、興味のある画像を見つけて次のコマンドでその画像のURLを使用するか、提供されたURLを使用してSammytheSharkを使用します。

もう一度IPythonマジックを使用して、イメージを作業ディレクトリにダウンロードし、sammy.pngというファイルに配置します。

ノート

!wget -O - 'https://assets.digitalocean.com/blog/static/sammy-the-shark-gets-a-birthday-makeover-from-simon-oxley/sammy-jetpack.png' > $workingdir/sammy.png

ノートブックでこのコマンドを実行すると、次の出力が表示されます。

Output--2017-08-15 20:03:27--  https://assets.digitalocean.com/blog/static/sammy-the-shark-gets-a-birthday-makeover-from-simon-oxley/sammy-jetpack.png
Resolving assets.digitalocean.com (assets.digitalocean.com)... 151.101.20.233
Connecting to assets.digitalocean.com (assets.digitalocean.com)|151.101.20.233|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 10483 (10K) [image/png]
Saving to: 'STDOUT'

-                   100%[===================>]  10.24K  --.-KB/s    in 0.001s  

2017-08-15 20:03:27 (12.9 MB/s) - written to stdout [10483/10483]

Imageコマンドを使用して、ノートブックに新しい画像を表示します。

ノート

Image('{}/sammy.png'.format(workingdir))

テスト実行と同じワークフローに従って、コンテンツ画像としてロケットサミーを使用し、スタイル画像と同じ星月夜の画像を使用して、芸術的なスタイル転送モデルを実行してみましょう。

以前と同じコードを使用しますが、今回はコンテンツ画像をsammy.png、スタイル画像をstarry_night.jpgに指定し、出力をファイルに書き込みます。 starry_sammy.jpgと呼ばれます。 次に、次のコマンドを実行します。

ノート

# specify the path to the main.py script
path2script = '{}/main.py'.format(workingdir)

# specify the list of arguments to be used as input to main.py
args = ['eval',
        '--content-image',
        '{}/sammy.png'.format(workingdir),
        '--style-image',
        '{}/images/21styles/starry_night.jpg'.format(workingdir),
        '--model',
        '{}/models/21styles.model'.format(workingdir),
        '--output-image',
        '{}/starry_sammy.jpg'.format(workingdir),
        '--cuda=0']

# build subprocess command
cmd = ['python3', path2script] + args

# run the bash command
x = subprocess.check_output(cmd, universal_newlines=True)

次に、Image関数を使用して、フィンセントファンヴォーの星月夜の芸術的なスタイルをロケットサミー画像のコンテンツに転送した結果を表示します。

ノート

Image('{}/starry_sammy.jpg'.format(workingdir))

新しい定型化されたロケットサミーが表示されます。

別のスタイルの画像をロケットサミーの写真にマッピングして、これをもう一度試してみましょう。 今回はピカソのミューズを使用します。 ここでも、コンテンツ画像としてsammy.pngを使用しますが、スタイル画像をla_muse.jpgに変更します。 出力をmusing_sammy.jpgに保存します。

ノート

# specify the path to the main.py script
path2script = '{}/main.py'.format(workingdir)

# specify the list of arguments to be used as input to main.py
args = ['eval',
        '--content-image',
        '{}/sammy.png'.format(workingdir),
        '--style-image',
        '{}/images/21styles/la_muse.jpg'.format(workingdir),
        '--model',
        '{}/models/21styles.model'.format(workingdir),
        '--output-image',
        '{}/musing_sammy.jpg'.format(workingdir),
        '--cuda=0']

# build subprocess command
cmd = ['python3', path2script] + args

# run the bash command
x = subprocess.check_output(cmd, universal_newlines=True)

コードの実行が終了したら、指定した出力ファイル名とImage関数を使用して、作業の出力を表示します。

ノート

Image('{}/musing_sammy.jpg'.format(workingdir))

これで、これらの変換の使用方法についての良いアイデアが得られたはずです。 まだ使用していない場合は、独自の画像をいくつか使用してみてください。

結論

このチュートリアルでは、Pythonとニューラルスタイル転送モデルのオープンソースPyTorch実装を使用して、画像にスタイル転送を適用しました。 機械学習とAIの分野は広大であり、これはそのアプリケーションの1つにすぎません。 探索できるその他の事項は次のとおりです。