ホーム >  機械学習 > Google Colaboratory >  【GoogleColab】ニューラルネットワークの画像生成 その1【オートエンコーダ】

投稿日:   |  最終更新日:

【GoogleColab】ニューラルネットワークの画像生成 その1【オートエンコーダ】

Google ColaboratoryPython機械学習

画像を生成するニューラルネットワークのプログラムGoogleColabでを実行します。

ニューラルネットワークで画像を生成

機械学習で画像を変換する研究が盛んに行われています。ある画像から別の画像へ徐々に変化させる「モーフィング」や写真を別のスタイル(画風)に変換する「スタイル変換」など、機械学習による成果によって発展しました。

どんな手法か?

画像生成を行うニューラルネットは、「生成モデル」に分類されます。

オートエンコーダー

もっとも有名な生成モデルの一つに、自己符号化(Autoencorder)と呼ばれるものがあります。もとの画素数よりもずっと小さい次元で画像を表現したりします。

敵対的生成ネットワーク

GAN(Generative Adversarial Network)と呼ばれるもので、低次元の乱数(ノイズ)から画像を生成できます。学習データとして与えた画像とは大きく違った画像も生成することも可能です。写真のような高精細な画像は、多くの場合GANを応用した手法で作られます。

潜在変数

オートエンコーダーでは、「小さい次元」や「低次元のノイズ」と呼んでいる部分がポイントです。いずれも潜在変数(Latent variables)と呼ばれます。この潜在変数から画像を生成するイメージをつかむ鍵になります。

必要なもの

必要なものはWindowsあるいはMacPCのみです。ただし、GoogleChoromeをインストールしている必要があります。GoogleColabを使うには、以下のステップが必要です。

①Googleアカウントを用意してログインする。

②Colabにアクセスし、プログラムを書き込むノートブックを作成する。

【無料】Google Colabを使ってサクッとPythonを使う【Python】

実行環境の準備

①Colabにアクセスします。

Colab

②左上の「ドライブにアクセス」をクリックします。

③「その他」の「アプリを追加」から「Colaboratory」をインストールします。

④ノートブックをひらけばpythonのコードが記述できます。


学習データ(画像)の取得

①GoogleColabに以下のコードはを記述します。PyTorchのモジュールの準備とデータの取得を行います。

import torch
import torch.nn as nn
import torchvision
from torchvision import datasets
from torchvision import transforms
import numpy as np
import matplotlib.pyplot as plt

# GPUを利用できる場合は、'cuda:0'を設定
device = torch.device( 'cuda:0' if torch.cuda.is_available( ) else 'cpu')

print(device)

#Fashion-MNISTのデータをダウンロード
DIR = '/content' #ダウンロード先
fmnist = datasets.FashionMNIST(root=DIR, train=False, download=True)

解説

学習用データとして、Fushion-MNISTのデータセットを利用します。

Fushion-MNIST

ニューラルネットワークを学んだり評価したりする場合は、MNISTと呼ばれる手書きの数字のデータセットがよく利用されます。Fashion-MNISTはその代替品の1つで、MNISTと同じ28×28ピクセルの画素数を持ったグレースケールで構成されています。シャツ、ドレス、コート、スニーカー。ブーツ、バッグといった物体のグレースケール画像が10カテゴリ(10クラス)用意されています。

PyTorch

import torch
import torch.nn as nn
import torchvision
from torchvision import datasets
from torchvision import transforms
import numpy as np
import matplotlib.pyplot as plt

Fashion-MNISTを取得するためのクラスが用意されています。上記の部分で、PyTorchのモジュールの準備が用意されています。

# GPUを利用できる場合は、'cuda:0'を設定
device = torch.device( 'cuda:0' if torch.cuda.is_available( ) else 'cpu')

GPUを利用できるか否かに応じて用いるデバイスを切り替えるために、変数deviceを用意しています。実行すると「cuda:0」と表示されます。この表示がでればColabのGPUが使える状態です。「cpu」と出る場合は、ColabのGPUの設定が間違っています。

DIR = '/content' #ダウンロード先
fmnist = datasets.FashionMNIST(root=DIR, train=False, download=True)

torchvisionのdatasets.FashionMNISTというクラスで、「download=True」を指定すると、rootで指定したフォルダーにFashion-MNISTのデータが自動的にダウンロードされます。

