0

PyTorch: visualize trained filters and feature maps

I just wrote a simple code to visualize trained filters and feature maps of pytorch. For simplicity, the below code uses pretrained AlexNet but the code must work with any network with Conv2d layers.

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import os
from itertools import product
import numpy as np

import imageio

import torch
import torch.nn as nn
import torchvision.models as models
from torch.autograd import Variable

def visualize_conv_filters(net, dirname, dataname):
    dirname = os.path.join(dirname, dataname)
    if not os.path.exists(dirname):
        os.mkdir(dirname)

    index_conv = 0
    for module in net.modules():
        if isinstance(module, nn.Conv2d):
            filters = module.weight.detach().numpy()

            shape = filters.shape
            filters_tile = np.zeros((shape[0]*shape[2],
                                     shape[1]*shape[3]))

            for i, j in product(range(shape[0]), range(shape[1])):
                filters_tile[i*shape[2]:(i+1)*shape[2],
                             j*shape[3]:(j+1)*shape[3]] = filters[i, j, :, :]
            filename = '%s_conv%d.png' % (dataname, index_conv)
            imageio.imwrite(os.path.join(dirname, filename),
                            filters_tile)

            index_conv += 1

def visualize_feature_maps(net, dirname, dataname, x):
    dirname_root = os.path.join(dirname, dataname)
    if not os.path.exists(dirname_root):
        os.mkdir(dirname_root)

    net.eval()
    for index, layer in enumerate(list(net.features)):
        dirname = os.path.join(dirname_root, 'layer'+str(index))
        if not os.path.exists(dirname):
            os.mkdir(dirname)

        x = layer(x)
        feature = x.detach().numpy()<span id="mce_SELREST_start" style="overflow:hidden;line-height:0;"></span>
        for i in range(feature.shape[1]):
            filename = 'layer%d_feature%d.png' % (index, i)
            imageio.imwrite(os.path.join(dirname, filename),
                            feature[0, i, :, :])

if __name__ == '__main__':
    net = models.alexnet(pretrained=True)

    visualize_conv_filters(net, './data/alexnet', 'filters')

    x = Variable(torch.randn(1, 3, 224, 224))
    visualize_feature_maps(net, './data/alexnet', 'random', x)
Advertisements
0

PyTorch: fine-tune a pre-trained model

See the tutorial.

Important note:

  1. torchvision provides several pre-trained models with their trained parameters.
    1. AlexNet, DenseNet, Inception, ResNet, VGG are available, see here.
  2. With pretrained=True, pre-trained parameters are available.
  3. The pre-trained models are classified into two types:
    1. (feature, classifier) model (AlexNet, DenseNet, VGG)
      1. This model has two sub-networks, feature and classifier.
      2. Each sub-network is implemented as a torch.nn.Sequential object.
    2. (…, fc) model (Inception, ResNet)
      1. This model has several components and the final fully-connected layer, accessible by net.fc.
  4. To custom final fully connected layer(s),
    1. define a pre-trained model with pretrained=True
    2. set all fixed parameters untrainable
    3. change final fully connected layer(s)
    4. give optimizer only trainable parameters
import torch
import torch.nn as nn
import torch.optim as optim
import torchvision

if __name__ == '__main__':

    B = 4
    C = 3
    H = 224
    W = 224
    num_classes = 8
    x = torch.rand(B, C, H, W)
    y = torch.rand(B, num_classes)

    # load the pre-trained model
    net = torchvision.models.vgg16_bn(pretrained=True)

    print('#layers in vgg16.features:', len(net.features))
    print(net.features)
    print('#layers in vgg16.classifier:', len(net.classifier))
    print(net.classifier)

    # fix all pre-trained parameters
    for n, param in enumerate(net.features.parameters()):
        param.requires_grad = False

    # change last FC layer
    net.classifier[-1] = nn.Linear(in_features=net.classifier[-1].in_features,
                                   out_features=num_classes)
    for n, module in enumerate(net.classifier):
        print(n, module)

    # training settings
    criterion = nn.MSELoss()
    optimizer = optim.SGD(net.classifier.parameters(),
                          lr=0.001,
                          momentum=0.9)

    for epoch in range(100):
        optimizer.zero_grad()

        y_pred = net(x)
        loss = criterion(y_pred, y)
        loss.backward()
        optimizer.step()

        print('%d: %f' % (epoch, loss.item()))

    # test
    net.eval()
    y = torch.rand(B, num_classes)
    y_pred = net(x)
    print(y)
    print(y_pred)

