機械学習第11章
事前学習済みモデルの利用
ResNet-18とVGG-19-BNの二つのモデルを使ってCIFAR-10の学習を行う
ファインチューニング
事前学習済みモデルのパラメータを初期値としては利用しますが、全てのレイヤー関数で学習する手法
転移学習
事前学習済みモデルのパラメータのうち、入力に近い部分のレイヤー関数は全て固定し、出力に近い部分のみ学習する手法
一般的に学習データが大量にある場合はファインチューニング、少ない場合は転移学習が向いていると言われている
今回は、ファインチューニングを使う。
適合的平均プーリング関数(nn.AdaptiveAvgPool2d)
レイヤー関数
この関数の目的は画像の画素数によらず入力画像として受付可能なモデルを作ること
この関数で指定するパラメータは変換後の画素数
データ準備
code:python
# transformsの定義
# 学習データ用
transform_train = transforms.Compose([
transforms.Resize(112),
transforms.RandomHorizontalFlip(p=0.5),
transforms.ToTensor(),
transforms.Normalize(0.5, 0.5),
transforms.RandomErasing(p=0.5, scale=(0.02, 0.33), ratio=(0.3, 3.3), value=0, inplace=False)
])
# 検証データ用
transform = transforms.Compose([
transforms.Resize(112),
transforms.ToTensor(),
transforms.Normalize(0.5, 0.5)
])
resize呼び出しで画素数を変換している
code:python
# データ取得用関数 Dataset
data_root = './data'
train_set = datasets.CIFAR10(
root = data_root, train = True,
download = True, transform = transform_train)
# 検証データの取得
test_set = datasets.CIFAR10(
root = data_root, train = False,
download = True, transform = transform)
code:python
# バッチサイズ指定
batch_size = 50
# データローダー
# 訓練用データローダー
# 訓練用なので、シャッフルをかける
train_loader = DataLoader(train_set, batch_size=batch_size, shuffle=True)
# 検証用データローダー
# 検証時にシャッフルは不要
test_loader = DataLoader(test_set, batch_size=batch_size, shuffle=False)
GoogleColabのような環境では、巨大なニューラルネットワークで学習を進めるとGPUメモリが不足する
→バッチサイズを小さくする
ResNet-18の読み込み
code:python
# 必要ライブラリのロード
from torchvision import models
# 事前学習済みモデルのロード
# pretraind = True で学習済みパラメータも一緒に読み込む
net = models.resnet18(pretrained = True)
最終レイヤー関数の付け替え
事前学習モデルの出力が1000次元になっているため10種類の分類に変更する
code:python
# 乱数の初期化
torch_seed()
# 最終レイヤー関数の入力次元数を確認
fc_in_features = net.fc.in_features
# 最終レイヤー関数の付け替え
net.fc = nn.Linear(fc_in_features, n_output)
学習の初期設定
code:python
# 乱数の初期化
torch_seed()
# 事前学習済みモデルのロード
# pretraind = True で学習済みパラメータも一緒に読み込む
net = models.resnet18(pretrained = True)
# 最終レイヤー関数の入力次元数を確認
fc_in_features = net.fc.in_features
# 最終レイヤー関数の付け替え
net.fc = nn.Linear(fc_in_features, n_output)
# GPUの利用
net = net.to(device)
# 学習率
lr = 0.001
# 損失関数定義
criterion = nn.CrossEntropyLoss()
# 最適化関数定義
optimizer = optim.SGD(net.parameters(), lr=lr, momentum=0.9)
# historyファイル初期化する
history = np.zeros((0, 5))
学習
code:python
# 学習
num_epochs = 5
history = fit(net, optimizer, criterion, num_epochs,
train_loader, test_loader, device, history)
結果
精度:94%
VGG-19-BNの利用
モデルの読み込み
code:python
# 事前学習済みモデルの読み込み
from torchvision import models
net = models.vgg19_bn(pretrained = True)
最終レイヤー関数の付け替え
code:python
# 乱数の初期化
torch_seed()
# 最終レイヤー関数の付け替え
in_features = net.classifier6.in_features net.classifier6 = nn.Linear(in_features, n_output) # features最後のMaxPool2dをはずす
net.features = net.features:-1 # AdaptiveAvgPool2dをはずす
net.avgpool = nn.Identity()
結果
精度:95%