밑바닥부터 시작하는 딥러닝(사이토 고키)라는 책을 읽으면서 딥러닝을 다시 공부해보고 있습니다.
오늘의 배운 것
numpy 객체를 저장하는데에 특화된 함수 np.save_compressed 가 있다. 파이썬 객체를 저장하는데 주로 쓰는 pickle도 있지만, npz 파일이 훨씬 빠르다고 한다. 링크
해본 것
오늘은 학습한 모델의 weight를 저장하고 불러오는 것을 구현하였다.
저장하는 부분의 코드이다. Affine, Convolution 계층의 weight 뿐만 아니라 BatchNormalization 계층의 이동평균, 이동분산 또한 저장하였다.
각 레이어 클레스의 정보는 jsonpickle이라는 패키지를 사용해서 직렬화/역직렬화를 구현하였다.
def save_model(self, path=None):
save_data = OrderedDict()
params = self.params
save_data["NetConfig"] = {
"weight_decay_lambda": self.weight_decay_lambda,
"is_use_dropout": self.is_use_dropout,
"dropout_ratio": self.dropout_ratio
}
layer_info = []
for layer in self.added_layer_list:
s = jsp.encode(layer)
layer_info.append(s)
save_data["LayerInfo"] = layer_info
for layer_idx, layer in enumerate(self.layers):
if isinstance(layer, Layer.BatchNormalization):
params[f"BN_m{layer_idx}"] = layer.running_mean
params[f"BN_v{layer_idx}"] = layer.running_var
save_data["Params"] = params
if path is None:
path = f"train_weight_{str(datetime.datetime.now())[:-7].replace(':', '')}.npz"
np.savez_compressed(path, **save_data)
print(f"Weight was saved at {path}")
모델을 로딩하는 부분의 코드이다.
def load_model(self, path):
print(f"Loading Model... {path}")
load_data = np.load(path, allow_pickle=True)
other_config_data = dict(load_data.get("NetConfig").item())
self.__init__(**other_config_data)
layer_info = load_data.get("LayerInfo")
for layer_encoded in layer_info:
layer = jsp.decode(layer_encoded)
self.add_layer(layer)
self.params = load_data.get("Params").item()
for param_name, param_value in self.params.items():
layer_idx = int(re.findall(r'[0-9]+', param_name)[0])
param_kind = re.sub(r'[0-9]+', '', param_name)
target_layer = list(self.layers.items())[layer_idx][1]
if param_kind == "W":
target_layer.W = param_value
elif param_kind == "b":
target_layer.b = param_value
elif param_kind == "BN_m":
target_layer.running_mean = param_value
elif param_kind == "BN_v":
target_layer.running_var = param_value
이제 다른 파일에서 npz 파일을 로딩해 숫자 예측을 해보았다.
from framework.network import MultiLayerNet
import random
from dataset.mnist import load_mnist
import numpy as np
import matplotlib.pyplot as plt
(x_train, t_train), (x_test, t_test) = load_mnist(flatten=False)
net = MultiLayerNet()
net.load_model("train_weight_2021-04-10 170307.npz")
for i in range(5):
img_idx = random.randrange(0, 10000)
plt.imshow(x_test[img_idx].reshape(28, 28), cmap='gray')
plt.show()
predict_num = np.argmax(net.predict(np.array([x_test[img_idx]]), train_flg=False), axis=1)[0]
correct_num = t_test[img_idx]
print(f"Predict : {predict_num}, Correct : {correct_num}")


잘 예측하는 것 같다!
실습한 코드는 https://github.com/woduq1414/deep-learning-without-tensorflow 에 있습니다.
