投稿日:
【GoogleColab】ニューラルネットワークの画像生成 その2【オートエンコーダ】
前回に続き、GoogleColabで画像を生成するニューラルネットワークのプログラムを実行します。画像データセットのインスタンスを生成して画像変換を行います。
オートエンコーダーの画像生成のデータセット完了
前回、オートエンコーダーで画像生成をする前準備として、学習データ(画像)の取得・準備を行いました。
前回までの作成プログラム
①PyTorchをインポートし、学習データMINISTを取得します。
→学習データ(画像)の取得
②読み込んだ学習データMINISTを表示して確認します。
→データセットの画像確認
③学習用データセットのクラスを作成します。
→学習用データセットの準備
必要なもの
必要なものはWindowsあるいはMacPCのみです。ただし、GoogleChoromeをインストールしている必要があります。GoogleColabを使うには、以下のステップが必要です。
①Googleアカウントを用意してログインする。
②Colabにアクセスし、プログラムを書き込むノートブックを作成する。
実行環境の準備
①Colabにアクセスします。
②左上の「ドライブにアクセス」をクリックします。
③「その他」の「アプリを追加」から「Colaboratory」をインストールします。
④ノートブックをひらけばpythonのコードが記述できます。
DataSubsetのインスタンス準備
DataSubsetのインスタンスを生成し、画像などの設定を行います。
IMG_MEAN, IMG_STD = (0.5, 0.5) trans = transforms.Compose([ transforms.Resize(64), transforms.ToTensor(), transforms.Normalize((IMG_MEAN,),(IMG_STD,)) ]) use_classes = [1,6,9] for c in use_classes: print(fmnist.classes) # FashionMNISTのラベルなしサブセットを用意 dataset = DataSubset(orig_dataset=fmnist, n_each = 200, #各クラス何枚用いるか use_classes = [1,6,9], #加えるクラス transform = trans #画像読み込み変換 ) print('dataset size:', len(dataset))
出力結果:
Trouser Shirt Ankle boot dataset size: 600
解説
trans = transforms.Compose([ transforms.Resize(64), transforms.ToTensor(), transforms.Normalize((IMG_MEAN,),(IMG_STD,)) ])
一連の画像処理を設定します。元は解像度が28×28ピクセルの画像ですが、「transforms.Resize(64)」で64×64に拡大しています。
# FashionMNISTのラベルなしサブセットを用意 dataset = DataSubset(orig_dataset=fmnist, n_each = 200, #各クラス何枚用いるか use_classes = [1,6,9], #加えるクラス transform = trans #画像読み込み変換 )
DataSubsetのインスタンスを生成します。DataSubsetクラスの「__init()__」にまず値を渡します。
orig_datasetで元のデータを渡しています。
n_eachで指定した枚数だけ取り出します。
use_classesで、「shirt」(シャツ)「Trouser」(ズボン)「Ankleboot」(ブーツ)の3クラスを指定します。(元々は10クラスあります。)
transformに、読み込みたい画像処理を指定します。
DataLoaderの設定
ニューラルネットワークの学習では、画像を入力しながらパラメーターを更新して学習を進めます。実際は1枚ずつ画像を入力するのではなく、ある程度の枚数をまとめて入力します。この画像集合体の1つの単位を「ミニバッチ」と呼びます。その枚数を「バッチサイズ」
batch_size = 32 #バッチサイズ loader = torch.utils.data.DataLoader( dataset, batch_size = batch_size, shuffle=True) def tensor_imshow(img, title = None, show=True): """Tensorを画像として表示""" img = img.numpy().transpose((1,2,0)) img = IMG_STD * img + IMG_MEAN plt.imshow(np.clip(img, 0, 1)) if title is not None: plt.title(title) if show: plt.show() #ミニバッチの表示 tensor_imshow(torchvision.utils.make_grid( next(iter(loader)) ))
表示結果:
解説
batch_size = 32 #バッチサイズ loader = torch.utils.data.DataLoader( dataset, batch_size = batch_size, shuffle=True)
データからミニバッチを読み込むためのクラスです。
- 第一引数・・・どのデータから読み込むかを指定します。
- 第二引数・・・バッチサイズを指定します。ここでは32を指定します。一度にbatch_size分だけ読み込みます。
- 第三引数・・・この引数をTrueにすると、データセット順に読み込むのではなく、ランダムに読み込みます。
def tensor_imshow(img, title = None, show=True): """Tensorを画像として表示""" img = img.numpy().transpose((1,2,0)) img = IMG_STD * img + IMG_MEAN plt.imshow(np.clip(img, 0, 1)) if title is not None: plt.title(title) if show: plt.show()
ミニバッチを1回読み込んで、画像を表示させてみます。TensorをNumpyのarrayに変換し、さらに画像として表示するための関数ternsor_imshow()を用意しておきます。
#ミニバッチの表示 tensor_imshow(torchvision.utils.make_grid( next(iter(loader)) ))
「next(iter(loader))」は、loaderをいったんイテレーターにします。その上でミニバッチを1つ読み込んでいます。これは32枚の画像ですので、torchvision.utils.make_grid()を用いでグリッド状に並べます。
ニューラルネットの準備
入力層から潜在変数へ変換するためのネットワークを「エンコーダー」と呼び、潜在変数から出力層までのネットワークを「デコーダー」と呼びます。
class Autoencoder(nn.Module): """"エンコーダー、デコーダー共に3層""" def __init__(self,img_size, nz): super(Autoencoder, self).__init__() input_size = img_size * img_size nz1 = input_size // 4 nz2 = nz1 // 4 self.encorder = nn.Sequential( nn.Linear(input_size, nz1), nn.ReLU(inplasce=True), nn.Linear(nz1,nz2), nn.ReLU(inplasce=True), nn.Linear(nz2,nz), ) self.dencorder = nn.Sequential( nn.Linear(nz, nz2), nn.ReLU(inplasce=True), nn.Linear(nz2,nz1), nn.ReLU(inplasce=True), nn.Linear(nz1,input_size), ) def forward(self, x): z=self.encoder(x) x=self.decoder(z) return x class LinearAE(nn.Module): """エンコーダー、デコーダー共に1層""" def __init__(self,img_size, nz): super(LinearAE, self).__init__() self.encorder = nn.Linear(img_size * img_size, nz) self.dencorder = nn.Linear(nz, img_size * img_size) def forward(self, x): z=self.encoder(x) x=self.decoder(z) return x
解説
input_size = img_size * img_size nz1 = input_size // 4 nz2 = nz1 // 4
入力層および中間層の次元を設定しています。入力層は、64×64ピクセルの画像を1次元にしているため、4096次元になります。1つ目の中間層はその1/4、その次の中間層はさらに1/4とします。真ん中の中間層は、引数をnzで指定した次元数とします(後でnz=2)。
self.encorder = nn.Sequential( nn.Linear(input_size, nz1), nn.ReLU(inplasce=True), nn.Linear(nz1,nz2), nn.ReLU(inplasce=True), nn.Linear(nz2,nz), )
エンコーダーの定義です。
self.dencorder = nn.Sequential( nn.Linear(nz, nz2), nn.ReLU(inplasce=True), nn.Linear(nz2,nz1), nn.ReLU(inplasce=True), nn.Linear(nz1,input_size), )
デコーダーの定義です。
class LinearAE(nn.Module): """エンコーダー、デコーダー共に1層""" def __init__(self,img_size, nz): super(LinearAE, self).__init__() self.encorder = nn.Linear(img_size * img_size, nz) self.dencorder = nn.Linear(nz, img_size * img_size) def forward(self, x): z=self.encoder(x) x=self.decoder(z) return x
性能比較のため、エンコーダーとデコーダーを共に線形としたオートエンコーダをLinearAEとして定義しています。層の間に非線形な活性関数を挟まない場合、多層にしても表現能力は向上しません。そのため、ここではエンコーダーデコーダー共に1層です。
結果表示用の関数
def input_add_reconst(net, loader, seed = None): """入力画像と再構成画像をミニバッチ分表示""" if seed is not None: torch.manual_seed(seed) net.eval() #推論モード with torch.no_grad(): #推論のみ(勾配計算なし) imgs = next(iter(loader)) #DataLoaderからミニバッチ抽出 imgs_in = imgs.view(-1, imgs.shape[2]*imgs.shape[3]) outputs = net(imgs_in.to(device)) #順伝播による推論 #入出力それぞれのグリッド画像を生成 grid_i = torchvision.utils.make_grid(imgs) grid_o = torchvision.utils.make_grid( outputs.view(-1, 1, imgs.shape[2], imgs.shape[3]). \ detach().cpu() ) #入力画像と再構成画像をミニバッチ単位で表示 tensor_imshow(grid_i, title = 'Inputs' ) tensor_imshow(grid_o, title = 'Reconstructed' )
解説
結果表示用の関数input_and_reconst()を用意しておきます。この関数では、引数で与えたオートエンコーダーをを使ってloaderのミニバッチをそれぞれエンコードし、再びデコードします。これによって再構成された画像を、入力画像と共に表示します。
元の画像をもとに戻す場合は、「生成」よりむしろ「再構成(復元)」(reconstruction)と呼びます。
次回
工事中。
- Python 111
- 制作 54
- RaspberryPi 41
- WordPress 40
- Django 40
- Linux 26
- VPS 22
- PHP 20
- JavaScript 20
- HTML・CSS 19
- AWS 16
- 仮想環境 15
- レスポンシブデザイン 13
- WEB全般 11
- マイコン 9
- Webサービス 8
- 動画製作 8
- 統合開発環境 8
- 起業・設立 7
- jQuery 7
- 機械学習 7
- PyCharm 7
- SEO 6
- pydata 6
- C# 6
- AfterEffects 6
- 携帯サイト 5
- heroku 5
- デザイン 5
- Mac 5
- Visual Studio 5
- 数学 5
- Anaconda 5
- Django REST framework 5
- symfony 4
- node.js 4
- Nginx 4
- illustrator 4
- インフラ 4
- Jupyter Notebook 4
- ツール 3
- データベース 3
- facebook 3
- Go言語 3
- PC 3
- Docker 3
- 作業効率化 3
- Webスクレイピング 3
- photoshop 3
- Cloud9 3
- Google Colaboratory 3
- Webサーバー 2
- movie 2
- ネットワーク 2
- Java 2
- ドローン 2
- コンテナ 2
- Kali Linux 2
- コマンド 2
- XSERVER 2
- MariaDB 2
- 音楽 2
- PCDJ 2
- DaVinci Resolve 2
- 知識 1
- アフィリエイトノウハウ 1
- スマートフォン 1
- アクセス解析 1
- windows 1
- 役立つ本・書籍 1
- git 1
- アニメ 1
- Rhino 1
- D3.js 1
- アニメーション 1
- TypeScript 1
- データサイエンス 1
- AI 1
- ownCloud 1
- ESP32 1
- API 1
- ネットワーク 1
- ムームードメイン 1
- S3 1
- JSON 1
- Bootstrap 1
- SSL 1
- バージョン管理システム 1
- Ansible 1