Before FC layer customization:

0 Linear(in_features=25088, out_features=4096, bias=True)
1 ReLU(inplace)
2 Dropout(p=0.5)
3 Linear(in_features=4096, out_features=4096, bias=True)
4 ReLU(inplace)
5 Dropout(p=0.5)
6 Linear(in_features=4096, <strong>out_features=1000</strong>, bias=True)

After FC layer customization:

0 Linear(in_features=25088, out_features=4096, bias=True)
1 ReLU(inplace)
2 Dropout(p=0.5)
3 Linear(in_features=4096, out_features=4096, bias=True)
4 ReLU(inplace)
5 Dropout(p=0.5)
6 Linear(in_features=4096, <strong>out_features=8</strong>, bias=True)
0

PyTorch: at evaluation/test phase

I got a runtime error at evaluation phase of my simple siamese network as RuntimeError: cuda runtime error (2) : out of memory at the line of executing forward pass.

Some comments on stackoverflow suggests to define x and y with volatile=True as

for x, y in dataloader:
    x = torch.autograd.Variable(x.cuda(), volatile=True)
    y = torch.autograd.Variable(y.cuda(), volatile=True)
    y_pred = net(x)
    loss = criterion(y, y_pred)
    ...

The above code further outputs user warning as UserWarning: volatile was removed and now has no effect. Use `with torch.no_grad():` instead, so I uses torch.no_grad as

with torch.no_grad():
    for x, y in dataloader:
        y_pred = net(x)
        loss = criterion(y, y_pred)
        ...

Finally, with torch.no_grad(), runtime error doesn’t occur!

0

PyTorch: AutoGrad

See this tutorial.

Set requires_grad=True for all tensors we compute gradients w.r.t. them.

# input and output
x = torch.randn(N, D_in, device=device, dtype=dtype)
y = torch.randn(N, D_out, device=device, dtype=dtype)

# parameters to be estimated
w1 = torch.randn(D_in, H, device=device, dtype=dtype, requires_grad=True)
w2 = torch.randn(H, D_out, device=device, dtype=dtype, requires_grad=True)

learning_rate = 1e-6
for t in range(500):
    # forward process
    y_pred = x.mm(w1).clamp(min=0).mm(w2)

    # compute loss
    loss = (y_pred - y).pow(2).sum()

    # backward process
    loss.backward()

    # update the weights
    with torch.no_grad():
        w1 -= learning_rate * w1.grad
        w2 -= learning_rate * w2.grad

        w1.grad.zero_()
        w2.grad.zero_()
0

PyTorch: define a neural network

See the tutorial.
It’s quite simple (Keras provides simpler interface though).

A neural network is defined as a class that has a forward function. The forward function defines how input data is processed through the network. PyTorch automatically defines a corresponding backward process (maybe only when the forward process is differentiable).

From the tutorial, the class defines all layers in __init()__ and defines how input data processes in forward().

0

PyTorchで学ぶニューラルネットワークと深層学習

PyTorchで学ぶニューラルネットワークと深層学習
杜 世橋
Amazon Services International, Inc.

KerasからPyTorchに移行しようか迷っていたのでAmazon Unlimitedで利用.
公式チュートリアルで学ぶ前に色々知れたので良かった.
ただ,数の数え方が変態的で,「Nつ,100つ」といった表現が散見されて気持ち悪い.

