備忘録です。DeZeroを使用して画像認識などをするときGPUを使用したいのでGoogle Colaboratoryを使用します。ただ、Google Colaboratoryは放っておくとセッションも切れてしまいますし、自分がチェックしたい画像を分類させるためにわざわざ学習から行うのも時間がかかってしまいます。学習済みのモデルは保存しておいていざ分類したいときはそのモデルを読み込むようにしたいです。今回はその方法をまとめておきます。
DeZeroのsave_weightsメソッド
こちらのメソッドはDeZeroのレイヤーを管理するクラスで実装されています。中身としてはnumpyのsavez_compressed()が呼び出され実行されます。
numpyのsavez_compressed()は1つのファイル(xxxx.npz)に、複数の配列を保存したり圧縮により、ファイルサイズを削減したりできるようです。
savez_compressed()はこちらに書かれている記事がとてもわかりやすかったです。
numpy.savez_compressed:複数のNumPy配列を圧縮&バイナリ保存 - Wizard Notes
メソッドの実装
実際に学習済みのモデルを保存するには下記のコードを追記すれば保存してくれます。
model.save_weights('ファイルのパス')
ファイル名を決めてそのパスを引数で渡します。
※modelはモデルのインスタンス変数です。
学習したモデルの読み込み
学習したモデルを簡単に読み込むには、自分でモデルを組むときにpretrainedというbooleanの変数を設定しておくと良いです。
例としては下記のような感じです。WEIGHTS_PATH に格納しているファイルのパスは上記の保存する時に使用したパスです。
__init__関数にある条件分岐でこのパスを読み込むかどうかを決めています。
class TestModel(Model):
WEIGHTS_PATH = "ファイルのパス"
def __init__(self, pretrained=False):
super().__init__()
self.conv1_1 = L.Conv2d(32, kernel_size=3, stride=1, pad=1)
self.conv1_2 = L.Conv2d(32, kernel_size=3, stride=1, pad=1)
self.conv2_1 = L.Conv2d(64, kernel_size=3, stride=1, pad=1)
self.conv2_2 = L.Conv2d(64, kernel_size=3, stride=1, pad=1)
self.conv3_1 = L.Conv2d(128, kernel_size=3, stride=1, pad=1)
self.conv3_2 = L.Conv2d(128, kernel_size=3, stride=1, pad=1)
self.conv4_1 = L.Conv2d(512, kernel_size=3, stride=1, pad=1)
self.conv4_2 = L.Conv2d(512, kernel_size=3, stride=1, pad=1)
self.fc5 = L.Linear(1024)
self.fc6 = L.Linear(6)
# ここで保存している学習済みのモデルを読み込むか決めている
if pretrained:
weights_path = TestModel.WEIGHTS_PATH
self.load_weights(weights_path)
def forward(self, x):
x = F.relu(self.conv1_1(x))
x = F.relu(self.conv1_2(x))
x = F.pooling(x, 2, 2)
x = F.relu(self.conv2_1(x))
x = F.relu(self.conv2_2(x))
x = F.pooling(x, 2, 2)
x = F.relu(self.conv3_1(x))
x = F.relu(self.conv3_2(x))
x = F.pooling(x, 2, 2)
x = F.relu(self.conv4_1(x))
x = F.relu(self.conv4_2(x))
x = F.pooling(x, 2, 2)
x = F.reshape(x, (x.shape[0], -1))
x = F.dropout(F.relu(self.fc5(x)))
x = self.fc6(x)
return x
@staticmethod
def preprocess(data, size=(224, 224), dtype=np.float32):
image = Image.open(data)
image = image.convert('RGB')
if size:
image = image.resize(size)
image = np.asarray(image, dtype=dtype)
image = image[:, :, ::-1]
image = image.transpose((2, 0, 1))
return image
このようにしてモデルのクラスを作成した場合、下記のように条件付けで簡単に学習済みのモデル、または、学習前のモデルインスタンスを生成できます。
# 学習済みモデルを使用しない場合(初回の学習時など)
model = TestModel(pretrained=False)
# 学習済みモデルを使用する場合(再度学習をさせる時や実際にモデルを使って予測をする場合)
model = TestModel(pretrained=True)