train=Falseとしているのは、テスト用データ(1万枚)の方を利用するためです。

この場合、Colabのサーバーの一時領域(/content)にダウンロードされますが、予めGoogleドライブをマウントしておけば、マイライブに保存することもできます。

②実行ボタンを押して、データの取得が実行されます。

データセットの画像確認

データセットの画像を確認します。

①以下の記述を実行します。

for i in range(10):
  print(i, fmnist.classes[fmnist[i][1]])
  plt.imshow(np.array(fmnist[i][0]), 'gray')
  plt.show()

1万枚のデータのうちに最初の10万枚の画像が、そのクラス名(シャツ、ドレス、などのカテゴリ)とともに表示されます。


学習用データセットの準備

一部のデータを読み込むための独自クラスを以下のように作成します。

class DataSubset(torch.utils.data.Dataset):
  def __init__(self, orig_dataset, use_classes, n_each,
                   transform = transforms.ToTensor()):
    self.orig_dataset = orig_dataset #元のデータセット
    self.use_classes = use_classes #用いるクラスidリスト
    self.n_each = n_each # 各クラスで用いる枚数
    self.transform = transform # 読み込み時の画像変換
    n_cls = len(self.use_classes) # 用いるクラス数

    # 元データセットへのインデックスリストを取得
    list_each = [[] for ci in range(n_cls)]
    for i, (_, label) in enumerate(orig_dataset):
      if all(len(list_each[ci]) >= n_each for ci in range(n_cls)):
        break
      if label in use_classes:
        list_each[use_classes.index(label)].append(i)
    #各クラスのリストのn_each個分を取り出し連結する
    self.idx_list = \
      sum([list_each[ci][0:n_each] for ci in range(n_cls)], [ ] )

  def __len__(self):
    """新データセットのサイズ(画像の枚数)"""
    return len(self.idx_list)

  def __getitem__(self, index):
    """画像を読み込む"""
    img = self.orig_dataset[self.idx_list[index]][0]
    return self.transform(img)

解説

class DataSubset(torch.utils.data.Dataset):

datasets.Fashion.MNISTなどの画像データセットは、torch.utils.data.Datasetというクラスを継承しています。datasets.Fashion.MNISTは、このままだと1万枚の画像全て順に読み込むことができます。「torch.utils.data.Dataset」を継承して、独自のクラス(DataSubset)を作成します。

    # 元データセットへのインデックスリストを取得
    list_each = [[] for ci in range(n_cls)]
    for i, (_, label) in enumerate(orig_dataset):
      if all(len(list_each[ci]) >= n_each for ci in range(n_cls)):
        break
        if label in use_classes:
          list_each[use_classes.index(label)].append(i)
    #各クラスのリストのn_each個分を取り出し連結する
    self.idx_list = \
      sum([list_each[ci][0:n_each] for ci in range(n_cls)], [ ] )

  def __len__(self):
    """新データセットのサイズ(画像の枚数)"""
    return len(self.idx_list)

元のデータセットの何番目を用いるか求め、リスト「self.idx_list」に保存します。

  list_each = [[] for ci in range(n_cls)]

リスト内包表記で、0~n_clsの要素を持つリストを作成します。

    #各クラスのリストのn_each個分を取り出し連結する
    self.idx_list = \
      sum([list_each[ci][0:n_each] for ci in range(n_cls)], [ ] )

sum()関数は、イテレータ内の合計値を返す関数になります。

    def __getitem__(self, index_list):
      """画像を読み込む"""
      img = self.orig_dataset[self.idx_list[index]][0]
      return self.transform(img)

上記の関数で実際の画像を読み込みます。idx_listを介して引数indexより元データセットのインデックスへの変換を行います。その後、元データセットの画像にアクセスします。


次回

次回は、画像データセットのインスタンスを生成します。画像変換の設定を行います。

【GoogleColab】ニューラルネットワークの画像生成 その2【オートエンコーダ】


トラックバック用のURL
プロフィール

名前:イワサキ ユウタ 職業:システムエンジニア、ウェブマスター、フロントエンドエンジニア 誕生:1986年生まれ 出身:静岡県 特技:ウッドベース 略歴 20

最近の投稿
人気記事
カテゴリー
広告