内容紹介:
[概要]
深層学習、ディープラーニング、ニューラルネットワーク。これらの単語を聞いたことがあり、興味はあるけど難しい数式ばかりでどこから勉強すればいいかわからないということはないでしょうか?この本は深層学習やニューラルネットワークを学習し、実際に自分で動かしてみたいという読者を対象に、近年急速に注目されているPyTorchという非常にシンプルで分かりやすいPythonのライブラリを用いて初心者でも分かりやすく解説した本です。高度な理論や数式の説明は最小限にとどめ、できるだけ例題ベースで実際に動くソースコードを書いていき、実践してから理解するスタイルを心がけています。この本では基本的な線形モデルからスタートし、多層パーセプトロンまで理解した後に様々な応用を紹介します。主な応用としては画像処理と自然言語処理を取り扱います。画像分野では畳み込みニューラルネットワークを用いて単純な画像の識別や粗い画像の高解像度化、GANによる画像生成などを作っていきます。自然言語分野では再帰ニューラルネットワークを用いて文章の識別、生成、そして翻訳のプログラムを作っていきます。また、これらのよくある応用分野ほのかにニューラルネットワークを使用した推薦エンジンやWebAPIの作り方、DockerやONNXを利用したアプリケーションのデプロイなど、ニューラルネットワークと深層学習を実際にプロダクトで使用するための方法についても触れています。

[対象者と目的]
本書はこれからニューラルネットワークや深層学習を学習し、実際に何らかのプロダクトやサービスで使用して見たいというエンジニアや大学生などを対象に、数式を極力使用せずに実例ベースで深層学習がどのように利用できるのか、どうアプリケーションを作るのかを説明し、実際に深層学習を使用するための最初の取っ掛かりになれることを目指しています。

[PyTorch]
PyTorchはFacebook社のメンバーが中心となって開発しているオープンソースの深層学習フレームワークです。老舗フレームワークのTorchを流れをくみ、比較的新しいフレームワークですが信頼性も高いといえます。他のフレームワークでよくあるシンボルを使用したスタイルとは異なり、PyTorchは動的ネットワーク方式を採用していて通常のPythonの関数と同じようにニューラルネットワークを組み立てて計算を行うことができます。そのため近年では研究者やエンジニアを中心に急速に支持を集めている注目のフレームワークです。

[目録]
はじめに
本書の対象と必要な事前知識
本書の構成
環境構築
第1章 PyTorchの基本
1.1 PyTorchの構成
1.2 Tensor
1.3 Variableと自動微分
まとめ
第2章 最尤推定と線形モデル
2.1 確率モデルと最尤推定
2.2 確率的勾配降下法
2.3 線形回帰モデル
2.4 ロジスティック回帰
まとめ
第3章 多層パーセプトロン
3.1 MLPの構築と学習
3.2 DatasetとDataLoader
3.3 学習効率化のTips
3.4 ネットワークのモジュール化
まとめ
第4章 画像処理と畳込みニューラルネット
4.1 画像と畳込み計算
4.2 CNNによる画像分類
4.3 転移学習
4.4 CNN回帰モデルによる画像の高解像度化
4.5 DCGANによる画像生成
まとめ
第5章 自然言語処理と回帰型ニューラルネット
5.1 RNNとは
5.2 テキストデータの数値化
5.3 RNNと文章のクラス分類
5.4 RNNによる文章生成
5.5 Encoder-Decoderモデルによる機械翻訳
まとめ
第6章 推薦システムと行列分解
6.1 行列因子分解
6.2 ニューラル行列因子分解
まとめ
第7章 アプリケーションへの組み込み
7.1 モデルの保存と読み込み
7.2 Flaskを用いたWebAPI化
7.3 Dockerを利用したデプロイ
7.4 ONNXを使用した他のフレームワークとの連携
まとめ
付録
TensorBoardによる可視化
(Amazonより)